- agy 카탈로그 이중 결함(탭 파서 5afd92f8 + SystemRoot 백필 6369f294) 수정 후
공개 런타임 6369f294 승격: capabilities 14모델·실생 터 응답·비용 계약 통과
- 워치독(install-public-runtime-task)·부트(register-boot-task) 태스크 모두 새 루트 재핀,
부트만 갱신 시 구 루트 워치독 되살림 경합 발생함을 기록
- 대시보드 210차 노트, SSOT 체커 59 PASS
공개 런타임 승격 체인이 psutil로 이전 프로세스 환경을 통째로 이식하는 과정에서
SystemRoot 가 유실됐고, Go 계열 CLI(agy)는 시스템 인증서 풀/홈 해석에 SystemRoot 가
필요해 agy models 가 조용히 빈 목록을 반환했다(관리자 AI 운영 화면의
'Agy가 선택 가능한 모델을 반환하지 않았습니다' 두 번째 원인).
- _cli_subprocess_env(): 상속 환경에서 빠진 SystemRoot/SystemDrive/ComSpec 만
기본값으로 백필해 모든 CLI 스폰(_run_process·codex app-server·agy stream·claude 세션)에 적용.
os.environ 의 Windows 대문자 정규화를 고려한 대소문자 무시 조회
- Set-CompleteProcessEnvironment: 이식본에 빠진 Windows 필수 키를 Machine 스코프
표준값으로 병합해 승격 체인 자체의 유실을 원천 보강
- 검증: 신규 2단위 RED→GREEN, engine_gateway 65 passed, app 924 passed,
PS 5.1 parser OK, SystemRoot 제거 환경에서 실제 agy CLI 14모델 live 조회 확인
agy CLI가 2026-08부터 'agy models'를 'model_id<TAB>라벨' 형태로 출력하는데
_discover_agy_cli가 공백 포함 줄을 전부 버려 카탈로그가 비어 available=false가 됐다
(관리자 AI 운영 화면에서 'Agy가 선택 가능한 모델을 반환하지 않았습니다').
- 탭 줄은 왼쪽 토큰을 id로, CLI 라벨을 우선 적용. 탭 없는 공백 줄(상태 문구)은 계속 무시하고
구형 베어 id 출력 계약 유지 — 형식 이중 호환
- _binary가 PATH에 없어도 LOCALAPPDATA agy bin 표준 설치 경로를 폴백으로 탐색
- 검증: 신규 탭 형식 회귀 RED→GREEN, engine_gateway 63 passed, 실제 agy CLI로
15모델 live 조회 확인(default gemini-3.6-flash-high)
- Cloudflare Pages production 4edc02d3(clean cf899b7f, 빌드×2 결정성 599파일):
7개 origin 143자산 보존(최종 742파일), 커스텀 도메인 새 엔트리 index-BWxBaCPM.js 서빙,
직전 엔트리 자산 200 보존 확인
- NAS 엔진 릴레이: start-nas-preview-engine.ps1 -CheckOnly 프리플라이트 통과
(4종 SHA pin + LAN 192.168.0.223:9100, mutation=false, NAS 무접촉). 실제 1회 시작은
엔진 구독 한도 리셋(15:00) 뒤 15:05 자동화가 직렬 게이트 재검증과 함께 수행
- HANDOFF 2026-08-18 절 직렬 게이트 삼각화·배포·릴레이 항 추가, 대시보드 209차 노트,
SSOT 체커 59 PASS
- 지원 티켓 작성 UI 신설(설정)·관리자 해결 노트 입력 신설(Admin): 서버 계약은 있었으나
웹 진입점이 없던 2결함
- a11y: outline 채널 포커스 링(ui/shell css), 세션바 44px 터치 타깃, 청록 하드코딩
그라디언트를 테마 토큰으로 교체, 설정 라벨/헤딩/대비·리뷰 44px·모바일 오버플로 수정
- uc-*.spec.ts 16테마 239 시나리오 신규(수집 1109 tests/61 files), 기존 스펙 5종 계약 드리프트 교정
- breakpoint-sweep: widthsFor 솎아내기가 실기기 대표 폭(360/390/1024)을 탈락시키는 테스트 결함 수정
— keep 시드를 전체 DEVICE_WIDTHS로, 3연폭 예외는 솎아내기 발생 여부 기준으로
- 검증: tsc PASS, 병렬 게이트 1040 passed(데스크톱 밀도 충돌 1건 해소 후 focused 68/68 GREEN),
직렬 게이트 52/5/4 삼각화 — breakpoint(테스트 결함)·kb(낡은 dev API 재기동)·voice(일시적) 해소,
교사 재평가 2건은 엔진 구독 한도(resets 3pm)로 skip 후 재검증 대기
- 문서/SSOT: HANDOFF·TODO·대시보드·testing 가이드 동기화, 증거 usecase-tdd-2026-08-18.json,
SSOT 체커 PASS(59)
PATH 탐색에 기대면 작업 스케줄러 컨텍스트의 PATH가 로그온 세션과 다를 때
powershell.exe를 찾지 못하고, 그 경우 워치독은 로그 한 줄 없이 실패만 남긴다.
%SystemRoot%\System32\WindowsPowerShell\v1.0\powershell.exe로 고정한다.
재부팅 뒤 워치독이 5분마다 콘솔 창에 실패만 뿌리던 문제의 원인 세 가지를 고친다.
- 워치독이 DB 다운을 감지하고 직접 복구한다. postgres(vignette-dev-db) 기동은
boot 담당이라 start-public-runtime.ps1 재호출로는 절대 복구되지 않았고, 그 결과
워치독은 고칠 수 없는 대상에 start를 무한 재시도하며 실패만 기록했다. db를
health check 항목에 넣고, 재시작 전에 컨테이너를 되살리며, 복구 실패 시에는
runtime 재시작을 시도하지 않고 종료한다.
- 작업 액션을 wscript 런처(watch-public-runtime-task.vbs) 경유로 등록한다.
powershell.exe를 직접 등록하면 -WindowStyle Hidden이어도 conhost 창이 매 실행
번쩍이고, 5분 주기에서는 그것이 곧 화면을 가리는 창이 된다. 런처는 pin 인자를
해석하지 않고 전달만 하며 provenance 검증은 기존대로 watchdog이 수행한다.
- boot이 web preview 상태를 보고 -SkipWebRestart를 조건부로 붙인다. 무조건 스킵하면
재부팅 직후처럼 vite가 죽은 상태에서 boot 경로로는 web이 영영 복구되지 않았다.
hidden trigger는 액션이 wscript 런처를 거치는지 함께 검증하도록 맞췄다.
pre 게이트 카드가 행 높이만큼 늘어나면서 base flex의 align-items:center가
살아남아 3축 블록이 1fr 행 한가운데 떠 있었다. 1920x1080에서 카드의 66.5%가
빈 공간이고 축 위아래로 각 277px의 죽은 여백이 생겼다. 척도 라벨은 0.54rem에
nowrap+ellipsis라 901~1279px에서 최대 12개가 잘렸고, 620px 이하에서는 15개
전부 display:none으로 사라져 숫자만 남았다. 320x568에서는 접힌 mid 전용 40px
고정 행이 게이트에도 걸려 카드가 눌리고 헤더와 축이 겹쳤다.
- 게이트 카드는 align-self:center + max-height:100% + 내부 스크롤로 중앙에 서고
높이는 내용이 정한다
- 3열 격자를 축별 세로 스택(질문 한 줄 + 전폭 5칸 척도)으로 바꿔 어느 폭에서도
라벨을 자르거나 숨기지 않는다. word-break:keep-all + overflow-wrap:normal로
어절 경계에서만 줄바꿈한다
- 정보가 없던 3 AXES 배지를 제출 버튼이 왜 잠겨 있는지 답하는 0/3 진행 표시로
교체한다
- 40px 고정 행 규칙을 :not(.sx-alliance-gated)로 접힌 mid 전용으로 되돌린다
- 선택 상태 글자색을 반투명 --surface에서 --text-on-accent로 고친다
시간 만료 상태에서 드러난 네 결함도 함께 닫는다. sx-timebar와 종료 모달 패널은
다크 stage 팔레트 시절 잔재로, 정의된 적 없는 --bg-panel의 하드코딩 다크 폴백
위에 테마 토큰 글자를 얹어 라이트에서 대비가 1.13:1까지 떨어졌다. 의미색 토큰과
불투명 표면으로 되돌렸다. sx-page--active > * 의 position:relative가 같은
특이도로 뒤에 있어 종료 모달의 fixed를 덮어써 오버레이가 1532x32px 띠로 눌렸고,
게이트 행 정의는 :has() 두 개짜리 규칙보다 특이도가 낮아 시간 만료 바가 뜨면
밀려나 빈 트랙이 남았다. 둘 다 선택자를 맞춰 정정했다.
계측: 빈 공간 0.665→0.127, 라벨 잘림 12→0, 숨김 15→0, 최소 탭 46x60,
가로 오버플로 0. 배너 대비 1.13→13.88, 모달 제목 2.68→15.79(다크 13.86/15.18).
검증: typecheck, session-layout+alliance-pulse+layout-visual-gate 31/31,
시간만료 종료 다이얼로그 2/2, pre/mid 잠금 2/2, full-sweep+self-directed 30 pass.
남은 음성 4건은 baseline에서도 동일 실패하는 기존 회귀다.