diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..dfdb8b7 --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +*.sh text eol=lf diff --git a/docs/HANDOFF.md b/docs/HANDOFF.md index a670206..d37f6c8 100644 --- a/docs/HANDOFF.md +++ b/docs/HANDOFF.md @@ -51,13 +51,14 @@ G8 배포 source 기준선은 branch `master`, HEAD `61a41d1f08239b5f9e99cfae42a NAS 설정·컨테이너·DB는 건드리지 않았다. 다음 mutation은 소유자 승인 뒤 단일 owner가 check-only→actual 1회→ NAS health/auth/OpenAPI/assets/실회기 재검증 순서로만 수행한다. - 마지막 full disposable GREEN은 clean `64e1b221…`의 `periodic-learner-e2e-20260812-150209.json`·SHA-256 - `a7b2f758…8071`이다. detached-clean `94666192…` 확인은 전용 engine ready 뒤 disposable DB init health에서 - 브라우저 전에 FAILED했고 receipt `periodic-learner-e2e-20260812-155929.json`·SHA-256 `1bd95e01…52a8`에 - public/NAS/active DB 접촉 0과 cleanup 0을 남겼다. 같은 heartbeat에서는 재시도하지 않았다. -- 현재 공유 worktree에는 이 실패의 cleanup 전 `compose ps`·db/api 로그를 secret/email/UUID/query-safe tail로 - 영수증에 고정하는 runner 보강과, 실제 NAS 390px에서 남은 10px 로그인 overflow를 block auto-size로 고치는 - scoped source가 있다. contract 14/14, 학생 route-fixture desktop/mobile 76/76, auth 2/2, dashboard 10/10, - type/API contract와 SSOT checker는 GREEN이지만 아직 commit/deploy/full run 전이다. + `a7b2f758…8071`이다. 새 진단과 NAS 로그인 폭 보정을 commit `f97e7fad…`·tree `bdc83f24…`로 고정한 뒤 + full run을 1회 실행했지만 detached checkout의 `infra/db/init/99_app_role.sh`가 CRLF가 돼 + `#!/usr/bin/env bash\r` exit 127로 DB가 재시작했다. receipt `periodic-learner-e2e-20260812-163742.json`· + SHA-256 `ad403712…d840f`은 브라우저 전 FAILED, public/NAS/active DB 접촉 0과 cleanup 잔여 0을 증명한다. +- 원인은 Git blob LF와 `core.autocrlf=true` detached worktree 사이의 checkout 계약 누락으로 확정했다. + 저장소 `.gitattributes`에 `*.sh text eol=lf`를 추가했으며, 같은 장애가 두 번째라 이번 heartbeat에서는 + full runner를 재실행하지 않는다. 다음 gate는 이 수정의 새 commit→새 detached checkout에서 CR 0 확인→ + preflight→single full run이다. auth overflow 수정도 아직 공개/NAS에 배포하지 않았다. - 마지막 완료 작업은 G8 source HEAD `61a41d1f…6af`·tree `87dec55d…3b77`·archive `4d15d055…119d4d`의 candidate 112/112와 actual NAS-origin 112/112다. API/Web `d5021950…e4b1`/`9796c092…4b36`, health ok·db/engine true·auth 401·OpenAPI 126, fresh dump `36ec8748…24db8`을 확인했다. @@ -714,7 +715,7 @@ route fixture는 90건이므로 전체 숫자를 실제 회기 폐루프로 부 검증한 뒤 sentinel resource·PID·listener·temp 잔여 0을 영수증으로 남긴다. 공개 8001/55432/9099와 NAS는 금지다. 최초 세 full run은 SSE body replay, durable turn 전 종료, 비종료 SSE `response.finished()` 대기를 차례로 찾아 모두 fail-closed했다. 4차 clean run은 reload 뒤 persisted episode를 `학습자만 실행`으로 표시하는 제품 결함을 검출했다. -5·6차 clean run은 핵심 동일 학습자 SSE·review·G4/G5 `0→1→1`을 연속 통과했지만 fixture 공유와 mobile success-state locator를 각각 fail-closed했다. 7차 clean `aa81af29…`는 첫 전체 GREEN을 만들었고 최신 full GREEN은 clean `64e1b221…`의 `periodic-learner-e2e-20260812-150209.json`·SHA-256 `a7b2f758…8071`이다. current `94666192…` 단일 run은 disposable DB init health에서 브라우저 전에 FAILED했으며 receipt `periodic-learner-e2e-20260812-155929.json`·SHA-256 `1bd95e01…52a8`은 public/NAS/active DB 접촉 0·cleanup 0을 증명한다. 당시 cleanup 전 로그가 없어 exact init 원인은 미확정이다. runner는 이제 `compose ps`와 db/api log tail을 secret/PII-safe로 영수증에 남기고 unit 14/14를 통과한다. current source는 새 clean commit 뒤 single full run GREEN 전까지 완료로 부르지 않는다. heartbeat는 최신 GREEN이 6시간 이상 오래됐거나 material milestone이 바뀐 경우에만 preflight 뒤 full runner를 최대 1회 실행하고 실패 시 자동 재시도하지 않는다. +5·6차 clean run은 핵심 동일 학습자 SSE·review·G4/G5 `0→1→1`을 연속 통과했지만 fixture 공유와 mobile success-state locator를 각각 fail-closed했다. 7차 clean `aa81af29…`는 첫 전체 GREEN을 만들었고 최신 full GREEN은 clean `64e1b221…`의 `periodic-learner-e2e-20260812-150209.json`·SHA-256 `a7b2f758…8071`이다. `94666192…` 단일 run은 disposable DB init health에서 브라우저 전에 FAILED했고 진단 보강 뒤 `f97e7fad…` 단일 run도 같은 단계에서 멈췄다. 두 번째 receipt `periodic-learner-e2e-20260812-163742.json`·SHA-256 `ad403712…d840f`의 cleanup 전 로그가 `99_app_role.sh`의 `#!/usr/bin/env bash\r` exit 127을 확정했다. 두 실행 모두 public/NAS/active DB 접촉 0·cleanup 0이다. Git blob은 LF지만 `core.autocrlf=true`의 새 worktree가 CRLF로 바꾼 것이 원인이므로 `.gitattributes`에 `*.sh text eol=lf`를 고정했다. 같은 장애가 두 번 반복돼 이번 heartbeat에서는 재시도하지 않으며, 새 clean commit/worktree의 CR 0을 확인한 다음 single full run GREEN 전까지 current source를 완료로 부르지 않는다. ## 9. 핵심 변경 파일 diff --git a/docs/TODO.md b/docs/TODO.md index cda9834..a7e3dba 100644 --- a/docs/TODO.md +++ b/docs/TODO.md @@ -166,7 +166,7 @@ > 6.3분 안에 동일 학습자 SSE·review ready·G4 원장 0→1까지 통과한 뒤, full reload가 persisted episode를 화면에 hydrate하지 > 못해 이미 기록된 상태를 `학습자만 실행`으로 되돌리는 제품 결함을 잡았다. 네 번 모두 public/NAS/active DB 접촉 0·자원 잔여 0이다. > 현재 UI는 현재 session+prescription의 persisted episode를 `현재 원장 상태`로 복원하며 route fixture desktop/mobile 6/6을 통과했다. -> 5·6차 clean run은 핵심 동일 학습자 SSE·review·G4/G5 `0→1→1`을 연속 통과했지만 fixture 공유와 mobile success-state locator를 각각 fail-closed했다. 보정 후 7차 clean `aa81af29…`는 same-learner SSE·review·G4/G5 `0→1→1`, 별도 zero-state returned desktop/mobile 4/4, route mock 0과 exact cleanup 0으로 첫 전체 GREEN을 만들었다. 최신 full GREEN은 clean `64e1b221…`의 `periodic-learner-e2e-20260812-150209.json`·SHA-256 `a7b2f758…8071`이다. current `94666192…` 단일 run은 disposable DB init health에서 브라우저 전에 FAILED했지만 public/NAS/active DB 접촉 0·exact cleanup 0을 유지했다. cleanup 전에 진단 로그를 보존하지 못한 공백은 secret/PII-safe `compose ps`·db/api tail receipt와 unit 14/14로 닫았다. current source는 clean commit 뒤 single full run이 GREEN이기 전까지 완료로 부르지 않으며, 실패한 heartbeat에서는 재시도하지 않는다. +> 5·6차 clean run은 핵심 동일 학습자 SSE·review·G4/G5 `0→1→1`을 연속 통과했지만 fixture 공유와 mobile success-state locator를 각각 fail-closed했다. 보정 후 7차 clean `aa81af29…`는 same-learner SSE·review·G4/G5 `0→1→1`, 별도 zero-state returned desktop/mobile 4/4, route mock 0과 exact cleanup 0으로 첫 전체 GREEN을 만들었다. 최신 full GREEN은 clean `64e1b221…`의 `periodic-learner-e2e-20260812-150209.json`·SHA-256 `a7b2f758…8071`이다. `94666192…`와 진단 보강 commit `f97e7fad…`의 single run은 모두 disposable DB init health에서 브라우저 전에 FAILED했지만 public/NAS/active DB 접촉 0·exact cleanup 0을 유지했다. 두 번째 receipt `periodic-learner-e2e-20260812-163742.json`·SHA-256 `ad403712…d840f`는 detached checkout의 `99_app_role.sh`가 CRLF라 `bash\r` exit 127이 난 것을 확정했다. `.gitattributes`에 `*.sh text eol=lf`를 추가했으며 같은 blocker가 두 번 반복돼 이번 heartbeat에서는 재시도하지 않는다. 새 clean commit/worktree에서 CR 0과 single full run GREEN을 확인하기 전까지 current source를 완료로 부르지 않는다. > 증거: [배포 증거](./ops/nas-preview-deployment-evidence-2026-08-07.md), [기계 판독 증거](./ops/evidence/nas-preview-current-deploy-2026-08-07.json), [브라우저 증거](./ops/evidence/nas-preview-live-turn-2026-08-07.png). 이는 G7 물리 마이크·독립 사람 평가 증거를 대체하지 않는다. - [ ] **claude_cli ↔ Anthropic API live 동일성** — provider 라우팅·모델 탐색·설정 저장 경로는 구현 완료. 남은 게이트는 연구팀/기관 `ANTHROPIC_API_KEY`를 게이트웨이 호스트에 주입한 뒤 같은 프롬프트의 live 응답·계량·오류 표면화를 비교하는 것이다. diff --git a/docs/dev_dashboard.html b/docs/dev_dashboard.html index 52a6549..e3949b6 100644 --- a/docs/dev_dashboard.html +++ b/docs/dev_dashboard.html @@ -681,6 +681,7 @@

202차 적용(2026-08-12): NAS relay 복구 스크립트를 기본 loopback·detached-clean HEAD/tree·launcher/Python/env SHA·exact consumer URL·명시 LAN 승인·외부 state/receipt로 fail-closed했다. wildcard·기존 listener 재사용·source 내부 또는 reparse-point 외부 경로를 거부하고, liveness 뒤 실제 provider /ready?force=true를 한 번만 호출한다. readiness/receipt 실패는 이번 실행이 소유한 PID/listener만 정리한다. Windows PowerShell parse, contract 8/8, Ruff·compile·diff-check를 통과했고 public 9099 listener는 1, NAS 9100 listener는 0을 유지했다. 같은 시각 public은 health ok·db/engine true·OpenAPI 126·auth 401·local voice exact였지만 NAS health는 3회 타임아웃했다. 실제 LAN relay·NAS/container/DB mutation은 소유자 승인 전 실행하지 않는다.

203차 관측·보강(2026-08-12): detached-clean 94666192…의 periodic full run은 전용 engine ready를 통과한 뒤 app.ci_regression_dag_node가 준비되지 않은 disposable PostgreSQL health에서 실패해 브라우저 단계 전에 종료됐다. receipt periodic-learner-e2e-20260812-155929.json·SHA-256 1bd95e01…52a8은 FAILED이며 public·NAS·active DB 접촉 0과 container·volume·network·listener·temp 잔여 0을 확인했다. stack source는 마지막 GREEN 64e1b221…과 동일하지만 cleanup 전에 DB/API 로그를 영수증에 남기지 않아 정확한 환경/init 원인은 미확정이다. 같은 heartbeat에서 재시도하지 않았다. runner는 이제 cleanup 전에 compose ps와 db/api 로그 tail을 캡처하고 secret·email·UUID·민감 query를 제거하며 raw SHA만 결속한다. contract 14/14·Ruff·compile을 통과했다.

204차 적용(2026-08-12): actual NAS 로그인 390×844에서 innerWidth=390, document usable width 380, login root width 390으로 10px 가로 넘침이 계속 재현돼 200차의 100vw→100% 보정만으로는 부족함을 확인했다. auth/login 최상위 shell을 block auto-size와 max-inline-size:100%로 바꿔 classic scrollbar를 usable scrollport에서 이중 계산하지 않게 했다. route-mocked 학생 자기주도·G1~G5·G7 desktop/mobile 76/76, 인증 2/2, 대시보드 10/10, type/API contract·SSOT checker를 통과했다. 이 수정은 아직 공개/NAS에 배포하지 않았고, 현 NAS는 health 타임아웃·실제 화면 overflow 10px인 DEGRADED 상태다.

+

205차 진단·보강(2026-08-12): 진단과 로그인 폭 수정을 commit f97e7fad…·tree bdc83f24…의 새 detached-clean worktree에 고정해 periodic full runner를 한 번 실행했다. 전용 engine ready 뒤 disposable DB가 restart 127로 unhealthy가 돼 브라우저 전에 fail-closed했다. receipt periodic-learner-e2e-20260812-163742.json·SHA-256 ad403712…d840f의 cleanup 전 secret/PII-safe 로그가 99_app_role.sh#!/usr/bin/env bash\rNo such file or directory를 확정했다. Git blob은 LF지만 Windows core.autocrlf=true가 새 worktree를 CRLF로 만든 것이 원인이다. .gitattributes*.sh text eol=lf를 추가했다. public·NAS·active DB 접촉 0, container·volume·network·listener·temp 잔여 0이며, 같은 blocker가 두 번 반복돼 이번 heartbeat에서는 재실행하지 않는다. 다음 gate는 새 commit→새 detached checkout CR 0→preflight→single full run이다.

래스터만 사용이미지 생성 도구 산출물은 PNG 기반 시안이다. SVG·벡터·와이어프레임·로고 시트로 해석하지 않는다.
기능 우선메인 라우트의 실제 액션과 정보 구조를 먼저 반영한다. 장식은 기능을 가리지 않는 수준에서만 쓴다.
diff --git a/docs/guides/testing.md b/docs/guides/testing.md index b2d9383..2dfe187 100644 --- a/docs/guides/testing.md +++ b/docs/guides/testing.md @@ -285,12 +285,13 @@ persisted episode를 UI에 hydrate하지 못하는 제품 결함을 각각 fail- SSE·review·G4/G5 `0→1→1`을 연속 통과했지만 fixture 공유와 mobile success-state locator를 각각 검출했다. 보정 후 7차 clean `aa81af29…`는 same-learner SSE·review·G4/G5 `0→1→1`, 별도 zero-state returned desktop/mobile 4/4, route mock 0, exact cleanup 0으로 첫 전체 GREEN receipt를 만들었다. 최신 full GREEN은 clean `64e1b221…`의 -`periodic-learner-e2e-20260812-150209.json`·SHA-256 `a7b2f758…8071`이다. current `94666192…` run은 -disposable DB init health에서 브라우저 전에 FAILED했지만 보호 runtime 접촉 0·exact cleanup 0을 유지했다. -당시 cleanup 전에 DB/API 로그를 보존하지 않아 exact 원인은 미확정이다. runner는 이제 실패 시 cleanup 전에 -`compose ps`와 db/api log tail을 수집하고 secret·email·UUID·민감 query를 제거한 뒤 raw SHA와 함께 receipt에 결속한다. -contract 14/14를 통과했다. hourly heartbeat는 최신 GREEN이 6시간 이상 오래됐거나 material milestone이 바뀔 때만 -preflight 뒤 full runner를 최대 1회 실행하며, 실패 시 같은 heartbeat에서 재시도하지 않는다. +`periodic-learner-e2e-20260812-150209.json`·SHA-256 `a7b2f758…8071`이다. `94666192…` run은 disposable DB +init health에서 브라우저 전에 FAILED했고, 진단 보강 commit `f97e7fad…`의 single run도 같은 단계에서 멈췄다. +두 번째 receipt `periodic-learner-e2e-20260812-163742.json`·SHA-256 `ad403712…d840f`의 cleanup 전 로그는 +detached checkout의 `infra/db/init/99_app_role.sh`가 CRLF라 `/usr/bin/env: ‘bash\r’: No such file or directory`로 +exit 127이 난 것을 확정했다. 두 실행 모두 보호 runtime 접촉 0·exact cleanup 0이다. Windows `core.autocrlf=true` +환경에서도 shell entrypoint를 LF로 checkout하도록 `.gitattributes`에 `*.sh text eol=lf`를 둔다. hourly heartbeat는 +동일 장애가 두 번 반복되면 같은 heartbeat에서 재실행하지 않고, 새 clean commit/worktree에서 CR 0을 먼저 확인한다. - **병렬 시나리오**: 166 tests (desktop 83 + mobile 83) - **`@single-run` 직렬 시나리오**: 49 tests (DB 영속화·세션 MVP·음성 성공경로·인증 시각 테마·회기말 평가 저장·교수자 명시 재평가 저장·교수자 턴 재평가 저장·교수자 UI 평가 재시도·교수자 사용자별 분석·source pack sync·이론모드 저장·동의 철회 후 voice 차단·브라우저 stream PII 마스킹·음성 transcript 저장 실패 UI 표면화 등) diff --git a/docs/ops/backlog-2026-06-26.md b/docs/ops/backlog-2026-06-26.md index 8c88604..5a9e35c 100644 --- a/docs/ops/backlog-2026-06-26.md +++ b/docs/ops/backlog-2026-06-26.md @@ -98,7 +98,7 @@ 무마이크 rehearsal은 완료됐지만 물리 마이크·human pack을 대체하지 않는다. 격리 NAS 프리뷰 `http://100.116.83.60:8088`은 전용 Compose 프로젝트·포트·네트워크·볼륨에 배포했고, 실제 브라우저 회기와 review API 저장 축어록 2턴을 확인했다. 기존 프로젝트 중단·재생성 명령은 실행하지 않았다. 매시간 `Vignette 앱 상태·회기 E2E 정기 검증` - heartbeat(automation id `vignette-e2e`)는 ACTIVE이며 공개/NAS 화면·health는 읽기 전용으로 보여준다. NAS 112건은 실 API/DB 22와 route fixture 90으로 영수증에서 분리한다. 동일 학습자 SSE→review→G4/G5 actual 폐루프 runner의 clean HEAD/tree·보호 포트 거부·sentinel·exact cleanup과 unit 14/14는 완료됐다. 최초 세 full run은 하네스, 4차는 reload ledger hydration, 5차는 fixture 공유, 6차는 mobile success-state locator를 fail-closed했다. 7차 clean `aa81af29…` 이후 최신 full GREEN은 clean `64e1b221…`의 `periodic-learner-e2e-20260812-150209.json`·SHA-256 `a7b2f758…8071`이다. current `94666192…` 확인은 disposable DB init health에서 브라우저 전에 FAILED했지만 public/NAS/active DB 접촉 0·cleanup 0을 유지했다. 당시 cleanup 전 로그 부재 때문에 exact 원인은 미확정이며 runner는 이제 secret/PII-safe `compose ps`·db/api tail을 실패 영수증에 고정한다. current source는 새 clean commit 뒤 single full run GREEN 전까지 완료로 부르지 않는다. heartbeat는 최신 GREEN이 6시간 이상 오래됐거나 material milestone이 바뀔 때만 preflight 뒤 full runner를 최대 1회 실행하고 실패 시 자동 재시도하지 않는다. release gate·NAS preflight·배포 SHA 변경 때만 프리뷰를 갱신한다. 2026-08-07 SHA `6030a677af7e87cbfabc422b553d108d53414fd3c446548734a13b036d35c611`의 localhost 108/108과 평문 origin UUID 24건 실패는 역사 기준선으로 보존한다. 실제 receipt-bound rollback은 같은 프리뷰에서 별도 helper로 두 번 실행해 종료했다([런북](./nas-preview-g8-rollback-proof-runbook.md), [기계 판독 증거](./evidence/nas-preview-g8-actual-rollback-2026-08-07.json)). 현재는 source HEAD/tree `61a41d1f…6af`/`87dec55d…3b77`의 active archive `4d15d055…119d4d`, exact API/Web `d5021950…e4b1`/`9796c092…4b36`이 실행 중이다. candidate 112/112와 실제 NAS-origin 112/112, health ok·db/engine true·auth 401·OpenAPI 126을 통과했고 fresh dump `36ec8748…24db8` 1,097,100 bytes·TOC 1,738/TABLE DATA 129와 previous `6030a677…c611`을 보존했다. 증거: [배포 증거](./nas-preview-deployment-evidence-2026-08-07.md), + heartbeat(automation id `vignette-e2e`)는 ACTIVE이며 공개/NAS 화면·health는 읽기 전용으로 보여준다. NAS 112건은 실 API/DB 22와 route fixture 90으로 영수증에서 분리한다. 동일 학습자 SSE→review→G4/G5 actual 폐루프 runner의 clean HEAD/tree·보호 포트 거부·sentinel·exact cleanup과 unit 14/14는 완료됐다. 최초 세 full run은 하네스, 4차는 reload ledger hydration, 5차는 fixture 공유, 6차는 mobile success-state locator를 fail-closed했다. 7차 clean `aa81af29…` 이후 최신 full GREEN은 clean `64e1b221…`의 `periodic-learner-e2e-20260812-150209.json`·SHA-256 `a7b2f758…8071`이다. `94666192…`와 `f97e7fad…` single run은 disposable DB init health에서 브라우저 전에 FAILED했지만 public/NAS/active DB 접촉 0·cleanup 0을 유지했다. 두 번째 receipt `periodic-learner-e2e-20260812-163742.json`·SHA-256 `ad403712…d840f`의 secret/PII-safe 로그가 detached checkout의 `99_app_role.sh` CRLF와 `bash\r` exit 127을 확정했다. `.gitattributes`에 `*.sh text eol=lf`를 추가했고 같은 blocker가 두 번 반복돼 이번 heartbeat에서는 자동 재시도하지 않는다. 새 clean commit/worktree의 CR 0과 single full run GREEN 전까지 current source를 완료로 부르지 않는다. release gate·NAS preflight·배포 SHA 변경 때만 프리뷰를 갱신한다. 2026-08-07 SHA `6030a677af7e87cbfabc422b553d108d53414fd3c446548734a13b036d35c611`의 localhost 108/108과 평문 origin UUID 24건 실패는 역사 기준선으로 보존한다. 실제 receipt-bound rollback은 같은 프리뷰에서 별도 helper로 두 번 실행해 종료했다([런북](./nas-preview-g8-rollback-proof-runbook.md), [기계 판독 증거](./evidence/nas-preview-g8-actual-rollback-2026-08-07.json)). 현재는 source HEAD/tree `61a41d1f…6af`/`87dec55d…3b77`의 active archive `4d15d055…119d4d`, exact API/Web `d5021950…e4b1`/`9796c092…4b36`이 실행 중이다. candidate 112/112와 실제 NAS-origin 112/112, health ok·db/engine true·auth 401·OpenAPI 126을 통과했고 fresh dump `36ec8748…24db8` 1,097,100 bytes·TOC 1,738/TABLE DATA 129와 previous `6030a677…c611`을 보존했다. 증거: [배포 증거](./nas-preview-deployment-evidence-2026-08-07.md), [브라우저 증거](./evidence/nas-preview-live-turn-2026-08-07.png). 위 health GREEN은 배포 당시 증거다. 2026-08-12 current NAS는 고정 LAN engine relay listener 상실로 degraded였고 15:24 KST local health 요청도 3회 타임아웃했다. source-pinned relay launcher와 loopback contract 8/8은 완료했지만 실제 9100 시작·NAS