릴리스 후보 부트 진단 게이트 보정
This commit is contained in:
parent
5221f79e3f
commit
21461ab323
5 changed files with 31 additions and 5 deletions
|
|
@ -905,7 +905,10 @@ test.describe("학습자 자기주도 전체 루프 — 실제 src UI / route fi
|
|||
});
|
||||
|
||||
test("React 부트가 실제로 비어 있으면 진단을 유지한다", async ({ page }) => {
|
||||
await page.route("**/src/main.tsx", (route) => route.abort("failed"));
|
||||
await page.route(
|
||||
/\/(?:src\/main\.tsx|assets\/index-[^/]+\.js)(?:\?.*)?$/,
|
||||
(route) => route.abort("failed"),
|
||||
);
|
||||
await page.goto("/learn", { waitUntil: "domcontentloaded" });
|
||||
|
||||
const diagnostic = page.locator("#vignette-boot-diagnostic");
|
||||
|
|
|
|||
|
|
@ -366,6 +366,21 @@ apps/web/test-results/g7-voice-consent-mobile.png
|
|||
`/src/lib/uuid.ts`를 import할 수 없는 gate 배치 오류라 별도 Vite gate로 분리했다. 남은 1건은 아래 제품 버그다.
|
||||
NAS mutation 0, rollback 불필요. 동일 전체 execute를 아직 다시 시도하지 않았다.
|
||||
|
||||
#### 2026-08-09 clean-head `5221f79e` 실행 결과 — NAS mutation 0
|
||||
|
||||
- exact include 52개를 Yun Chan으로 커밋했다. HEAD `5221f79e…1c69`, tree `e4f15001…308b`, 2회 동일 archive
|
||||
`1109bf86…0f4b`(482,662,400 bytes)를 detached clean worktree에서 고정했다.
|
||||
- 새 milestone과 dry-run은 active `6030a677…c611` → desired `1109bf86…0f4b`,
|
||||
`deployment_mutated=false`로 통과했다. 실행 직전 NAS custom dump
|
||||
`6f4b95a7…b529f`(1,015,222 bytes, TOC 1,752 / TABLE DATA 129, 전용 pgdata volume)를 생성했다.
|
||||
- execute는 API 921, API types, typecheck, build, insecure-context 6/6, candidate stack과 DB-backed
|
||||
single-run 후반부까지 통과했지만 **110 passed / 2 failed**에서 승격 전에 중단됐다. 실패는 제품 화면이 아니라
|
||||
`React 부트가 실제로 비어 있으면 진단을 유지한다`의 desktop/mobile 두 복제였다.
|
||||
- 원인은 테스트가 Vite 개발 entry `/src/main.tsx`만 차단해 production candidate의 hashed entry
|
||||
`/assets/index-*.js`를 차단하지 못한 환경 계약 누락이다. 두 entry를 함께 차단하도록 수정했고 Vite source 2/2와
|
||||
production preview 2/2를 각각 통과했다. 전체 execute를 즉시 반복하지 않고 이 수정의 새 clean commit·archive를
|
||||
다시 결속한 뒤 한 번만 재실행한다.
|
||||
|
||||
#### P0 수정 완료 — 회기 timestamp UTC 전송과 KST 표시 날짜
|
||||
|
||||
- 최초 실패 스펙: `session-persistence.spec.ts`의 `persists AI tutor coaching history through reload @single-run`.
|
||||
|
|
@ -381,8 +396,8 @@ apps/web/test-results/g7-voice-consent-mobile.png
|
|||
- 고유 Compose project/volume의 실제 DB/API/engine/browser에서 KST context로 focused 1/1 PASS했다. UTC suffix,
|
||||
`status=active`, `ended_at=null`, 회기 나이 10분 미만, 화면 `00:00-09:59`, timebar/dialog 0,
|
||||
coach mark 실제 클릭과 DB history/source-pack dialog를 모두 검증했다. 종료 뒤 container/volume/listener는 0이다.
|
||||
- **테스트 강제 클릭이나 모달 닫기 우회는 사용하지 않았다.** 현재 clean source HEAD `94c681d…7fb`에는 이 수정과
|
||||
controller 변경이 없으므로 사용자에게 commit 승인을 받은 뒤 새 clean commit의 HEAD/tree/archive를 다시 산출한다.
|
||||
- **테스트 강제 클릭이나 모달 닫기 우회는 사용하지 않았다.** 첫 clean source `5221f79e…1c69`에는 제품 수정과
|
||||
controller 변경이 포함됐고, production entry 차단 회귀 2건의 테스트 수정만 후속 clean commit으로 다시 고정한다.
|
||||
|
||||
### 6.2 G8: NAS preview 배포와 실제 origin E2E
|
||||
|
||||
|
|
|
|||
|
|
@ -500,7 +500,10 @@
|
|||
- [ ] **G8 NAS-origin 재검증** — `randomUuid()` 수정과 insecure-origin 6/6 회귀를 포함한 current HEAD를
|
||||
위 clean-head mode로 격리 NAS preview에 배포한다. `started_at`의 9시간 오차 P0는 UTC `+00:00`, KST 달력 날짜,
|
||||
KST browser focused 실DB E2E로 수정했고 API 전체 921 passed와 코칭 이력 1/1을 통과했다. 시간종료 모달 강제
|
||||
닫기 우회는 없다. 사용자 승인 아래 새 clean commit·HEAD/tree/archive를 결속해 실제
|
||||
닫기 우회는 없다. 첫 clean commit `5221f79e` execute는 API/types/build와 candidate DB-backed 회기 후반까지
|
||||
통과했지만 Vite 전용 `/src/main.tsx` 차단 테스트가 production hashed entry를 차단하지 못해 110/2에서
|
||||
mutation 없이 중단됐다. source와 production preview에서 수정 회귀 2/2씩 통과했다. 이 테스트 수정의 새 clean
|
||||
commit·HEAD/tree/archive를 결속해 실제
|
||||
`http://100.116.83.60:8088` origin에서 전체 회기
|
||||
E2E 0 failure·SSE→DB review·student returned-practice desktop/mobile을 다시 검증하기 전에는 G8 전체를 DONE으로
|
||||
올리지 않는다.
|
||||
|
|
|
|||
|
|
@ -655,6 +655,7 @@
|
|||
<p class="dg-note">187차 적용(2026-08-09): G8 clean-head dry-run은 active <code>6030a677…c611</code>→desired archive <code>6b1b15bd…a3f7</code>를 mutation 0으로 결속했다. execute 1은 archive CRLF/API type byte-check에서, execute 2는 API·types·build 통과 뒤 session E2E <code>109 passed / 5 failed</code>에서 모두 승격 전에 fail-closed되어 NAS active/image/DB는 바뀌지 않았다. source-only UUID 4건은 production 번들에서 <code>/src/lib/uuid.ts</code> import가 불가능한 gate 배치 오류라 별도 Vite gate 6/6으로 분리했다. 남은 실제 제품 blocker는 timezone 없는 <code>started_at</code>을 KST 브라우저가 약 9시간 경과로 오인해 시간종료 모달이 정상 코칭 이력을 가리는 문제다. backend UTC offset/Z 계약과 focused disposable DB/browser 회귀를 닫고 새 clean commit을 만든 뒤에만 NAS 배포를 재개한다.</p>
|
||||
<p class="dg-note">188차 적용(2026-08-09): 회기 시간 P0를 우회 없이 수정했다. browser-facing <code>started_at</code>/<code>ended_at</code>과 learner/teacher dashboard timestamp는 UTC <code>+00:00</code>을 반환하고, 리뷰의 달력 날짜는 서버 locale 대신 KST(+09:00)를 사용한다. backend 관련 65 passed, 후속 voice 계약을 포함한 API 전체 921 passed, Ruff·compile·web typecheck를 통과했다. 고유 Compose DB/API/Web/engine과 <code>Asia/Seoul</code> browser에서 코칭 이력 focused 1/1은 active/null·UTC suffix·10분 미만 경과·timebar/dialog 0·reload 후 coach mark 실제 클릭과 source-pack dialog를 확인했다. 종료 뒤 container·volume·listener 0이다. 이제 새 clean commit 결속과 NAS-origin 전체 E2E가 남았다.</p>
|
||||
<p class="dg-note">189차 적용(2026-08-09): G7 외부 실행 전 P0를 소스에서 닫았다. production runner exit 0은 canonical checker 0·<code>gate_closed=true</code>에 결속하고, browser Origin allowlist를 API/WSS/admin/topology transport host·scheme과 분리했다. capture는 최소 3,120초·ceil+terminal sample이며 checker는 voice/runtime/topology 공통 교집합 3,000초를 강제한다. Windows 증거는 detached-clean commit/tree, runner/collector/checker SHA, <code>psutil==6.1.1</code>을 매 sample 전후 검증한다. fresh public launcher는 mutation 전에 source·Python·cloudflared·config SHA를 고정하고, legacy API와 exact-config cloudflared를 bounded 교체해 새 PID/start/exe·command SHA/실제 cwd의 raw command-line 없는 receipt를 남긴다. receipt destination은 runtime mutation 전에 create/flush/atomic-replace 권한을 검사하고 기존 receipt를 보존한 채 원자 게시한다. 검증: G7 runner/checker/topology 86/86, launcher/sidecar 80/80, 통합 166/166, API 921, gateway 58, Web api-types·typecheck·build, 자기주도 desktop/mobile 6/6, Ruff·compile·PS5.1 parser·diff-check PASS. 실제 public 실행·마이크·사람 평가는 하지 않았으므로 G7은 external GATE다.</p>
|
||||
<p class="dg-note">190차 적용(2026-08-09): exact include 52개를 clean commit <code>5221f79e…1c69</code>으로 고정하고 tree <code>e4f15001…308b</code>, 2회 동일 archive <code>1109bf86…0f4b</code>를 결속했다. fresh NAS dump <code>6f4b95a7…b529f</code>(1,015,222 bytes·TOC 1,752/TABLE DATA 129) 뒤 execute는 API 921·types·typecheck·build·insecure-context 6/6·candidate DB 회기 후반까지 통과했지만 <b>110/112</b>에서 승격 전에 fail-closed했다. 실패 2건은 Vite entry <code>/src/main.tsx</code>만 차단하던 boot 진단 테스트가 production hashed entry <code>/assets/index-*.js</code>를 차단하지 못한 환경 계약 누락이었다. 두 entry를 함께 차단하도록 고쳐 Vite source 2/2와 production preview 2/2를 통과했다. NAS mutation·rollback·DB migration은 0이며, 테스트 수정의 새 clean commit을 재결속한 한 번의 execute가 남았다.</p>
|
||||
<div class="dg-principles" aria-label="디자인 생성 가드레일">
|
||||
<div><b>래스터만 사용</b><span>이미지 생성 도구 산출물은 PNG 기반 시안이다. SVG·벡터·와이어프레임·로고 시트로 해석하지 않는다.</span></div>
|
||||
<div><b>기능 우선</b><span>메인 라우트의 실제 액션과 정보 구조를 먼저 반영한다. 장식은 기능을 가리지 않는 수준에서만 쓴다.</span></div>
|
||||
|
|
@ -913,7 +914,7 @@
|
|||
</article>
|
||||
<article class="scard" data-status="doing" data-cat="Outcome OS·에이전틱" data-owner="0">
|
||||
<button class="scard-head" aria-expanded="false"><span class="chip c-doing">G8 BUILD · RECEIPT DONE · RUNTIME REVALIDATION</span><span class="scard-mid"><span class="scard-title">Autonomous Content & Continuous Improvement</span><span class="scard-sum">실제 rollback receipt는 완료됐다. 비-secure origin UUID 수정 배포와 NAS-origin 회기 E2E 재검증이 남았다.</span></span><span class="caret" aria-hidden="true"></span></button>
|
||||
<div class="scard-body"><div class="kv"><b>agentic worker + 운영 환류 + human gate</b><p>승인 source의 실제 hash·PII를 engine 호출 전에 검사하고 structured generator 1개, 결과를 공유하지 않는 red-team 2개, variant generator와 variant별 독립 judge 3개 이상을 실행한다. 정답 누수·PII·unknown source claim·open finding·안전/보상 해킹·모델/structured 실패는 store 호출 전에 차단한다. repo-approved source는 기본 비활성 scheduler가 durable lease/retry job으로 관리한다. 실제 <code>claude_cli/claude-opus-4-8</code> 7 calls와 dev PostgreSQL reviewer 2·variant 3·pass rate 1.0을 거쳐 synthetic payload를 <code>pending_human_approval</code>로 저장했다. G6 canonical drift trigger는 metadata-only incident→DAG→job을 원자 enqueue하고, 실제 pending 후보의 관리자 검수는 catalog 0→1·approval 1과 역할 403·멱등/409·민감정보 비노출을 통과했다. 별도 누수 후보는 422·저장 0이다. 상세: <code>ops/outcome-os-g8-agentic-worker-evidence-2026-08-07.md</code>.</p></div><div class="kv k-warn"><b>NAS-origin runtime 재검증</b><p>SHA <code>6030a677…c611</code>의 API/Web 이미지는 health 3/3·db/engine true, OpenAPI 126·auth 401·실제 SSE→DB-backed review를 통과했다. 그러나 108/108은 localhost candidate 결과였고 같은 NAS 평문 origin에서는 <code>crypto.randomUUID</code> 예외로 24건이 실패했다. 소스의 <code>randomUuid()</code> 수정은 source-only Vite 6/6·typecheck·build를 통과했다. clean-head controller도 HEAD/tree/archive 2회 결정성·archive-only candidate·patch 무회귀와 commit 전 actual-origin 11-spec rollback gate를 unit 30/30로 고정했고 새 predeploy dump <code>72698232…5d41c</code>를 보존했다. 두 execute는 모두 승격 전 fail-closed되어 mutation 0이다. 후속으로 UTC timestamp·KST 날짜 계약을 구현해 API 전체 921 passed와 KST 실DB browser 코칭 이력 1/1을 통과했다. 사용자 승인 아래 새 clean commit을 결속하고 동일 NAS-origin 회기 묶음이 GREEN이 되기 전에는 G8 전체를 DONE으로 올리지 않는다.</p></div><div class="kv k-good"><b>실제 rollback receipt DONE</b><p>runtime+release_gate 전용 executor는 승인·idempotency·artifact·Compose/env/resolved-policy SHA와 exact API/Web image를 일회성 manifest에 결속하고 HMAC journal·crash recovery·previous-image 복구를 고정한다. 2026-08-07 격리 NAS에서 별도 loopback control-plane API(<code>127.0.0.1:8018</code>)와 별도 executor(<code>127.0.0.1:18149</code>)로 <b>실제 image rollback 2회</b>를 실행했다. <code>rollback-old</code>는 receipt <code>nas-g8-723eeef2…</code>로 previous 이미지 <code>79ec…4450</code>/<code>c530…2f28</code>를, <code>restore-current</code>는 receipt <code>nas-g8-2738846c…</code>로 current 이미지 <code>52e0…8b2d</code>/<code>6fdb…f215</code>를 활성화했다. release gate·approval 각각 2회 멱등, lifecycle <code>rollback/executed</code> 2건, 승인 <code>authorize_rollback</code> 2건, silent auto-promotion 0, HMAC journal 6-record 체인 검증, health 3/3·OpenAPI 126·auth 401·Web 200을 확인했다. helper는 image 상속 compose label을 baseline으로 두고 project/service를 격리 override하는 계약으로 검증했다(<code>launch-nas-preview-g8-helpers.py</code>, 37/37). 상세: <a href="./ops/nas-preview-g8-rollback-proof-runbook.md">런북</a> · <a href="./ops/evidence/nas-preview-g8-actual-rollback-2026-08-07.json">기계 판독 증거</a>.</p></div></div>
|
||||
<div class="scard-body"><div class="kv"><b>agentic worker + 운영 환류 + human gate</b><p>승인 source의 실제 hash·PII를 engine 호출 전에 검사하고 structured generator 1개, 결과를 공유하지 않는 red-team 2개, variant generator와 variant별 독립 judge 3개 이상을 실행한다. 정답 누수·PII·unknown source claim·open finding·안전/보상 해킹·모델/structured 실패는 store 호출 전에 차단한다. repo-approved source는 기본 비활성 scheduler가 durable lease/retry job으로 관리한다. 실제 <code>claude_cli/claude-opus-4-8</code> 7 calls와 dev PostgreSQL reviewer 2·variant 3·pass rate 1.0을 거쳐 synthetic payload를 <code>pending_human_approval</code>로 저장했다. G6 canonical drift trigger는 metadata-only incident→DAG→job을 원자 enqueue하고, 실제 pending 후보의 관리자 검수는 catalog 0→1·approval 1과 역할 403·멱등/409·민감정보 비노출을 통과했다. 별도 누수 후보는 422·저장 0이다. 상세: <code>ops/outcome-os-g8-agentic-worker-evidence-2026-08-07.md</code>.</p></div><div class="kv k-warn"><b>NAS-origin runtime 재검증</b><p>SHA <code>6030a677…c611</code>의 API/Web 이미지는 health 3/3·db/engine true, OpenAPI 126·auth 401·실제 SSE→DB-backed review를 통과했다. 그러나 108/108은 localhost candidate 결과였고 같은 NAS 평문 origin에서는 <code>crypto.randomUUID</code> 예외로 24건이 실패했다. 소스의 <code>randomUuid()</code> 수정은 source-only Vite 6/6·typecheck·build를 통과했다. clean-head controller도 HEAD/tree/archive 2회 결정성·archive-only candidate·patch 무회귀와 commit 전 actual-origin 11-spec rollback gate를 unit 30/30로 고정했다. 첫 current clean commit <code>5221f79e</code>와 fresh dump <code>6f4b95a7…b529f</code>를 결속한 execute는 API·types·build·candidate DB 후반까지 통과했지만 production entry 차단 테스트 2건으로 110/112에서 승격 전 중단돼 mutation 0이다. entry 수정은 source/production preview 각 2/2를 통과했다. 새 clean commit을 결속하고 동일 NAS-origin 회기 묶음이 GREEN이 되기 전에는 G8 전체를 DONE으로 올리지 않는다.</p></div><div class="kv k-good"><b>실제 rollback receipt DONE</b><p>runtime+release_gate 전용 executor는 승인·idempotency·artifact·Compose/env/resolved-policy SHA와 exact API/Web image를 일회성 manifest에 결속하고 HMAC journal·crash recovery·previous-image 복구를 고정한다. 2026-08-07 격리 NAS에서 별도 loopback control-plane API(<code>127.0.0.1:8018</code>)와 별도 executor(<code>127.0.0.1:18149</code>)로 <b>실제 image rollback 2회</b>를 실행했다. <code>rollback-old</code>는 receipt <code>nas-g8-723eeef2…</code>로 previous 이미지 <code>79ec…4450</code>/<code>c530…2f28</code>를, <code>restore-current</code>는 receipt <code>nas-g8-2738846c…</code>로 current 이미지 <code>52e0…8b2d</code>/<code>6fdb…f215</code>를 활성화했다. release gate·approval 각각 2회 멱등, lifecycle <code>rollback/executed</code> 2건, 승인 <code>authorize_rollback</code> 2건, silent auto-promotion 0, HMAC journal 6-record 체인 검증, health 3/3·OpenAPI 126·auth 401·Web 200을 확인했다. helper는 image 상속 compose label을 baseline으로 두고 project/service를 격리 override하는 계약으로 검증했다(<code>launch-nas-preview-g8-helpers.py</code>, 37/37). 상세: <a href="./ops/nas-preview-g8-rollback-proof-runbook.md">런북</a> · <a href="./ops/evidence/nas-preview-g8-actual-rollback-2026-08-07.json">기계 판독 증거</a>.</p></div></div>
|
||||
</article>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -35,6 +35,10 @@
|
|||
SHA/size/TOC와 DB identity를 별도 증거로 결속한다. agent 자동 rollback은 image/Compose/active-state 범위뿐이며,
|
||||
적용 migration/data restore는 별도 owner 승인을 받는다. remote release root/Compose mode `0777` P1도 최소권한
|
||||
preflight로 닫는다. 이때만 G8 전체 DONE이 가능하다.
|
||||
첫 current clean commit `5221f79e`는 HEAD/tree/archive와 fresh NAS dump를 결속했지만 candidate E2E
|
||||
110/112에서 production hashed entry를 차단하지 못한 boot-diagnostic 테스트 desktop/mobile 2건으로 승격 전
|
||||
중단됐다. NAS mutation 0이다. `/src/main.tsx`와 `/assets/index-*.js`를 함께 차단하는 수정은 Vite source 2/2,
|
||||
production preview 2/2를 통과했으며 새 clean commit으로 한 번만 재실행한다.
|
||||
|
||||
> B1 완료 항목(학생 리뷰 1~5 척도 320px 반응형 재배치, 셸 구분선, 세션 종료 UX/다크테마, 아바타 SVG 리그 복귀와 래스터 비활성화, SEO/공유 카드, 레이아웃 정렬, 권한 위임,
|
||||
> 메일링, 아카이브 API, TTS voice map, 빈상태 레이아웃, 평가 실패 복구 UX, SSE 저장, live-coach 표면화,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue