diff --git a/CHANGELOG.md b/CHANGELOG.md index 0744de468..04c5298ee 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ - Add a Noema-owned exact-claim evidence receipt contract whose execution and research producers serialize one canonical artifact that binds every receipt semantic field, including command/result/isolation/network or source revision/excerpt/retrieval policy. Admission accepts only a receipt ID from untrusted model output. The owner API first verifies the exact authenticated OpenCode-handoff manifest digest, canonical envelope bytes, reviewed producer-to-kind policy, and repository/head/workflow/run/attempt identity before it can construct an immutable typed index; admission then reconstructs each canonical artifact and verifies time/claim/artifact identity. The version-2 manifest now binds a separate producer-authenticated `ClaimEvidenceRequirement` containing the exact claim, independently required evidence kind, and `context` or `finding` publication authority. Raw current-head source lines are context only: they are withheld from finding-reference prompts and cannot publish a finding or `request_changes`; an explicitly producer-authorized source finding remains usable and retains exact path/line checks. Finding-free model `request_changes` and `blocked` verdicts cannot bypass receipt admission to publish a vacuous blocking review. Requirement/receipt kind mismatch, fixed-artifact semantic substitution, caller-supplied receipt dictionaries, model self-classification, stale identities, cross-kind receipts, marker-only sandbox output, noncanonical artifact bytes, and expired receipts fail closed before the GitHub publisher. This remains the owner prerequisite for ContextualWisdomLab/.github#1641 and issue #555. The reviewed `sandboxed_verify` adapter exists in owner source, but its actual central stdout/stderr/marker-to-manifest wiring and the trusted research producer are not yet integrated; exact-head hosted GREEN, immutable release, and the verified central consumer bump remain required. ## Unreleased +- Protected #710 exact `8bc768756a10bab1d32b14039cdcfdb48d001931`, integrated by GitHub-verified normal merge `de0f3b5a9b5040ce4700a0888539f3d4f1d723bc`, binds tag-triggered immutable-release verification to the freshly resolved current protected `main`. The gate resolves only `refs/heads/main` from canonical `origin` with non-shell `git ls-remote --refs`, disables prompting, enforces a 20-second timeout and 16 KiB output ceiling, and admits exactly one canonical lowercase full SHA. Repository substitution, malformed or ambiguous ref output, noncanonical SHA identity, and any release-commit/current-main mismatch fail closed; pull-request and local verification remain network-independent. Protected #710 does not prove Release Policy Auditor provisioning, live immutable-release enablement, an immutable Noema Release, production deployment/recovery/KPI evidence, reproducibility/rollback completion, or legal/outbound-rights authority. - Protected #708 exact `8e4a35c28418fa3049e1dc13470088e8dacf2306`, integrated by GitHub-verified normal merge `2026878cc4627ef2cc781c9aa68da0e11b066fd1`, makes immutable buyer publication fail closed across the draft-staging race window. Before staging, the authenticated paginated release inventory must contain no release or retained draft for the tag; after the bounded six-asset draft is staged, the workflow requires exactly one total same-tag release, verifies that it is the mutable draft with a numeric release ID, verifies every staged asset name/size/GitHub SHA-256 digest, re-dereferences the tag, and publishes only that verified numeric release ID. A moved tag or same-tag ambiguity leaves the draft unpublished. Protected source does not prove live immutable-release enablement, Release Policy Auditor provisioning, an immutable Noema Release, production deployment/recovery/KPI evidence, reproducibility/rollback completion, or legal/outbound-rights authority. - PR #706 repairs immutable GitHub Release policy authorization: GitHub's repository immutable-release settings read requires `Administration: read`, so release publication no longer assumes the job `GITHUB_TOKEN` can prove that prerequisite. A dedicated repository-scoped Release Policy Auditor App token requests exactly `Administration: read` and `Metadata: read`, is admitted only through the owner-only bounded capability file, and is used only for the immutable-policy GET; exact-tag/release-absence checks and release creation/verification remain on the ordinary release job `GITHUB_TOKEN`. The existing Maintainer App is not broadened. Source integration does not prove App installation or credential provisioning, immutable-policy enablement, or an immutable Noema Release. - Protected #704 exact `42b15e865bdf88fde622c3bba2c0b123770d18be`, integrated by GitHub-verified normal merge `e8c2002e5af8fa5611880091dab81916bb716c35`, requires Agent Runtime to admit private Workflow / Task Execution current-state evidence only when a successful response declares the owner-emitted JSON media type application/json with optional `charset=utf-8` parameter; other media-type parameters are rejected. Missing or non-JSON media types fail closed with the stable `invalid_workflow_state_response` classification before bounded parsing. Rejected-media body cancellation is best-effort cleanup: synchronous throw, asynchronous rejection, null body, or non-settling cleanup cannot replace or delay the fail-closed decision. The existing fixed 1 MiB retained buffer, 10-second absolute read deadline, fatal UTF-8/JSON admission, canonical execution binding, and reader-lock lifecycle remain unchanged. Workflow / Task lifecycle truth, provider/model routing, destination/outbound policy, credential authority, quarantine/security, Policy / Approval, State / Checkpoint, release/deployment, and foreign-domain authority remain with their existing owners; protected source/checks/merge are not an immutable release, deployed Durable Object recovery, or production p95/heap evidence. @@ -146,4 +147,4 @@ - `/exchange` 401 응답에 `WWW-Authenticate: Bearer realm="noema"` challenge를 추가하고 인증 누락은 `invalid_request`, 잘못된 토큰은 `invalid_token`으로 구분. - `x-request-id`/`x-correlation-id` 및 client IP 계열 헤더를 길이/문자 기준으로 제한해 로그 오염과 rate-limit key 폭주를 방지. - `KRW 2,000,000,000` 매각 가능성 Goal 등록서, buyer due diligence index, library/submodule 경계 판단서를 추가하고 `npm run acquisition:audit`로 ARR/LOI/이전성/saleable evidence를 실패-폐쇄 방식으로 검증. -- Protected #695 normalizes synchronous reader acquisition on the contextual-orchestrator `/healthz` response consumer at exact source `c9d526093e543167645383e937096fd089b337f8`. If a locked or otherwise non-stream-readable response body makes `response.body.getReader()` throw synchronously, Noema fails closed with `contextual-orchestrator health response body is not stream-readable` instead of leaking a runtime-specific stream exception. The existing 65,536-byte ceiling, optional caller-supplied deadline with no invented default timeout, fixed retained buffer, best-effort cancellation, fatal UTF-8, duplicate-key/JSON admission, and reader-lock lifecycle after successful acquisition remain unchanged. Contextual-orchestrator service/provider/model routing, credentials, outbound authority, quarantine/security authority, release/deployment authority, and foreign-domain truth remain with their existing owners; protected source is not an immutable release or deployed availability/p95/recovery evidence. PR #695. +- Protected #695 normalizes synchronous reader acquisition on the contextual-orchestrator `/healthz` response consumer at exact source `c9d526093e543167645383e937096fd089b337f8`. If a locked or otherwise non-stream-readable `/healthz` response body makes `response.body.getReader()` throw synchronously, Noema fails closed with `contextual-orchestrator health response body is not stream-readable` instead of leaking a runtime-specific stream exception. The existing 65,536-byte ceiling, optional caller-supplied deadline with no invented default timeout, fixed retained buffer, best-effort cancellation, fatal UTF-8, duplicate-key/JSON admission, and reader-lock lifecycle after successful acquisition remain unchanged. Contextual-orchestrator service/provider/model routing, credentials, outbound authority, quarantine/security authority, release/deployment authority, and foreign-domain truth remain with their existing owners; protected source is not an immutable release or deployed availability/p95/recovery evidence. PR #695. diff --git a/docs/product-technical-gap-baseline.md b/docs/product-technical-gap-baseline.md index 55f339036..a6407d506 100644 --- a/docs/product-technical-gap-baseline.md +++ b/docs/product-technical-gap-baseline.md @@ -4,11 +4,11 @@ 이 문서는 protected source, active candidate, transient workflow evidence와 foreign-owner authority를 분리한다. Open PR exact head, protected base, required workflow, review thread, release와 central dependency는 mutation·merge·release 직전에 다시 읽는다. predecessor GREEN, queued/pending/in_progress/skipped/cancelled run, 오래된 PR base snapshot과 scanner/model judgement는 다음 revision의 merge authority로 전용하지 않는다. queued는 GREEN이 아니다. -Current protected source는 mutation·merge·release 시점에 live protected `main`을 다시 조회해 결정한다. 이 문서 안의 exact source SHA는 dated observation 또는 protected history일 뿐 future merge 뒤 evergreen current authority로 사용하지 않는다. Dated protected observation for this repair는 `main@2026878cc4627ef2cc781c9aa68da0e11b066fd1`이다. Dated protected source identity is also protected main `2026878cc4627ef2cc781c9aa68da0e11b066fd1`. #681의 GitHub-verified normal merge identity `1fd5d80018837d374bb3776f46ebed54db4dc6af`, #678의 GitHub-verified normal merge identity `a49d8532df6ac4d2eead11867047c1c4d0fa3359`, #683의 GitHub-verified normal merge identity `20452140e6d6f91e92f2491c15f53e8eef0dc6f8`, #685의 GitHub-verified normal merge identity `0ba3fe2f484cbd8e6f6f8b32df4768cba9a8baa2`, #687의 GitHub-verified normal merge identity `f9d08f4a78f55989b58eb8b12d152933e40cc807`, #689의 GitHub-verified normal merge identity `620b29fae9a5dad5d463aff83dd6adb6b67f9305`, 그리고 #708의 GitHub-verified normal merge identity `2026878cc4627ef2cc781c9aa68da0e11b066fd1`는 protected history에 포함되며, 이후 protected-main 전진을 이 문서의 evergreen authority로 전용하지 않는다. +Current protected source는 mutation·merge·release 시점에 live protected `main`을 다시 조회해 결정한다. 이 문서 안의 exact source SHA는 dated observation 또는 protected history일 뿐 future merge 뒤 evergreen current authority로 사용하지 않는다. Dated protected observation for this repair는 `main@de0f3b5a9b5040ce4700a0888539f3d4f1d723bc`이다. Dated protected source identity is also protected main `de0f3b5a9b5040ce4700a0888539f3d4f1d723bc`. #681의 GitHub-verified normal merge identity `1fd5d80018837d374bb3776f46ebed54db4dc6af`, #678의 GitHub-verified normal merge identity `a49d8532df6ac4d2eead11867047c1c4d0fa3359`, #683의 GitHub-verified normal merge identity `20452140e6d6f91e92f2491c15f53e8eef0dc6f8`, #685의 GitHub-verified normal merge identity `0ba3fe2f484cbd8e6f6f8b32df4768cba9a8baa2`, #687의 GitHub-verified normal merge identity `f9d08f4a78f55989b58eb8b12d152933e40cc807`, #689의 GitHub-verified normal merge identity `620b29fae9a5dad5d463aff83dd6adb6b67f9305`, #708의 GitHub-verified normal merge identity `2026878cc4627ef2cc781c9aa68da0e11b066fd1`, 그리고 #710의 GitHub-verified normal merge identity `de0f3b5a9b5040ce4700a0888539f3d4f1d723bc`는 protected history에 포함되며, 이후 protected-main 전진을 이 문서의 evergreen authority로 전용하지 않는다. Dated central control-plane observation for this repair는 central `.github/main@cb0872c9a20d5584703dffacca65c096fc034c6c`다. Noema runtime의 reviewed immutable central consumer pin은 `c9052e607e5f3cc76e73207e7786b21500721b79`이고 runtime authority 표현은 `ALLOWED_WORKFLOW_SHA = c9052e607e5f3cc76e73207e7786b21500721b79`다. Moving foreign head와 reviewed immutable pin을 같은 권위로 취급하지 않으며 central moving head가 전진했다고 consumer pin을 자동 승격하지 않는다. -Protected history에는 merged PR #535 exact `82b20b293f0a5f0ac0e69857c1b61dddfe478491`, merged PR #540 exact `05bc2d47c3899ebe17538070f9a30172f90307ac`, merged PR #542 exact `ca839298fcaeec409091dc909789b6f87eb67fdc`, merged PR #547 exact `30b7e7e5cdab8de65715834a16f994b2047eafa6`, merged PR #550 exact `f2ec2dc6709814070cc3e3d6932ce280aee966db`, merged PR #553 exact `3bd9f543e97ce856f78b1c608141436298ce9e74`, merged PR #558 exact `2f91bf8641212ecae435b5fbcc9084cc0acd6295`, merged PR #556 exact `860714cba46dba06260a5dce09d0e9152fcb0a8c`, merged PR #560 exact `5aab7c098f3478069127f34e398326415ec599a4`, merged PR #582 exact `0f20a4dc78e423fd5df49e137a4eb286c7075ea4`, documentation-authority integration #583, protected procedural graph source #585/#586, documentation convergence #587/#588/#590/#595, workflow-backed current-state integration #589, procedural decision/evaluation/authentication integrations #591/#592/#593/#594/#596, State / Checkpoint history #597, Policy / Approval CAS #601, publication preflight #603, Workflow / Task exact-object operability integration #605, documentation-authority convergence #606, merged PR #607 exact `0afd68d2e33b7fd9be2307ba78b370b534cc0f54`, merged PR #610 exact `0a516bc54d682817ffea3206ec8b24b214aa94ea`, merged PR #612 exact `a919be3bc2a04068e25a4592e0c9c26f8e63534b`, merged PR #614 exact `77c5116a2e58e8a154ee893a3825da19c9c1f357`, merged PR #616 exact `da8461f1f5a6d02d926dd295fc88abe2c6167dfa`, documentation-authority convergence PR #617 exact `38b3b56837d875d19ae458f3f5491951ad7afb1c`, merged PR #618 exact `fb166ec6ecc769a19fd4ae4502f6d0994fc89e33`, merged PR #620 exact `b746846e4890c84b568bb29937594e1b17364fa1`, documentation-authority convergence #639, merged PR #640 exact `72ff4897822b5a8122540509346be4f3278a1379`, merged PR #641 exact `73f13b3a3826c5d6f7aafc89d1ff23747f8cf8e9`, merged PR #642 exact `3427e5a66d7a0ea9379ddc7915ba2b3d1872c492`, merged PR #643 exact `b13903e3208232086871d7f117f8f20e753eb583`, merged PR #644 exact `79a89f5775d0fb56de9f1908c1927df0b498b70f`, merged PR #645 exact `1b4dc38581e99b92342769dd03059f5015ee9f04`, merged PR #646 exact `3005086fca2c6376fae951b774230fa1c06ba587`, merged PR #647 exact `ea3a36bc65df88153aa69a05e3144f0b5352b5a6`, merged PR #648 exact `133ce20c4bb7fb9ba05e3e4bedeb0492334faf38`, merged PR #649 exact `f334f40193da8811a6e15efcb2d589aa80104931`, merged PR #650 exact `f59fce008a4da70f89e9927f692b823506594ed5`, documentation-authority convergence #651, merged PR #652 exact `23fabd95f3ef886c6bef0ae9ff6ead50dc0ce342`, documentation-authority convergence PR #653 exact `41ff085c89e27a97a00ce85ced968931f506a147`, merged PR #654 exact `f8d4b6b6b095c7674037a9ea5281b9ffa2f0f864`, merged PR #655 exact `dc851fc9ea67e38799e8c30cf4916a31c9e9661e`, merged PR #657 exact `fa4a2ab25231fa4c8b9a8451a4da6f29e04abaf7`, documentation-authority convergence PR #658 exact `5fe54442068646ad9581d39b23dd6d60a737aa66`, merged PR #659 exact `6357ac65db6a0db9f3bbb3f82196853b787f33cc`, merged PR #661 exact `5a5e147c5a7168277332eb828652b4aea4f7f2ba`, merged PR #663 exact `29dfa79692ec55cdc23ed892081425630ac916b5`, merged PR #665 exact `592ae00f090f642e8cb71ffb132d4a8b7bfe993a`, merged PR #668 exact `efaaebae161a71b1274f5aa0f26e27376a3edb3a`, merged PR #670 exact `14b4c9a46692df0084a03b9a3b2ae4acf1178a83`, merged PR #673 exact `6f9dc4ca047817e4c9ef5ae8a55816493b1c558d`, merged PR #676 exact `f8de7fc27d475c76477271fa50dd7032afd82a6c`, merged PR #681 exact `7072822253b1975cea76dcd7922e1a01d67e7681`, merged PR #678 exact `ac367cb535525742a1b6f3682d3ab5b14ef66f23`, merged PR #683 exact `01adb5af3d26788926164003bc44a761f5ff3654`, merged PR #685 exact `93dcf4c50018ce051e3ca917a4e1d63cbca3102d`, merged PR #687 exact `98ec07552f4081bd4ff6b25f1f3ed691c0f3f2b9`, merged PR #689 exact `b838c352a7cd0f7f58a905857537a3a9675a56f2`, 그리고 merged PR #708 exact `8e4a35c28418fa3049e1dc13470088e8dacf2306`가 포함돼 있다. 이 식별자는 역사 증거이지 open-candidate authority가 아니다. +Protected history에는 merged PR #535 exact `82b20b293f0a5f0ac0e69857c1b61dddfe478491`, merged PR #540 exact `05bc2d47c3899ebe17538070f9a30172f90307ac`, merged PR #542 exact `ca839298fcaeec409091dc909789b6f87eb67fdc`, merged PR #547 exact `30b7e7e5cdab8de65715834a16f994b2047eafa6`, merged PR #550 exact `f2ec2dc6709814070cc3e3d6932ce280aee966db`, merged PR #553 exact `3bd9f543e97ce856f78b1c608141436298ce9e74`, merged PR #558 exact `2f91bf8641212ecae435b5fbcc9084cc0acd6295`, merged PR #556 exact `860714cba46dba06260a5dce09d0e9152fcb0a8c`, merged PR #560 exact `5aab7c098f3478069127f34e398326415ec599a4`, merged PR #582 exact `0f20a4dc78e423fd5df49e137a4eb286c7075ea4`, documentation-authority integration #583, protected procedural graph source #585/#586, documentation convergence #587/#588/#590/#595, workflow-backed current-state integration #589, procedural decision/evaluation/authentication integrations #591/#592/#593/#594/#596, State / Checkpoint history #597, Policy / Approval CAS #601, publication preflight #603, Workflow / Task exact-object operability integration #605, documentation-authority convergence #606, merged PR #607 exact `0afd68d2e33b7fd9be2307ba78b370b534cc0f54`, merged PR #610 exact `0a516bc54d682817ffea3206ec8b24b214aa94ea`, merged PR #612 exact `a919be3bc2a04068e25a4592e0c9c26f8e63534b`, merged PR #614 exact `77c5116a2e58e8a154ee893a3825da19c9c1f357`, merged PR #616 exact `da8461f1f5a6d02d926dd295fc88abe2c6167dfa`, documentation-authority convergence PR #617 exact `38b3b56837d875d19ae458f3f5491951ad7afb1c`, merged PR #618 exact `fb166ec6ecc769a19fd4ae4502f6d0994fc89e33`, merged PR #620 exact `b746846e4890c84b568bb29937594e1b17364fa1`, documentation-authority convergence #639, merged PR #640 exact `72ff4897822b5a8122540509346be4f3278a1379`, merged PR #641 exact `73f13b3a3826c5d6f7aafc89d1ff23747f8cf8e9`, merged PR #642 exact `3427e5a66d7a0ea9379ddc7915ba2b3d1872c492`, merged PR #643 exact `b13903e3208232086871d7f117f8f20e753eb583`, merged PR #644 exact `79a89f5775d0fb56de9f1908c1927df0b498b70f`, merged PR #645 exact `1b4dc38581e99b92342769dd03059f5015ee9f04`, merged PR #646 exact `3005086fca2c6376fae951b774230fa1c06ba587`, merged PR #647 exact `ea3a36bc65df88153aa69a05e3144f0b5352b5a6`, merged PR #648 exact `133ce20c4bb7fb9ba05e3e4bedeb0492334faf38`, merged PR #649 exact `f334f40193da8811a6e15efcb2d589aa80104931`, merged PR #650 exact `f59fce008a4da70f89e9927f692b823506594ed5`, documentation-authority convergence #651, merged PR #652 exact `23fabd95f3ef886c6bef0ae9ff6ead50dc0ce342`, documentation-authority convergence PR #653 exact `41ff085c89e27a97a00ce85ced968931f506a147`, merged PR #654 exact `f8d4b6b6b095c7674037a9ea5281b9ffa2f0f864`, merged PR #655 exact `dc851fc9ea67e38799e8c30cf4916a31c9e9661e`, merged PR #657 exact `fa4a2ab25231fa4c8b9a8451a4da6f29e04abaf7`, documentation-authority convergence PR #658 exact `5fe54442068646ad9581d39b23dd6d60a737aa66`, merged PR #659 exact `6357ac65db6a0db9f3bbb3f82196853b787f33cc`, merged PR #661 exact `5a5e147c5a7168277332eb828652b4aea4f7f2ba`, merged PR #663 exact `29dfa79692ec55cdc23ed892081425630ac916b5`, merged PR #665 exact `592ae00f090f642e8cb71ffb132d4a8b7bfe993a`, merged PR #668 exact `efaaebae161a71b1274f5aa0f26e27376a3edb3a`, merged PR #670 exact `14b4c9a46692df0084a03b9a3b2ae4acf1178a83`, merged PR #673 exact `6f9dc4ca047817e4c9ef5ae8a55816493b1c558d`, merged PR #676 exact `f8de7fc27d475c76477271fa50dd7032afd82a6c`, merged PR #681 exact `7072822253b1975cea76dcd7922e1a01d67e7681`, merged PR #678 exact `ac367cb535525742a1b6f3682d3ab5b14ef66f23`, merged PR #683 exact `01adb5af3d26788926164003bc44a761f5ff3654`, merged PR #685 exact `93dcf4c50018ce051e3ca917a4e1d63cbca3102d`, merged PR #687 exact `98ec07552f4081bd4ff6b25f1f3ed691c0f3f2b9`, merged PR #689 exact `b838c352a7cd0f7f58a905857537a3a9675a56f2`, merged PR #708 exact `8e4a35c28418fa3049e1dc13470088e8dacf2306`, 그리고 merged PR #710 exact `8bc768756a10bab1d32b14039cdcfdb48d001931`가 포함돼 있다. 이 식별자는 역사 증거이지 open-candidate authority가 아니다. 이 baseline과 executable documentation-authority test는 active documentation-authority lane 하나만 write한다. mutation 직전 open PR/Issue/branch를 fresh-read해 writer를 결정하며 merged/closed historical PR 번호를 active sole writer로 고정하지 않는다. 다른 feature lane의 과거 baseline blob은 ordinary/non-force semantic convergence 때 current authority로 승계하지 않는다. @@ -72,7 +72,7 @@ Released procedural graph schema는 `context-graph-contracts`, signer trust와 k PR #605 exact `b4fd8abb77a69847655e04a03fa63a72ea6d56b4`는 application CI `34542741791`, reviewer-ci `34542741784`, required Security Scan `34542741748`, patch-validator-image `34542741760` terminal SUCCESS와 clean exact-head review 뒤 normal merge됐다. Resulting protected merge는 GitHub-verified `98942c88c228c18d44808db1c29bd8f165aa4167`이다. -Protected #605는 기존 execution-scoped `NOEMA_WORKFLOW_STATE` private command surface에 observation-only `read_operability`를 추가한다. Router는 admitted plan에서 canonical object identity를 다시 도출하고 caller-only field를 private transport에서 제거한다. Durable Object는 `DurableWorkflowStateRepository.readState(plan)`으로 retained execution-plan/state authority를 먼저 검증한 뒤에만 `ctx.storage.sql.databaseSize`를 읽어 `{ database_size_bytes }`만 반환한다. Uninitialized/malformed/mismatched retained authority, foreign object routing과 unavailable/throwing/negative/non-integer storage metadata는 fail closed한다. 두 번째 state/metrics store, public route, mutation/retry/recovery authority는 만들지 않는다. +Protected #605는 기존 execution-scoped `NOEMA_WORKFLOW_STATE` private command surface에 observation-only `read_operability`를 추가한다. Router는 admitted plan에서 canonical object identity를 다시 도출하고 caller-only field를 private command transport에서 제거한다. Durable Object는 `DurableWorkflowStateRepository.readState(plan)`으로 retained execution-plan/state authority를 먼저 검증한 뒤에만 `ctx.storage.sql.databaseSize`를 읽어 `{ database_size_bytes }`만 반환한다. Uninitialized/malformed/mismatched retained authority, foreign object routing과 unavailable/throwing/negative/non-integer storage metadata는 fail closed한다. 두 번째 state/metrics store, public route, mutation/retry/recovery authority는 만들지 않는다. ADR 0013은 `Proposed`다. Source-level exact-object observation은 deployed Durable Object transaction/restart/recovery, representative storage-growth denominator, synchronous-path p95, PITR/rollback 또는 immutable release evidence가 아니다. #541의 다음 acceptance는 exact immutable release/deployment/object/workload/window/retention에 결합된 before/after storage evidence와 실제 transaction/restart/recovery 및 rollback rehearsal이다. @@ -174,3 +174,9 @@ Repository Actions configuration uses variable `NOEMA_RELEASE_AUDITOR_APP_CLIENT Protected #708 exact `8e4a35c28418fa3049e1dc13470088e8dacf2306`, integrated by GitHub-verified normal merge `2026878cc4627ef2cc781c9aa68da0e11b066fd1`, closes the pre-publication tag/draft identity race without claiming an exclusive release lock. Before staging, the authenticated paginated release inventory must contain no published release or retained draft for the exact tag. Noema then stages the bounded six-asset set as a draft, re-reads the authenticated inventory, requires exactly one total same-tag release and requires that object to be the mutable draft with a numeric release ID. It verifies every staged asset name, byte size, and GitHub SHA-256 digest, re-dereferences the tag after asset staging and immediately before publication, and publishes only that verified numeric release ID through the release update API. A moved tag or ambiguous same-tag inventory leaves the draft unpublished and fail-closed. Protected #708 does not prove that immutable releases are enabled, that the Release Policy Auditor App is provisioned, that an immutable Noema Release exists, or that production deployment/recovery/KPI acceptance has occurred. It does not transfer provider/model routing, destination/outbound policy, credential authority, quarantine/security, production deployment, recovery-state, or foreign-domain authority into release automation. Live policy evidence, actual immutable publication, reproducibility/rollback, production evidence, and legal/outbound-rights remain separate acceptance classes. + +## Protected exact-main release admission — merged PR #710 + +Protected #710 exact `8bc768756a10bab1d32b14039cdcfdb48d001931`, integrated by GitHub-verified normal merge `de0f3b5a9b5040ce4700a0888539f3d4f1d723bc`, binds tag-triggered immutable-release verification to the freshly resolved current protected `main`. The admission gate resolves only `refs/heads/main` from canonical `origin` with non-shell `git ls-remote --refs`, prompting disabled, a 20-second timeout, and a 16 KiB output ceiling. It admits exactly one canonical lowercase full SHA and requires the release commit to equal that freshly resolved protected-main SHA. Repository substitution, malformed or ambiguous ref output, noncanonical SHA identity, and any release-commit/current-main mismatch fail closed; pull-request and local verification remain network-independent. + +Protected #710 does not prove Release Policy Auditor provisioning, live immutable-release enablement, an immutable Noema Release, production deployment/recovery/KPI acceptance, reproducibility/rollback completion, or legal/outbound-rights authority. It does not transfer provider/model routing, destination/outbound policy, credential authority, quarantine/security, production deployment, recovery-state, or foreign-domain authority into release automation. Live policy evidence, actual immutable publication, production evidence, and legal/outbound-rights remain separate acceptance classes. diff --git a/test/release-protected-710-authority.test.ts b/test/release-protected-710-authority.test.ts new file mode 100644 index 000000000..7ff63448c --- /dev/null +++ b/test/release-protected-710-authority.test.ts @@ -0,0 +1,48 @@ +import { readFileSync } from "node:fs"; +import { describe, expect, it } from "vitest"; + +const protectedSourceExact = "8bc768756a10bab1d32b14039cdcfdb48d001931"; +const protectedMergeExact = "de0f3b5a9b5040ce4700a0888539f3d4f1d723bc"; + +function section(document: string, heading: string): string { + const start = document.indexOf(heading); + if (start < 0) return ""; + const rest = document.slice(start + heading.length); + const next = rest.search(/\n## /); + return next < 0 ? document.slice(start) : document.slice(start, start + heading.length + next); +} + +function listItem(document: string, prefix: string): string { + return document + .split("\n") + .find((line) => line.startsWith(prefix)) ?? ""; +} + +describe("protected #710 release source authority", () => { + it("converges protected #710 into changelog and product-gap authority", () => { + const changelog = readFileSync("CHANGELOG.md", "utf8"); + const baseline = readFileSync("docs/product-technical-gap-baseline.md", "utf8"); + const heading = "## Protected exact-main release admission — merged PR #710"; + const changelogAuthority = listItem(section(changelog, "## Unreleased"), "- Protected #710 "); + const authority = section(baseline, heading); + + for (const document of [changelogAuthority, authority]) { + expect(document).toContain("Protected #710"); + expect(document).toContain(protectedSourceExact); + expect(document).toContain(protectedMergeExact); + expect(document).toContain("freshly resolved current protected `main`"); + expect(document).toContain("canonical `origin`"); + expect(document).toContain("`refs/heads/main`"); + expect(document).toContain("non-shell `git ls-remote --refs`"); + expect(document).toContain("20-second timeout"); + expect(document).toContain("16 KiB output ceiling"); + expect(document).toContain("exactly one canonical lowercase full SHA"); + expect(document).toContain("Repository substitution"); + expect(document).toContain("malformed or ambiguous ref output"); + expect(document).toContain("noncanonical SHA identity"); + expect(document).toContain("network-independent"); + expect(document).toContain("fail closed"); + expect(document).toContain("does not prove"); + } + }); +});