vignette/docs/ops/outcome-os-release-hunk-map-2026-08-07.json
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

1122 lines
45 KiB
JSON
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

{
"schema_version": "1.0",
"map_id": "outcome-os-release-hunk-map-2026-08-07",
"base_commit": "76d0b9ae9bb11b62af86ccd9a55e798bbedc9e31",
"manifest": "docs/ops/outcome-os-clean-release-manifest-2026-08-07.json",
"output_patch": "docs/ops/evidence/outcome-os-release-only-2026-08-07.patch",
"policy": {
"selection_mode": "fail-closed",
"whole_file_source": "manifest classifications.related, excluding release-governance artifacts",
"mixed_default": "blocked unless every current hunk has an exact SHA-256 mapping",
"generated_file_rule": "api.gen.ts는 수동 hunk를 적용하지 않고 clean HEAD에 related apps/api 소스를 overlay한 뒤 공식 npm script로 재생성한다.",
"working_tree_rule": "assembly와 git apply --check는 임시 디렉터리에서만 실행하며 현재 worktree 파일을 덮어쓰지 않는다. 후보 patch는 모든 guard 통과 후에만 기존 artifact를 원자 교체하고 실패 시 이전 artifact를 복구한다.",
"line_ending_rule": "모든 patch hunk를 canonical LF로 정규화하고 clean checkout git apply --check와 임시 canonical index git apply --cached --check를 모두 통과해야 한다.",
"base_guard": "patch는 base_commit 76d0b9ae9bb11b62af86ccd9a55e798bbedc9e31 전용이며 다른 HEAD/index에는 적용하지 않는다."
},
"payload": {
"excluded_related_group_ids": [
"clean-release-governance"
],
"excluded_paths": [
"docs/ops/evidence/outcome-os-release-only-2026-08-07.patch",
"docs/ops/evidence/g1-alliance-mid-chromium-desktop-2026-08-07.png",
"docs/ops/evidence/g1-alliance-mid-chromium-mobile-2026-08-07.png",
"docs/ops/evidence/g1-alliance-pre-chromium-desktop-2026-08-07.png",
"docs/ops/evidence/g1-alliance-pre-chromium-mobile-2026-08-07.png",
"docs/ops/evidence/nas-preview-live-turn-2026-08-07.png",
"docs/ops/evidence/nas-preview-learner-home-2026-08-07.png",
"docs/ops/evidence/nas-preview-learner-session-2026-08-07.png",
"docs/ops/evidence/self-directed-loop-active-session-320x568-chromium-mobile-2026-08-07.png",
"docs/ops/evidence/self-directed-loop-active-session-chromium-desktop-2026-08-07.png",
"docs/ops/evidence/self-directed-loop-active-session-chromium-mobile-2026-08-07.png",
"docs/ops/evidence/self-directed-loop-home-chromium-desktop-2026-08-07.png",
"docs/ops/evidence/self-directed-loop-home-chromium-mobile-2026-08-07.png",
"docs/ops/evidence/self-directed-loop-repractice-prestart-chromium-desktop-2026-08-07.png",
"docs/ops/evidence/self-directed-loop-repractice-prestart-chromium-mobile-2026-08-07.png",
"docs/ops/evidence/self-directed-loop-review-prescription-chromium-desktop-2026-08-07.png",
"docs/ops/evidence/self-directed-loop-review-prescription-chromium-mobile-2026-08-07.png"
]
},
"generated_files": [
{
"path": "apps/web/src/lib/api.gen.ts",
"strategy": "regenerate-from-clean-related-api-sources",
"related_source_prefix": "apps/api/",
"generate_command": "npm.cmd run generate:api-types",
"check_command": "npm.cmd run check:api-types",
"required_markers": [
"AllianceScores: {",
"\"/sessions/{session_id}/alliance-pulses\"",
"\"/sessions/{session_id}/outcome-trajectory\"",
"\"/sessions/{session_id}/ruptures\"",
"\"/practice/learners/me\"",
"\"/calibration/learners/me\"",
"\"/supervision-research/supervision-view\"",
"\"/sessions/{session_id}/multimodal-alliance\"",
"\"/continuous-improvement\""
],
"forbidden_markers": [
"token_unmetered_turns",
"recorded_cost_usd",
"estimated_cost_usd",
"cost_basis"
],
"rationale": "현재 생성물에는 G0-G8 계약과 X2 가격·Claude usage 계약이 함께 있다. clean-base 재생성은 G0-G8 라우트는 보존하고 제외된 API 소스의 새 telemetry schema를 포함하지 않는다."
}
],
"documents": [
{
"path": "apps/api/app/routes/admin.py",
"hunks": [
{
"header": "@@ -40 +39,0 @@ from ..runtime_policy import require_runtime_fallback_allowed",
"sha256": "b806f8c1065805d38ebc44d9ebf84f0ffc36988ca5247c121aeabe48a989b35f",
"decision": "include",
"goals": ["G7"],
"rationale": "기존 voice_service import 위치를 제거하고 G7 runtime import 블록으로 이동한다."
},
{
"header": "@@ -41,0 +41,6 @@ from ..services import evaluator, notifications, rag",
"sha256": "f58a8acf0af3857cd75976f5a884f070e0bf24305b3dc3e4439070356952624e",
"decision": "split-added-lines",
"include_added_line_numbers": [5, 6],
"exclude_added_line_numbers": [1, 2, 3, 4],
"goals": ["G7"],
"rationale": "같은 순수 삽입 hunk에서 X2 가격 import 4줄은 제외하고 G7 voice runtime import 2줄만 포함한다."
},
{
"header": "@@ -48,0 +54,6 @@ UsageBudgetStatus = Literal[\"disabled\", \"ok\", \"warn\", \"exceeded\"]",
"sha256": "adf5330a722262c46f5a23b793453dcd6cf85709f8757bbec40f966d84f8cef2",
"decision": "exclude",
"goals": [],
"rationale": "X2 usage cost-basis 계약이므로 G7 릴리스에서 제외한다."
},
{
"header": "@@ -71,0 +83,6 @@ USAGE_AGGREGATE_COLUMNS_SQL = \"\"\"",
"sha256": "96ff66f751165775bf7721a7ab693afa6eb4effde46d9fbf5c584842d4f6d309",
"decision": "exclude",
"goals": [],
"rationale": "X2 token metering SQL이므로 G7 릴리스에서 제외한다."
},
{
"header": "@@ -74 +91,10 @@ USAGE_AGGREGATE_COLUMNS_SQL = \"\"\"",
"sha256": "76cf86350fcc6caf43e876b292261c9398c23491e391ee5f4e95c66898424027",
"decision": "exclude",
"goals": [],
"rationale": "X2 가격 추정 집계 SQL이므로 G7 릴리스에서 제외한다."
},
{
"header": "@@ -145,0 +172,2 @@ class AdminUsageBreakdown(BaseModel):",
"sha256": "57c2c6aa426e75cff1d7268381d3d0b9e458c7800dba5cb9f8c25d24f38c0b33",
"decision": "exclude",
"goals": [],
"rationale": "X2 token coverage 응답 필드이므로 제외한다."
},
{
"header": "@@ -148,0 +177,5 @@ class AdminUsageBreakdown(BaseModel):",
"sha256": "bee7b09c71dfe80f12aaf25288a3d227d78c74e8cc27c999e0ec5806f15c5c3e",
"decision": "exclude",
"goals": [],
"rationale": "X2 비용 근거 응답 필드이므로 제외한다."
},
{
"header": "@@ -183,0 +217,2 @@ class AdminUsageResponse(BaseModel):",
"sha256": "f57dcc26382024550483d6ce0cb7dfd2babb0e9d7271e8b2d3ee8247f4c3f6f3",
"decision": "exclude",
"goals": [],
"rationale": "X2 token coverage 합계 필드이므로 제외한다."
},
{
"header": "@@ -186,0 +222,2 @@ class AdminUsageResponse(BaseModel):",
"sha256": "d42088c3c9761283e2757e53316d167b42aef12d048ba9266082ce15ccff45e3",
"decision": "exclude",
"goals": [],
"rationale": "X2 비용 합계 필드이므로 제외한다."
},
{
"header": "@@ -421,0 +459,64 @@ def _safe_usage_int(value: object) -> int:",
"sha256": "fd8ed3bcaf6fb22693438feb1b7ead7c697fd97a64a9ab2f5810a8d7f1c9e595",
"decision": "exclude",
"goals": [],
"rationale": "X2 provider/model 비용 breakdown 계산이므로 제외한다."
},
{
"header": "@@ -529,0 +631,9 @@ async def _usage_from_database(window_days: int) -> AdminUsageResponse:",
"sha256": "0d859ef6d396e26dbff9c40ac35e774a5bfd099974ae3c0efeaaacd9a8123e75",
"decision": "exclude",
"goals": [],
"rationale": "X2 DB token coverage 집계이므로 제외한다."
},
{
"header": "@@ -548,5 +657,0 @@ async def _usage_from_database(window_days: int) -> AdminUsageResponse:",
"sha256": "ab1c9bb19ae9c3bc46440efa6ac8dde1a78126019d7b1a78bc5c1583e7724e7f",
"decision": "exclude",
"goals": [],
"rationale": "X2 usage 정렬 변경의 일부이므로 제외한다."
},
{
"header": "@@ -559,0 +665,2 @@ async def _usage_from_database(window_days: int) -> AdminUsageResponse:",
"sha256": "d74498de4e921d23ddb9a176041320e81e1bf972f098d3fedc9962b484a65aaf",
"decision": "exclude",
"goals": [],
"rationale": "X2 provider/model 일별 집계이므로 제외한다."
},
{
"header": "@@ -564,2 +671,2 @@ async def _usage_from_database(window_days: int) -> AdminUsageResponse:",
"sha256": "9b88ae31c9a127c4da9a64e69be0b1f62eda33d6811004e0271bfeaccc5794f8",
"decision": "exclude",
"goals": [],
"rationale": "X2 provider/model SQL grouping이므로 제외한다."
},
{
"header": "@@ -570 +677,52 @@ async def _usage_from_database(window_days: int) -> AdminUsageResponse:",
"sha256": "3dda40929b2c5e684294946184df9ddac410fbead3ac786e6f748cef441e31ad",
"decision": "exclude",
"goals": [],
"rationale": "X2 recorded/reference cost breakdown 조립이므로 제외한다."
},
{
"header": "@@ -577,0 +736,6 @@ async def _usage_from_database(window_days: int) -> AdminUsageResponse:",
"sha256": "bbddffe78c5c0fec8c7757550c23b5a8cf2d05acaf5db47d5043db19580d1628",
"decision": "exclude",
"goals": [],
"rationale": "X2 token coverage 응답 조립이므로 제외한다."
},
{
"header": "@@ -580,0 +745,2 @@ async def _usage_from_database(window_days: int) -> AdminUsageResponse:",
"sha256": "61c78dbbc984b35b8ee867f72c669f1f61643f080dda81c3e0ceef3c390707bb",
"decision": "exclude",
"goals": [],
"rationale": "X2 비용 합계 응답 조립이므로 제외한다."
},
{
"header": "@@ -583,11 +749 @@ async def _usage_from_database(window_days: int) -> AdminUsageResponse:",
"sha256": "c25d38bc91a2152fd742cdffc6cbdbab223114d2030e60f4e8a6c5d74e685a8d",
"decision": "exclude",
"goals": [],
"rationale": "X2 usage breakdown 응답 교체이므로 제외한다."
},
{
"header": "@@ -596,5 +752,5 @@ async def _usage_from_database(window_days: int) -> AdminUsageResponse:",
"sha256": "23c6f8523e60f550d74a138c4ed4942078c12ac4db224271d624a7730a2ee02a",
"decision": "exclude",
"goals": [],
"rationale": "X2 일별 비용 bucket 응답이므로 제외한다."
},
{
"header": "@@ -602 +758 @@ async def _usage_from_database(window_days: int) -> AdminUsageResponse:",
"sha256": "cbb352a280ec60254162ba61ac7e54a64b3324300ab67ae252c74f549adbb70c",
"decision": "exclude",
"goals": [],
"rationale": "X2 일별 비용 bucket 순회 변경이므로 제외한다."
},
{
"header": "@@ -875,0 +1032,2 @@ def _usage_from_runtime_store(window_days: int) -> AdminUsageResponse:",
"sha256": "34dc1e145fb8ea5cef95dc5d2b79e4e8698ddff5995d23503122521189c08671",
"decision": "exclude",
"goals": [],
"rationale": "X2 runtime token coverage 누계이므로 제외한다."
},
{
"header": "@@ -878,0 +1037,2 @@ def _usage_from_runtime_store(window_days: int) -> AdminUsageResponse:",
"sha256": "d828c75b8fca36a3b594ab7c667a5a09417e8438f15b4300fcc181f571d260c4",
"decision": "exclude",
"goals": [],
"rationale": "X2 runtime 비용 누계이므로 제외한다."
},
{
"header": "@@ -904,0 +1065,5 @@ def _usage_from_runtime_store(window_days: int) -> AdminUsageResponse:",
"sha256": "028dfd4d301fca8dfb2ce3bf26cf466e3f079159dde2e06fafc691c9d653b2d3",
"decision": "exclude",
"goals": [],
"rationale": "X2 runtime token metering 판정이므로 제외한다."
},
{
"header": "@@ -907 +1072,15 @@ def _usage_from_runtime_store(window_days: int) -> AdminUsageResponse:",
"sha256": "50341c03dd77b79ed76a78b982b6ae2384809ec4d53b6ad029ee7aee3ef60a58",
"decision": "exclude",
"goals": [],
"rationale": "X2 runtime turn 비용 breakdown이므로 제외한다."
},
{
"header": "@@ -911 +1090,10 @@ def _usage_from_runtime_store(window_days: int) -> AdminUsageResponse:",
"sha256": "abe5f388c7082245249877833c25f8c6a8635567aa215ed5dfe87c745fd9fc98",
"decision": "exclude",
"goals": [],
"rationale": "X2 runtime provider bucket 확장이므로 제외한다."
},
{
"header": "@@ -913,0 +1102,4 @@ def _usage_from_runtime_store(window_days: int) -> AdminUsageResponse:",
"sha256": "a6abfd3e8b82942e997ee5811d2d7686b29811a62e361abc113e1616c81b5ad8",
"decision": "exclude",
"goals": [],
"rationale": "X2 runtime token coverage bucket이므로 제외한다."
},
{
"header": "@@ -916 +1108,8 @@ def _usage_from_runtime_store(window_days: int) -> AdminUsageResponse:",
"sha256": "26e0d0094af0a055fe572d345727a09272d96055ab09b52eb5d82bbc40c1ae06",
"decision": "exclude",
"goals": [],
"rationale": "X2 runtime unpriced token bucket이므로 제외한다."
},
{
"header": "@@ -925 +1124,3 @@ def _usage_from_runtime_store(window_days: int) -> AdminUsageResponse:",
"sha256": "642e0ae1d06e23f69cf15d6b8431a7365e75782d3641e6f074310dfc239f244e",
"decision": "exclude",
"goals": [],
"rationale": "X2 일별 추정비용 누계이므로 제외한다."
},
{
"header": "@@ -928 +1129 @@ def _usage_from_runtime_store(window_days: int) -> AdminUsageResponse:",
"sha256": "225329bdedf7d3bdd4f56c986b13a1f992d0ff3176faba5a027a39628dced135",
"decision": "exclude",
"goals": [],
"rationale": "X2 runtime usage helper 전환이므로 제외한다."
},
{
"header": "@@ -931,0 +1133,2 @@ def _usage_from_runtime_store(window_days: int) -> AdminUsageResponse:",
"sha256": "3bb2a691657ad3c491dd9d1c1179a46d425a6a073aeee7c526f9f7155c74d525",
"decision": "exclude",
"goals": [],
"rationale": "X2 runtime token coverage 필드이므로 제외한다."
},
{
"header": "@@ -934 +1137,3 @@ def _usage_from_runtime_store(window_days: int) -> AdminUsageResponse:",
"sha256": "b729b7ca2e191c2538ba3604d39e1db40519dec3d21c6f28d50a738c0d5b0e33",
"decision": "exclude",
"goals": [],
"rationale": "X2 runtime 비용 근거 입력이므로 제외한다."
},
{
"header": "@@ -936,8 +1141 @@ def _usage_from_runtime_store(window_days: int) -> AdminUsageResponse:",
"sha256": "7e9aab4965a2cde5385304fb0ea2f48f67bb3c4593d6745aac3f8d1d69a9847b",
"decision": "exclude",
"goals": [],
"rationale": "X2 runtime breakdown 순회 변경이므로 제외한다."
},
{
"header": "@@ -944,0 +1143,9 @@ def _usage_from_runtime_store(window_days: int) -> AdminUsageResponse:",
"sha256": "7bbf11ae7521dbdbad01f540dd3371e44481e874546c842340ffe117566d0f57",
"decision": "exclude",
"goals": [],
"rationale": "X2 runtime breakdown 정렬이므로 제외한다."
},
{
"header": "@@ -953,0 +1161,2 @@ def _usage_from_runtime_store(window_days: int) -> AdminUsageResponse:",
"sha256": "cfe2625d26540ebcfc39138fd2bd69afa0d92383f7654c1c1a1f31407dabf30a",
"decision": "exclude",
"goals": [],
"rationale": "X2 runtime token coverage 응답이므로 제외한다."
},
{
"header": "@@ -956,0 +1166,2 @@ def _usage_from_runtime_store(window_days: int) -> AdminUsageResponse:",
"sha256": "3582493478c59af39dcca4df2ae16dd09437c27dd5e414764a13f68ada74821c",
"decision": "exclude",
"goals": [],
"rationale": "X2 runtime 비용 합계 응답이므로 제외한다."
},
{
"header": "@@ -959 +1170 @@ def _usage_from_runtime_store(window_days: int) -> AdminUsageResponse:",
"sha256": "50f4b537b95c0817edaed80c8f754a8cdf603c2a34ff8e7f6470e4b33e2ff612",
"decision": "exclude",
"goals": [],
"rationale": "X2 runtime breakdown 제한이므로 제외한다."
},
{
"header": "@@ -1485,0 +1697,9 @@ async def admin_health(principal: AdminPrincipal) -> AdminHealthResponse:",
"sha256": "8256627e63a283d745d16a97797d7a7fab170859dc6e9ac21e8efbe8a1d13fa1",
"decision": "include",
"goals": ["G7"],
"rationale": "관리자 인증 경계 안에서 metadata-only voice worker high-water snapshot을 제공하는 G7 endpoint다."
}
]
},
{
"path": "docs/dev_dashboard.html",
"hunks": [
{
"header": "@@ -53 +53 @@",
"sha256": "3c1e057cb1b73c9816216fc0d403128e4bae7223ead89a290e1c346f7d75395e",
"decision": "include",
"goals": [
"G0",
"G1",
"G2",
"G3",
"G4",
"G5",
"G6",
"G7",
"G8"
],
"rationale": "Outcome OS 단계 rail 추가를 위한 6열 전환이다."
},
{
"header": "@@ -204 +204 @@",
"sha256": "af98ae7e7fd3189ba04bd08a3b7dab8a34b68dd8607b6d2258fc6c9055223248",
"decision": "include",
"goals": [
"G0",
"G1",
"G2",
"G3",
"G4",
"G5",
"G6",
"G7",
"G8"
],
"rationale": "Outcome OS roadmap 카드가 추가된 현재 3열 배치다."
},
{
"header": "@@ -275 +275 @@",
"sha256": "5e85518a2306180cc5930f0ba4874b19877f9e831824ed00f544cf4e525f95d5",
"decision": "include",
"goals": [
"G0",
"G1",
"G2",
"G3",
"G4",
"G5",
"G6",
"G7",
"G8"
],
"rationale": "Outcome OS 승격 스냅샷 날짜다."
},
{
"header": "@@ -285 +285 @@",
"sha256": "d4d86e841da6e1bb45d0afa47dacf917f804f86bf33743c8e024de9c0e60817b",
"decision": "include",
"goals": [
"G0",
"G1",
"G2",
"G3",
"G4",
"G5",
"G6",
"G7",
"G8"
],
"rationale": "공개 Outcome 승격, G8 agentic worker의 현행 BUILD 경계와 G7 외부 gate를 pulse에 기록한다."
},
{
"header": "@@ -290 +290,2 @@",
"sha256": "01538f799d36cad20a003479e248f74b53619575d271d716176f88a4e505ada7",
"decision": "include",
"goals": [
"G0",
"G1",
"G2",
"G3",
"G4",
"G5",
"G6",
"G7",
"G8"
],
"rationale": "clean release E2E·시각 게이트와 G1 gold 결과 chip이다."
},
{
"header": "@@ -292,2 +293,2 @@",
"sha256": "d2dff79506ee1829f38ff3d4712e2a689b9ecb13e39a7162b1b5cd54547d15e4",
"decision": "include",
"goals": [
"G0",
"G1",
"G2",
"G3",
"G4",
"G5",
"G6",
"G7",
"G8"
],
"rationale": "공개 G1~G8 route와 direct-runtime app-role preflight 종료 chip이다."
},
{
"header": "@@ -610,0 +612,23 @@",
"sha256": "eb067b7b4a657a9bd2416d2cdb9c27764120a3620a1f63676e356ba3447d155c",
"decision": "split-added-lines",
"include_added_line_numbers": [
4,
5,
6,
7,
8,
9,
10,
11,
12,
13,
14,
15,
16,
17,
18,
19,
20,
21,
22,
23
],
"exclude_added_line_numbers": [
1,
2,
3
],
"goals": [
"G1",
"G2",
"G3",
"G4",
"G5",
"G6",
"G7",
"G8"
],
"rationale": "연속 삽입 23줄 중 X2 가격·Claude usage 3줄은 제외하고 G1~G8, self-directed, producer, gateway/NAS preview·G8 폐루프·G7 외부 증거 준비와 새 exact SHA 승격 기록 20줄만 포함한다."
},
{
"header": "@@ -825,0 +850,43 @@",
"sha256": "94aa27466e398e829e4435603f0e75d776e1e3175b5d3e5a5dd55bcc72e43fca",
"decision": "include",
"goals": [
"G0",
"G1",
"G2",
"G3",
"G4",
"G5",
"G6",
"G7",
"G8"
],
"rationale": "G8 공개 종료와 G7 명시 동의 물리/50분 gate가 반영된 Outcome & Alliance OS G0-G8 정식 상태 track 전체다."
},
{
"header": "@@ -838 +905 @@",
"sha256": "66518ff65b799aefc392cd0c7acc43ccb19d297902e2aa2ab1b0a4eaec87a1fe",
"decision": "include",
"goals": [
"G0",
"G1",
"G2",
"G3",
"G4",
"G5",
"G6",
"G7",
"G8"
],
"rationale": "기존 로드맵 제목에 Outcome OS를 추가한다."
},
{
"header": "@@ -845,0 +913 @@",
"sha256": "2b216f4879ab98d8c2f50d8bdbf823619447e2f2c855ba820ffc2de5656d2d08",
"decision": "include",
"goals": [
"G0",
"G1",
"G2",
"G3",
"G4",
"G5",
"G6",
"G7",
"G8"
],
"rationale": "G0~G6·G8와 AOS-001~012 완료, G7 잔여 gate를 보여주는 Outcome OS roadmap phase 카드다."
},
{
"header": "@@ -932 +1000 @@",
"sha256": "948bd12a757292010d4417a463f828865667f30fac786f0bbda7f05aa1cac791",
"decision": "include",
"goals": [
"G7",
"G8"
],
"rationale": "G7 실제 외부 음성 gate와 G8 worker의 남은 운영 폐루프를 과장 없이 유지한다."
},
{
"header": "@@ -975,0 +1044,6 @@",
"sha256": "8aed1150b1b638c3265fd069fd6de88265d7711b16aba4b9256e56b3fecbd22e",
"decision": "include",
"goals": [
"G0",
"G1",
"G3"
],
"rationale": "G0~G6 production producer와 self-directed loop를 포함한 Outcome 검증 행이다."
},
{
"header": "@@ -978,2 +1052,2 @@",
"sha256": "a1611143c1e07cf112e87c28d2a754b838c0cf3b3f60e06aa0a0524de7a4f6b0",
"decision": "exclude",
"goals": [],
"rationale": "Backend 전체 baseline과 X2 evaluator 가격·cache·cost 검증 갱신으로 Outcome 전용 증거가 아니다."
},
{
"header": "@@ -1008 +1082 @@",
"sha256": "ec4a3fefb38b3d98867669c4f73f2a53b47940ceb25813624faf30268dd94577",
"decision": "exclude",
"goals": [],
"rationale": "관리자 AI 비용·token telemetry UI 검증 갱신이다."
},
{
"header": "@@ -1027,0 +1102 @@",
"sha256": "56e0fd3d0a67dc255d1bbf3a06aa01fd3a055191bd548d4fc76375367a3faa8c",
"decision": "include",
"goals": [
"G7"
],
"rationale": "G7 동의·public v4 lifecycle·runtime/topology·human-held-out 외부 증거 준비와 실제 미실행 BUILD 경계를 검증 행에 기록한다."
},
{
"header": "@@ -1042,0 +1118 @@",
"sha256": "7288c9ab5747be9bb86b177753676eb94c1f00722cb5eb5c1be1bccb088c09d6",
"decision": "include",
"goals": [
"G0",
"G1",
"G2",
"G3",
"G4",
"G5",
"G6",
"G7",
"G8"
],
"rationale": "NAS 격리 프리뷰의 실제 브라우저 회기, durable review, 자동 회귀 감시와 G7 잔여 외부 gate를 검증 행에 기록한다."
},
{
"header": "@@ -1076 +1152 @@",
"sha256": "ccfffb08dad64afd15042e767a6da0a2330d39ca2b608e4da0bb620ae16fffe1",
"decision": "exclude",
"goals": [],
"rationale": "Claude CLI token backfill 원장 증거다."
},
{
"header": "@@ -1094 +1170 @@ powershell -NoProfile -ExecutionPolicy Bypass -File scripts\\start-public-runtime",
"sha256": "cb1a903eef2276889e2e948bb9d4eca264613dc13d61ccfdafe571ef4dcc01c5",
"decision": "include",
"goals": [
"G7"
],
"rationale": "환경 제약 목록에서 내부 완료된 OpenAI TTS 권리·고지를 제거하고 실제 외부 음성 실증만 유지한다."
},
{
"header": "@@ -1241 +1317,2 @@ powershell -NoProfile -ExecutionPolicy Bypass -File scripts\\start-public-runtime",
"sha256": "a93424b73210474624d83183f93743ede1c5e7afb474838d4ee7c59a9e2ec93c",
"decision": "include",
"goals": [
"G0",
"G1",
"G2",
"G3",
"G4",
"G5",
"G6",
"G7",
"G8"
],
"rationale": "대시보드 진행 rail에 AOS를 추가한다."
}
]
},
{
"path": "docs/guides/architecture.md",
"hunks": [
{
"header": "@@ -60 +60 @@ vignette/",
"sha256": "241cd42400e39a08e2628a1c474cec37db64f085c7af9cb6519a2efd2a806f22",
"decision": "include",
"goals": [
"G7"
],
"rationale": "음성 외부 provider 경계를 HTTPS/WSS로 명시한다."
},
{
"header": "@@ -62,2 +62,2 @@ vignette/",
"sha256": "02172cc769819ec69eb42d9dbdc6adb2c771d9cab9e118be4daf2370e1486094",
"decision": "include",
"goals": [
"G7"
],
"rationale": "Deepgram/OpenAI/Higgs streaming STT/TTS provider 구조를 아키텍처 도식에 반영한다."
},
{
"header": "@@ -74,0 +75 @@ vignette/",
"sha256": "2c1572f6af3c86b253d2b47b289bd69deab088563f817279e596bdc4efdf882f",
"decision": "include",
"goals": [
"G0",
"G1",
"G2",
"G3",
"G4",
"G5",
"G6",
"G7",
"G8"
],
"rationale": "API EngineClient가 선택 shared secret을 모든 gateway 호출에 전달하는 경계다."
},
{
"header": "@@ -231 +232,7 @@ RBAC×AIView로 차단된다. 이 모듈은 평가 신호만 산출한다.",
"sha256": "fa4c8a6a6eed185741e8aaecccb03c552084466287067dc065d20edad867bc0f",
"decision": "exclude",
"goals": [],
"rationale": "Provider 비용 추정 basis와 미등록 단가 처리다."
},
{
"header": "@@ -308 +315,6 @@ STT/TTS 어댑터(순수 변환 + voice preset 매핑). 상담 로직은 라우",
"sha256": "519f12c68a85f606362ae17cd1723fbb479fe37211cadd5a264902069b65257e",
"decision": "include",
"goals": [
"G7"
],
"rationale": "Deepgram streaming과 OpenAI batch fallback의 provider 계약이다."
},
{
"header": "@@ -325 +337,3 @@ STT/TTS 어댑터(순수 변환 + voice preset 매핑). 상담 로직은 라우",
"sha256": "1dd0e57302304f2a44d213fd92d81a80a68a23f4413d85cc83d01750ae95bd31",
"decision": "include",
"goals": [
"G7"
],
"rationale": "credential 부재와 fallback metadata의 fail-closed 경계다."
},
{
"header": "@@ -334,0 +349,4 @@ server: ready → state(listening) → state(thinking) → transcript → reply",
"sha256": "ad841ea6f2c8eeb7e1f2ccb407abe276b5afa546abde7b1a536de9443ae04fe1",
"decision": "include",
"goals": [
"G7"
],
"rationale": "ready provider/model 계약과 열린 stream의 1초 동의 재검사를 설명한다."
},
{
"header": "@@ -343,0 +362,2 @@ server: ready → state(listening) → state(thinking) → transcript → reply",
"sha256": "4506a14d08d5c30abff4f5002686d8ebe8308798c229dab7ee60014fbe215022",
"decision": "include",
"goals": [
"G7"
],
"rationale": "음성 단절 시 텍스트 보존과 재연결 recovery 계약이다."
},
{
"header": "@@ -564,0 +585,6 @@ Codex CLI, Agy CLI의 모델 탐색·실행 차이를 흡수한다. Claude CLI",
"sha256": "e3b034c7f25d0b5ce2b819bfb1f24fae32a109679283e5bf889db5cf62b426be",
"decision": "include",
"goals": [
"G0",
"G1",
"G2",
"G3",
"G4",
"G5",
"G6",
"G7",
"G8"
],
"rationale": "gateway shared-secret의 liveness 예외, constant-time 검증과 비-placeholder 설정 계약이다."
},
{
"header": "@@ -579 +605 @@ cd apps/api && uvicorn engine_gateway.gateway:app --host 0.0.0.0 --port 9099",
"sha256": "dabd5aafd2b0e0c04fe8900cc5d794e8ed608316e0df010f3c54d6be564a35b8",
"decision": "exclude",
"goals": [],
"rationale": "gateway SSE done의 token telemetry 확장이다."
},
{
"header": "@@ -590,0 +617,10 @@ provider 라우팅 모드는 `ENGINE_MODE`(`app/config.py`) 또는 DB의 관리",
"sha256": "335b565f51b4c76440d71ae84ec1fcb2451a530dc20af4c6c8b03a742d37fb66",
"decision": "exclude",
"goals": [],
"rationale": "Claude modelUsage 집계·가격 추정·과거 token 백필 설명이다."
},
{
"header": "@@ -681 +717 @@ DB는 PostgreSQL 16 + pgvector(단일 SoR). 초기화 SQL은 `infra/db/init/`에",
"sha256": "02d7dd29805cc2464be9a6f39fa0c1588e401fb54a8c4948a166f4bb6463e090",
"decision": "include",
"goals": [
"G0"
],
"rationale": "G0 measurement foundation migration을 순서에 추가한다."
},
{
"header": "@@ -716,0 +753,93 @@ DB는 PostgreSQL 16 + pgvector(단일 SoR). 초기화 SQL은 `infra/db/init/`에",
"sha256": "03d3c4f21ee0704449419230c0c203f62f4f909e456ae1c53065c73209548ca5",
"decision": "include",
"goals": [
"G0",
"G1",
"G2",
"G3",
"G4",
"G5",
"G6",
"G7",
"G8"
],
"rationale": "G0-G8 원장, production producer와 역할·동의·승인 경계를 설명하는 Outcome OS 아키텍처다."
},
{
"header": "@@ -748,0 +878,3 @@ DB는 PostgreSQL 16 + pgvector(단일 SoR). 초기화 SQL은 `infra/db/init/`에",
"sha256": "2cb51ac51ea78dadfac3d7bedca6ad55deef21f9f7188be4d791d85c978581e8",
"decision": "include",
"goals": [
"G0",
"G1"
],
"rationale": "측정 실행 audit.model_run provenance 계약이다. provider/model 필드는 비용 telemetry가 아니라 G0/G1 측정 근거다."
},
{
"header": "@@ -755,0 +888,4 @@ AI자동(1R) → 인간검수(2R) → IAA 게이트(κ≥0.6, ICC≥0.75) → ",
"sha256": "3a5287091968e6b6b68ddaac2959cf91d1b107618f13c28db28c2622a08f09cd",
"decision": "include",
"goals": [
"G0"
],
"rationale": "G0 deterministic benchmark pack 설명이다."
},
{
"header": "@@ -760 +896,2 @@ DB 레벨 이중강제(`04_audit_eval_rls.sql` §5, `app/db.py` `acquire()`):",
"sha256": "6623c832adcf9af7c5f5a5da3970165dcdfc2973d6fe391f7590a5ec52743582",
"decision": "include",
"goals": [
"G0",
"G6"
],
"rationale": "measurement 원장의 supervisor/research AI view 확장이다."
},
{
"header": "@@ -868 +1005,2 @@ DB 레벨 이중강제(`04_audit_eval_rls.sql` §5, `app/db.py` `acquire()`):",
"sha256": "56930e445632763317beb46441a48ec276100710245571599388eea9db04f474",
"decision": "include",
"goals": [
"G7"
],
"rationale": "Deepgram credential fallback과 운영 OpenAI TTS exact model·AI 생성 음성 고지의 장애 경계다."
}
]
},
{
"path": "docs/guides/testing.md",
"hunks": [
{
"header": "@@ -18,2 +18,2 @@ Vignette 저장소의 모든 검증 수단(백엔드 단위 테스트, 웹 타",
"sha256": "f3eb2fdcdf86a6dc3ea28d0b98f1aa584ff8798ca30fa153b36ca3f54cd1bc50",
"decision": "exclude",
"goals": [],
"rationale": "2026-07-31 X2 작업 뒤 전체 suite 숫자 갱신이며 Outcome OS 이전 기록이다."
},
{
"header": "@@ -45,2 +45,2 @@ Vignette 저장소의 모든 검증 수단(백엔드 단위 테스트, 웹 타",
"sha256": "16ef768e138d8eee595fd6b695b99e350697e6bbf5d288053fcd9716cd837a90",
"decision": "exclude",
"goals": [],
"rationale": "2026-07-31 전체 suite 실행 주석 갱신이다."
},
{
"header": "@@ -52,2 +52,2 @@ python -m pytest engine_gateway/ -q # 게이트웨이 단위 테스트: 2026-0",
"sha256": "9163bb9438bd7cd94527278b251bb7eadffc2b1c8b55a0efe39a993363c5beaf",
"decision": "exclude",
"goals": [],
"rationale": "2026-07-31 collection 숫자 갱신이다."
},
{
"header": "@@ -277,0 +278,148 @@ VITE_API_BASE=http://127.0.0.1:8000 npm run e2e # 프록시 대신 API ",
"sha256": "14f4c3b78c3420ed6046dd8ac36c52274afb00584dc0c021890731b54b0b27b4",
"decision": "include",
"goals": [
"G0",
"G1",
"G2",
"G3",
"G4",
"G5",
"G6",
"G7",
"G8"
],
"rationale": "G0-G8 runtime producer, self-directed UI, gateway auth, NAS preview, G7 공개 경계와 release-only assembly의 Outcome 전용 검증 기록이다."
},
{
"header": "@@ -324,0 +473,3 @@ VITE_API_BASE=http://127.0.0.1:8000 npm run e2e # 프록시 대신 API ",
"sha256": "e7eff7f3d67107436b67cb0296dcbfd295b705371ed46a0d22354d1d5b700959",
"decision": "exclude",
"goals": [],
"rationale": "관리자 가격 원장, Claude usage와 과거 token 백필 검증이다."
}
]
},
{
"path": "apps/api/engine_gateway/gateway.py",
"hunks": [
{
"header": "@@ -13,0 +14 @@ import os",
"sha256": "ac6dfe9f8659c123012f6db8494ac5ff21e4f8b29219be7f8f361cc0a4a52183",
"decision": "include",
"goals": [
"G0",
"G1",
"G2",
"G3",
"G4",
"G5",
"G6",
"G7",
"G8"
],
"rationale": "constant-time 비교를 위한 secrets import다."
},
{
"header": "@@ -19 +20 @@ from typing import Any, Optional",
"sha256": "189d01a5ead31de834b1af6183a8e46fa7272dc5e50d0f54e38bddedc0aba43f",
"decision": "include",
"goals": [
"G0",
"G1",
"G2",
"G3",
"G4",
"G5",
"G6",
"G7",
"G8"
],
"rationale": "HTTP 인증 middleware의 Request import다."
},
{
"header": "@@ -60,0 +62,17 @@ GATEWAY_FALLBACK_MODEL_NAME = \"claude-opus-4-8\"",
"sha256": "9b96f4f6dcb8d77c3263ee52ce3b80c28eef20506c33b8d480ff56149fe1e9a4",
"decision": "include",
"goals": [
"G0",
"G1",
"G2",
"G3",
"G4",
"G5",
"G6",
"G7",
"G8"
],
"rationale": "32자 이상 비-placeholder gateway secret의 fail-fast 로드 계약이다."
},
{
"header": "@@ -85,0 +104,48 @@ BASE_ARGS = [",
"sha256": "e77229ed71bdf404d7fae9dfb5918e8e771fb2d367deb9b56294e09c0d3bcb4b",
"decision": "exclude",
"goals": [],
"rationale": "X2 Claude usage/modelUsage 집계 helper다."
},
{
"header": "@@ -160,0 +227 @@ class EngineSession:",
"sha256": "e4e9e46d62a46515103a8b5bfa5288f9e73927b66ec45fc5d847feed71c4ef2a",
"decision": "exclude",
"goals": [],
"rationale": "X2 Claude session token 추출이다."
},
{
"header": "@@ -171,0 +239,2 @@ class EngineSession:",
"sha256": "ecf05516b02091f5a2734c063fa78a75aa74e41d51a34151cbdcfe9b25308a25",
"decision": "exclude",
"goals": [],
"rationale": "X2 Claude session token 응답 필드다."
},
{
"header": "@@ -239,0 +309 @@ class EngineSession:",
"sha256": "955e0e6412df6a56632b67b899a1b24b0b6304b7bf98758c169feee1188b4708",
"decision": "exclude",
"goals": [],
"rationale": "X2 Claude stream token 추출이다."
},
{
"header": "@@ -251,0 +322,2 @@ class EngineSession:",
"sha256": "b8e58dc34900af3b94da92bad364b2f87742bdbe0995023723071282851d6543",
"decision": "exclude",
"goals": [],
"rationale": "X2 Claude stream token 응답 필드다."
},
{
"header": "@@ -274,0 +347,15 @@ app = FastAPI(title=\"Vignette Engine Gateway\")",
"sha256": "229485dcb3bc98726d491b29b54252f5bbd3dcd4f093021bc0161dab4ed650cf",
"decision": "include",
"goals": [
"G0",
"G1",
"G2",
"G3",
"G4",
"G5",
"G6",
"G7",
"G8"
],
"rationale": "/health만 예외로 두고 나머지 경로를 constant-time shared-secret으로 보호한다."
},
{
"header": "@@ -670,2 +757,2 @@ async def v1_generate(req: GwGenerateReq):",
"sha256": "ebd9019abc2927e7e4a342534bd0af096cfb90b97045c06c822f53de425d2838",
"decision": "exclude",
"goals": [],
"rationale": "X2 generate token telemetry 전달이다."
},
{
"header": "@@ -750,2 +837,2 @@ async def v1_stream(req: GwGenerateReq):",
"sha256": "350d963596bc3f84463761e3e781aed9e2b6f2232e3a282d3e64619617f99841",
"decision": "exclude",
"goals": [],
"rationale": "X2 stream token telemetry 전달이다."
}
]
},
{
"path": "apps/api/engine_gateway/test_gateway_model.py",
"hunks": [
{
"header": "@@ -2,0 +3 @@ import json",
"sha256": "19b6871b10b8276a02faee4b047c75ca9a528d97dcfdc9e4d03b65e267e1fe25",
"decision": "include",
"goals": [
"G0",
"G1",
"G2",
"G3",
"G4",
"G5",
"G6",
"G7",
"G8"
],
"rationale": "인증 비교 회귀의 secrets import다."
},
{
"header": "@@ -10,0 +12 @@ from jsonschema import Draft202012Validator",
"sha256": "e7de3a3d0a445e7a0636cef0950ba37c3d8b7814d21eb4ea9166d9a975596ebc",
"decision": "include",
"goals": [
"G0",
"G1",
"G2",
"G3",
"G4",
"G5",
"G6",
"G7",
"G8"
],
"rationale": "인증 HTTP 회귀의 TestClient import다."
},
{
"header": "@@ -197,0 +200,100 @@ class _FakeStreamSession:",
"sha256": "aa4b0dadfc81cba54d79b602c37715e2072c08ab288cdd50e732c050bfe36d66",
"decision": "include",
"goals": [
"G0",
"G1",
"G2",
"G3",
"G4",
"G5",
"G6",
"G7",
"G8"
],
"rationale": "localhost 호환, 401, /health 예외, /ready 보호, 약한 secret 거부, header 비노출과 EngineClient 전달 회귀다."
},
{
"header": "@@ -613 +715,19 @@ class GatewayModelTest(unittest.TestCase):",
"sha256": "6e1d1f34c2dcc5a6e02d02d1200f6e655baac7e6d84cc3cc3ea49e5c78f31c2b",
"decision": "exclude",
"goals": [],
"rationale": "X2 Claude modelUsage fixture다."
},
{
"header": "@@ -632,0 +753,2 @@ class GatewayModelTest(unittest.TestCase):",
"sha256": "24ac42d7a6d441dd708ee9d0195acaa9620adb1fa7805052e735da690bc4b6ba",
"decision": "exclude",
"goals": [],
"rationale": "X2 Claude token 합산 단언이다."
},
{
"header": "@@ -639,0 +762,15 @@ class GatewayModelTest(unittest.TestCase):",
"sha256": "385e8dd4c57f62af14eec207d80aafea76f866d9dbff771672e5c3e6b594e5d6",
"decision": "exclude",
"goals": [],
"rationale": "X2 최상위 usage fallback 회귀다."
},
{
"header": "@@ -773 +910,7 @@ class GatewayModelTest(unittest.TestCase):",
"sha256": "6d7d7078d0efe9e3f722479dfedb587523bdc58502824d0f931f0ce89f6f3721",
"decision": "exclude",
"goals": [],
"rationale": "X2 재사용 session token fixture다."
},
{
"header": "@@ -786,0 +930,2 @@ class GatewayModelTest(unittest.TestCase):",
"sha256": "072d44dcb22a97d3e14a7233c1968027b3b5b111fdb632e3c4382f9ed4d0b11a",
"decision": "exclude",
"goals": [],
"rationale": "X2 재사용 session token 단언이다."
},
{
"header": "@@ -804 +949,7 @@ class GatewayModelTest(unittest.TestCase):",
"sha256": "89f3fd909c5a4d7294356d2903c78f0eee71866a334aacef7353f5ff6ee46dee",
"decision": "exclude",
"goals": [],
"rationale": "X2 신규 session token fixture다."
},
{
"header": "@@ -819,0 +971,2 @@ class GatewayModelTest(unittest.TestCase):",
"sha256": "61c47d3db01694cabd167aae05aec3091954bc91d76d6f20e0fb301d4bc800b6",
"decision": "exclude",
"goals": [],
"rationale": "X2 신규 session token 단언이다."
},
{
"header": "@@ -853 +1006,7 @@ class GatewayModelTest(unittest.TestCase):",
"sha256": "1ad447055372b21b2d8f32bc2aa2052ab97ca6c3b0708ac094ec624b3792495f",
"decision": "exclude",
"goals": [],
"rationale": "X2 SSE done token fixture다."
},
{
"header": "@@ -870,0 +1030,2 @@ class GatewayModelTest(unittest.TestCase):",
"sha256": "d27e0551b05f7ef1b5ccfac1eabb31e5c5af80ac1c0c042f1934bcb411e137f0",
"decision": "exclude",
"goals": [],
"rationale": "X2 SSE done token 단언이다."
}
]
}
],
"verification": {
"command": "py -3.11 -X utf8 scripts/build-outcome-os-release-patch.py --json",
"required": [
"all current mixed document hunks match mapped SHA-256",
"api.gen.ts is regenerated and check:api-types passes",
"forbidden unrelated API markers are absent",
"release patch applies to clean base with git apply --check",
"current worktree tracked and untracked content hashes do not change except the declared output patch"
],
"last_result": {
"executed_at": "2026-08-07T12:36:00+09:00",
"status": "passed",
"deterministic_runs": 2,
"patch_files": 304,
"patch_bytes": 4412868,
"patch_sha256": "a8c27b0aadcb9dacea86c4be5e62e19277b9cc2678ebca51aa02998d2c2d1a0d",
"api_generated_sha256": "5a2f6c1810af0d9405eb47e77b0ffa9305572b728ec975f78b9a1f55ac552163",
"git_apply_check": "passed-on-clean-temporary-head",
"git_apply_cached_check": "passed-on-canonical-clean-index",
"patch_line_endings": "lf-only",
"source_worktree": "unchanged-except-output-patch"
}
}
}