{ "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" } } }