vignette/docs/ops/outcome-os-g8-agentic-worker-evidence-2026-08-07.md
Yun Chan 16e791e044 G0~G8 성과·동맹 측정 OS 작업 일괄 고정
8월 7일까지 워킹트리에만 남아 있던 미커밋 작업을 커밋한다. 여러 사본
폴더(worktree·clone)에 흩어져 있던 중간 스냅샷을 정리하기 전에 원본을
git 이력으로 고정하는 것이 목적이다.

- contracts/routes/services: measurement, outcome_trajectory, rupture_repair,
  deliberate_practice, calibration_transfer, supervision_research,
  multimodal_alliance, continuous_improvement 계열 신규 모듈과 테스트
- infra/db/init: 07~16 마이그레이션(측정 기반~calibration transfer 실행)
- apps/web: 세션 리뷰 카드·관리 화면·E2E 스펙 추가
- docs/ops: G0~G8 라이브 통합·배포·롤백 증거 문서와 evidence JSON/PNG
- scripts: smoke·ledger·릴리스 에이전트·NAS 프리뷰 운영 스크립트

engine.public 로그 .bak과 apps/web/test-results 산출물은 커밋에서 제외했다.
2026-08-08 01:30:53 +09:00

166 lines
12 KiB
Markdown

# G8 agentic content worker 구현 증거 — 2026-08-07
## 판정
G8의 기존 수동 JSON control-plane 앞에 실제 engine 호출을 소유하는 worker를 추가했다. 승인된 synthetic
source pack은 source hash와 PII gate를 통과한 뒤 draft generator, 서로 결과를 공유하지 않는 두 red-team
lane, variant generator, variant별 독립 judge를 거친다. 전 단계가 성공하고 정답 누수·PII·무근거 주장·안전
실패·보상 해킹이 0인 경우에만 기존 append-only store가 candidate와 생성 payload를
`pending_human_approval`로 저장한다. catalog 자동 승격은 계속 금지한다.
이 문서는 controlled fake-engine seam뿐 아니라 opt-in scheduled producer와 실제 dev engine/PostgreSQL
실행 증거까지 포함한다. 약한 benchmark/drift 자동 탐색, 사람의 pending payload 검수 E2E, 회귀·배포·public
proof·SSOT를 수행하는 release agent의 운영 증거는 아직 아니다.
## 실행 경계
- `POST /internal/continuous-improvement/agentic-content-pipelines`
- 호출자는 완성 draft/review/benchmark를 제출하지 않는다.
- 승인 source artifact와 source 본문, 목표 kind·난이도·variant 수만 제출한다.
- source 본문의 실제 SHA-256 일치와 PII 0건을 engine 호출 전에 fail-closed로 검사한다.
- `app.services.continuous_improvement_agentic`
- structured draft generator 1회.
- `safety/identity/pii/grounding``answer_leakage/cultural_bias/difficulty`를 분리한 독립
red-team agent 2회를 병렬 실행한다. 각 agent는 다른 lane의 결과를 입력으로 받지 않는다.
- 최소 3개 adversarial variant를 생성하고 각 variant를 별도 judge call로 평가한다.
- structured output 누락·schema 오류·model 예외·PII·hidden-answer token overlap·unknown source ref·open
finding·judge failure가 하나라도 있으면 store를 호출하지 않는다.
- `app.services.continuous_improvement_store`
- `submission_id`의 기존 pipeline과 generation prompt fingerprint를 먼저 조회한다. 같은 입력 재시도는
model을 다시 호출하지 않고 durable 결과를 반환하며, 다른 입력은 `409` conflict다.
- agentic candidate는 hash만 남기지 않고 synthetic `draft_payload` JSONB도 함께 보존한다. 관리자 read
model에서 pending payload를 검토할 수 있다. 기존 수동 pipeline row는 nullable payload로 호환한다.
- 응답은 항상 `human_approval_required=true`, `catalog_promoted=false`,
`clinical_claim_allowed=false`여야 한다.
- 운영 오류 환류
- `POST /internal/continuous-improvement/incidents/{incident_record_id}/adversarial-content-pipelines`
기존 metadata-only incident를 승인 provenance source로 변환하고 동일 agentic benchmark gate에 넣는다.
- incident에 `pii_included=false`인 기존 계약을 유지하며 raw transcript를 source로 만들지 않는다.
- scheduled producer
- repo-approved synthetic source pack을 immutable `app.ci_agentic_job`으로 멱등 등록한다.
- API lifespan은 G8 schema contract가 ready이고
`VIGNETTE_CONTINUOUS_IMPROVEMENT_PRODUCER_ENABLED=true`일 때만 producer를 시작한다. 기본값은
`false`다.
- `FOR UPDATE SKIP LOCKED` lease와 bounded batch로 job을 격리한다. engine/structured 실패는 candidate
저장 없이 `retry_wait`, source/classification/안전 gate 실패는 `rejected`, 전 단계 통과만
`completed` + `pending_human_approval`이다.
- interval/startup delay/retry delay/lease/engine timeout/batch를 각각 명시 설정하며, producer에는 사람
approval event나 catalog entry를 만드는 코드 경로가 없다.
## 실제 engine + dev PostgreSQL 증거
실행 명령:
```powershell
$python311 = 'C:\Users\encep\AppData\Local\Programs\Python\Python311\python.exe'
& $python311 -X utf8 -B scripts\smoke-continuous-improvement-agentic-producer.py `
--out docs\ops\evidence\continuous-improvement-agentic-producer-live-2026-08-07.json
```
결과 JSON:
[`evidence/continuous-improvement-agentic-producer-live-2026-08-07.json`](./evidence/continuous-improvement-agentic-producer-live-2026-08-07.json)
- engine readiness `ok=true`, 실제 provider/model은 모든 call에서
`claude_cli/claude-opus-4-8`이었다.
- 실제 호출은 generator 1 + 서로 독립적인 reviewer 2 + variant generator 1 + 독립 judge 3 = `7`회다.
- dev PostgreSQL 결과는 reviewer `2`, variant `3`, pass rate `1.0`, benchmark `qualified=true`다.
- pipeline과 qualification은 모두 `pending_human_approval`, source usage는 `approved`, source content hash와
prompt/payload SHA-256 및 repo provenance가 보존됐다.
- human approval event `0`, catalog row `0`, `clinical_claim_allowed=false`다.
- 같은 deterministic submission/qualification을 다시 실행하면 `idempotent_replay=true`, engine call `0`,
두 UUID가 모두 동일했다.
실패 폐쇄도 실제 DB에서 확인했다.
- [`evidence/continuous-improvement-agentic-producer-live-failure-2026-08-07.json`](./evidence/continuous-improvement-agentic-producer-live-failure-2026-08-07.json):
engine 호출 실패가 `retry_wait`로 남고 pipeline/qualification/catalog은 0건.
- [`evidence/continuous-improvement-agentic-producer-answer-leakage-failure-2026-08-07.json`](./evidence/continuous-improvement-agentic-producer-answer-leakage-failure-2026-08-07.json):
deterministic answer-leakage gate 거절 시 저장 0건.
- [`evidence/continuous-improvement-agentic-producer-redteam-failure-2026-08-07.json`](./evidence/continuous-improvement-agentic-producer-redteam-failure-2026-08-07.json):
실제 generator와 독립 reviewer 2개 호출 뒤 unresolved finding에서 저장 0건.
초기 live 출력은 입력용 contextless Korean-name 정규식이 `서운함`, `고쳐나가야` 같은 일반어를 NAME으로
오탐했다. source/input에는 기존 고재현율 PII gate를 유지하고, 이미 hash/PII 검증된 synthetic source에서 나온
모델 출력에만 라벨형 이름·자기소개·관계+이름·호칭·기관·연락처·주소 등 고신뢰 규칙을 적용했다. 명시적 이름과
전화번호 차단 회귀를 추가했다. answer leakage는 단일 주제어 공유가 아니라 opaque marker 정확 일치 또는 4-token
연속 답안 구절 재현을 결정론적으로 차단하고, 의미 수준 누출은 독립 reviewer와 judge가 계속 fail-closed로 판정한다.
## 자동 검증
```powershell
$python311 = 'C:\Users\encep\AppData\Local\Programs\Python\Python311\python.exe'
& $python311 -X utf8 -B -m pytest -p no:cacheprovider `
app/test_continuous_improvement_agentic.py `
app/test_continuous_improvement.py `
app/test_continuous_improvement_store.py `
app/test_runtime_schema_ssot.py `
app/test_measurement_contract.py -q
```
- agentic/scheduler/PII focused 결과: `42 passed`, producer+agentic focused 결과: `19 passed`.
- 전체 API/gateway 결과: `858 passed`, 기존 Starlette `python_multipart` pending-deprecation warning 1건.
- fake engine seam이 generator 1 + 독립 red-team 2 + variant generator 1 + judge 3 = 7 calls를 확인한다.
- source/prompt/payload hash와 reviewer payload hash 일치, reviewer ID 독립성, variant 3건 독립 judge를 확인한다.
- structured output 실패, 생성 PII, visible answer leakage, red-team 무근거 임상 주장 finding, reward-hacking
judge 실패 각각에서 store 미호출을 확인한다.
- 같은 submission 재시도는 agent call 0, changed input은 model call 전 conflict를 확인한다.
- 운영 incident→adversarial source hash/provenance→benchmark runner 인계를 확인한다.
- Ruff: 변경 Python 파일 전건 통과.
- OpenAPI generated types 재생성 후 `npm run check:api-types` 통과.
- `npm run typecheck` 통과.
## 운영 drift trigger와 독립 안전 감사
- `VIGNETTE_CONTINUOUS_IMPROVEMENT_DRIFT_TRIGGER_ENABLED=false`를 별도 기본값으로 추가했다. producer와
trigger가 모두 true일 때만 G6 합성 drift 원장을 주기적으로 읽는다.
- G6의 전체 `-0.05`·subgroup `-0.10` canonical 임계값과 `supervision_drift_subgroup_metric` 근거를 다시
대조하고, 점수·표본수·delta·alert 집합이 일치할 때만 metadata-only incident·4-node DAG·
`scheduled_incident` job을 같은 research 트랜잭션에서 멱등 enqueue한다.
- 독립 리뷰가 `drift_flagged`와 alert 문자열만 믿던 fail-open을 RED로 재현해 위 검증으로 수정했다.
- 실 DB에서 research view 후보 5·supervisor view 0, incident 1·DAG 4·job 1, replay 중복 0,
approval/catalog 증가 0, rollback residue 0과 advisory-lock 동시성을 확인했다.
- 채워진 dev DB에서 전역 row count를 가정하던 G8 ledger smoke도 실행 UUID 범위로 격리했다. 연속 재실행 뒤
관련 16개 테이블 fixture residue 0, 기존 가시 데이터 SHA-256 전후 동일을 확인했다.
## 실제 pending payload 사람 검수 → approved-only catalog
- 기존 실제 Claude 7-call 후보 `2713aa69-3f54-5749-b1f9-dda75d43c896`를 사용했다. 새 모델 호출은 0회다.
- 격리 API `8011`·web `5181` 관리자 브라우저에서 승인 전 catalog 0→승인 후 정확히 1,
append-only approval event 1을 확인하고 DB의 `catalog_rows=1`, `approval_rows=1`과 대조했다.
- learner/teacher는 403, 동일 승인 replay는 멱등, 내용이 달라진 replay는 409다.
- catalog projection과 UI에는 hidden answer·raw transcript·PII·clinical claim이 노출되지 않는다.
- 별도 실제 엔진 생성은 독립 reviewer가 `answer_leakage:high`를 찾아 422로 거절했다. 이 후보는
pipeline/catalog에 저장되지 않았고 gate를 완화하거나 재시도하지 않았다.
- route/store/agentic 53 passed, 관리자 cockpit desktop/mobile 8/8, live E2E 1 passed·생성형 1 skipped,
typecheck·build·API schema gate를 통과했다. 격리 8011/5181 프로세스와 포트는 종료했다.
## release agent 폐루프
- `scripts/run-outcome-os-release-agent.py`는 기본 dry-run이며 정확한 격리 NAS target만 허용한다.
- material milestone, release patch 2회 결정성, manifest SHA binding, clean HEAD/canonical index,
API 전체·web contract/type/build·회기 E2E를 통과한 변경 SHA만 승격한다.
- 현재 API/web 이미지와 canonical Compose 경로를 snapshot한 뒤 API/web/proxy만 갱신하고,
semantic health·401 auth·G0~G8 OpenAPI·실제 브라우저 SSE→DB-backed review를 확인한다.
- postdeploy 실패는 이전 이미지·Compose로 rollback하고 이미지 ID와 복구 뒤 runtime을 다시 증명한다.
- 독립 감사에서 untracked active-state/image drift, 경로 탈출, candidate env secret archive 포함,
병렬 후보 Compose volume 충돌 네 결함을 RED→최소 수정했다.
- release-agent 20/20, release manifest·preflight·NAS env 포함 governance, 전체 API/gateway 891 passed,
web API contract·typecheck·build, 자기주도/관리자/회기 desktop/mobile 26/26을 통과했다.
## 실제 격리 NAS 승격
- exact release SHA `e9b482ccba616a610c1f4862366d44aabae20ee8c82d8ef7f2cf16069f2d6e99`
`vignette-preview-20260807`에 실제 승격했다.
- 최종 이미지: API `sha256:3f195b5d7dd7ac4dd215bb4a9d6cb571cc333a0ee4761f69f5ba030ea9e81c72`,
Web `sha256:b8c08c5d3f4a6c7a83050dbc1e6c76c412664ab8b2c65227deff362142829452`.
- 최종 runtime은 health ok·db/engine true·OpenAPI 123·auth 401·G0~G8를 통과했고,
readiness는 API/Web 교체 뒤 3회째 성공했다.
- 실제 NAS postdeploy browser SSE→DB-backed review가 통과했고 물리 마이크는 사용하지 않았다.
- 승격 직후 단발 502를 만난 선행 실행은 기존 이미지로 자동 rollback한 뒤 이미지 ID, health,
OpenAPI 122, auth 401을 재검증했다. 이 실증을 바탕으로 transient readiness만 bounded retry하고
영구 계약 실패는 즉시 rollback하도록 강화했다.
- Windows clean candidate `bash\r`, legacy NAS env 경로, readiness race를 각각 RED 증거로 재현하고
LF 정규화·snapshot env 추적/preflight·180초 bounded readiness로 닫았다.
이 exact SHA의 대시보드·TODO·백로그·manifest handoff까지 동기화했다. G7의 Deepgram·물리 마이크·
50분 외부 증거와는 독립된 G8 릴리스 게이트이며, G8은 DONE이다.