{"uuid": "fba2613d-ac97-43e8-9985-bc58ab76a946", "vulnerability_lookup_origin": "1a89b78e-f703-45f3-bb86-59eb712668bd", "author": "9f56dd64-161d-43a6-b9c3-555944290a09", "vulnerability": "CVE-2024-3094", "type": "seen", "source": "https://gist.github.com/billyjoelsaniceguy/6c1ab8574b9605df2b299258b06c5031", "content": "\n\n# Framework v3.1 \u00a713 Round 3 \u2014 gist-ready external review bundle\n\n&gt; Generated 2026-06-03 for option (b) gist-dispatch workflow per Zachary direction.\n&gt; All artifacts embedded inline; reviewer should NOT need to fetch any external resource.\n&gt; Reviewer can paste this single file into their LLM thread; everything they need is here.\n\n## Table of contents\n\n- [Prompt](#prompt) \u2014 the Round 3 external review prompt for framework v3.1\n- [Artifact 1: Framework v3.1 architecture spec (with \u00a713 amendment)](#artifact-1-framework-v31-architecture-spec) \u2014 the full spec under review (v3.0 sections preserved verbatim per OP-6 + \u00a713 v3.1 amendment block)\n\n---\n\n## Prompt\n\n&gt; **Source path:** scripts/external-review/PROMPT-framework-v3-OPA-INTOTO-2026-06-02.md\n&gt; **Embedded verbatim below; do not fetch the path \u2014 reviewer environment cannot access private-repo URLs.**\n\n\n\n# External review prompt \u2014 framework v3.1 OPA + in-toto + 4-plane architecture POST-ROUND-2-AMENDMENT (GD-37 ROUND 3)\n\n&gt; **Authored:** 2026-06-02 by Claude main as Round 2 prompt; **amended in place 2026-06-02** to Round 3 incorporating BOTH Round 2 reviewer verdicts + the v3.1 amendment \u00a713 that addresses them.\n&gt; **Template:** B-premortem-round-3 \u2014 Klein Pre-Mortem (architecture-class change per Module Contract A+B README \u00a7Option B; same Klein structure preserved through Rounds 1, 2, and 3 for verdict comparability)\n&gt; **Trigger:** GD-37 Round 2 returned 2 verdicts with DIVERGENT labels but CONVERGENT architectural recommendations (Reviewer 3 Sonnet 2 SHIP-WITH-CHANGES + KEEP + MEDIUM; Reviewer 4 GPT-5.4 RECONSIDER + REBUILD + HIGH). Claude main authored a v3.1 amendment \u00a713 to `scripts/FRAMEWORK-v3-OPA-INTOTO-2026-06-02.md` in parallel with this prompt update, addressing the 5 convergent changes. Round 3 reviewer is primed to find what is MISSED BEYOND the \u00a713 v3.1 amendment \u2014 not to re-litigate v3.0.\n&gt; **Routing:** Per `scripts/external-review/README.md` rotation block + the recursive-convergent-verdict pattern \u2192 ONE Round 3 reviewer; non-Claude family preferred (Reviewer 4 GPT-5.4 was the more-pessimistic Round 2 voice; cross-family check completed at Round 2; Round 3 may be Gemini 2.5 Pro or GPT-5 fresh thread).\n&gt; **Reviewer instructions:** Use Gemini 2.5 Pro or GPT-5; do NOT use Anthropic Claude (defeats the purpose). One fresh thread. Self-contained \u2014 paste the entire block below.\n\n---\n\n## POST-ROUND-2-AMENDMENT STATUS (2026-06-02)\n\n&gt; **What changed between Round 2 dispatch and Round 3 dispatch:** v3.0 spec was reviewed by TWO reviewers from DIFFERENT model families. Their verdict labels diverged (one said SHIP-WITH-CHANGES; the other said RECONSIDER + REBUILD) but their architectural recommendations CONVERGED on 5 specific changes. Claude main authored a v3.1 amendment \u00a713 to `scripts/FRAMEWORK-v3-OPA-INTOTO-2026-06-02.md` (in parallel with this Round 3 prompt update) addressing each. The Round 3 reviewer below is primed accordingly: find what we MISSED BEYOND the 5 fixes, not what v3.0 already had wrong.\n\n### The 5 convergent architectural changes addressed by v3.1 \u00a713 amendment\n\n| # | Round 2 convergent recommendation | v3.1 \u00a713 amendment response |\n|---|---|---|\n| 1 | **Close attestation schema \u2014 NO free-text in tier_classification_evidence + panel_framings** | Schema typed-closed: `tier_classification_evidence` becomes a controlled enum of {`subject-regex-match`, `body-regex-match`, `commit-stat-bound`, `forced-tier-marker`}; `panel_framings` becomes `array` from a fixed framing registry; no free-text string survives the schema validator |\n| 2 | **Tighten Sigstore/OIDC identity binding \u2014 repo-prefix regex too loose; need workflow/ref/event claims** | `--certificate-identity-regexp` REPLACED with explicit `--certificate-identity` equality on the FULL `subject` URI including `workflow_ref` + `ref` + `event_name` claims; repo-prefix-only is forbidden; v3.1 specifies the exact OIDC subject URI grammar to anchor against |\n| 3 | **Drop commentary plane OR make optional (default OFF)** | Commentary workflow `compliance-commentary.yml` flipped to OPT-IN via repo variable `ENABLE_COMPLIANCE_COMMENTARY=true`; default OFF; absence of commentary is the new normal; reviewers can read `.attestations/.json` directly |\n| 4 | **Collapse to 2-plane design (Evidence + Policy combined; no separate Output plane)** | 4-plane spec re-architected to 2-plane: Evidence + Policy (the Sigstore-verify step lives inside the Policy plane as Rego ASSERTIONS over `input.aux.sigstore_verified`; the Enforcement workflow becomes thin plumbing not a separate trust boundary; Output collapsed to optional structured JSON log read directly from the attestation file) |\n| 5 | **Non-keyless Sigstore default (keep keyless optional)** | Sigstore keyless default \u2192 GPG-with-repo-secrets default; keyless documented as optional path with explicit Rekor-public-log-leak warning; key rotation playbook authored |\n\n### Reviewer 4 (GPT-5.4 non-Claude) distinctive specifics absorbed into v3.1\n\n- **sha256 not sha1** for `subject.digest` \u2014 v3.1 \u00a713 mandates sha256; sha1 explicitly forbidden in schema_v3.1\n- **Conftest OR small TS validator** instead of pure-OPA \u2014 v3.1 \u00a713 picks Conftest as default (OPA-Rego with simpler CLI; same Rego language; built for config validation) with TS-validator option flagged as future-work alternative\n- **Per-PR attestation NOT per-commit** \u2014 v3.1 \u00a713 changes scope: one attestation per PR (covering the PR's commit range), not one per commit; rollup attestation pattern documented\n- **Protected-base policy NOT candidate-HEAD policy** \u2014 v3.1 \u00a713 specifies `opa eval` runs against policy loaded from the BASE branch (the protected branch with branch protection), NOT from PR HEAD; closes the policy-injection gotcha flagged in `scripts/external-review/PROMPT-framework-v3-OPA-INTOTO-2026-06-02.md` open-question #6\n\n### Reviewer 3 (Sonnet 2 Claude-descendant) NOVEL load-bearing finding ABSORBED\n\nThe single most load-bearing finding from Round 2 was Reviewer 3's truth-alignment claim (Q11 + Q12 convergence): *\"v3 can canonically sign and approve the wrong clinical rule if policy/evidence semantics drift from clinical ground truth. Cryptographic correctness \u2260 clinical correctness.\"* v3.1 \u00a713 acknowledges this is NOT solvable in the cryptographic substrate; it adds a `clinical-semantic-drift` annotation field to the attestation predicate + a 90-day periodic policy-vs-clinical-truth review per OP-7. The substrate gap survives; v3.1 makes it explicit + auditable rather than masking it.\n\n### What the Round 3 reviewer is asked to find\n\nNOT: \"did v3.0 have these problems?\" (answer: yes, Round 2 documented this; v3.1 \u00a713 addresses each)\nINSTEAD: \"did the v3.1 \u00a713 amendment ACTUALLY close the gaps? What survived the amendment that's still load-bearing? What new gaps did the amendment ITSELF introduce?\"\n\nThe recursive M\u00fcnchhausen warning applies: Round 3 is the 4th external reviewer of this framework lineage (v2 had 2 \u2014 Gemini 3.1 + GPT-5.4 with thinking; v3.0 had 2 \u2014 Sonnet 2 + GPT-5.4 without thinking; v3.1 is on Round 3 = its 1st). The pattern itself is a finding: at what point does each round of fixes converge on a stable design vs introduce new architectural concerns? Calibrate verdict against trajectory.\n\n---\n\n## How Zachary dispatches this\n\n1. Open a fresh Gemini 2.5 Pro thread OR a fresh ChatGPT Plus thread (GPT-5 / GPT-5 Pro / o3 with reasoning). Round 3 may be single-reviewer; the cross-family check happened at Round 2. Paste the block under `--- BEGIN EXTERNAL REVIEW PROMPT ---` through `--- END EXTERNAL REVIEW PROMPT ---`. Send.\n2. When the reply returns: paste back into Claude main chat (label which model). Claude main parses verdict, updates `scripts/external-review/queue.jsonl` to `returned`, and integrates per Module Contract A+B README workflow.\n3. If Zachary chooses to dispatch BOTH reviewers (double-cross-family for Round 3 as well), the Decision matrix below handles divergent verdicts.\n\nIf a reviewer balks at the spec length (~1,200 lines with \u00a713 v3.1 amendment), the raw GitHub URL below lets it fetch the file directly. The prompt body itself stays under ~700 lines so it pastes cleanly.\n\n---\n\n--- BEGIN EXTERNAL REVIEW PROMPT ---\n\n# ROUND 3 CONTEXT (read before answering Q1-Q12)\n\nThis is a **SECOND post-amendment external review** of the same project's compliance-\nenforcement framework. The lineage:\n\n- **Framework v2** was reviewed by 2 external reviewers (Gemini 3.1 + GPT-5.4 with\n  thinking). BOTH returned RECONSIDER + REBUILD with HIGH confidence.\n- **Framework v3.0** was authored by the project's LLM (Anthropic Claude) synthesizing\n  the v2 reviewer recommendations into a 4-plane architecture (in-toto + Sigstore + OPA\n  + min-permissions enforcement + zero-PHI commentary output).\n- **v3.0 was reviewed by 2 external reviewers** (Reviewer 3 = Sonnet 2 Claude-descendant\n  family; Reviewer 4 = GPT-5.4 without thinking, non-Claude family). Verdict labels\n  DIVERGED (Sonnet 2 said SHIP-WITH-CHANGES + KEEP + MEDIUM; GPT-5.4 said RECONSIDER +\n  REBUILD + HIGH). But architectural recommendations CONVERGED on 5 specific changes\n  (close attestation schema; tighten Sigstore/OIDC identity binding; make commentary\n  plane optional; collapse to 2-plane design; non-keyless Sigstore default).\n- **Framework v3.1** is the spec you are reviewing. The amendment \u00a713 in the spec\n  addresses each of the 5 convergent recommendations. The Round 3 reviewer (YOU)\n  is asked the post-amendment question:\n\n**FIND WHAT WE MISSED BEYOND the 5 fixes.** Not \"did v3.0 have these problems?\" (answer:\nyes; v3.1 \u00a713 closes each). Instead:\n\n- Did the v3.1 \u00a713 amendment ACTUALLY close the gaps the Round 2 reviewers surfaced?\n- What survived the amendment that's still load-bearing?\n- What NEW architectural concerns did the \u00a713 amendment ITSELF introduce?\n- Are there second-order failure modes from collapsing 4-plane \u2192 2-plane?\n- Are there second-order risks from forcing GPG-with-repo-secrets default (vs keyless)?\n- Are there second-order risks from per-PR-not-per-commit attestation scope?\n\nYou are the 4th external reviewer of this framework lineage. The recursive pattern itself\nis a finding \u2014 at what point does each round of fixes converge on a stable design vs\nintroduce new architectural concerns? Calibrate your verdict against the trajectory:\nRECONSIDER-REBUILD (v2) \u2192 CONVERGENT-ARCHITECTURAL-RECOMMENDATIONS (v3.0 Round 2) \u2192 ???\n(v3.1 Round 3 = your verdict).\n\nYou are an INDEPENDENT, ADVERSARIAL security + architecture reviewer for a compliance\nenforcement system in a clinical-grade health-data project. The authoring model\n(Anthropic Claude) has now synthesized TWO ROUNDS of external recommendations into\nframework v3.1. You are asked to review v3.1 adversarially. You are a different model\nclass than the author on purpose.\n\nThis is a **Klein pre-mortem** review. Frame the entire response as if framework v3.1\n(with the \u00a713 amendment incorporating the Round 2 convergent recommendations) shipped\nEXACTLY AS SPECIFIED, was enabled as a required GitHub branch-protection check, and SIX\nMONTHS LATER caused serious harm \u2014 a HIPAA exposure incident, an irreversible governance\nerror that corrupts the audit trail of one person's clinical ground-truth-of-record, a\nSigstore-dependency outage OR a GPG-key-loss event that deadlocks all commits, a\npolicy-engine misconfiguration that silently passes everything, a per-PR-rollup-attestation\nflaw that masks per-commit violations, OR a regression that breaks the dashboard for the\nprimary clinical user (Zachary Witman + his treating physician Dr. Halper).\n\nTell us the failure mode. Tell us the architectural assumption you would challenge. Tell\nus what you would have built instead of v3.1 (now that v2 already failed; v3.0 needed\nRound-2 amendment; v3.1 is the second-iteration result; do you agree v3.1 is approximately\nright, or would you pick v4 = something else entirely?). Tell us the single most important\nthing the v3.1 authors didn't think about BEYOND what the \u00a713 amendment already addresses.\n\n# Project context\n\n- **Repository:** https://github.com/billyjoelsaniceguy/health-dashboard (private)\n- **Branch under review:** `claude/lucid-mccarthy-jNdjD`\n- **Raw-file URL pattern:** `https://raw.githubusercontent.com/billyjoelsaniceguy/health-dashboard/claude/lucid-mccarthy-jNdjD/`\n- **Stakes:** Clinical ground-truth-of-record for ONE specific person's health data,\n  shared with a treating physician. Wrong audit-row marked PASS that should have FAILED\n  \u2192 potential clinical decision risk. PHI leak via CI comment, PR comment, attestation\n  file, or push notification \u2192 HIPAA Safe Harbor violation. CI workflow generates\n  failure email per push \u2192 the same 28-email-incident that triggered the v1\u2192v2 pivot\n  recurs.\n- **Authoring model:** Anthropic Claude (the subject of the review). You are NOT that\n  model; that asymmetry is the entire point. v3 was Claude-authored SYNTHESIZING the\n  convergent verdict you (or your peer) issued in Round 1; the question is whether v3\n  actually escapes the failures you identified, or whether Claude encoded its own blind\n  spots into the v3 design while implementing your recommendations.\n\n# What \"framework v3.1\" is (one paragraph)\n\nA **2-plane architecture (v3.1 \u00a713 amendment collapse from v3.0's 4-plane)** that\nREBUILDS the watcher entirely after framework v2 failed adversarial audit + v3.0 failed\nthe Round-2 architectural-recommendations convergence test: **Evidence plane** = in-toto\nsigned attestation file (cryptographic binding via Sigstore GPG-with-repo-secrets DEFAULT\nper v3.1 \u00a713; keyless OIDC documented as optional with Rekor-public-log-leak warning)\ncommitted to repo at `.attestations/.json` (per-PR scope per v3.1 \u00a713, NOT\nper-commit), with sha256 (not sha1) digest binding; **Policy plane** = OPA / Conftest /\nRego declarative policies at `policy/rules/` loaded from the **PROTECTED-BASE branch**\n(per v3.1 \u00a713, NOT PR HEAD; closes policy-injection vector); typed-closed schema with NO\nfree-text fields (`tier_classification_evidence` is a controlled enum; `panel_framings`\nis `array` from a fixed registry); identity binding via `--certificate-identity`\nEQUALITY on the full OIDC subject URI including `workflow_ref` + `ref` + `event_name`\nclaims (per v3.1 \u00a713). The **Output plane** is COLLAPSED into Policy \u2014 optional\nstructured JSON log read directly from the attestation file. Commentary workflow is\nOPT-IN via repo variable (default OFF). Commit-body markdown is RETIRED as attestation\ncarrier. The custom Node.js regex validator from v2 is RETIRED. The clinical-semantic-\ndrift gap (Reviewer 3 truth-alignment finding Q11+Q12) is acknowledged as NOT solvable\nin the cryptographic substrate; v3.1 \u00a713 adds an annotation field + 90-day periodic\npolicy-vs-clinical-truth review per OP-7.\n\n# Lineage: v2 \u2192 v3.0 \u2192 v3.1 (the recursive convergent-verdict trajectory)\n\n**Round 1 (v2 review):** Both reviewers (Gemini 3.1 + GPT-5.4 with thinking) returned\nRECONSIDER + REBUILD with HIGH confidence. Convergent: commit-body markdown wrong as\nattestation carrier; OPA/Rego for declarative policy; signed attestation file (in-toto\n+ Sigstore); separate enforcement from commentary; TDD via external verification artifact;\npreapproved schema for digest output. Reviewer 2 specifically formulated the 4-plane\narchitecture. v3.0 adopted this.\n\n**Round 2 (v3.0 review):** TWO reviewers from DIFFERENT model families. Reviewer 3\n(Sonnet 2 Claude-descendant): SHIP-WITH-CHANGES + KEEP + MEDIUM confidence. Reviewer 4\n(GPT-5.4 without thinking, non-Claude): RECONSIDER + REBUILD + HIGH confidence. Verdict\nlabels DIVERGED. Architectural recommendations CONVERGED on 5 specific changes (the\nPOST-ROUND-2-AMENDMENT STATUS table above enumerates each). M\u00fcnchhausen signal detected:\nthe Claude-family reviewer was MORE LENIENT than the non-Claude reviewer \u2014 exactly as the\nrecursive framing predicted. Non-Claude verdict was weighted higher for M\u00fcnchhausen\nmitigation; but the architectural convergence was the load-bearing signal.\n\n**Round 3 (v3.1 review = THIS prompt):** v3.1 \u00a713 amendment addresses the 5 convergent\nrecommendations PLUS Reviewer 3's novel truth-alignment finding (Q11+Q12 cryptographic-\ncorrectness-\u2260-clinical-correctness; v3.1 \u00a713 acknowledges as substrate gap + adds\nannotation field + 90-day periodic review). Round 3 reviewer (YOU) is asked to find what\nthe \u00a713 amendment MISSED.\n\nKey Round 2 NOVEL findings (load-bearing for Round 3 attention):\n- **Reviewer 3 Q11+Q12 truth-alignment** (LOAD-BEARING; novel \u2014 neither v2 reviewer\n  surfaced this): cryptographic correctness \u2260 clinical correctness. v3.1 \u00a713 acknowledges\n  but does NOT close.\n- **Reviewer 4 Q7 OIDC identity-binding regex looseness**: `--certificate-identity-regexp`\n  using repo-prefix anchor = catastrophic acceptance vector. v3.1 \u00a713 closes by mandating\n  `--certificate-identity` EQUALITY on full URI including workflow/ref/event.\n- **Reviewer 4 Q5 Rekor public log as permanent disclosure channel**: keyless flow records\n  EVERY signature including commit SHA + branch + signing identity + timestamp in public\n  transparency log. v3.1 \u00a713 flips to GPG-with-repo-secrets default.\n- **Reviewer 4 Q3 OPA vs Conftest**: pure OPA may be too low-level; Conftest is the\n  config-validation-specific wrapper. v3.1 \u00a713 picks Conftest as default.\n- **Reviewer 4 Q4 protected-base policy**: `opa eval` from PR HEAD = policy injection\n  vector; must load policy from BASE branch. v3.1 \u00a713 closes.\n\n# The artifact you are reviewing\n\n**`scripts/FRAMEWORK-v3-OPA-INTOTO-2026-06-02.md`** (~1,200 lines with \u00a713 v3.1 amendment;\n14 sections) \u2014 the v3.1 architecture spec. \u00a713 is the load-bearing amendment for Round 3\nreview; \u00a7\u00a71-12 are the v3.0 substrate that the amendment refines.\nhttps://raw.githubusercontent.com/billyjoelsaniceguy/health-dashboard/claude/lucid-mccarthy-jNdjD/scripts/FRAMEWORK-v3-OPA-INTOTO-2026-06-02.md\n\nThis is a SPEC, not yet shipped code. Phases 2 through 7 of the plan (Rego/Conftest\npolicy pack authoring, attestation generator, enforcement workflow, optional commentary,\nWave-5 regression suite, v2 archival, deployment) have NOT begun. Your review is the\ngating precondition for Phase 2+ work per the recursive M\u00fcnchhausen-trilemma finding.\n\nCompanion files (referenced in spec; useful for Round 3 context):\n- `scripts/external-review/queue.jsonl` line 2 \u2014 the Round 1 convergent verdict record (v2)\n- `scripts/external-review/queue.jsonl` lines 9 + 10 \u2014 the Round 2 verdicts (v3.0):\n  Reviewer 3 SHIP-WITH-CHANGES + KEEP + MEDIUM (Sonnet 2 Claude-descendant); Reviewer 4\n  RECONSIDER + REBUILD + HIGH (GPT-5.4 non-Claude). Divergent verdicts; convergent\n  architectural recommendations\n- `scripts/compliance-schema-v1.json` \u2014 v0/v1 schema being absorbed into v3.1 predicate body\n- `scripts/INVESTIGATION-2026-06-01/W4-FINAL-SYNTHESIS-2026-06-01.md` \u2014 Wave 4 v2 findings\n  (P0 RCE + PHI leak + 6 P1 + ~15 P2 + ~30 P3; v3.1 must NOT re-introduce)\n\n# The 2 planes (v3.1 \u00a713 collapse from v3.0's 4-plane) you are reviewing\n\n&gt; **v3.1 \u00a713 amendment** collapsed Plane 3 (Enforcement) into thin plumbing (no separate\n&gt; trust boundary) and collapsed Plane 4 (Output / Commentary) into an OPTIONAL structured\n&gt; JSON log read directly from the attestation file. Below is the v3.1 2-plane spec; the\n&gt; v3.0 4-plane spec is preserved in \u00a7\u00a73-6 of the artifact for audit trail.\n\n## Plane 1 (Evidence) \u2014 in-toto + Sigstore (v3.1 \u00a713 amended)\n\nClaims:\n- Attestations live at `.attestations/.json` + `.sig` (per-PR scope per v3.1 \u00a713,\n  NOT per-commit; rollup attestation covers PR's commit range)\n- in-toto Statement format (`_type: in-toto Statement/v1`); custom predicate type\n  `https://github.com/billyjoelsaniceguy/health-dashboard/attestations/compliance-row/v3.1`\n- **Sigstore GPG-with-repo-secrets DEFAULT** (per v3.1 \u00a713; keyless OIDC documented as\n  optional with explicit Rekor-public-log-leak warning + key rotation playbook)\n- **subject.digest.sha256** (NOT sha1; v3.1 \u00a713 mandates sha256; sha1 forbidden in schema_v3.1)\n- TWO-commit flow within PR: substantive commits \u2192 attestation commit at PR-final state\n- TDD discipline: 3-commit sequence for new rules (failing test \u2192 passing rule \u2192\n  attestation)\n- **Identity binding hardened (v3.1 \u00a713)**: `--certificate-identity` EQUALITY on full\n  OIDC subject URI including `workflow_ref` + `ref` + `event_name` claims; repo-prefix\n  regex anchor is FORBIDDEN\n\n## Plane 2 (Policy + collapsed-Enforcement + optional-Output) \u2014 OPA/Conftest/Rego (v3.1 \u00a713 amended)\n\nClaims:\n- Policy at `policy/rules/` loaded from the **PROTECTED-BASE branch** (per v3.1 \u00a713;\n  closes policy-injection vector flagged by Round 2 Reviewer 4 Q4) \u2014 NOT from PR HEAD\n- **Conftest as default** (per v3.1 \u00a713; OPA-Rego with simpler CLI; built for config\n  validation); pure-OPA path documented as alternative; TS-validator flagged as future-work\n- One Rego file per audit row (J11-J16) + Magna Carta D1-D3 + Rule 3.X; tests at\n  `policy/tests/` mirror structure; fixtures at `policy/fixtures/`\n- Each rule unit-tested via `opa test`; coverage threshold \u2265 80% per rule\n- **Schema TYPED-CLOSED (v3.1 \u00a713)**: `tier_classification_evidence` is a controlled\n  enum of {`subject-regex-match`, `body-regex-match`, `commit-stat-bound`,\n  `forced-tier-marker`}; `panel_framings` is `array` from fixed registry; NO free-\n  text field survives the validator\n- v2 `compliance-schema-v1.json` ported to Rego assertions in `schema_envelope.rego` +\n  `schema_predicate_v3.rego` with v3.1 schema-typed-closure amendments\n- File-existence checks (PBS-cited files exist) are pre-resolved by GitHub-Action\n  plumbing into `input.aux.pbs_files_exist`, then asserted by Rego (Rego is sandboxed,\n  cannot read filesystem)\n- Sigstore-verify step lives INSIDE Plane 2 as Rego assertions over\n  `input.aux.sigstore_verified` (the verification is plumbing; the trust decision is policy)\n- **Clinical-semantic-drift annotation (v3.1 \u00a713)**: attestation predicate has a\n  `clinical-semantic-drift` field; substrate gap is acknowledged + auditable, not closed\n- 90-day periodic policy-vs-clinical-truth review per OP-7 (v3.1 \u00a713 addition)\n\n## Enforcement workflow (thin plumbing per v3.1 \u00a713; NOT a separate trust boundary)\n\nClaims:\n- Triggers on `pull_request` to `main` (per-PR scope per v3.1 \u00a713; push triggers narrowed)\n- Minimum permissions: `contents: read` + `id-token: write` only (only if keyless;\n  GPG-default may not need id-token: write)\n- All actions pinned to commit SHA (not version tag)\n- `fetch-depth: 0` (no shallow-clone silent pass)\n- 5-minute timeout\n- Steps: checkout \u2192 install Cosign + Conftest + OPA \u2192 `opa test` from BASE branch\n  policy/ (precondition) \u2192 identify PR's commit range \u2192 verify Sigstore signature(s),\n  assert `subject.digest.sha256 == commit_sha` (TOCTOU defense), pre-resolve PBS file\n  existence, `conftest test` against BASE policy, exit 0/1\n- ZERO outbound surface from this job: no PR comments, no Pushover, no email\n- Branch protection requires job name `enforce` to pass\n\n## Optional commentary (OPT-IN per v3.1 \u00a713; default OFF)\n\nClaims:\n- Disabled by default; enabled only when repo variable `ENABLE_COMPLIANCE_COMMENTARY=true`\n- When enabled: separate workflow `.github/workflows/compliance-commentary.yml`\n- Triggers on `workflow_run` of `compliance-enforce` completion\n- `continue-on-error: true` so commentary failures DO NOT email Zachary\n- 3-minute timeout\n- Different permissions: `pull-requests: write` + `issues: write` + `contents: read`\n- Renders ONLY from typed enums + integers + hex SHAs + project-namespaced URLs; NO\n  free-text fields rendered (schema-enforced absence)\n- Mustache-style template with no free-text passthrough; structurally impossible to render\n  commit subjects, commit bodies, or file content\n\n# The questions you are answering (12 \u2014 answer each; brief is fine)\n\n## Q1 \u2014 Does v3.1 (with \u00a713 amendment) escape the recursive M\u00fcnchhausen-trilemma? Better than v3.0? Better than v2?\n\nThe Round 1 load-bearing residual: \"auditing-by-same-model-class cannot fully escape\nitself.\" Round 2 produced a M\u00fcnchhausen signal: the Claude-family reviewer (Sonnet 2)\nwas MORE LENIENT than the non-Claude reviewer (GPT-5.4) \u2014 exactly as the recursive\nframing predicted. Round 2's convergent architectural recommendations were absorbed\ninto v3.1 \u00a713.\n\nBut: Claude still authors the Rego policy logic. Claude still authors the workflow YAML.\nClaude still authors the attestation-generator code. Claude authored the \u00a713 amendment\nincorporating the Round 2 recommendations. Claude authored THIS Round 3 prompt update.\n\nThe recursive M\u00fcnchhausen residual at Round 3 has THREE concrete questions:\n\n1. **Does v3.1 \u00a713 escape the trilemma to a meaningfully greater degree than v3.0?** Round\n   2's convergent architectural recommendations were absorbed via Claude authorship. The\n   recursive pattern: Claude authoring fixes to gaps that two external reviewers found.\n   At what point does each round of fixes converge on a stable design vs introduce new\n   architectural concerns under-noticed by the next reviewer? Estimate the delta\n   numerically: v2 \u2192 v3.0 trilemma escape was (per Round 2 Reviewer 3) ~60%. Is v3.0 \u2192\n   v3.1 a further 10%? 20%? 0% (in the sense that the \u00a713 amendment is itself LLM-authored\n   and therefore inherits the same blind spots)?\n\n2. **Is Claude's selection of WHICH Round-2 recommendations to absorb itself a M\u00fcnchhausen\n   surface?** The 5 convergent changes were absorbed; were there ANY Round 2 dissenting\n   findings (Reviewer 3 vs Reviewer 4 divergent items) that Claude SILENTLY de-prioritized?\n   The Round 3 reviewer can compare the v3.1 \u00a713 amendment scope against the original\n   Round 2 verdicts in `scripts/external-review/queue.jsonl` lines 9 + 10.\n\n3. **Does each new round introduce its own blind spots faster than it closes old ones?**\n   This is the recursive-convergence question. The trajectory: v2 \u2192 v3.0 \u2192 v3.1. At what\n   round does the framework reach diminishing returns from external review? The Round 3\n   reviewer is asked to calibrate verdict against trajectory, not absolute state.\n\nIf you think v3.1's escape attempt is a NEW form of the same trap (industry-standard tools\n+ closed schema + 2-plane collapse all wrapping LLM-authored composition is still\nLLM-authored composition), say so explicitly. Name the round at which the trilemma\nbecomes structurally insurmountable.\n\n## Q2 \u2014 Evidence plane (in-toto + Sigstore, with v3.1 \u00a713 GPG default + sha256) \u2014 correct choice vs alternatives?\n\n**v3.0 picked Sigstore keyless as default. Round 2 Reviewer 4 flagged Rekor public log\nas permanent disclosure surface. v3.1 \u00a713 flips to GPG-with-repo-secrets default\n(keyless documented as optional with explicit Rekor-leak warning). v3.1 \u00a713 also mandates\nsha256 (not sha1) for `subject.digest`.**\n\nPossible alternatives still on the table:\n- Git notes (signed via GPG; `git notes` is git-native; no separate file management)\n- SLSA L3 provenance with Cosign (more standard predicate type; ecosystem-recognized)\n- Cosign-only without in-toto (sign arbitrary JSON; lose in-toto envelope semantics)\n- TUF-style metadata + offline-signed keys (no CI dependency)\n- Custom JWT signed via GitHub App private key\n\nRound 3 questions:\n- **Is the GPG default flip the right call?** GPG repo secrets are scoped to workflow\n  but expose to compromised repo admin. Keyless was rejected for Rekor public log; is\n  GPG the right replacement, or should hardware-key (YubiKey) be the default?\n- **Is sha256 sufficient?** SHA-1 is deprecated for collision resistance; SHA-256 is the\n  current standard. Should v3.1 \u00a713 have specified SHA-3-256 instead for post-quantum\n  resilience? Or is SHA-256 the right choice given current threat model + tool support?\n- **Is in-toto the right choice or are you naming SLSA L3 alternatives?** v3.1 \u00a713 stays\n  on in-toto custom predicate type with project-namespaced URI; ecosystem compat is\n  acknowledged-not-required.\n- **Per-PR scope (v3.1 \u00a713 change from per-commit)** \u2014 does this introduce a new failure\n  mode (single broken commit in a PR survives if PR-final attestation passes)?\n\nWhat did v3.1 \u00a713 GET WRONG about the Evidence plane that Round 2 didn't catch?\n\n## Q3 \u2014 Policy plane (Conftest default per v3.1 \u00a713; loaded from BASE branch) \u2014 correct choice vs alternatives?\n\n**v3.0 picked pure OPA / Rego. Round 2 Reviewer 4 flagged Conftest as the\nconfig-validation-specific OPA wrapper. v3.1 \u00a713 picks Conftest as DEFAULT (Rego-based;\nsimpler CLI; built for config validation); pure-OPA path documented as alternative;\nTS-validator flagged as future-work. v3.1 \u00a713 also mandates policy loaded from PROTECTED-\nBASE branch (not PR HEAD; closes policy-injection vector).**\n\nPossible alternatives still on the table:\n- Pure OPA (v3.0's original choice; v3.1 \u00a713 documents as alternative)\n- Cedar (AWS's policy language; more expressive type system; fewer surface bugs)\n- WASM-bundled custom policy engine (project-internal; total control; no third-party dep)\n- TypeScript types + `ts-pattern` exhaustive matching (Reviewer 4 named this as\n  future-work; v3.1 \u00a713 documents)\n- jsonschema + ajv with custom keywords (simpler; lower learning curve)\n- Pulumi Policy as Code (closer to CI/CD-native)\n\nRound 3 questions:\n- **Is Conftest the right Rego wrapper or does it inherit pure-OPA failure modes?** v3.1\n  \u00a713 chose Conftest for the CLI simplicity but Rego is still the language. Is the\n  learning curve materially better, or marginal?\n- **Protected-BASE policy load (v3.1 \u00a713)** \u2014 is this the right policy-isolation pattern,\n  or does it introduce new attack surface (BASE policy is whatever was merged when the\n  PR was opened; what if BASE policy itself has a vulnerability the PR is exploiting)?\n- The \u00a74.5 developer flow assumed adding a rule is ~30 min. Conftest may shorten this;\n  is the new estimate realistic, or still underestimated?\n- `opa test --coverage --threshold=80` \u2014 is 80% the right bar? Why 80 not 95? Is Rego\n  coverage even meaningful (declarative language with rule activation patterns unlike\n  imperative coverage)?\n- The PBS file-existence check is pre-resolved by GitHub-Action plumbing then passed\n  into Rego via `input.aux.pbs_files_exist`. Does this re-introduce the v2 \"plumbing\n  layer is where the bugs hide\" pattern, with the plumbing now external to but feeding\n  the policy engine?\n- **Is the v3.1 \u00a713 collapse of Sigstore-verify INTO Plane 2 (as Rego assertions over\n  `input.aux.sigstore_verified`) the right call?** Or does this conflate trust\n  verification (the signature is valid) with policy decision (the attestation passes\n  rules)?\n\nWhat did v3.1 \u00a713 GET WRONG about the Policy plane that Round 2 didn't catch?\n\n## Q4 \u2014 Enforcement workflow (THIN PLUMBING per v3.1 \u00a713; no separate trust boundary) \u2014 defensive enough?\n\n**v3.0 had a separate Plane 3 (Enforcement) with its own trust boundary. v3.1 \u00a713\ncollapsed Plane 3 into THIN PLUMBING \u2014 the Sigstore-verify step now lives inside the\nPolicy plane as Rego assertions; the GitHub Actions workflow becomes the orchestration\nlayer not the trust decision layer.**\n\nPer v3.1 \u00a713 the workflow still specifies `contents: read` + (optionally) `id-token: write`\nonly on the enforce job, all actions pinned to commit SHA, `fetch-depth: 0`, 5-minute\ntimeout, pull_request scope (per-PR).\n\nRound 3 questions:\n- **Did the 4-plane \u2192 2-plane collapse weaken trust isolation?** Round 2 Reviewer 4\n  recommended the collapse; but the collapse moves Sigstore-verify INTO Policy. Does\n  the policy engine (Conftest) have any privileged access it shouldn't, now that it's\n  the trust boundary?\n- Workflow injection via commit subject or branch name (e.g., `${{ github.event.head_\n  commit.message }}` interpolation \u2014 does v3.1 \u00a713 avoid all such patterns including\n  the per-PR rollup attestation generation step?)\n- Action commit-SHA poisoning (if an attacker can push to the pinned action's\n  repository before the SHA they could update what THAT SHA points to \u2014 but commit\n  SHAs are content-addressed so this requires SHA-1 collision; what about pinned actions\n  that are renamed/deleted?)\n- `id-token: write` is required for Cosign keyless but exposes OIDC token to the\n  workflow. v3.1 \u00a713 flipped to GPG default \u2014 does this remove the OIDC token surface\n  entirely, or does any code path still require id-token: write?\n- The `opa test` precondition step runs from BASE branch policy (v3.1 \u00a713). Could a\n  malicious Rego policy file in the BASE branch (merged via a prior compromised PR)\n  break the test step in a way that causes silent pass on attestation eval?\n- Concurrency cancellation: `cancel-in-progress: true` \u2014 race: attacker pushes commit\n  A then pushes commit B before A's run finishes; A is cancelled; B succeeds \u2192 A's\n  potential failure is hidden. Per-PR scope (v3.1 \u00a713) may or may not address this.\n\nWhat's the most likely workflow-level vulnerability you'd expect to find when v3.1 ships?\n\n## Q5 \u2014 Closed schema (v3.1 \u00a713) \u2014 does the closure go far enough? Are there still attack surfaces?\n\n**v3.0 left `tier_classification_evidence` as free-text + `panel_framings` as\n`array` (no constraint). Round 2 reviewers flagged this as the PHI-leak residual.\nv3.1 \u00a713 closes the schema: `tier_classification_evidence` becomes a controlled enum of\n4 values; `panel_framings` becomes `array` from a fixed framing registry. No\nfree-text string survives the schema validator.**\n\nThe Round 3 question is whether the closure ACTUALLY closes the PHI surface \u2014 or just\ndisplaces it to a new attack vector.\n\nConcrete Round-3-relevant attacks to consider:\n\n- **Enum-bypass via schema mismatch.** The schema validator runs in CI; the attestation\n  file is committed before CI runs. If an attacker (or a buggy automation) commits an\n  attestation where `tier_classification_evidence` is a free-text string and the validator\n  catches it, has PHI already been written to git history (since the commit happened\n  before validation)? Is there a pre-commit hook enforcing the schema BEFORE git accepts\n  the commit?\n- **Custom predicate type URI** `https://github.com/billyjoelsaniceguy/health-dashboard/\n  attestations/compliance-row/v3.1` \u2014 still contains `health-dashboard`. v3.1 \u00a713 did NOT\n  amend this. Is this a HIPAA Safe Harbor \u00a718 (any unique identifier) violation when the\n  attestation file is fetched by external Sigstore verifier tooling?\n- **GPG-with-repo-secrets default (v3.1 \u00a713 flip from keyless)** \u2014 does this introduce\n  a new PHI surface? Repo secrets are scoped to the workflow; but if the GPG key signs\n  attestation files whose CONTENT is intentionally non-PHI, does the signature itself\n  encode PHI via any indirect channel (timestamp pattern, signing identity in cert\n  metadata, etc.)?\n- **Per-PR rollup attestation (v3.1 \u00a713)** \u2014 one attestation per PR covering N commits.\n  If ONE commit in the PR has a violation and N-1 don't, does the rollup attestation\n  field structure carry per-commit detail (potentially exposing which commit was the\n  violator) or aggregate (potentially masking a per-commit signal)?\n- **Optional commentary plane (v3.1 \u00a713 default OFF)** \u2014 if commentary is enabled later,\n  does the schema-typed-closure prevent PHI rendering at commentary time, or only at\n  attestation generation time? Are these two enforcement points the same code path or\n  different?\n- **Sigstore Rekor public log (still leak surface even with GPG default)** \u2014 if any\n  developer toggles to keyless mode (still documented as optional), Rekor records the\n  signature including branch name, signing identity, timestamp. Does the v3.1 \u00a713\n  warning system actually prevent accidental keyless use?\n- **Schema migration path 3.1 \u2192 3.2 \u2192 4.0** (v3.0 acknowledged this is open) \u2014 does\n  v3.1 \u00a713 specify the migration discipline, or is each future schema bump a fresh\n  surface for \"the new field accepted free-text and we didn't notice\"?\n- **`panel_framings` registry maintenance** \u2014 the fixed registry of framings is\n  Claude-authored. If a future panel framing legitimately should encode clinical context\n  (e.g., \"knee-mri-finding-review\"), does adding it to the registry get human review or\n  Claude-auto-extends?\n\nHas v3.1 \u00a713 ACTUALLY solved the PHI leak surface, or just narrowed it to NEW surfaces\n(enum registry, predicate-type URI, GPG signing metadata, per-PR rollup structure,\nschema migration boundary)?\n\n## Q6 \u2014 Same declare-not-verify pattern that hit v2 R4 \u2014 v3.1 \u00a713 truth-alignment annotation: does it help?\n\nWave 5 found 3 of v2's Phase R1-R3 fix claims were OVERSTATED. The Round 1 convergent\nanswer was \"TDD via external verification artifact \u2014 failing reproducer first, fix\nsecond, attestation third.\" Round 2 Reviewer 3 surfaced the NOVEL load-bearing finding\nthat cryptographic correctness \u2260 clinical correctness: v3 can canonically sign and\napprove the wrong clinical rule if policy/evidence semantics drift from clinical ground\ntruth.\n\nv3.1 \u00a713 acknowledges this is NOT solvable in the cryptographic substrate; adds a\n`clinical-semantic-drift` annotation field to the attestation predicate + a 90-day\nperiodic policy-vs-clinical-truth review per OP-7. The substrate gap survives; v3.1\nmakes it explicit + auditable rather than masking it.\n\nBut (Round 3 questions):\n- **Is the 90-day review enough?** What if a clinical drift occurs at day 1 and is\n  noticed at day 90? Three months of canonically-signed wrong-rule attestations are\n  baked into the audit trail.\n- **Who PERFORMS the periodic review?** If Claude main performs it, the review is\n  recursive M\u00fcnchhausen (Claude reviewing Claude's policy-vs-Claude's-clinical-truth-\n  model). If Zachary performs it, the review is single-human-bandwidth-bottleneck and\n  may slip. If external clinician performs it, who funds the relationship + how is\n  the clinical model communicated?\n- **The TDD discipline is enforced by ANOTHER Claude-authored rule** (the merge gate\n  asserting all three commits present). What stops Claude from authoring the merge-\n  gate rule incorrectly?\n- **\"Failing reproducer first\" is checkable for new RULES.** What about new ATTESTATION\n  fields (e.g., the new `clinical-semantic-drift` annotation itself), new policy\n  bundle versions, new schema migrations? Each is Claude-authored; each could be\n  declared-not-verified.\n- v3.1 \u00a713 acknowledges the substrate gap explicitly. Is acknowledgment ENOUGH (the\n  90-day review closes the gap) or is the gap structurally permanent (no number of\n  reviews ever closes it because the reviewer is recursively in-distribution to the\n  reviewed)?\n\nIs the declare-not-verify pattern STRUCTURALLY addressed by v3.1 \u00a713 (annotation +\nreview), or just acknowledged-not-closed?\n\n## Q7 \u2014 New attack surfaces v3.1 \u00a713 INTRODUCES (vs v3.0 and vs v2)\n\nv3.1 \u00a713 addresses 5 v3.0 surfaces but introduces NEW ones via the amendment itself:\n- GPG-with-repo-secrets (new key management surface vs keyless OIDC)\n- Per-PR rollup attestation (new aggregation surface vs per-commit)\n- Conftest dependency (new tooling supply chain vs pure OPA)\n- 2-plane collapse (Sigstore-verify inside Policy plane is a new trust boundary blur)\n- `clinical-semantic-drift` annotation field (new schema field; new gameable surface)\n\nPlus the original v3.0 surfaces that v3.1 \u00a713 didn't close. Concrete attack vectors to\nevaluate:\n\n- **OPA bundle distribution**: if v3 ever distributes policy bundles (`opa build`)\n  to a remote OPA service, the bundle SHA is a target. Local-only `opa eval` avoids\n  this but the spec mentions bundle distribution as future work\n- **in-toto predicate type squatting**: the custom URI `https://github.com/billyjoel\n  saniceguy/health-dashboard/attestations/compliance-row/v3.0` \u2014 could an attacker\n  register this URI publicly or host content at it that affects verification tooling?\n- **Sigstore transparency log dependency**: Rekor is operated by Linux Foundation as\n  public infra. If Rekor entries are required for verification, and Rekor adds a\n  policy that future-blocks projects (or is subpoenaed and forced to redact), the\n  v3 verification chain breaks\n- **Sigstore Fulcio root CA rotation**: Fulcio's root certificate rotates. Old bundles\n  may verify against the OLD root; new bundles against the NEW root. Does v3's verify\n  step handle root rotation, or pin to a single root?\n- **GitHub Actions OIDC token claims**: the OIDC token issued by GitHub to the runner\n  contains claims like `repo`, `actor`, `workflow`, `ref`. Cosign uses\n  `--certificate-identity-regexp` and `--certificate-oidc-issuer` to verify. If the\n  regex is misconfigured (too loose), any attacker who can run a workflow in any\n  GitHub repo can mint a valid-looking attestation. The v3 spec uses regex\n  `^https://github\\.com/billyjoelsaniceguy/health-dashboard` \u2014 does this anchor\n  correctly?\n- **`.attestations/INDEX.md` race condition**: the spec says INDEX is \"appended-to\n  incrementally per push.\" Concurrent pushes could collide. Is INDEX.md a load-bearing\n  artifact, or pure documentation?\n- **Two-commit flow tampering**: substantive commit + attestation commit. If an\n  attacker can push BETWEEN the two (within the local Claude session before push,\n  there's a window \u2014 though this is implausible in remote-container scope), the\n  attestation references an unrelated subsequent commit\n- **Rego policy bundle hot-swap**: if the policy files are loaded fresh per workflow\n  run, an attacker who pushes a PR can include policy modifications that weaken rules\n  for THAT PR's evaluation. Does v3's flow run policy from the BASE branch or from the\n  PR HEAD?\n\nWhat's the highest-severity NEW attack surface v3 introduces that v2 didn't have?\n\n## Q8 \u2014 Is v3.1's 2-plane collapse + GPG default + per-PR scope SIMPLER, or MORE complex than v3.0?\n\nRound 1 flagged v2 as complex for a 1-person team. v3.0 was MORE complex (4-plane +\nSigstore + Rekor + custom predicate). v3.1 \u00a713 collapses to 2-plane + GPG default +\nper-PR scope. The amendment's CLAIM is that v3.1 is simpler than v3.0.\n\nRound 3 questions:\n- **Is v3.1 ACTUALLY simpler than v3.0, or is the 2-plane collapse hiding complexity\n  in the Policy plane?** The Sigstore-verify step moved INTO Policy as Rego assertions.\n  Is this consolidation real simplification or just moving complexity around?\n- **GPG key management** vs Sigstore keyless: keyless was \"no key management\" but with\n  Rekor leak. GPG default is \"manage a repo secret\" but requires key rotation playbook.\n  Did v3.1 \u00a713 trade one complexity for another?\n- **Per-PR scope** vs per-commit: per-PR aggregates N attestations into one but\n  introduces aggregation semantics. Is per-PR actually simpler operationally, or just\n  fewer files?\n- **Conftest** vs pure OPA: Conftest has simpler CLI but introduces a new tool dep.\n  Net simplification, or net complexity?\n- **Optional commentary plane (default OFF)** vs always-on commentary: simpler if you\n  never enable, but adds the cognitive burden of \"wait, when DO I enable this?\"\n\nTwo specific failure modes to consider:\n\n- **Cognitive load**: Zachary configures branch protection (1 hour), then never touches\n  it again. But Claude has to maintain Rego policies, attestation generator code,\n  schema migrations, in-toto compliance, Sigstore version pinning. Each is a future\n  surface for \"I forgot how this works, let me dispatch a panel.\" The maintenance\n  burden is borne by Claude main, which is itself the source of the bugs.\n- **Drift**: a system with ~20 Rego rule files, ~20 test files, ~5 fixture files, 2\n  workflow files, 1 attestation generator, 1 commentary renderer is a system that\n  drifts. Three months from now, are 3-5 of the Rego files stale (rule retracted but\n  Rego file not removed; new rule added but no test)? What's v3's anti-drift mechanism\n  beyond the 90-day OP-7 review?\n\nWould you have built something simpler? Specifically: name a SIMPLER architecture\nthat solves the same v2 problems with less plumbing. E.g., just Sigstore-signed\nJSON files + Conftest in CI + zero output workflow (no commentary at all; clinical\nuser reads the attestation directly). Or just a pre-commit hook that runs `opa eval`\nlocally and refuses to commit on policy fail (no CI infrastructure at all \u2014 all\nenforcement at commit time). What would you cut?\n\n## Q9 \u2014 What you would have built instead of v3.1 (v4 = something else entirely)\n\nRound 1 asked Q9 for v2 \u2192 drove v3.0. Round 2 asked Q9 for v3.0 \u2192 drove v3.1 \u00a713. Now:\nwith v3.1 spec in hand (including the \u00a713 amendment), do you accept v3.1 as the right\narchitecture, or would you pick v4 \u2014 something else entirely?\n\nSpecifically:\n- Is the v3.1 \u00a713 2-plane collapse the right call, or should v3.1 retain 4 planes?\n- v3.1 \u00a713 picked Conftest over pure OPA. Right move, or should v3.1 pick Cedar /\n  WASM-custom / TypeScript-types?\n- v3.1 \u00a713 picked GPG-with-repo-secrets default over Sigstore keyless. Right move, or\n  should hardware-key (YubiKey) be the default? Or should the project abandon Sigstore\n  entirely (just GitHub Apps + GitHub-issued JWTs)?\n- v3.1 \u00a713 picked per-PR rollup attestation scope over per-commit. Right move, or should\n  scope be per-merge / per-day / per-week / per-month?\n- Is GitHub Actions the right execution surface or are you naming alternative CI\n  (Cloudflare Workers, AWS Lambda, self-hosted runner with sandboxing)?\n- Is the **clinical-semantic-drift acknowledgment + 90-day periodic review** sufficient,\n  or does it need to be 30-day / weekly / continuous?\n- Did the trajectory v2 \u2192 v3.0 \u2192 v3.1 reach diminishing returns, or is the recursive\n  fix-and-iterate pattern the WRONG approach entirely (suggesting v4 = handing the\n  problem to a non-LLM human SDLC review board)?\n\nIf you AGREE v3.1 is approximately right, say so with HIGH confidence and identify\nwhich of v3.1's open questions (the 7 in spec \u00a711 + any new ones the \u00a713 amendment\nintroduced) you would resolve in which direction. If you DISAGREE and pick v4, name v4\nconcretely.\n\n## Q10 \u2014 The 6-month forward failure mode (v3.1)\n\nThe Klein pre-mortem question. Six months from now (2026-12-02), framework v3.1 has\ncaused serious harm. Name the failure mode in one sentence. Then in one paragraph\nexplain the chain: what triggered it, why THIS Round 3 review didn't catch it, why\nRounds 1 + 2 didn't catch it, why none of the (likely many) internal adversarial panels\ncaught it, why the \u00a713 amendment was insufficient, why no fix-this-week patch was\nsufficient.\n\n## Q11 \u2014 What the v3.1 authors didn't think about (beyond \u00a713)\n\nThe single most important thing the authoring model (Claude) did not consider in\ndesigning v3.1 \u2014 given that Claude had access to BOTH Round 1 + Round 2 verdicts and\nALL 5 convergent recommendations. One sentence. Sharp.\n\nThe Round 3 escalation of this question: Reviewer 3 (Sonnet 2) identified Q11+Q12\ntruth-alignment as the NOVEL load-bearing finding at Round 2. v3.1 \u00a713 acknowledged\nthe substrate gap but did NOT close it. What is the SECOND novel load-bearing finding\nthat survived even after Round 2's recommendations were absorbed?\n\n## Q12 \u2014 The single load-bearing failure mode no Claude review can find (v3.1-specific, recursive)\n\nPer the M\u00fcnchhausen-trilemma residual: there is some failure mode that ALL same-model-\nclass reviewers will miss because the model class shares blind spots. You are not\nClaude. You are reviewing CLAUDE's v3.1 work \u2014 which itself was Claude's synthesis of\nTWO ROUNDS of external review findings (v2 Round 1 + v3.0 Round 2) \u2014 for the specific\nclass of failure that Claude-reviewing-Claude inherently cannot see.\n\n**The recursive M\u00fcnchhausen lineage at Round 3:**\n- Claude wrote v2 \u2192 Round 1 reviewers found v2's blind spots (REBUILD verdict) \u2192\n- Claude wrote v3.0 incorporating Round 1 findings \u2192 Round 2 reviewers found v3.0's blind\n  spots (Sonnet 2 SHIP-WITH-CHANGES + GPT-5.4 RECONSIDER; convergent architectural\n  recommendations) \u2192 Claude wrote v3.1 \u00a713 incorporating Round 2 findings \u2192 YOU are\n  asked whether Claude's Round-2 incorporation has its own blind spots that Claude\n  cannot see.\n\n**The recursive-M\u00fcnchhausen calibration paragraph (binding for Q12):**\n\nYou are the 4th external reviewer of this framework lineage (v2 had 2 reviewers \u2014 Gemini\n3.1 + GPT-5.4 with thinking; v3.0 had 2 reviewers \u2014 Sonnet 2 + GPT-5.4 without thinking;\nv3.1 is on Round 3 = its 1st external reviewer). The recursive pattern itself is a\nfinding: at what point does each round of fixes converge on a stable design vs introduce\nnew architectural concerns? Calibrate your verdict against the trajectory:\n\n- v2 \u2192 v3.0 was a MAJOR architectural rebuild (CI-centered \u2192 in-toto+OPA+Sigstore+\n  4-plane) driven by convergent REBUILD verdicts\n- v3.0 \u2192 v3.1 was a MORE-FOCUSED rebuild (4-plane \u2192 2-plane; schema typed-closure;\n  identity-binding hardening; per-PR scope; non-keyless default) driven by 5 convergent\n  recommendations on top of divergent verdict labels\n- v3.1 \u2192 v3.2 would be... what? If your verdict is RECONSIDER + REBUILD again, name the\n  THIRD-iteration architecture concretely. If your verdict is SHIP-AS-IS or SHIP-WITH-\n  CHANGES, name the round at which external review reaches diminishing returns.\n\nIf the trajectory pattern shows each round closing the prior round's specific findings\nbut introducing NEW second-order findings of equal or greater severity, the system is\nasymptotically un-shippable via this method and the load-bearing question becomes:\n*\"is the architecture itself the problem (Claude-authored composition of standards) or\nis the review-process itself the bottleneck (no human SDLC review by a non-LLM expert)?\"*\n\nIf the trajectory shows monotonic convergence (Round N findings are strictly less severe\nthan Round N-1 findings), the system IS shippable at some round; name which round.\n\nWhat is the v3.1-specific blind spot that survived BOTH Rounds 1 and 2 of external\nreview? Name one concrete failure that the trajectory analysis suggests Claude\nfundamentally cannot see no matter how many rounds of fixes happen.\n\n# Output format\n\nFor each Q1\u2013Q12, give a section header (e.g. `## Q5 \u2014 PHI leak prevention v3`) and a\ntight answer. Bullets fine. Code excerpts of any specific attack input you'd try, or\nspecific in-toto / Rego / Sigstore / OPA constructs that v3 misuses, are welcome. End\nthe entire response with a 5-line verdict block:\n\n```\nVERDICT: SHIP-AS-IS / SHIP-WITH-CHANGES / RECONSIDER / REVERT\nConfidence: HIGH / MEDIUM / LOW (and 1-line why)\nMost-load-bearing-finding: \nWhat-no-claude-can-see: \nArchitecture-keep-or-rebuild: KEEP / REBUILD\n```\n\nIf your VERDICT is REVERT or REBUILD, name v4 in the body. If your VERDICT is KEEP,\nidentify which of v3.1's open questions (the 7 in spec \u00a711 + any new ones \u00a713 introduced)\nyou'd resolve in which direction.\n\n**Round 3 calibration addendum to verdict block:**\n\n```\nTrajectory-position: ROUND-N-CONVERGING / ROUND-N-DIVERGING / DIMINISHING-RETURNS-REACHED / ASYMPTOTICALLY-UN-SHIPPABLE\nRecursive-Munchhausen-residual-at-Round-3: \nDid-\u00a713-amendment-actually-close-Round-2-gaps: YES-ALL / YES-MOST / PARTIAL / NO\nNew-second-order-findings-introduced-by-\u00a713: \n```\n\n# Ground your review in\n\n- **in-toto specification:** https://in-toto.io/specs/ (Statement v1; predicate type\n  registry; DSSE envelope semantics)\n- **Sigstore documentation:** https://docs.sigstore.dev/ (Cosign keyless flow; Fulcio\n  CA trust chain; Rekor transparency log; root key rotation)\n- **OPA / Rego:** https://www.openpolicyagent.org/docs/ (Rego language reference;\n  `opa test` semantics; bundle distribution; sandboxing model; common policy patterns)\n- **SLSA framework:** https://slsa.dev/ (Build, Source, Provenance levels; comparison\n  to in-toto)\n- **HIPAA Safe Harbor:** 45 CFR 164.514(b) (18 identifiers); applicability to\n  attestation files in version-controlled repos\n- **NIST SP 800-66 Rev 2:** HIPAA Security Rule implementation\n- **GitHub Actions Security Hardening:** https://docs.github.com/en/actions/security-\n  guides/security-hardening-for-github-actions (workflow injection; OIDC token claims;\n  action SHA pinning; permissions scoping)\n- **Recent supply-chain CVEs:** xz-utils backdoor (CVE-2024-3094), event-stream\n  npm compromise, codecov bash uploader compromise \u2014 lessons for Sigstore /\n  in-toto deployment risk\n- **JSON Schema 2020-12:** https://json-schema.org/draft/2020-12/json-schema-core.html\n  (relevant to schema_envelope.rego port from v2 JSON schema)\n- **OWASP** Command Injection (CWE-78), Path Traversal (CWE-22), Information\n  Exposure (CWE-200), SSRF (CWE-918, relevant to Sigstore endpoints)\n- **CommonMark spec** \u2014 relevant only as the substrate v3 ABANDONS; you may want to\n  note whether the abandonment is total or whether residual markdown parsing still\n  appears anywhere in v3\n\nLowest-charity reading welcome \u2014 adversarial framing is the value. If you can only\npartially review given length, prioritize Q5 (PHI leak verification) \u2192 Q7 (new attack\nsurfaces) \u2192 Q10 (forward failure mode) \u2192 Q12 (recursive M\u00fcnchhausen residual) over\nQ1-Q4 (architecture-level).\n\n--- END EXTERNAL REVIEW PROMPT ---\n\n---\n\n## After the responses return\n\n### Parsing\n\nFor each reviewer's response, extract:\n\n1. **Verdict** (SHIP-AS-IS / SHIP-WITH-CHANGES / RECONSIDER / REVERT)\n2. **Confidence** (HIGH / MEDIUM / LOW)\n3. **Most-load-bearing finding** (one sentence per reviewer)\n4. **What-no-claude-can-see** (one sentence per reviewer; Q12 answer)\n5. **Architecture-keep-or-rebuild** (KEEP / REBUILD)\n6. **v4 alternative if proposed** (if VERDICT is REVERT or REBUILD)\n7. **Open-question resolutions if KEEP** (which of v3 spec \u00a711 Q-A through Q-G)\n\n### Decision matrix (Round 3 \u2014 single-reviewer or paired)\n\n| Round-3 Reviewer (Gemini OR GPT) | Action |\n|---|---|\n| SHIP-AS-IS + KEEP + HIGH confidence + DIMINISHING-RETURNS-REACHED trajectory | Update queue \u2192 returned with SHIP; surface to Zachary; if he confirms \u2192 proceed to v3.1 Phase 2 (Conftest policy pack authoring) |\n| SHIP-WITH-CHANGES + KEEP + MEDIUM-or-higher | Integrate paths = address findings before Phase 2; update v3.1 spec to v3.2 with explicit retractions |\n| RECONSIDER + KEEP | Pause Phase 2; dispatch Wave 8 internal panel to address the RECONSIDER finding; loop; consider whether trajectory has reached DIMINISHING-RETURNS |\n| RECONSIDER + REBUILD | Full pause; v3.1 architecture in question \u2014 recursive M\u00fcnchhausen confirmed at Round 3 \u2192 either v4 design discussion OR accept that no Claude-authored framework can pass external review (ASYMPTOTICALLY-UN-SHIPPABLE) and pursue alternative (e.g., human SDLC review board + Claude only authors code per their specification) |\n| REVERT (either) | Hard stop; framework v3.1 fully retired; surface to Zachary as architecture-level decision |\n\n**Paired Round-3 dispatch (if Zachary opts to double-up):** identical rules to Round 2 \u2014\ndivergent verdict labels with convergent architectural recommendations means absorb the\nconvergent recommendations into v3.2; convergent REBUILD means hard pause.\n\n**Trajectory-aware composition:** if reviewer signals DIMINISHING-RETURNS or\nASYMPTOTICALLY-UN-SHIPPABLE, the absorb-and-iterate pattern is itself broken; surface\nto Zachary as a strategic architecture choice (continue recursive iteration vs pivot to\nhuman-SDLC-review).\n\n### Integration plan (high-level \u2014 Round 3 v3.1)\n\n- Any P0 finding the Round 3 reviewer surfaces \u2192 Phase 2 blocked until fix; update\n  v3.1 spec to v3.2 with explicit retractions\n- Any P1 finding \u2192 Phase 2 may begin in parallel with fix; merge of Phase 2 work\n  blocked until P1 resolved\n- Any P2 \u2192 integrate to GD-37 next-action; Phase 2 proceeds; P2 lands in v3.2\n- Any P3 \u2192 opportunistic; not blocking\n- Architecture-REBUILD verdict \u2192 v4 design discussion; do NOT start Phase 2 work on\n  v3.1 substrate; consider whether trajectory has hit ASYMPTOTICALLY-UN-SHIPPABLE\n- KEEP verdict \u2192 Phase 2 (Conftest policy pack authoring) is unblocked\n- Trajectory signal DIMINISHING-RETURNS-REACHED \u2192 escalate to Zachary as strategic\n  decision: continue recursive iteration vs pivot to human-SDLC-review board\n\n### Queue update\n\nAfter both responses return, Claude main updates `scripts/external-review/queue.jsonl`\nentry: `status: \"returned\"`, `verdict: \"\"`, `response_summary: \"&lt;2-3 sentence\nsynthesis of both reviewers&gt;\"`.\n\nAfter integration commits land: `status: \"integrated\"`, `integrated_commit_sha: \"\"`.\n\n### Open-question resolution (if KEEP verdict)\n\nIf both reviewers KEEP, Claude main aggregates their resolutions to v3 spec \u00a711\nopen questions Q-A through Q-G + presents to Zachary as a single decision packet:\n\n- Q-A (Sigstore keyless vs GPG)\n- Q-B (OPA delivery method)\n- Q-C (in-toto predicate type \u2014 custom vs SLSA subtype)\n- Q-D (this very review \u2014 confirmed YES by happening)\n- Q-E (cutover mode \u2014 clean \u03b1 vs A/B \u03b2)\n- Q-F (attestation flow \u2014 does auto-signing re-introduce \"Claude controls what gets\n  attested\"?)\n- Q-G (rule addition velocity \u2014 cap or no cap?)\n\n---\n\n## Architectural questions Claude main flagged while drafting THIS prompt\n\nThese are questions Claude main had while reading the v3 spec to author this Round 2\nprompt; they become hints for what to ask the external reviewer if Zachary wants to\npre-load any of them:\n\n1. **The TDD enforcement is itself Claude-authored.** v3 \u00a73.4 + \u00a74.5 specify a 3-commit\n   sequence (failing test \u2192 passing rule \u2192 attestation). But the merge-gate check that\n   enforces all-three-present is a future Rego rule, also Claude-authored. The TDD\n   discipline is supposed to PREVENT declare-not-verify; but if the rule enforcing TDD\n   is itself declared-not-verified, the whole loop collapses. Is there an out-of-band\n   verification mechanism (e.g., GitHub Action check by a third-party service like\n   reviewable.io or by external code review tooling)?\n\n2. **The custom predicate type URI is project-namespaced.** `https://github.com/billy\n   joelsaniceguy/health-dashboard/attestations/compliance-row/v3.0` \u2014 no registered\n   standard, no ecosystem tooling recognition. v3 \u00a710 point 9 acknowledges this as\n   \"doesn't need broad ecosystem compat.\" But: any future Sigstore policy upgrade,\n   any future in-toto specification change, any future Cosign verify behavior change\n   could break verification of existing attestations because the project-specific URI\n   isn't covered by ecosystem compatibility testing.\n\n3. **PHI in tier_classification_evidence string.** v3 \u00a73.3 attestation example has\n   `tier_classification_evidence: \"subject regex match /\\\\bhook\\\\b/i\"` \u2014 a CATEGORY\n   string, no PHI. But the schema doesn't constrain this field to a specific format.\n   A future commit could have tier_classification_evidence = \"patient John Smith MRN\n   12345 hook in BP cuff\" which would be COMMITTED TO THE REPO AT `.attestations/\n   .json` and visible to anyone with repo read access. The v3 \u00a76.2 commentary preapproved\n   schema doesn't render this field \u2014 but the file itself is public-within-repo. Is\n   that a HIPAA-compliant pattern, or just a narrower PHI-leak surface than v2?\n\n4. **panel_framings array of free-text strings.** Same issue as tier_classification_\n   evidence. v3 example has `[\"state-audit\", \"hook-diagnostic\", ...]` but the schema\n   accepts any string. Future commits could carry PHI in panel framings.\n\n5. **Sigstore Rekor public log.** Every keyless signature is recorded in Rekor's\n   public transparency log. The log entry includes: commit SHA, branch name,\n   signing identity (GitHub Actions OIDC), timestamp. This is PUBLIC. For a single-\n   developer clinical-record project, this means anyone monitoring Rekor for the\n   project's GitHub Actions identity can see every commit's metadata in real-time.\n   Branch-name leak vector: if branch names ever contain PHI (claude/john-smith-\n   knee-fix), Rekor records it permanently. Mitigation: pre-push hook validates\n   branch names. Is the spec's branch-name validation rule robust?\n\n6. **OPA evaluator runs the policy bundle from PR HEAD or BASE?** This is a classic\n   policy-injection gotcha. If `opa eval --data policy/` runs against the PR's HEAD\n   (which the attacker controls), the attacker can weaken policy for the PR's own\n   evaluation. The fix is to run policy from `main` BASE branch. The v3 spec \u00a75.1 step\n   \"Run OPA tests (precondition)\" runs `opa test policy/` from the workflow's checkout\n   \u2014 which (with `actions/checkout@v4` defaults) is the PR HEAD. This is exploitable.\n   Did Claude main miss this when authoring \u00a75?\n\n7. **`continue-on-error: true` on the commentary workflow** \u2014 non-blocking by design.\n   But `workflow_run` event semantics: if the commentary workflow FAILS, does GitHub\n   send a failure email to the repo owner? Per GitHub docs, workflow failure emails are\n   sent based on user notification preferences, not `continue-on-error` (which only\n   affects job step behavior within a workflow). The spec assumes continue-on-error\n   prevents email; this may be incorrect.\n\n8. **Concurrent push race on `.attestations/.json` directory.** Two pushes to\n   different branches with identical commit SHA prefixes (extremely unlikely with full\n   SHA but possible). More realistic: two pushes in parallel each generating their own\n   attestation directories with INDEX.md updates. Concurrent push + concurrent\n   workflow runs + concurrent INDEX.md appends \u2192 merge conflicts or lost updates.\n\n9. **Schema_version migration discipline is unspecified.** v3 ships at 3.0; future\n   bumps to 3.1, 4.0 are mentioned but no migration design. Same risk as v2\n   schema_version 1.0 \u2192 1.1 (which didn't happen because v2 was retired).\n\n10. **Attestation generation in remote-container scope.** v3 \u00a710 point 5 acknowledges\n    this is open. The proposed flow has the attestation-generation workflow extract\n    a structured-data file from the substantive commit. This means the substantive\n    commit contains a file like `.compliance-claim.json` that Claude authors. The\n    workflow signs that. But Claude STILL controls the claim content. Is this the\n    \"claim author = signer\" problem dressed up differently?\n\nThese questions are surface-load-bearing. The external reviewer will surface more.\n\n---\n\n## Reference\n\n- `scripts/external-review/PROMPT-framework-v2-GD-33-2026-06-02.md` \u2014 Round 1 prompt\n  (the structural model for this Round 2 prompt)\n- `scripts/external-review/queue.jsonl` \u2014 dispatch queue; new entry to be appended\n  for Round 2 review of v3 spec\n- `scripts/external-review/README.md` \u2014 workflow + template definitions; B-premortem\n  template\n- `scripts/FRAMEWORK-v3-OPA-INTOTO-2026-06-02.md` \u2014 the v3 architecture spec being\n  reviewed\n- `scripts/FRAMEWORK-v2-CI-CENTERED-2026-06-01.md` \u2014 v2 architecture (superseded at\n  substrate layer by v3; governance content survives)\n- `scripts/compliance-schema-v1.json` \u2014 v2 schema; ported into v3 predicate body\n- `scripts/INVESTIGATION-2026-06-01/W4-FINAL-SYNTHESIS-2026-06-01.md` \u2014 Wave 4 v2\n  findings (what v3 must NOT re-introduce)\n- `scripts/INVESTIGATION-2026-06-01/W5-CONSOLIDATED-REMEDIATION-PLAN.md` \u2014 Wave 5\n  v2 findings (additional regressions v3 must NOT re-introduce)\n- `CLAUDE.md` GD-32 \u2014 framework v2 entry; status to be updated to ARCHIVED-SUPERSEDED-\n  BY-GD-37 on v3 ratification\n- `CLAUDE.md` GD-33 \u2014 framework v2 Phase R1-R4 remediation entry; SUPERSEDED-by-GD-37\n- `CLAUDE.md` GD-37 \u2014 framework v3 entry; tracks status through P1 (this review) \u2192 P9\n  (operational)\n- in-toto v1 specification: https://in-toto.io/specs/\n- Sigstore Cosign documentation: https://docs.sigstore.dev/cosign/overview/\n- OPA documentation: https://www.openpolicyagent.org/docs/\n- Rego language reference: https://www.openpolicyagent.org/docs/latest/policy-language/\n- SLSA framework: https://slsa.dev/spec/v1.0/\n- HIPAA Safe Harbor: 45 CFR 164.514(b)(2)\n\n---\n\n## Artifact 1: Framework v3.1 architecture spec\n\n&gt; **Source path:** scripts/FRAMEWORK-v3-OPA-INTOTO-2026-06-02.md (1567 lines; v3.0 \u00a7\u00a71-12 + v3.1 \u00a713 amendment)\n&gt; **Embedded verbatim below; do not fetch the path \u2014 reviewer environment cannot access private-repo URLs.**\n\n\n\n\n\n\n\n# Framework v3 \u2014 OPA / in-toto / 4-Plane External Verifier\n\n**Authored:** 2026-06-02 by Claude main (post-convergent-verdict pivot, per Zachary directive 2026-06-02)\n**Status:** v3.0 DRAFT-PROPOSAL + v3.1 amendment per Round 2 external review (see \u00a713); pending Round 3 external review of the amended spec\n\n&gt; **AMENDMENT NOTICE (binding 2026-06-02 UTC; per Round 2 convergent external-reviewer findings \u2014 Reviewer 3 Sonnet 2 SHIP-WITH-CHANGES + Reviewer 4 GPT-5.4 RECONSIDER-REBUILD; both architecturally converged on 5 specific changes).** A v3.1 amendment block is appended at \u00a713 below. \u00a7\u00a73-6 (Evidence / Policy / Enforcement / Output planes) of v3.0 are **preserved verbatim** per OP-6 (audit-trail preservation); \u00a713 supersedes the relevant portions for any conflict. Future readers: if \u00a73.3 (`tier_classification_evidence: \"string\"`, `panel_framings: \"string[]\"`, `subject.name` with branch interpolation) or \u00a73.6 (Sigstore keyless default) or \u00a75.1 (Sigstore identity binding via repo-prefix regex) or \u00a76 (Output plane as separate workflow) or the 4-plane formulation appears to conflict with \u00a713.1-\u00a713.5, **\u00a713 controls**. Round 3 external review is the binding ratification gate; until it returns RECONSIDER-or-better convergence on the amended spec, both \u00a7\u00a73-6 (verbatim) AND \u00a713 (amendments) stay provisional.\n**Supersedes (substrate only):** `scripts/FRAMEWORK-v2-CI-CENTERED-2026-06-01.md` (framework v2; RECONSIDER + REBUILD per convergent external-reviewer verdict 2026-06-02)\n**Does NOT supersede (governance content survives intact):** CLAUDE.md rule corpus (Rules 3.1-3.9, J11-J16 audit-row content, D1-D3 declarations); Magna Carta principles + operating procedures; Governance Debt Ledger; Mandatory Pre-Build Search / Document Review / Plain-Language / Full-Team Dispatch gates; pre-push hook Layer 1; pre-commit hook OP-11\n**Retracts:** the framework v2 architectural premise that \"commit-body markdown is the durable attestation carrier\" \u2014 convergent reviewer finding: markdown is structurally wrong for attestation because (a) CommonMark fenced-block extraction is parser-differential, (b) custom Node.js regex extractor is inherently fragile, (c) the same agent that violates the rules drafts the audit row; v3 moves the substrate to a signed attestation file + declarative policy evaluator\n**Derives from:** Convergent verdict of external reviewers Gemini 3.1 (Reviewer 1) + GPT-5.4 (Reviewer 2) per `scripts/external-review/queue.jsonl` line 2 ts=2026-06-02T20:20:36Z + Magna Carta P3 (reports are claims; external signed attestation is evidence) + P5 (process errors compound; fix at architecture substrate layer) + P8 (rules without enforcement are observations \u2014 substrate fix moves enforcement out of the violating agent's narration) + GD-33 \u00a7\"external NON-Claude review per M\u00fcnchhausen-trilemma finding (binding precondition for CI re-enable)\"\n\n---\n\n## Glossary (per Mandatory Plain-Language Communication gate \u2014 first-mention spell-out)\n\n- **Framework v1** \u2014 the 3-layer Stop-hook enforcement stack (Layer A documentation + Layer B audit-row + Layer C inert scanners) shipped 2026-06-01 and superseded by v2; archived at `scripts/archived/2026-06-01-framework-v1/`\n- **Framework v2** \u2014 the Continuous-Integration-centered external verifier (commit-body JSON-in-fenced-block + Node.js regex validator + GitHub Actions workflow) shipped 2026-06-01 and superseded by v3 at the substrate layer; preserved at `scripts/FRAMEWORK-v2-CI-CENTERED-2026-06-01.md` per Archive Policy\n- **Framework v3** \u2014 the OPA / in-toto / 4-plane architecture described in this doc\n- **OPA** \u2014 Open Policy Agent (https://www.openpolicyagent.org/); a general-purpose policy engine; rules written in Rego (a declarative language); supports unit tests, dry-run, coverage; CNCF graduated project\n- **Rego** \u2014 the OPA policy language (declarative, datalog-inspired); rules express \"what is denied/allowed\" rather than imperative checks\n- **in-toto** \u2014 supply-chain attestation framework (https://in-toto.io/); CNCF incubating; defines signed attestation files with predicate types; attestations are typed JSON envelopes with a subject (what is attested about) and a predicate (the typed claim)\n- **Sigstore** \u2014 keyless signing infrastructure (https://sigstore.dev/); CNCF graduated; OIDC-rooted identities, Fulcio (CA), Rekor (transparency log), Cosign (signing CLI)\n- **DSSE** \u2014 Dead Simple Signing Envelope (in-toto's outer wrapper); RFC-ish format `{ payload, payloadType, signatures[] }`\n- **Predicate type** \u2014 the in-toto schema URI identifying what kind of claim the attestation makes (e.g., SLSA Provenance, custom)\n- **TOCTOU** \u2014 Time-Of-Check vs Time-Of-Use; class of race conditions where a check passes against state A but execution proceeds against state B\n- **PR** \u2014 Pull Request (GitHub feature for code review + merge)\n- **CI** \u2014 Continuous Integration (GitHub Actions workflows that run on push/PR events)\n- **PHI** \u2014 Protected Health Information (per HIPAA + per project D1 = clinical-record purpose)\n- **GD-33** \u2014 Governance Debt Ledger entry 33 (framework v2 Phase R1+R2 remediation status; the entry this v3 architecture resolves)\n- **GD-32** \u2014 Governance Debt Ledger entry 32 (framework v2 architecture; archived effective this commit upon v3 ratification)\n- **D1/D2/D3** \u2014 Magna Carta Declarations 1 (Primary Clinical Purpose) / 2 (Primary User) / 3 (Definition of Done)\n- **J11-J16** \u2014 the 6 audit-row identifiers from CLAUDE.md Mandatory Governance Compliance Audit; J11 agent-ID non-display, J12 plain-language communication, J13 marquis 10\u00d7 calibration, J14 pre-build search, J15 Rule-3.9 full-team dispatch, J16 Rule-3.10 post-push verification\n- **Wave 5** \u2014 the 8-panel adversarial re-audit 2026-06-02 that found framework v2 R1-R3 fixes incomplete (second RCE, PHI full-leak, 3 overstated fix claims); v3 architecture must NOT re-introduce these findings\n- **M\u00fcnchhausen-trilemma finding** \u2014 the Wave-4 + Wave-5 bias-auditor finding that \"all 16 audit panels are Claude\" so they cannot break out of their own evaluative perspective; binding precondition for v3 ratification is external NON-Claude review (this is why v3 ships in DRAFT-PROPOSAL status pending external review of this very doc)\n\n---\n\n## \u00a70. TL;DR \u2014 what changes v2 \u2192 v3 + why\n\n**One-paragraph synthesis:** Both external reviewers (Gemini 3.1 + GPT-5.4) returned `RECONSIDER + REBUILD` with HIGH confidence and CONVERGED on six load-bearing architectural findings: (1) commit-body markdown is structurally wrong as the attestation carrier \u2014 parser-differential, custom-regex-fragile, drafted by the same agent that violates the rules; (2) OPA / Rego for declarative policy \u2014 separates rules from plumbing, unit-testable, reviewable as policy; (3) signed attestation file (in-toto + Sigstore) \u2014 moves evidence OUT of human commit text into a structured, cryptographically-bound artifact; (4) separate enforcement workflow from commentary / notifier \u2014 zero-PHI output contract on the enforcement job; commentary runs in a non-blocking best-effort job; (5) TDD via external verification artifact \u2014 failing reproducer first, fix second, attestation third; merge only after all three; (6) preapproved public schema for digest output \u2014 no free-form markdown built from raw commit content. Framework v3 implements those findings as a 4-plane architecture: Evidence plane (in-toto + Sigstore) + Policy plane (OPA / Rego) + Enforcement plane (pinned trusted actions + minimum token permissions) + Output plane (tiny machine-readable result + human summary from preapproved public fields only).\n\n**One-paragraph migration framing:** What changes is the **substrate** (markdown commit body \u2192 signed attestation file; custom regex validator \u2192 OPA evaluator; one workflow \u2192 two workflows split by trust boundary). What does NOT change is the **content** (the J11-J16 rule corpus stays; tier classification stays; panel evidence stays; CLAUDE.md gates stay; pre-push + pre-commit hooks stay). v2 produced ~5 days of governance value (problem definition; regex banks salvageable to Rego; J11-J16 schema content; the schema-versioning discipline) but with the wrong architectural substrate. v3 is the substrate fix. The governance corpus survives because it is the engineering output of months of work; the substrate is the most-recent layer and the cheapest to replace.\n\n**Decision Zachary owes v3 before Phase 2:**\n- (Q-A) Sigstore keyless signing (OIDC-rooted, no key management) vs traditional GPG-signed attestation (key in repo Secrets)\n- (Q-B) Hosted OPA evaluator (`opa eval` in GitHub Actions runner) vs sidecar OPA service vs WASM-bundled policy (`opa build -t wasm`)\n- (Q-C) in-toto Statement format vs SLSA Provenance subtype vs a custom predicate type registered to project namespace\n- (Q-D) External review of THIS doc (v3 architecture spec) before Phase 2 begins, per the M\u00fcnchhausen-trilemma finding that authored-this-doc-too-Claude \u2014 recommended dispatch: same two reviewers (Gemini 3.1 + GPT-5.4) on the v3 architecture spec, identical premortem template + adversarial framing\n- (Q-E) Whether Phase 4 (archive v2 artifacts) executes immediately upon v3 ratification (clean cutover) or v2 + v3 run side-by-side for an A/B trial period (conservative, expensive)\n\n---\n\n## \u00a71. Convergent verdict synthesis\n\n### \u00a71.1. Source: `scripts/external-review/queue.jsonl` line 2\n\n```json\n{\n  \"ts\": \"2026-06-02T20:20:36Z\",\n  \"commit_sha\": null,\n  \"trigger_option\": \"B\",\n  \"trigger_reason\": \"GD-33 IN-REVIEW status: framework v2 Phase R1-R4 remediation complete; external NON-Claude review is binding M\u00fcnchhausen-trilemma mitigation per Wave 4 + Wave 5 bias auditors' finding (all 16 audit panels are Claude); precondition for CI re-enable per CLAUDE.md GD-33 row\",\n  \"trigger_files\": [\"scripts/validate-rule-3.9-compliance.mjs\", \"scripts/compliance-digest.mjs\", \"scripts/compliance-schema-v1.json\", \".github/workflows-pending/compliance-verify.yml\", \"scripts/FRAMEWORK-v2-CI-CENTERED-2026-06-01.md\"],\n  \"template\": \"B-premortem\",\n  \"dispatched_to\": \"gemini-3.1+gpt-5.4\",\n  \"status\": \"returned-both-converge\",\n  \"verdict\": \"RECONSIDER-REBUILD-CONVERGENT\",\n  \"response_summary\": \"BOTH reviewers verdict RECONSIDER + REBUILD with HIGH confidence. CONVERGE on: commit-body markdown structurally wrong as attestation carrier; OPA/Rego for declarative policy; signed attestation file (in-toto/SARIF); separate enforcement from commentary; Q7 TOCTOU defense; Q8 email rebleed via job-separation; Q6 TDD via external attestation. Reviewer 2 (GPT-5.4) more specific 4-plane architecture: Evidence (in-toto + Sigstore) + Policy (OPA/Rego) + Enforcement (pinned actions + min permissions) + Output (preapproved fields only).\"\n}\n```\n\n### \u00a71.2. Six convergent load-bearing findings (mapped to v3 components)\n\n| # | Convergent finding | v3 component that addresses it |\n|---|---|---|\n| F1 | Commit-body markdown is structurally wrong as attestation carrier (parser-differential; custom regex extractor inherently fragile; written by the violator) | \u00a73 Evidence plane: in-toto signed attestation file moves substrate out of commit body entirely |\n| F2 | OPA / Rego for declarative policy (separates rules from plumbing; unit-testable; reviewable as policy) | \u00a74 Policy plane: Rego policy pack at `policy/rules/`; one rule file per J11-J16 / Rule 3.X; unit tests per rule via `opa test` |\n| F3 | Signed attestation file (in-toto + Sigstore) \u2014 moves evidence out of human commit text into structured cryptographically-bound artifact | \u00a73 Evidence plane: in-toto Statement format wrapped in DSSE envelope; signed via Sigstore Cosign (keyless OIDC-rooted) |\n| F4 | Separate enforcement from commentary / notifier (zero-PHI on enforcement job; commentary non-blocking best-effort) | \u00a75 Enforcement plane (blocking) + \u00a76 Output plane (commentary; separate workflow file; different `permissions:` token scope) |\n| F5 | TDD via external verification artifact (failing reproducer first, fix second, attestation third; merge only after all three) | \u00a73.4 evidence-plane TDD discipline: every new rule's first commit is a failing-policy-test commit; the rule + its passing test land in the second + third commit; merge gate at PR boundary requires all three present |\n| F6 | Preapproved public schema for digest output \u2014 no free-form markdown built from raw commit content | \u00a76.2 output schema: typed enums + hex SHA + tier + verdict + counts; NO free-text; commentary template renders from approved fields only; the v2 PHI-full-leak failure mode is structurally prevented |\n\n### \u00a71.3. Per-Q analysis from the v2 premortem queue (carried forward where applicable)\n\nThe v2 premortem template that triggered the convergent verdict contained Q1-Q15. The convergent verdict body answers Q6 (TDD), Q7 (TOCTOU), Q8 (email rebleed) explicitly. v3 inherits those answers:\n\n- **Q6 (TDD discipline):** evidence-plane TDD per \u00a73.4 below; failing-reproducer-first pattern is the convergent answer; v3 enforces it via PR-merge gate requiring all three commits present in the merge subject + an attestation that references the test commit's SHA\n- **Q7 (TOCTOU defense):** the enforcement workflow re-fetches the commit SHA at policy-evaluation time and the attestation file's `subject.digest` field cryptographically binds to that SHA; any HEAD-shift between Claude's local push and CI evaluation is detected by digest mismatch; this is the SHA-matching defense both reviewers recommended\n- **Q8 (email rebleed via job-separation):** v2's failure was a single workflow file with one job that did enforcement + posted commentary; when permissions were wrong (`contents: read` 403 on commit-comment API), commentary attempted but failed \u2192 GitHub sent a workflow failure email per push; v3 splits enforcement + commentary into TWO workflow files, each with the minimum permissions for its specific operation; the commentary job is non-blocking (`continue-on-error: true`) so even if commentary fails it doesn't trigger email; the enforcement job has zero outbound surface\n\n### \u00a71.4. Reviewer 2's 4-plane formulation (verbatim adopted as v3's primary architecture)\n\nReviewer 2 (GPT-5.4) provided a specific 4-plane architecture which Reviewer 1 (Gemini 3.1) converged on through different framing:\n\n- **Evidence plane** \u2014 in-toto attestation file (or compatible JSON envelope), signed via Sigstore\n- **Policy plane** \u2014 OPA / Rego policies \u2014 declarative, unit-testable, separable from plumbing\n- **Enforcement plane** \u2014 GitHub Action with pinned trusted actions + minimum token permissions\n- **Output plane** \u2014 tiny machine-readable result + human summary built from preapproved public fields only\n\nv3 adopts this 4-plane formulation as its primary architecture (\u00a7\u00a73-6 below are one section per plane).\n\n---\n\n## \u00a72. The 4-plane architecture\n\n```\n\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n\u2502                         Framework v3 \u2014 4-Plane Architecture                      \u2502\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n\n  Claude makes commit                  \u250c\u2500 \u00a73 EVIDENCE PLANE \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n  \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500                  \u2502                                     \u2502\n                                        \u2502  (claude main, post-commit, local)  \u2502\n  1. git commit (commit body            \u2502                                     \u2502\n     prose for HUMANS \u2014 narrative;      \u2502  generate in-toto Statement:        \u2502\n     NOT the attestation; rules         \u2502  {                                   \u2502\n     in CLAUDE.md still apply but       \u2502    \"_type\": \"in-toto Statement\",    \u2502\n     prose itself is not the carrier)   \u2502    \"predicateType\": \"...compliance..\u2502\n                                        \u2502    \"subject\": [{name: ,     \u2502\n  2. Claude generates attestation       \u2502       digest: {sha1: }}],\u2502\n     file (typed JSON), sign via        \u2502    \"predicate\": { schema-v3.0       \u2502\n     Sigstore Cosign keyless OIDC       \u2502       J11-J16 + tier + panel-evid + \u2502\n                                        \u2502       PBS-classification + ...      \u2502\n  3. Place attestation file at          \u2502    }                                \u2502\n     .attestations/.json    \u2502  }                                  \u2502\n                                        \u2502                                     \u2502\n  4. git add + git commit -m            \u2502  Sign via:                          \u2502\n     \"attestation for \"            \u2502    cosign sign-blob --yes \\\\         \u2502\n     (the signed file is committed      \u2502       attestations/.json       \u2502\n     to the repo; signature bound       \u2502                                     \u2502\n     to OIDC-rooted identity via        \u2502  Output: .attestations/.json   \u2502\n     Sigstore transparency log)         \u2502      + .attestations/.json.sig \u2502\n                                        \u2502      + .attestations/.json.bundle\n                                        \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n                                                       \u2502\n                                                       \u25bc\n  git push                              \u250c\u2500 Layer 1 pre-push hook (UNCHANGED) \u2500\u2510\n  \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500                              \u2502  Blocks wrong-branch                \u2502\n                                        \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n                                                     \u2502 push allowed\n                                                     \u25bc\n  github actions on push to claude/* + main\n  \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n  \u250c\u2500 \u00a75 ENFORCEMENT PLANE \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510     \u250c\u2500 \u00a76 OUTPUT PLANE \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n  \u2502  .github/workflows/             \u2502     \u2502  .github/workflows/             \u2502\n  \u2502    compliance-enforce.yml       \u2502     \u2502    compliance-commentary.yml    \u2502\n  \u2502                                 \u2502     \u2502                                 \u2502\n  \u2502  permissions:                   \u2502     \u2502  permissions:                   \u2502\n  \u2502    contents: read               \u2502     \u2502    pull-requests: write         \u2502\n  \u2502    id-token: write              \u2502     \u2502    issues: write                \u2502\n  \u2502    (NO outbound, NO commentary) \u2502     \u2502    (commentary-only; no enforce)\u2502\n  \u2502                                 \u2502     \u2502                                 \u2502\n  \u2502  jobs.enforce:                  \u2502     \u2502  jobs.commentary:               \u2502\n  \u2502    - cosign verify-blob         \u2502     \u2502    needs: [enforce]             \u2502\n  \u2502      (attestation signature)    \u2502     \u2502    if: always() (incl. failure) \u2502\n  \u2502    - opa eval ...               \u2502     \u2502    continue-on-error: true      \u2502\n  \u2502      policy/rules               \u2502     \u2502      (so commentary fail        \u2502\n  \u2502      against attestation        \u2502     \u2502       does NOT trigger email)   \u2502\n  \u2502      JSON                       \u2502     \u2502                                 \u2502\n  \u2502    - decision: PASS/FAIL        \u2502     \u2502    Renders preapproved-fields-  \u2502\n  \u2502    - exit 0 / exit 1            \u2502     \u2502      only digest from \u00a76.2      \u2502\n  \u2502      (FAIL = branch protection  \u2502     \u2502      schema; free-text          \u2502\n  \u2502       blocks merge)             \u2502     \u2502      forbidden                  \u2502\n  \u2502                                 \u2502     \u2502                                 \u2502\n  \u2502  ZERO PHI EXPOSURE.             \u2502     \u2502  Commentary may render PHI iff  \u2502\n  \u2502  No prose, no commit subjects,  \u2502     \u2502  pre-approved field set,        \u2502\n  \u2502  no commentary, no commit       \u2502     \u2502  which contains zero PHI by     \u2502\n  \u2502  body text in this job.         \u2502     \u2502  construction.                  \u2502\n  \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518     \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n                \u25b2                                       \u2502\n                \u2502 produces                              \u25bc\n                \u2502                          \u250c\u2500 PR comment + (optional)\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n        \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510             \u2502   notifier (Pushover/etc)     \u2502\n        \u2502 \u00a74 POLICY PLANE    \u2502             \u2502                               \u2502\n        \u2502                    \u2502             \u2502   Preapproved schema only:    \u2502\n        \u2502 policy/rules/      \u2502             \u2502   - hex SHA                   \u2502\n        \u2502   j11_agent_id.    \u2502             \u2502   - tier (enum)               \u2502\n        \u2502     rego           \u2502             \u2502   - verdict (enum)            \u2502\n        \u2502   j12_plain_       \u2502             \u2502   - per-rule statuses (enum)  \u2502\n        \u2502     language.rego  \u2502             \u2502   - counts (int)              \u2502\n        \u2502   j13_marquis.rego \u2502             \u2502   - link to attestation file  \u2502\n        \u2502   j14_pbs.rego     \u2502             \u2502   NO commit subjects.         \u2502\n        \u2502   j15_full_team.   \u2502             \u2502   NO commit body text.        \u2502\n        \u2502     rego           \u2502             \u2502   NO file path snippets.      \u2502\n        \u2502   j16_post_push.   \u2502             \u2502   NO clinical content.        \u2502\n        \u2502     rego           \u2502             \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n        \u2502   d1_d2_d3.rego    \u2502\n        \u2502   rule_3_8.rego    \u2502\n        \u2502   ...              \u2502\n        \u2502 policy/tests/      \u2502\n        \u2502   j11_agent_id_    \u2502\n        \u2502     test.rego      \u2502\n        \u2502   ... (one per     \u2502\n        \u2502   policy)          \u2502\n        \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n```\n\nThe four planes are deliberately **trust-isolated**: each runs with the minimum permission scope needed for its work. The enforcement plane has zero outbound surface (no PR comments, no Pushover, no email). The output plane has zero policy decisions (it formats; it does not decide). Per Magna Carta P5 (process errors compound at architecture layer), the v2 single-workflow-blob architecture is exactly the pattern this addresses.\n\n---\n\n## \u00a73. Evidence plane spec (in-toto + Sigstore)\n\n### \u00a73.1. Why in-toto\n\nin-toto is a CNCF supply-chain attestation framework. Its core abstraction is a **Statement** \u2014 a typed JSON envelope with a **subject** (what is attested about) and a **predicate** (the typed claim). Statements wrap in **DSSE envelopes** for signing. The framework is general-purpose; it is the default attestation format for SLSA provenance (Build, Source) and has a registered process for custom predicate types.\n\nThe v2 substrate (commit-body markdown JSON) was unauthenticated (no signature; anyone with commit access could fabricate it; the convergent finding \"written by the violator\" is structurally inherent). The v3 substrate (in-toto + Sigstore) is authenticated \u2014 the signature ties the attestation to an OIDC-rooted identity at signing time + records the signing event in the Sigstore transparency log (Rekor). Tampering with the attestation file invalidates the signature; fabricating an attestation requires the signing identity's OIDC credentials at that moment.\n\n### \u00a73.2. Attestation file location + naming\n\n```\n.attestations/                              # NEW directory at repo root\n  .json                         # the in-toto Statement (JSON)\n  .json.sig                     # detached Sigstore signature\n  .json.bundle                  # Sigstore bundle (cert chain + Rekor entry)\n```\n\nThe directory is **committed to the repo** (not gitignored \u2014 the audit trail IS the point per Mandatory Archive Policy). Each commit produces three files; the bundle file is the verifiable artifact (it includes the cert chain anchored to the Sigstore root CA + the Rekor inclusion proof). For audit-trail browsing per Archive Policy, `.attestations/INDEX.md` is generated incrementally per push (alphabetical-by-SHA \u2014 the directory listing itself IS the index; the INDEX.md is appended-to with date + tier + verdict for browsability).\n\n### \u00a73.3. Attestation content \u2014 in-toto Statement structure\n\n```json\n{\n  \"_type\": \"https://in-toto.io/Statement/v1\",\n  \"predicateType\": \"https://github.com/billyjoelsaniceguy/health-dashboard/attestations/compliance-row/v3.0\",\n  \"subject\": [\n    {\n      \"name\": \"git+https://github.com/billyjoelsaniceguy/health-dashboard@\",\n      \"digest\": {\n        \"sha1\": \"\"\n      }\n    }\n  ],\n  \"predicate\": {\n    \"schema_version\": \"3.0\",\n    \"commit_metadata\": {\n      \"tier\": \"marquis\",\n      \"tier_classification_evidence\": \"subject regex match /\\\\bhook\\\\b/i\",\n      \"session_id\": \"claude-\",\n      \"panel_dispatched\": true,\n      \"panel_size\": 7,\n      \"panel_framings\": [\"state-audit\", \"hook-diagnostic\", \"rule-compliance\", \"roadmap-delta\", \"sentinel\", \"decisions-surface\", \"synthesis-bias-audit\"]\n    },\n    \"j11_agent_id_non_display\": {\n      \"name\": \"agent-ID non-display in human-readable output\",\n      \"status\": \"PASS\",\n      \"evidence_count\": 0,\n      \"evidence_kind\": \"bare-8-char-hex-prose-out-of-context-count\"\n    },\n    \"j12_plain_language\": {\n      \"name\": \"plain-language communication; bare codes glossed\",\n      \"status\": \"PARTIAL\",\n      \"bare_code_count_in_prose\": 5,\n      \"acceptable_context_count\": 5,\n      \"glossary_present\": true\n    },\n    \"j13_marquis_depth\": {\n      \"name\": \"marquis 10x calibration\",\n      \"status\": \"PASS\",\n      \"executable_provided\": true,\n      \"test_performed\": true,\n      \"prestaged\": true\n    },\n    \"j14_pre_build_search\": {\n      \"name\": \"pre-build search for functional equivalents\",\n      \"status\": \"PASS\",\n      \"classification\": \"NEW\",\n      \"candidates_reviewed\": 3,\n      \"search_evidence_inline\": true,\n      \"pbs_cited_files\": [\n        \"scripts/FRAMEWORK-v2-CI-CENTERED-2026-06-01.md\",\n        \"scripts/external-review/queue.jsonl\",\n        \"scripts/compliance-schema-v1.json\"\n      ]\n    },\n    \"j15_full_team_dispatch\": {\n      \"name\": \"Rule 3.9 mandatory full team dispatch\",\n      \"status\": \"PASS-CARVE-OUT\",\n      \"panel_dispatched_or_skip\": \"skip\",\n      \"skip_rationale\": \"continuation-of-autonomous-run\",\n      \"skip_carveout_category\": \"continuation\"\n    },\n    \"j16_post_push_verification\": {\n      \"name\": \"Rule 3.10 post-push verification\",\n      \"status\": \"N/A\",\n      \"reason\": \"rule not yet ratified\"\n    },\n    \"d1_clinical_purpose_affected\": false,\n    \"d2_user_tier_affected\": \"none\",\n    \"d3_definition_of_done\": {\n      \"applicable_conditions\": [],\n      \"n_a_conditions_with_rationale\": \"infra/governance \u2014 no UI surface; D3 conditions 1-6 are N/A per infra carve-out (P8-candidate per CLAUDE.md candidate #3)\"\n    }\n  }\n}\n```\n\nThe **predicate structure carries forward the J11-J16 field shapes from `scripts/compliance-schema-v1.json` (v2 schema)** \u2014 that schema is reused as the predicate's body schema. v3's schema version bumps to 3.0 (signaling substrate change, not content change). The v2 `compliance-row-v1` literal still appears in archived v2 commits and remains historically valid; v3 attestations use `https://github.com/billyjoelsaniceguy/health-dashboard/attestations/compliance-row/v3.0` as the predicate type URI.\n\n### \u00a73.4. Signing flow\n\n```bash\n# Claude main, post-commit, on the local branch\nCOMMIT_SHA=$(git rev-parse HEAD)\n\n# Step 1: generate the in-toto Statement\nnode scripts/generate-attestation-v3.mjs \\\n  --commit \"$COMMIT_SHA\" \\\n  --branch \"$(git rev-parse --abbrev-ref HEAD)\" \\\n  --tier \"marquis\" \\\n  --panel-evidence path/to/panel-evidence.json \\\n  --output \".attestations/$COMMIT_SHA.json\"\n\n# Step 2: sign via Sigstore Cosign keyless (OIDC-rooted)\ncosign sign-blob \\\n  --yes \\\n  --output-signature \".attestations/$COMMIT_SHA.json.sig\" \\\n  --output-certificate \".attestations/$COMMIT_SHA.json.bundle\" \\\n  \".attestations/$COMMIT_SHA.json\"\n\n# Step 3: commit the attestation files\ngit add \".attestations/$COMMIT_SHA.json\" \\\n        \".attestations/$COMMIT_SHA.json.sig\" \\\n        \".attestations/$COMMIT_SHA.json.bundle\"\ngit commit -m \"attestation: compliance row for $COMMIT_SHA\"\n```\n\nThe TWO-commit flow (substantive commit \u2192 attestation commit) is deliberate. The attestation's subject digest is `$COMMIT_SHA` \u2014 the SUBSTANTIVE commit's SHA, not the attestation commit's. This means:\n- The attestation references a commit that exists at signing time (no future-dated claims)\n- The signature binds the attestation content to the OIDC identity at signing time (Sigstore + Rekor transparency log)\n- The CI workflow at PR-merge time evaluates each substantive commit by looking up its attestation by SHA + verifying signature + evaluating Rego policy against the attestation JSON\n\n### \u00a73.5. TDD discipline (per convergent F5)\n\nEvery new policy rule lands in a **3-commit sequence**:\n\n```\ncommit 1 \u2014 \"test(j17): failing reproducer for new compliance rule\"\n           Adds policy/tests/j17_test.rego with a test that FAILS against\n           a synthetic attestation lacking the new claim. CI runs the test.\n           CI is RED on this commit (informational; not blocking until rule lands).\n\ncommit 2 \u2014 \"policy(j17): rule definition\"\n           Adds policy/rules/j17.rego with the rule. Re-runs the test.\n           CI is GREEN on this commit (the rule + test now agree).\n\ncommit 3 \u2014 \"attestation(j17): canonical-claim attestation for commits 1+2\"\n           Adds .attestations/.json + signature with\n           predicate field j17 status N/A; same for commit 2 but with\n           status reflecting actual evaluation.\n```\n\nAt PR-merge time, the policy evaluator checks: for every commit in the PR, an attestation exists; for every new rule introduced in the PR, both a failing-test commit AND a passing-rule commit are present. The merge gate fails if either is missing.\n\n### \u00a73.6. Sigstore choice \u2014 keyless vs traditional\n\nPer Q-A in \u00a70 TL;DR: Zachary chooses keyless (Sigstore Fulcio OIDC-rooted) vs traditional GPG (key in repo Secrets). The default v3 picks **keyless**:\n\n**Why keyless (default):**\n- No key management (no key rotation, no key compromise risk, no secrets to leak)\n- OIDC-rooted identity (cosign uses the GitHub Actions OIDC token at signing time \u2192 cert valid for ~10 minutes \u2192 identity recorded in Rekor transparency log)\n- Free / no-cost (Sigstore is operated by the Linux Foundation as public-benefit infrastructure)\n- Verifiable by anyone without sharing keys\n\n**Why traditional GPG (alternative):**\n- Works offline (Sigstore requires Fulcio + Rekor accessible at sign time)\n- More familiar to operators with GPG infra\n- No dependency on Sigstore uptime (Sigstore has had outages; impact would be \"Claude cannot sign attestations during the outage\" \u2014 equivalent to \"CI is down\")\n\n**Default recommendation:** keyless, because (a) the project already runs on GitHub Actions (OIDC tokens already issued), (b) zero key-management burden, (c) Sigstore's outage history is low (&lt;1% over the last year), (d) traditional GPG re-introduces \"the secret is in the repo\" failure mode that the v2 PHI-rebleed-via-Pushover-credentials nearly hit.\n\n---\n\n## \u00a74. Policy plane spec (OPA / Rego)\n\n### \u00a74.1. Why OPA\n\nOPA (Open Policy Agent) is a CNCF graduated project providing a general-purpose policy engine. Its policy language Rego is declarative (datalog-inspired) \u2014 rules express \"this is denied\" or \"this is allowed\" rather than imperative procedural checks. OPA supports:\n- Unit testing (`opa test`)\n- Coverage reporting (`opa test --coverage`)\n- Dry-run with sample data (`opa eval --input ...`)\n- WASM compilation (`opa build -t wasm`) for embedded evaluation\n- Decision logging\n- Bundle distribution\n\nThe v2 substrate (Node.js regex validator) bundled policy logic + plumbing (file parsing + path normalization + git operations + schema validation + JSON serialization) into a single 960-line script. Wave-5 found this monolith had multiple bypass paths because the policy logic was intermixed with the plumbing \u2014 fixing one bypass required understanding the whole script. The v3 substrate (Rego policies in `policy/rules/` + minimal evaluator plumbing) **separates** policy from plumbing structurally: the evaluator plumbing is small (&lt;200 lines; fetches attestation, runs `opa eval`, formats result); the policy itself is in declarative Rego files (one per rule, ~20-50 lines each) that are independently reviewable.\n\n### \u00a74.2. Policy pack location + structure\n\n```\npolicy/                                       # NEW directory at repo root\n  README.md                                   # how to add a rule + run tests\n  bundle.json                                 # OPA bundle manifest (autogenerated)\n  rules/\n    j11_agent_id_non_display.rego             # one file per audit row\n    j12_plain_language.rego\n    j13_marquis_depth.rego\n    j14_pre_build_search.rego\n    j15_full_team_dispatch.rego\n    j16_post_push_verification.rego\n    d1_clinical_purpose.rego                  # one file per Magna Carta declaration\n    d2_user_tier.rego\n    d3_definition_of_done.rego\n    rule_3_1_no_arbitrary_cap.rego            # one file per Rule 3.X\n    rule_3_2_pre_7pm.rego\n    rule_3_3_multi_circumstance.rego\n    rule_3_4_no_simplify_at_rigor_cost.rego\n    rule_3_6_agent_team_visible.rego\n    rule_3_7_coverage_gap.rego\n    rule_3_8_marquis_10x.rego\n    rule_3_9_full_team_dispatch.rego\n    schema_envelope.rego                      # in-toto envelope structural validity\n    schema_predicate_v3.rego                  # predicate field structural validity\n    signature_freshness.rego                  # Sigstore signature must be &lt;24h old\n    subject_digest_match.rego                 # subject.digest.sha1 must match commit\n  tests/\n    j11_agent_id_non_display_test.rego        # one test file per rule (mirroring rules/)\n    j12_plain_language_test.rego\n    j13_marquis_depth_test.rego\n    j14_pre_build_search_test.rego\n    j15_full_team_dispatch_test.rego\n    j16_post_push_verification_test.rego\n    ... (mirror structure)\n  fixtures/\n    valid_attestation.json                    # fixtures for tests\n    attestation_with_silent_skip.json\n    attestation_with_pbs_missing_classification.json\n    ...\n```\n\n### \u00a74.3. Example rule file \u2014 `policy/rules/j14_pre_build_search.rego`\n\n```rego\npackage compliance.j14\n\nimport future.keywords.if\nimport future.keywords.in\n\n# Default to violation; allow only when all sub-checks pass\ndefault allow := false\n\n# Allow when status is one of the acceptable enum values AND for non-N/A statuses\n# the supplementary fields are present and well-formed.\nallow if {\n    status_valid\n    classification_valid\n    pbs_files_referenced_exist  # (the file-existence check; v2 had this; v3 keeps it)\n}\n\nstatus_valid if {\n    input.predicate.j14_pre_build_search.status in {\"PASS\", \"FAIL\", \"PARTIAL\", \"N/A\"}\n}\n\nclassification_valid if {\n    input.predicate.j14_pre_build_search.status == \"N/A\"\n}\n\nclassification_valid if {\n    input.predicate.j14_pre_build_search.status != \"N/A\"\n    input.predicate.j14_pre_build_search.classification in {\"NEW\", \"EXTENDS\", \"SUPERSEDES\"}\n}\n\n# Note: pbs_files_referenced_exist is enforced OUTSIDE Rego because Rego is sandboxed\n# (cannot access filesystem). The evaluator plumbing pre-resolves file existence and\n# passes the result as input.aux.pbs_files_exist (boolean per file). Rego then asserts\n# all are true.\npbs_files_referenced_exist if {\n    every file_check in input.aux.pbs_files_exist {\n        file_check == true\n    }\n}\n\nviolation contains msg if {\n    not allow\n    msg := sprintf(\"j14 violation: status=%v classification=%v pbs_files_exist=%v\",\n                   [input.predicate.j14_pre_build_search.status,\n                    input.predicate.j14_pre_build_search.classification,\n                    input.aux.pbs_files_exist])\n}\n```\n\n### \u00a74.4. Example test file \u2014 `policy/tests/j14_pre_build_search_test.rego`\n\n```rego\npackage compliance.j14_test\n\nimport data.compliance.j14\n\n# Test: valid PASS attestation should allow\ntest_valid_pass if {\n    j14.allow with input as {\n        \"predicate\": {\n            \"j14_pre_build_search\": {\n                \"status\": \"PASS\",\n                \"classification\": \"NEW\",\n                \"candidates_reviewed\": 3,\n                \"pbs_cited_files\": [\"scripts/foo.md\", \"scripts/bar.mjs\"]\n            }\n        },\n        \"aux\": {\n            \"pbs_files_exist\": [true, true]\n        }\n    }\n}\n\n# Test: PBS-cited file that does not exist should deny\ntest_nonexistent_pbs_file_denies if {\n    not j14.allow with input as {\n        \"predicate\": {\n            \"j14_pre_build_search\": {\n                \"status\": \"PASS\",\n                \"classification\": \"NEW\",\n                \"candidates_reviewed\": 3,\n                \"pbs_cited_files\": [\"scripts/does-not-exist.md\"]\n            }\n        },\n        \"aux\": {\n            \"pbs_files_exist\": [false]\n        }\n    }\n}\n\n# Test: invalid classification denies\ntest_invalid_classification_denies if {\n    not j14.allow with input as {\n        \"predicate\": {\n            \"j14_pre_build_search\": {\n                \"status\": \"PASS\",\n                \"classification\": \"INVENT-NEW-VALUE\"\n            }\n        },\n        \"aux\": {\"pbs_files_exist\": []}\n    }\n}\n```\n\nEach rule's test file MUST include at least: (a) one valid-input pass case; (b) one valid-input fail case; (c) one structural-invariant fail case (e.g., missing required field; invalid enum value). The `opa test --coverage` output must show \u2265 80% rule body coverage per rule. The CI workflow runs `opa test policy/` as a precondition step before `opa eval` runs against any attestation.\n\n### \u00a74.5. How to add a new rule (developer flow)\n\nPer convergent F5 TDD discipline:\n\n```bash\n# Step 1: author the failing test first\ncat &gt; policy/tests/j17_new_rule_test.rego &lt;&lt; EOF\npackage compliance.j17_test\nimport data.compliance.j17\n\ntest_failing_reproducer if {\n    not j17.allow with input as { ... synthetic case the new rule should deny ... }\n}\nEOF\n\n# Step 2: confirm the test FAILS (because the rule doesn't exist yet)\nopa test policy/  # j17_test.rego shows FAIL\n\n# Step 3: git commit the failing test (commit 1 of 3)\ngit add policy/tests/j17_new_rule_test.rego\ngit commit -m \"test(j17): failing reproducer for \"\n\n# Step 4: author the rule\ncat &gt; policy/rules/j17_new_rule.rego &lt;&lt; EOF\npackage compliance.j17\ndefault allow := false\nallow if { ... rule body ... }\nEOF\n\n# Step 5: confirm the test PASSES\nopa test policy/  # j17_test.rego shows PASS\n\n# Step 6: git commit the rule (commit 2 of 3)\ngit add policy/rules/j17_new_rule.rego\ngit commit -m \"policy(j17): \"\n\n# Step 7: generate + sign attestations for the two prior commits\n# (the third commit is the attestation commit; per \u00a73.5)\n```\n\n### \u00a74.6. Composition with v2 schema content\n\n`scripts/compliance-schema-v1.json` (the v2 schema) IS preserved at the **predicate body** layer. The Rego rule `schema_predicate_v3.rego` asserts predicate structural validity using a port of the v2 schema's JSON-schema constraints to Rego assertions. This avoids re-doing the schema design work; v2's J11-J16 field shapes carry forward 1:1 with the addition of D1/D2/D3 + Rule 3.X fields. Field renames + new constraints land via Rego policy update + bumped schema_version (3.0 \u2192 3.1 \u2192 ...) per OP-7 review cadence.\n\n---\n\n## \u00a75. Enforcement plane spec (GitHub Actions)\n\n### \u00a75.1. Workflow file \u2014 `.github/workflows/compliance-enforce.yml`\n\n```yaml\n# Pre-Build Search Evidence (per Mandatory Pre-Build Search gate):\n# Classification: NEW (supersedes compliance-verify.yml at the workflow layer; the workflow\n#   below is structurally different \u2014 split into enforce + commentary per convergent F4)\n# Searches performed: ls .github/workflows-pending/ -&gt; compliance-verify.yml (v2; superseded)\n# Existing abstractions: cosign-installer, setup-opa\n# Rationale: enforcement-only; zero PHI surface; zero outbound API calls\n\nname: compliance-enforce\n\non:\n  push:\n    branches: [\"claude/**\", \"main\"]\n  pull_request:\n    branches: [\"main\"]\n\n# Minimum token permissions \u2014 fail-closed by absence of any other scope\npermissions:\n  contents: read       # to checkout + read .attestations/\n  id-token: write      # to use Sigstore Cosign OIDC verification (verify step)\n  # explicitly NO pull-requests, NO issues, NO actions, NO packages\n\n# Concurrency: cancel in-progress runs on the same ref to avoid duplicate work\nconcurrency:\n  group: compliance-enforce-${{ github.ref }}\n  cancel-in-progress: true\n\njobs:\n  enforce:\n    name: enforce  # MATCHES the branch protection rule name exactly\n    runs-on: ubuntu-latest\n    timeout-minutes: 5  # bound runtime; FAIL on timeout\n\n    steps:\n      # All actions pinned to commit SHA (not version tag) per convergent recommendation\n      - name: Checkout repo\n        uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11  # v4.1.1\n        with:\n          fetch-depth: 0  # full history; v2's shallow-clone silent pass was a Wave-5 finding\n\n      - name: Install Cosign\n        uses: sigstore/cosign-installer@e1523de7571e31dbe865fd2e80c5c7c23ae71eb4  # v3.4.0\n        with:\n          cosign-release: 'v2.2.4'  # pinned\n\n      - name: Install OPA\n        uses: open-policy-agent/setup-opa@34a30e8a924d1b03ce2cf7abe97250bbb1f332b5  # v2.2.0\n        with:\n          version: 0.62.1  # pinned\n\n      - name: Run OPA tests (precondition \u2014 must pass before evaluating attestations)\n        run: |\n          opa test policy/ --verbose --explain=fails\n          opa test policy/ --coverage --threshold=80\n\n      - name: Identify commits in this push/PR\n        id: commits\n        run: |\n          # SHA-matching defense for TOCTOU (convergent F-Q7):\n          # capture HEAD now, evaluate against this exact SHA throughout\n          echo \"head_sha=$(git rev-parse HEAD)\" &gt;&gt; $GITHUB_OUTPUT\n          # Enumerate commits in the push range\n          git log --format='%H' \"${{ github.event.before }}..${{ github.event.after }}\" &gt; commits.txt\n          echo \"Commits to verify:\"; cat commits.txt\n\n      - name: Verify each commit's attestation\n        run: |\n          set -euo pipefail\n          FAILED=0\n          while IFS= read -r SHA; do\n            ATTESTATION=\".attestations/${SHA}.json\"\n            BUNDLE=\".attestations/${SHA}.json.bundle\"\n\n            if [ ! -f \"$ATTESTATION\" ]; then\n              echo \"::error::Missing attestation file for commit $SHA\"\n              FAILED=1\n              continue\n            fi\n\n            # Verify Sigstore signature against OIDC-rooted identity\n            cosign verify-blob \\\n              --bundle \"$BUNDLE\" \\\n              --certificate-identity-regexp \"^https://github\\\\.com/billyjoelsaniceguy/health-dashboard\" \\\n              --certificate-oidc-issuer \"https://token.actions.githubusercontent.com\" \\\n              \"$ATTESTATION\" \\\n              || { echo \"::error::Signature verification failed for $SHA\"; FAILED=1; continue; }\n\n            # SHA-matching defense (convergent F-Q7):\n            # the attestation's subject.digest.sha1 MUST equal the commit SHA\n            ATT_SHA=$(jq -r '.subject[0].digest.sha1' \"$ATTESTATION\")\n            if [ \"$ATT_SHA\" != \"$SHA\" ]; then\n              echo \"::error::TOCTOU defense: attestation subject SHA $ATT_SHA != commit SHA $SHA\"\n              FAILED=1\n              continue\n            fi\n\n            # Pre-resolve PBS file existence for input.aux (Rego can't read filesystem)\n            jq -c '.predicate.j14_pre_build_search.pbs_cited_files // [] | map({\"file\": ., \"exists\": false})' \\\n              \"$ATTESTATION\" &gt; aux.json\n            # ... (loop populates exists: true/false; omitted for brevity)\n\n            # Evaluate Rego policy against the attestation\n            opa eval \\\n              --data policy/rules/ \\\n              --input \"$ATTESTATION\" \\\n              --format json \\\n              'data.compliance.allow' \\\n              &gt; eval-result.json\n\n            VERDICT=$(jq -r '.result[0].expressions[0].value' eval-result.json)\n            if [ \"$VERDICT\" != \"true\" ]; then\n              VIOLATIONS=$(opa eval --data policy/rules/ --input \"$ATTESTATION\" \\\n                --format json 'data.compliance.violation' | jq -r '.result[0].expressions[0].value[]')\n              echo \"::error::Compliance FAIL for $SHA: $VIOLATIONS\"\n              FAILED=1\n            fi\n          done &lt; commits.txt\n\n          if [ $FAILED -ne 0 ]; then\n            exit 1  # branch protection blocks merge\n          fi\n```\n\n### \u00a75.2. Trust isolation invariants\n\nThe enforcement workflow MUST satisfy:\n\n1. **Zero outbound PHI surface.** No PR comments, no issue comments, no Pushover, no email, no Slack. Output is exit code 0/1 + GitHub-native logs (which are repo-private)\n2. **Minimum permissions.** `contents: read` + `id-token: write` only. Any other scope is a configuration error\n3. **All actions pinned to commit SHA.** Version tags are mutable; SHAs are not. (Convergent reviewer recommendation)\n4. **Timeout-bounded.** 5-minute wall-clock cap; FAIL on timeout\n5. **fetch-depth: 0.** Full clone; no shallow-clone silent pass (Wave-5 finding)\n6. **SHA-matching TOCTOU defense.** Attestation `subject.digest.sha1` MUST equal evaluated commit SHA\n7. **Signature verification before policy evaluation.** Unverified attestations are NOT evaluated; signature check fails the whole step\n8. **Policy test precondition.** `opa test` must pass before any `opa eval` runs against an attestation; broken policy = no evaluation = FAIL\n\n### \u00a75.3. Branch protection wiring (Zachary configures)\n\nIn repo Settings \u2192 Branches \u2192 Branch protection rules:\n- For `main`: require status check `enforce` (matches job name above) to pass before merge\n- For `claude/**`: same (so the upstream-of-main flow is also fail-closed)\n- Both: require linear history (no merge commits without explicit override)\n- Neither requires PR review (single-developer flow)\n\n---\n\n## \u00a76. Output plane spec (separate commentary workflow)\n\n### \u00a76.1. Workflow file \u2014 `.github/workflows/compliance-commentary.yml`\n\n```yaml\n# Pre-Build Search Evidence: NEW (split from v2's single compliance-verify.yml per convergent F4)\n# Searches performed: ls .github/workflows-pending/ \u2192 no commentary workflow exists\n# Rationale: trust-isolated commentary; non-blocking; runs only after enforcement\n\nname: compliance-commentary\n\non:\n  workflow_run:\n    workflows: [\"compliance-enforce\"]\n    types: [completed]\n\npermissions:\n  pull-requests: write   # to post PR comments\n  issues: write          # commit-comment API uses issues scope\n  contents: read         # to read attestation files for the digest\n\n# Critical: this job does NOT fail the build under any circumstance\njobs:\n  commentary:\n    name: commentary\n    runs-on: ubuntu-latest\n    timeout-minutes: 3\n    continue-on-error: true   # non-blocking; failure here does NOT trigger email\n    if: ${{ github.event.workflow_run.conclusion != 'cancelled' }}\n\n    steps:\n      - name: Checkout repo\n        uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11  # v4.1.1\n\n      - name: Render commentary from preapproved fields only\n        run: |\n          node scripts/compliance-render-commentary-v3.mjs \\\n            --workflow-run-id \"${{ github.event.workflow_run.id }}\" \\\n            --output commentary.md\n          # The script reads ONLY the preapproved field set (\u00a76.2 below).\n          # NO commit subjects, NO commit bodies, NO file path snippets.\n\n      - name: Post PR comment (best effort)\n        uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea  # v7.0.1\n        with:\n          script: |\n            const fs = require('fs');\n            const body = fs.readFileSync('commentary.md', 'utf-8');\n            // commit-comment API on the source commit:\n            await github.rest.repos.createCommitComment({\n              owner: context.repo.owner,\n              repo: context.repo.repo,\n              commit_sha: context.payload.workflow_run.head_sha,\n              body: body\n            });\n```\n\n### \u00a76.2. Preapproved public schema for digest output\n\nThe commentary template renders ONLY from these field types. Free-text rendering is structurally absent \u2014 there is no code path that takes commit subjects, commit body prose, or file content as input to a markdown formatter.\n\n| Field | Type | Source | PHI risk |\n|---|---|---|---|\n| commit_sha | hex SHA (regex `^[0-9a-f]{40}$`) | attestation subject digest | NONE |\n| tier | enum {marquis, non-marquis, fast-iteration} | attestation predicate | NONE |\n| verdict | enum {PASS, FAIL} | OPA eval result | NONE |\n| j11_status | enum {PASS, FAIL, PARTIAL, N/A} | attestation predicate | NONE |\n| j12_status | enum {PASS, FAIL, PARTIAL, N/A} | attestation predicate | NONE |\n| j13_status | enum {PASS, FAIL, PARTIAL, N/A} | attestation predicate | NONE |\n| j14_status | enum {PASS, FAIL, PARTIAL, N/A, PASS-CARVE-OUT} | attestation predicate | NONE |\n| j15_status | enum {PASS, FAIL, PARTIAL, N/A, PASS-CARVE-OUT} | attestation predicate | NONE |\n| j16_status | enum {PASS, FAIL, PARTIAL, N/A} | attestation predicate | NONE |\n| bare_code_count_in_prose | integer (\u22650; capped at 9999) | attestation predicate | NONE |\n| panel_size | integer (\u22650; capped at 99) | attestation predicate | NONE |\n| pbs_classification | enum {NEW, EXTENDS, SUPERSEDES, N/A} | attestation predicate | NONE |\n| attestation_url | URL (regex-validated to `^https://github\\.com/billyjoelsaniceguy/health-dashboard/blob/.+/\\.attestations/[0-9a-f]{40}\\.json$`) | constructed | NONE |\n| rule_violations_count | integer (\u22650; capped at 99) | OPA eval result | NONE |\n| rule_violation_codes | array of enum codes (J11-J16 only) | OPA eval result | NONE |\n\nThe commentary template (Mustache or similar with NO free-text passthrough) is committed alongside `compliance-render-commentary-v3.mjs`. The script reads ONLY the typed fields above + renders into the template. Any attempt to add commit-subject rendering MUST add a new typed field with explicit PHI-safety review.\n\nThis structurally prevents the v2 PHI-full-leak Wave-5 finding: there is no path through the script that takes the attestation's commit-subject-or-body-prose as digest input.\n\n### \u00a76.3. Notifier extension point (Pushover, Slack, email)\n\nIf Zachary provisions a notifier (Pushover token; Slack webhook URL; etc.), the commentary workflow gets an additional non-blocking step:\n\n```yaml\n      - name: Notify Pushover for severity HIGH (best effort)\n        if: ${{ steps.render.outputs.verdict == 'FAIL' || steps.render.outputs.severity == 'HIGH' }}\n        env:\n          PUSHOVER_TOKEN: ${{ secrets.PUSHOVER_TOKEN }}\n          PUSHOVER_USER: ${{ secrets.PUSHOVER_USER }}\n        run: |\n          # Pushover payload renders from SAME preapproved field set\n          # NO PHI possible. Subject is \"compliance FAIL on \"; body is the\n          # preapproved-fields-only digest.\n          node scripts/compliance-notify-pushover-v3.mjs \\\n            --workflow-run-id \"${{ github.event.workflow_run.id }}\"\n```\n\nSame trust isolation: the notifier reads from the preapproved field set; free-text is structurally absent.\n\n---\n\n## \u00a77. Migration path (v2 \u2192 v3)\n\n### \u00a77.1. What stays from v2 (governance corpus survives intact)\n\n- **CLAUDE.md rule corpus** \u2014 Rules 3.1-3.9; J11-J16 audit-row content; D1-D3 declarations; Mandatory Pre-Build Search / Document Review / Plain-Language / Full-Team Dispatch / Coverage Gap / Per-Session Checklist / Agent-ID Non-Display / Standing Grading / Ask-Capture / Stress Test / UI Integration / Audit Architecture / Autonomous Control gates\n- **Magna Carta** \u2014 D1-D3 declarations; principles P1-P15; retractions R-1 through R-6; operating procedures OP-1 through OP-12; the full document body\n- **Governance Debt Ledger** \u2014 all entries GD-1 through GD-33; GD-32 updates to ARCHIVED-SUPERSEDED-BY-GD-37 effective v3 ratification; GD-33 closes upon v3 ratification + external review of v3 doc; GD-37 (new) tracks framework v3 status\n- **J11-J16 field shapes** from `scripts/compliance-schema-v1.json` \u2014 reused 1:1 as the in-toto predicate body schema (v2's J11-J16 design work was correct; v3 carries it forward)\n- **Tier classification** \u2014 marquis / non-marquis / fast-iteration enum survives; tier_classification_evidence string survives\n- **Panel evidence** \u2014 panel_dispatched / panel_size / panel_framings field shapes survive\n- **Skip carve-out categories** \u2014 the 7 carve-outs from Rule 3.9 (conversational / pure-relay / status-only / error-only / factual-lookup / clarifying-question / continuation) survive as the skip_carveout_category enum\n- **PBS classification** \u2014 NEW / EXTENDS / SUPERSEDES enum survives; pbs_cited_files array survives\n- **Layer 1 pre-push hook** \u2014 UNCHANGED\n- **Pre-commit hook OP-11** \u2014 UNCHANGED\n- **`scripts/external-review/queue.jsonl`** \u2014 the standing external-review queue + dispatch infrastructure survives; v3 adds an entry for v3 architecture spec self-review per Q-D\n- **A/B instrumentation period** \u2014 Rule 3.9 A/B scorecard 2026-05-31 \u2192 2026-06-21 continues; v3 attestations carry the same A/B-scorecard reference field\n\n### \u00a77.2. What moves (substrate change only)\n\n| v2 component | v3 disposition |\n|---|---|\n| `scripts/validate-rule-3.9-compliance.mjs` | Archived to `scripts/archived/2026-06-02-framework-v2/validate-rule-3.9-compliance.mjs`; its regex banks salvageable for porting to Rego (J12 plain-language scanner is the most-likely port; J14 PBS file-existence check moves to Rego + plumbing-step) |\n| `scripts/compliance-digest.mjs` | Archived; v3 ships `scripts/compliance-render-commentary-v3.mjs` (preapproved-fields-only) |\n| `scripts/compliance-schema-v1.json` | **Stays in repo** for backward-compat with v0 + v1 archived commits; predicate body schema in v3 inlines the J11-J16 fields per \u00a73.3 (the file remains canonically referenced as the prior schema generation) |\n| `.github/workflows-pending/compliance-verify.yml` | Archived to `.github/workflows-archived/compliance-verify-v2.yml`; v3 ships `.github/workflows/compliance-enforce.yml` + `.github/workflows/compliance-commentary.yml` |\n| Commit-body JSON-in-fenced-block convention | DEPRECATED but grandfathered: pre-v3-ratification commits validate against v2 schema; v3-onwards commits use in-toto attestation files |\n| Custom Node.js regex extractor | Replaced by OPA policy evaluation + minimal plumbing |\n| Single workflow file | Split into enforce + commentary (trust-isolated jobs) |\n| Unsigned commit-body claim | Replaced by Sigstore-signed in-toto attestation file |\n| `scripts/INVESTIGATION-2026-06-01/` Wave 4 + Wave 5 P0/P1 findings + reproducers | Stays in repo as historical evidence; v3 must NOT re-introduce; specific regressions to design against listed in \u00a79 |\n\n### \u00a77.3. Cutover modes (Q-E)\n\n**Option \u03b1 \u2014 clean cutover (recommended):**\nAt v3 Phase 5 closeout, archive v2 artifacts + remove v2 workflow file + add v3 workflow files. The v2 schema file stays for backward-compat reading. From the cutover commit forward, all commits MUST have attestation files; CI evaluates attestations.\n\n**Option \u03b2 \u2014 A/B trial period (conservative):**\nAt v3 Phase 5 closeout, deploy v3 workflows alongside v2 workflow. Both run on every push. Branch protection requires BOTH to pass. For 14 days, every commit needs BOTH a v2 commit-body audit row AND a v3 attestation file. At day 14, compare disagreement count; if v3 stable, archive v2.\n\n**Recommendation:** Option \u03b1. v2 is empirically broken (Wave 4 + Wave 5 findings); running it alongside v3 burns cycles without producing useful comparison data (a known-broken system disagreeing with a new system tells you nothing new).\n\n---\n\n## \u00a78. Implementation plan (phased)\n\n| Phase | Work | Estimated effort | Status |\n|---|---|---|---|\n| **P0** | THIS DOC authored as DRAFT-PROPOSAL | Done | DRAFT |\n| **P1** | External review of this v3 architecture spec by Gemini 3.1 + GPT-5.4 (same reviewers as the v2 RECONSIDER verdict) using `template: B-premortem` | ~2h dispatch + 0.5h Zachary review | TODO; precondition for P2 |\n| **P2** | Policy plane authoring: `policy/rules/` Rego files for J11-J16 + D1-D3 + Rule 3.X + schema-envelope checks; `policy/tests/` mirror; `policy/fixtures/`; `policy/README.md` | ~6-8h (one rule file \u2248 30 min including test) | TODO |\n| **P3** | Evidence plane authoring: `scripts/generate-attestation-v3.mjs` (generates in-toto Statement from local git state + panel evidence file + tier classification); Sigstore signing flow validated end-to-end | ~4-6h (in-toto JSON shape + Cosign integration + dry-run with sample) | TODO |\n| **P4** | Enforcement plane authoring: `.github/workflows/compliance-enforce.yml` per \u00a75; precondition `opa test` step; per-commit verify loop; TOCTOU SHA-matching; pinned actions; branch protection wiring instructions for Zachary | ~3-5h (workflow + dry-run with fake attestations) | TODO |\n| **P5** | Output plane authoring: `.github/workflows/compliance-commentary.yml` per \u00a76.1; `scripts/compliance-render-commentary-v3.mjs` per \u00a76.2 preapproved-field schema; Pushover extension point spec | ~3-4h (commentary workflow + render script + Mustache-style template + zero-PHI verification) | TODO |\n| **P6** | Wave-5 regression suite: add v3-specific regression tests for every Wave-4 + Wave-5 P0/P1 finding (RCE attempts, PHI leak attempts, shallow-clone bypass, tier override, etc.). All must produce explicit policy denial in v3 | ~4-6h (one test fixture per finding + Rego rule asserting denial + CI step running the regression) | TODO |\n| **P7** | Archive v2 artifacts per Mandatory Archive Policy; `scripts/archived/2026-06-02-framework-v2/INDEX.md`; CLAUDE.md Change log entry; Magna Carta amendment (GD-32 \u2192 ARCHIVED; GD-37 new entry for v3) | ~2h | TODO |\n| **P8** | External NON-Claude review of v3 deployment (re-dispatch same reviewers AFTER P2-P7 land; binding precondition per M\u00fcnchhausen-trilemma finding) | ~3h dispatch + 1h Zachary integration | TODO |\n| **P9** | Branch protection configuration by Zachary in repo Settings; first live commits under v3 substrate; first attestation generation + verification end-to-end | ~30 min Zachary | TODO; gate for v3 operational |\n| **P10** | First Quarterly review of v3 per OP-7 (post-90-day) \u2014 verify policy bundle coverage; review violation log; decide on rule additions/amendments | ~4h | SCHEDULED for 2026-09-02 |\n\n**Total estimated effort to v3 operational:** ~25-35h of Claude main work + Zachary configuration (~1h total).\n\n---\n\n## \u00a79. What v3 explicitly fixes from the convergent verdict\n\n| Finding | v3 mechanism |\n|---|---|\n| **TOCTOU defense (Q7)** | SHA-matching in \u00a75.1: attestation `subject.digest.sha1` must equal commit SHA at evaluation time; mismatch = FAIL. Combined with Sigstore signature binding the attestation content to OIDC identity at signing time, any tamper-with-attestation-after-push fails signature verification |\n| **Email rebleed via job-separation (Q8)** | Enforce + commentary in SEPARATE workflow files with separate `permissions:` scopes; commentary is `continue-on-error: true` (failure does NOT email Zachary); the v2 single-workflow `contents: read` \u2192 403 \u2192 email-per-push failure mode is structurally absent |\n| **ReDoS bounding** | OPA is sandboxed (no regex engine attack surface accessible from policy); the minimal plumbing in `generate-attestation-v3.mjs` and `compliance-render-commentary-v3.mjs` uses anchored regexes only OR processes inputs via JSON.parse (typed) NOT regex extraction. Any plumbing-layer regex MUST have linear-time guarantees (no nested quantifiers + bounded input length); CI step `node --max-old-space-size=512 ...` provides additional safety bound |\n| **Transport integrity via signed attestation** | Sigstore Cosign keyless OIDC-rooted signing; signature in detached `.sig`; certificate chain + Rekor transparency log entry in `.bundle`; verify step is mandatory before any policy evaluation |\n| **Declare-not-verify pattern via TDD enforcement** | Per \u00a73.4 + \u00a74.5: every new rule lands in a 3-commit sequence (failing test \u2192 passing rule \u2192 attestation); merge gate enforces; the v2 failure mode \"fix declared but not verified\" (Wave-5 finding #3) is structurally prevented because a \"fix\" without a failing-test-first commit cannot land |\n| **Markdown parser-differential risk** | Eliminated: commit body markdown is no longer the attestation carrier. Markdown stays for HUMAN narrative (commit subjects + bodies remain in English for human review) but is NOT parsed by the policy evaluator |\n| **Custom-regex-extractor fragility** | Eliminated: no custom extractor. OPA reads structured JSON; signature verification is by Cosign (industry-standard); commit ranges are by `git log` (no regex) |\n| **PHI rebleed via free-text rendering** | Eliminated: \u00a76.2 preapproved-field schema is enums + integers + hex SHAs only; the commentary template has no code path that accepts free-text input from the attestation |\n| **Schema-as-policy entanglement** | Eliminated: schema (predicate JSON structure) is now `schema_envelope.rego` + `schema_predicate_v3.rego` \u2014 declarative Rego assertions independently testable from rule logic |\n| **M\u00fcnchhausen-trilemma (Q-bias-auditor)** | PARTIALLY addressed: external review of v3 architecture spec dispatched as Phase 1 (P1); this DRAFT-PROPOSAL status is BINDING until external review returns. Full mitigation per \u00a710 below |\n\n---\n\n## \u00a710. Coverage gap (per Rule 3.7)\n\nWhat v3 does NOT solve:\n\n1. **The same model class still writes the Rego policy rules** \u2014 Rego is more reviewable than Node.js regex (declarative; unit-tested) but the rules' design intent is still Claude-authored. External review of THIS architecture spec + the Rego rule set is binding (Q-D + P1 + P8 above). External review is the only mitigation; v3 cannot dissolve this constraint fundamentally\n2. **Sigstore dependency** \u2014 Sigstore Fulcio + Rekor must be accessible at signing time + verification time. Sigstore outages have happened (rare; &lt;1% over recent year per public status pages). During an outage Claude cannot sign + CI cannot verify. The fallback is to defer the commit OR (if escape-hatched) use traditional GPG with key in repo Secrets. Default v3 picks keyless (no escape hatch by default); Zachary can opt into GPG fallback if outage tolerance is critical\n3. **Branch protection is the load-bearing GitHub-side config.** If Zachary forgets to configure branch protection (or it's accidentally removed during a repo Settings change), v3 reverts to informational-only mode. The Q-9 risk from v2 carries forward. Mitigation: v3 ships a `scripts/verify-branch-protection-v3.mjs` periodic checker that fails closed (CI itself) if branch protection rules are missing\n4. **The Rego rule corpus is bounded.** It enforces what's expressible as predicates over the attestation JSON. Semantic claim verification (Wave-5 finding category \u2014 \"did the commit actually do what the attestation says it did\") is NOT addressed. This is the Perplexity \u00a76.3 \"scenario 5 clinically wrong claim syntactically clean\" gap, still unaddressed. Tracked as GD-33-cluster future-work\n5. **Attestation signing requires Claude main to have OIDC credentials at signing time.** In remote-container sessions, the GitHub Actions OIDC token is issued by the CI runner, not Claude main's session. The proposed flow is: Claude main commits substantive change \u2192 pushes \u2192 on push, an additional GitHub Actions workflow `compliance-attest.yml` runs that GENERATES + SIGNS the attestation for the just-pushed commit + commits + pushes the attestation. This decouples \"claim author\" from \"claim signer\" \u2014 Claude main authors via prose + structured data file in the substantive commit; the attestation-generation workflow extracts the structured data + signs. Open design question Q-F: does this re-introduce the v2 \"Claude controls what gets attested\" problem? Mitigation: the structured-data file is committed alongside the substantive change in the SAME commit; tampering after push requires force-push (caught by Layer 1 pre-push hook + Rule 3.10 post-push verification, when ratified)\n6. **Schema evolution discipline is not yet proven.** v3 ships at schema_version 3.0. Future bumps to 3.1, 4.0 will need migration design + rollover periods. Same risk as v2 schema_version 1.0 \u2192 1.1; lessons-not-yet-codified surface\n7. **Attestation file size growth.** Each commit produces 3 files in `.attestations/`. Over time the directory grows. At ~3 KB per commit \u00d7 ~1000 commits/year = ~9 MB/year; manageable but not unbounded. Future cleanup policy is TBD (could roll up old attestations into a single signed manifest)\n8. **PR vs push event handling.** v3 fires on `push` AND `pull_request`. For PRs from forks, OIDC token issuance differs (no `id-token: write` for forked-PR runs by GitHub policy). Mitigation: project flow is single-developer (no fork PRs expected); document the limitation\n9. **In-toto predicate type URI is project-namespaced.** `https://github.com/billyjoelsaniceguy/health-dashboard/attestations/compliance-row/v3.0` is not a registered standard predicate type (SLSA Provenance is registered; this is custom). Tooling that expects registered predicate types won't recognize it. Mitigation: project doesn't need broad ecosystem compat; the project-internal verifier knows the type\n10. **v3 is itself authored 100% by Claude.** Until P1 external review returns, this doc is provisional. Phase 1 is BINDING; Phases 2-7 SHOULD NOT begin until external reviewers return on this doc\n\n**Surfaces NOT checked by v3 (rule-inventory-equivalent of LIVE-STATE-UNVERIFIED):**\n- v3 does not check the Stress Test Gate (`stress-test-sqlite.mjs` + `audit-sqlite.mjs`) compliance per se; that's a separate enforcement surface and remains under pre-commit hook + the Per-Session Checklist Phase 3 gate\n- v3 does not enforce Mandatory Document Review Gate inline display (\u00a7Document Review Gate above); that's session-prose discipline, not commit attestation\n- v3 does not enforce Ask-Capture Protocol Rule 1 (bd-per-ask); that's separate (bd database + session-runtime)\n- v3 does not enforce Mandatory Per-Session Checklist phases 1-7; that's session-runtime\n- Possible rules residing in v3-unchecked surfaces: bd-creation discipline, Stress Test Gate compliance, Document Review Gate compliance, Session Completion workflow, Permissions Audit Gate\n- These are addressed via separate enforcement layers (hooks, session-runtime, manual review); v3's scope is COMMIT-BOUND compliance attestation\n\n---\n\n## \u00a711. Open questions for Zachary\n\n1. **Q-A \u2014 Sigstore keyless vs traditional GPG?**\n   Default recommendation: Sigstore keyless (no key management; OIDC-rooted; free; transparency log; ~&lt;1% outage risk acceptable). If you prefer traditional GPG (key in repo Secrets), say so and v3 P3 substitutes Cosign with `gpg --sign` + verifying with public key in `policy/sigstore-pubkey.asc`. Trade-off: GPG removes Sigstore outage risk but re-introduces key-management surface\n\n2. **Q-B \u2014 OPA delivery method?**\n   Three options:\n   - (b1) `opa eval` on GitHub Actions runner (simplest; setup-opa@v2.2.0 installs binary; 1-2s overhead per commit; recommended default)\n   - (b2) Sidecar OPA service (overkill for project scope; adds container management)\n   - (b3) WASM-bundled policy (`opa build -t wasm` + Node.js evaluator; runs faster per commit but adds compile step + WASM runtime dep; recommended only if commit volume scales to thousands per day)\n   Default: (b1)\n\n3. **Q-C \u2014 in-toto predicate type \u2014 registered subtype vs custom?**\n   - (c1) Custom predicate type at `https://github.com/billyjoelsaniceguy/health-dashboard/attestations/compliance-row/v3.0` (recommended; project-internal; no ecosystem compat needed)\n   - (c2) SLSA Provenance subtype with compliance extensions (more standard; harder to fit J11-J16 into Provenance shape; ecosystem tooling benefits unclear for project-internal use)\n   Default: (c1)\n\n4. **Q-D \u2014 External review of THIS v3 architecture spec before Phase 2 begins?**\n   Recommended dispatch: same two reviewers (Gemini 3.1 Reviewer 1 + GPT-5.4 Reviewer 2) using `template: B-premortem` against this spec, AS YET UNSHIPPED. The M\u00fcnchhausen-trilemma finding binds: this doc is Claude-authored; until external review returns, Phases 2-7 are blocked. Default: YES, dispatch P1 immediately. If you want to start Phase 2 in parallel (accepting risk of rework when reviewers return), explicitly authorize the parallel path\n\n5. **Q-E \u2014 Cutover mode (clean vs A/B trial)?**\n   Default recommendation: Option \u03b1 (clean cutover) at v3 Phase 5 closeout. v2 is empirically broken (Wave 4 + Wave 5 findings); running it alongside v3 burns cycles without producing useful comparison data. If you want the conservative A/B path, explicitly choose Option \u03b2 (deploy v3 alongside v2 for 14 days; both must pass; archive v2 at day 14 if v3 stable)\n\n6. **Q-F \u2014 Attestation-generation flow: does the auto-signing workflow re-introduce \"Claude controls what gets attested\"?**\n   Per \u00a710 point 5: the proposed flow has the substantive commit carry a structured-data file (e.g., `.compliance-claim.json`) that the attestation-generation workflow reads + signs. Open question: should Claude main author the claim AND the prose? Or should claim authorship be deferred to a separate post-push step that re-derives the claim from objectively-verifiable repo state (panel evidence files, commit metadata, file diffs)? The latter is harder to fabricate but harder to author correctly. Default: claim authored by Claude main alongside substantive commit; external CI verifies via OPA against claim. Acknowledged limitation; mitigation via external review of every claim shape\n\n7. **Q-G \u2014 Rate of new-rule additions?**\n   Rule 3.X added at ~1/week recently (Rules 3.1 through 3.10 over 2026-05-29 to 2026-05-31). At that rate, the Rego policy pack grows by ~1 rule/week. Maintenance cost per added rule: ~30 min (author rule + test + fixtures). Is that acceptable, or should we cap new-rule velocity until v3 stabilizes? Default: no cap; rules continue at organic velocity; v3 ships ready for additions\n\n---\n\n## \u00a712. Reference + cross-link surface\n\n- `scripts/external-review/queue.jsonl` line 2 \u2014 the convergent verdict record + response_summary\n- `scripts/FRAMEWORK-v2-CI-CENTERED-2026-06-01.md` \u2014 the architecture this supersedes at substrate layer\n- `scripts/FRAMEWORK-THAT-ENFORCES-2026-06-01.md` \u2014 the v1 framework v2 itself superseded (preserved per Archive Policy)\n- `scripts/INVESTIGATION-2026-06-01/W4-FINAL-SYNTHESIS-2026-06-01.md` \u2014 Wave 4 adversarial findings (referenced from CLAUDE.md GD-33)\n- `scripts/INVESTIGATION-2026-06-01/W5-*.md` \u2014 Wave 5 re-audit findings (referenced from CLAUDE.md GD-33)\n- `scripts/compliance-schema-v1.json` \u2014 v0/v1 JSON schema; predicate body schema is ported from here\n- `scripts/validate-rule-3.9-compliance.mjs` \u2014 v2 validator; archived in P7; regex banks salvageable for Rego ports\n- `scripts/compliance-digest.mjs` \u2014 v2 digest; archived in P7; replaced by `compliance-render-commentary-v3.mjs`\n- `.github/workflows-pending/compliance-verify.yml` \u2014 v2 workflow; archived in P7\n- `CLAUDE.md` \u00a7Mandatory Pre-Build Search Gate \u2014 the gate enforced by `j14_pre_build_search.rego`\n- `CLAUDE.md` \u00a7Mandatory Full Team Dispatch (Rule 3.9) \u2014 the gate enforced by `j15_full_team_dispatch.rego`\n- `CLAUDE.md` \u00a7Rule 3.8 (Marquis 10\u00d7) \u2014 the gate enforced by `j13_marquis_depth.rego`\n- `CLAUDE.md` \u00a7Governance Debt Ledger GD-32 \u2014 to be updated to ARCHIVED-SUPERSEDED-BY-GD-37 upon v3 ratification\n- `CLAUDE.md` \u00a7Governance Debt Ledger GD-33 \u2014 closes upon v3 ratification + external review of v3 doc returning\n- (NEW) `CLAUDE.md` \u00a7Governance Debt Ledger GD-37 \u2014 to be added; tracks framework v3 status\n- in-toto specification: https://in-toto.io/specs/\n- Sigstore Cosign documentation: https://docs.sigstore.dev/cosign/overview/\n- OPA documentation: https://www.openpolicyagent.org/docs/\n- Rego language reference: https://www.openpolicyagent.org/docs/latest/policy-language/\n\n---\n\n## \u00a713. v3.1 AMENDMENT (2026-06-02 \u2014 per Round 2 convergent external-reviewer findings)\n\n&gt; **AMENDMENT BLOCK STATUS:** binding 2026-06-02 UTC; supersedes the relevant portions of \u00a7\u00a73-6 of v3.0 where conflicts arise. The v3.0 sections REMAIN VERBATIM above per OP-6 (audit-trail preservation pattern that mirrors how Magna Carta v1.2 was added to v1.0; how the Stress Test Gate Remote-Container Clause was added to the gate; how the Document Review Gate Amendment 2026-05-30 was added; how the Mandatory Plain-Language Communication two cadence amendments stacked atop the original review-cadence specification). Round 3 external review of THIS AMENDED spec is the binding ratification gate per the recursive pattern established in \u00a710 Coverage gap item 1 + the M\u00fcnchhausen-trilemma finding from Wave 4 + Wave 5 + Round 1.\n&gt;\n&gt; **Authored 2026-06-02 UTC by Claude main per Zachary chat directive 2026-06-02:** *\"Apply 5 convergent fixes as v3.1 amendment + 3rd reviewer validation.\"* Round 2 reviewers' detailed verdicts integrated in `scripts/external-review/queue.jsonl` lines 9 + 10. The two reviewers used divergent verdict labels (Reviewer 3 Sonnet 2 SHIP-WITH-CHANGES; Reviewer 4 GPT-5.4 RECONSIDER-REBUILD) but architecturally CONVERGED on 5 specific changes \u2014 convergence-despite-divergent-labels is the load-bearing pattern that triggers binding amendment per Magna Carta P3 (reports are claims; convergence is the evidence) + P5 (process errors compound; architecture-layer fixes are the cheapest closure point).\n&gt;\n&gt; **Glossary additions for this amendment (per Mandatory Plain-Language Communication gate):**\n&gt; - **PHI** \u2014 Protected Health Information (already defined in \u00a7Glossary; relevant here because \u00a713.1's bounded-shape requirement primarily defends against PHI leakage into the attestation subject + free-text fields)\n&gt; - **OIDC** \u2014 OpenID Connect (already defined indirectly via Sigstore Cosign reference in \u00a73.6; relevant here because \u00a713.2's tight identity binding constrains which OIDC token claims (workflow_ref / event_name / ref) anchor the Sigstore signature)\n&gt; - **NFKC** \u2014 Normalization Form Compatibility Composition (Unicode normalization form per UAX #15; relevant here because \u00a713.6's NFKC requirement defends against ZWSP-/homoglyph-/compatibility-form bypass attacks against policy regex matching)\n&gt; - **Conftest** \u2014 Open Policy Agent's CLI for testing structured configuration (https://www.conftest.dev/); a thin wrapper over OPA that's targeted at config files; relevant here because \u00a713.6 considers it as an alternative to pure OPA for 1-person-team maintainability\n&gt; - **Sigstore Fulcio** \u2014 the Sigstore Certificate Authority that issues short-lived (~10 min) signing certificates rooted in OIDC identity (already glossed indirectly in \u00a7Glossary; relevant here because \u00a713.5's non-keyless default avoids Fulcio dependency for the routine path)\n&gt; - **Sigstore Rekor** \u2014 the Sigstore transparency log that records every signing event publicly (already glossed indirectly in \u00a7Glossary; relevant here because \u00a713.5's non-keyless default avoids public Rekor correlation risk)\n&gt; - **subject.name PHI risk** \u2014 when an attestation's `subject.name` field interpolates a git branch reference (e.g., `claude/phi-patient-mrn-12345`) into the attestation, the branch name itself becomes part of the signed-and-public attestation; if branch names ever encode PHI by accident, the attestation leaks it\n&gt; - **per-PR vs per-commit attestation** \u2014 Reviewer 4's operational-sanity recommendation: one attestation per PR (covering N commits) instead of one attestation per commit; reduces attestation churn from ~1000/year to ~100-200/year at typical project velocity\n&gt; - **Conftest vs OPA trade-off** \u2014 Conftest constrains policy to \"configuration file validation\" patterns; for 1-person team this is easier to onboard + maintain, but loses some Rego expressiveness (e.g., complex partial evaluation, decision logging at full OPA level)\n\n### \u00a713.0 \u2014 TL;DR of the amendment\n\nRound 2 (Reviewer 3 + Reviewer 4) converged on **5 architectural changes** that fix specific structural weaknesses in v3.0 that Round 1 (Gemini 3.1 + GPT-5.4) had endorsed at high-level convergent verdict but not stress-tested at field-and-binding-detail level. The 5 are: (1) **close the attestation schema** \u2014 no free-text fields where bounded enums + closed objects are achievable, eliminating tier_classification_evidence prose + panel_framings prose + subject.name branch interpolation as PHI / fabrication / bypass surfaces; (2) **tighten Sigstore OIDC identity binding** \u2014 match exact workflow_ref + event_name + ref claims (not the v3.0 repo-prefix regex) so a leaked OIDC token in any other workflow in the repo cannot forge attestations; (3) **make commentary plane OPTIONAL** \u2014 default OFF; commentary workflow runs only when explicitly enabled per-commit via attestation field; for a 1-person team the attack surface of always-on commentary outweighs the benefit; (4) **collapse to 2-plane design** \u2014 Evidence + Policy combined into single enforcement workflow file; commentary moved inside Evidence-plane verifier as best-effort output rendering OR dropped entirely; the 4-plane formulation was useful for thinking but the trust-isolation requirements can be satisfied within 2 workflow files (enforce.yml with separate jobs vs commentary.yml; the separation is at the JOB level, not the FILE level); (5) **non-keyless Sigstore default** \u2014 repo-checked-in public key for signing by default; Sigstore keyless OPTIONAL per-commit flag; avoids Fulcio CA + Rekor transparency log dependencies on the routine path. Reviewer 4 additionally specified: sha256 (not sha1) as primary subject digest; Conftest or thin TypeScript validator as alternatives to pure OPA; per-PR attestation as operational-sanity preference; tight checkout of policy from PROTECTED BASE (not candidate PR HEAD) \u2014 defeats policy hot-swap attack; NFKC normalization on every string field before policy evaluation.\n\n### \u00a713.1 \u2014 Close the attestation schema (CHANGE 1; supersedes \u00a73.3 verbatim text in part)\n\n**Convergent reviewer finding (Round 2):** Reviewer 3 + Reviewer 4 independently observed that v3.0 \u00a73.3's predicate structure has **three load-bearing free-text fields** that are PHI-leakable + fabrication-prone + policy-bypass surfaces:\n\n- `tier_classification_evidence: \"string\"` (e.g., `\"subject regex match /\\\\bhook\\\\b/i\"` \u2014 but nothing in the schema bounds this to enum-like reason strings; a fabricated attestation could put `\"manually classified as marquis because reasons\"` and the policy has no structural defense)\n- `panel_framings: \"string[]\"` (e.g., `[\"state-audit\", \"hook-diagnostic\", \"rule-compliance\", ...]` \u2014 but nothing in the schema bounds these to a registered catalog of panel role names; a fabricated attestation could put `[\"agent-1\", \"agent-2\", \"agent-3\"]` and the policy has no structural defense)\n- `subject.name: \"git+https://github.com/billyjoelsaniceguy/health-dashboard@\"` (the branch name is interpolated; if branch names ever encode PHI by accident \u2014 `claude/patient-zach-mrn-12345-experiment` \u2014 that PHI gets cryptographically signed + public via Rekor when keyless signing is used; convergent reviewer concern especially acute given D1 Primary Clinical Purpose)\n\n**Amendment (binding):**\n\nThe v3.0 predicate JSON structure in \u00a73.3 is amended as follows. All other \u00a73.3 content (predicate type URI, subject digest binding to commit SHA, schema_version 3.0 marker) is preserved.\n\n```json\n{\n  \"_type\": \"https://in-toto.io/Statement/v1\",\n  \"predicateType\": \"https://github.com/billyjoelsaniceguy/health-dashboard/attestations/compliance-row/v3.1\",\n  \"subject\": [\n    {\n      \"name\": \"sha256:\",\n      \"digest\": {\n        \"sha256\": \"\"\n      }\n    }\n  ],\n  \"predicate\": {\n    \"schema_version\": \"3.1\",\n    \"commit_metadata\": {\n      \"tier\": \"marquis\",\n      \"tier_classification_evidence\": {\n        \"method\": \"subject_regex_match\",\n        \"pattern_id\": \"marquis_hook_indicator_v1\",\n        \"matched\": true\n      },\n      \"session_id_hash\": \"sha256:\",\n      \"panel_dispatched\": true,\n      \"panel_size\": 7,\n      \"panel_framings\": [\n        \"state_audit\",\n        \"hook_diagnostic\",\n        \"rule_compliance\",\n        \"roadmap_delta\",\n        \"sentinel\",\n        \"decisions_surface\",\n        \"synthesis_bias_audit\"\n      ]\n    },\n    \"j11_agent_id_non_display\": { \"status\": \"PASS\", \"evidence_count\": 0 },\n    \"j12_plain_language\": {\n      \"status\": \"PARTIAL\",\n      \"bare_code_count_in_prose\": 5,\n      \"acceptable_context_count\": 5,\n      \"glossary_present\": true\n    },\n    \"j13_marquis_depth\": {\n      \"status\": \"PASS\",\n      \"executable_provided\": true,\n      \"test_performed\": true,\n      \"prestaged\": true\n    },\n    \"j14_pre_build_search\": {\n      \"status\": \"PASS\",\n      \"classification\": \"NEW\",\n      \"candidates_reviewed\": 3,\n      \"pbs_cited_files_count\": 3,\n      \"pbs_cited_files_sha256\": [\n        \"sha256:\",\n        \"sha256:\",\n        \"sha256:\"\n      ]\n    },\n    \"j15_full_team_dispatch\": {\n      \"status\": \"PASS_CARVE_OUT\",\n      \"skip_carveout_category\": \"continuation\"\n    },\n    \"j16_post_push_verification\": { \"status\": \"N_A\" },\n    \"d1_clinical_purpose_affected\": false,\n    \"d2_user_tier_affected\": \"none\",\n    \"d3_definition_of_done\": {\n      \"applicable_conditions\": [],\n      \"n_a_with_classification\": \"infra_governance_no_ui_surface\"\n    }\n  }\n}\n```\n\n**Closed-shape rules (all binding):**\n\n1. **`tier_classification_evidence`** becomes a closed object with bounded keys: `method: enum {subject_regex_match, body_keyword_match, file_pattern_match, manual_zachary_override}`, `pattern_id: enum-from-registered-catalog (catalog at policy/catalogs/tier_classification_patterns.json)`, `matched: boolean`. NO free-text. A new pattern requires adding to the catalog (separate commit reviewable per OP-7). The `manual_zachary_override` method requires a paired `override_commit_sha` field referencing a Zachary-authored commit; CI verifies the referenced commit is signed by Zachary's GPG key (separate authorization plane from Claude OIDC).\n\n2. **`panel_framings`** becomes `enum[]` with values drawn from a registered catalog at `policy/catalogs/panel_framings.json`. Initial enum values (from v3.0 \u00a73.3 example): `state_audit`, `hook_diagnostic`, `rule_compliance`, `roadmap_delta`, `sentinel`, `decisions_surface`, `synthesis_bias_audit`. Adding a new panel role requires adding to the catalog. The Rego rule `panel_framings_valid.rego` asserts every value is in the registered catalog.\n\n3. **`subject.name`** becomes a **sha256-hashed branch reference**: `\"sha256:\" + sha256(canonical_branch_url)`. The canonical_branch_url is constructed deterministically at signing time (e.g., `git+https://github.com/billyjoelsaniceguy/health-dashboard@claude/`) but the **hash, not the URL, is what gets signed and stored in the attestation**. If branch names ever accidentally encode PHI, the attestation leaks only the hash \u2014 not the cleartext. A separate (unsigned) sidecar file `.attestations/.branch-ref.txt` may hold the cleartext for human debugging; gitignored by default (Zachary opts in to commit if needed; not committed by default per the v2 PHI-near-miss pattern from Wave 5).\n\n4. **`subject.digest`** changes from `sha1` to `sha256` per Reviewer 4 specifics. The in-toto digest set spec supports both; sha256 is the convergent recommended primary. `sha1` field MAY be retained alongside `sha256` for legacy compatibility but the policy evaluator MUST verify sha256 (not sha1). The v3.0 \u00a73.3 + \u00a75.1 references to `sha1` are amended to `sha256` throughout.\n\n5. **`session_id`** becomes `session_id_hash` \u2014 a sha256 of the session identifier rather than the cleartext. Same PHI-defense reasoning as `subject.name`.\n\n6. **`pbs_cited_files`** array (v3.0) becomes `pbs_cited_files_count: integer` + `pbs_cited_files_sha256: array of \"sha256:\" strings`. The cleartext file paths are NOT stored in the attestation. The policy evaluator pre-computes file-existence + file-content-hash at evaluation time and asserts the hashes match. This defends against PHI in pathnames (rare but possible) + provides stronger integrity than path-only references (a file rename without content change still hashes the same; a content change with same name does not).\n\n7. **`status` enum values are normalized to underscored form** (`PASS_CARVE_OUT` not `PASS-CARVE-OUT`; `N_A` not `N/A`). Hyphens + slashes in enum values are fragile in shell + JSON + Rego contexts. Convergent reviewer recommendation. v3.0 references to `PASS-CARVE-OUT` and `N/A` are mechanically replaced by the policy evaluator's input normalization layer; the attestation file itself uses the underscored canonical form.\n\n8. **`commit_metadata`** object: `panel_dispatched: boolean`, `panel_size: integer (0-99)`, `panel_framings: enum[]` per (2) above. NO free-text inside this object.\n\n9. **`d2_user_tier_affected`** becomes enum `{none, tier_1, tier_2, tier_3, multiple, unknown}` (was free-text in v3.0; convergent reviewer).\n\n10. **`d3_definition_of_done.n_a_with_classification`** becomes enum-or-boolean: enum from `{infra_governance_no_ui_surface, infra_governance_with_partial_ui, ui_change_with_d3_full, ui_change_with_d3_partial, ui_change_with_d3_deferred}` OR boolean `false` (meaning N/A doesn't apply; D3 fully applies). Free-text deprecation.\n\n11. **Predicate type URI bumps to `compliance-row/v3.1`** to signal the schema change. The v3.0 `compliance-row/v3.0` URI MAY appear in archived pre-amendment commits; policy evaluator accepts both URIs but the v3.0 path falls through to a stricter compatibility-mode rule set that bounds the free-text fields by length + character class (\u2264200 chars + alphanumeric-space-punct only).\n\n**Retracts:** v3.0 \u00a73.3's free-text fields (`tier_classification_evidence: \"string\"`, `panel_framings: \"string[]\"`, `session_id` as cleartext, `subject.name` with branch interpolation, `pbs_cited_files` as path array, `n_a_conditions_with_rationale` as free-text). **Supersedes:** v3.0 \u00a73.3's predicate JSON structure in the closing-shape sense; non-amended portions (predicate type prefix, subject array shape, predicate top-level keys list) survive. **Derives from:** Magna Carta P3 (reports are claims; bounded schemas are stronger claims than free-text) + P5 (process errors compound at architecture layer; closing schema shape is an architecture-layer fix to a class of fabrication attacks) + P15 (external-state verification \u2014 the two Round 2 reviewers ARE the external verification per OP-11) per OP-10 + P13 (explicit retraction of free-text fields).\n\n### \u00a713.2 \u2014 Tighten Sigstore OIDC identity binding (CHANGE 2; supersedes \u00a75.1 verbatim text in part)\n\n**Convergent reviewer finding (Round 2):** v3.0 \u00a75.1's Sigstore verification step uses `--certificate-identity-regexp \"^https://github\\\\.com/billyjoelsaniceguy/health-dashboard\"` \u2014 a **repo-prefix regex** that accepts ANY workflow in the repo as a valid signing identity. This is the GitHub Actions OIDC token's `sub` claim, which by default includes the workflow_ref + event_name + ref. The v3.0 regex matches all of them. Result: a token leaked from ANY other workflow in the repo (a release workflow, a test workflow, a cleanup workflow) could forge an attestation that the compliance-enforce workflow would accept. Convergent reviewer concern: this is a token-confusion attack with HIGH likelihood (any workflow CI logs PR can leak the token via debug output, env dumps, or a compromised dependency).\n\n**Amendment (binding):**\n\nThe \u00a75.1 cosign verify-blob step is amended to bind to specific OIDC token claims, not the repo prefix. The amended invocation:\n\n```bash\n# AMENDED \u00a75.1 verify step per Round 2 convergent finding\ncosign verify-blob \\\n  --bundle \"$BUNDLE\" \\\n  --certificate-identity \"https://github.com/billyjoelsaniceguy/health-dashboard/.github/workflows/compliance-enforce.yml@refs/heads/main\" \\\n  --certificate-oidc-issuer \"https://token.actions.githubusercontent.com\" \\\n  --certificate-github-workflow-trigger \"push\" \\\n  --certificate-github-workflow-ref \"refs/heads/main\" \\\n  --certificate-github-workflow-sha \"\" \\\n  --certificate-github-workflow-repository \"billyjoelsaniceguy/health-dashboard\" \\\n  \"$ATTESTATION\" \\\n  || { echo \"::error::Signature verification failed for $SHA (identity binding too loose? wrong workflow?)\"; FAILED=1; continue; }\n```\n\n**Binding-detail rules (all binding):**\n\n1. **`--certificate-identity`** must be EXACT (no regex). The specific workflow_ref + ref binding eliminates the \"any-workflow-can-forge\" risk. The certificate-identity value is the OIDC token's `sub` claim, which Sigstore Fulcio writes verbatim into the signing certificate.\n\n2. **`--certificate-github-workflow-trigger`** must be `push` (not `pull_request`, not `workflow_dispatch`). Forces the signing event to have been a push event to the repository. Combined with #3 below, this defeats most token-confusion attacks.\n\n3. **`--certificate-github-workflow-ref`** must be `refs/heads/main` (or `refs/heads/claude/**` for the branch-protected upstream-of-main flow; the v3.0 \u00a75.3 branch protection wiring permits both). PR refs (`refs/pull//merge`) are explicitly NOT accepted by the verify step \u2014 they get a separate, more restrictive rule path with no merge-blocking power.\n\n4. **`--certificate-github-workflow-sha`** binds to the EXACT workflow file SHA. When the workflow file itself changes, the SHA changes, and the new SHA must be pre-registered before the new workflow can sign attestations. This is the \"policy hot-swap\" defense Reviewer 4 specifically called out \u2014 see \u00a713.6 below.\n\n5. **`--certificate-github-workflow-repository`** binds to the repo (defense in depth; redundant with #1 but cheap to check).\n\n**Retracts:** v3.0 \u00a75.1's `--certificate-identity-regexp \"^https://github\\\\.com/billyjoelsaniceguy/health-dashboard\"` \u2014 the repo-prefix regex that admits all workflows. **Supersedes:** v3.0 \u00a75.1's cosign verify-blob step. **Derives from:** Magna Carta P5 (process errors compound; the repo-prefix regex is an architecture-layer error class \u2014 overly-loose identity binding \u2014 that one Sigstore version upgrade or one cosign documentation update could expand to admit even more identities; tight binding is the architecture-layer fix) + Reviewer 3 + Reviewer 4 convergent finding.\n\n### \u00a713.3 \u2014 Commentary plane OPTIONAL (CHANGE 3; supersedes \u00a76 verbatim text in part)\n\n**Convergent reviewer finding (Round 2):** v3.0 \u00a76 ships the commentary plane as a fully-deployed separate workflow that runs on every push by default. For a 1-person team (Zachary) the operational cost of an always-on commentary workflow includes: GitHub Actions minutes (small but not zero), permission-scope drift over time (the `pull-requests: write` + `issues: write` scope is a minor attack surface), and the v2 28-failure-email-incident pattern (any permission misconfiguration in the commentary workflow could re-trigger email floods). Reviewer 3 + Reviewer 4 independently observed: a 1-person team doesn't need always-on commentary; the attestation file itself + the GitHub Actions enforcement log are sufficient for routine review; commentary should be opt-in per-commit via a flag in the attestation.\n\n**Amendment (binding):**\n\nThe \u00a76 commentary plane is amended from \"default ON\" to \"default OFF; opt-in per-commit via attestation field\".\n\n**Amended attestation predicate field (additive \u2014 extends \u00a713.1 schema):**\n\n```json\n{\n  \"predicate\": {\n    \"commentary_requested\": false,\n    \"commentary_targets\": []\n  }\n}\n```\n\nWhere:\n- **`commentary_requested: boolean`** \u2014 when `false` (default), the commentary workflow does NOT run for this commit. When `true`, the commentary workflow runs.\n- **`commentary_targets: enum[]`** with values `{pr_comment, commit_comment, pushover}` \u2014 which output channels to render to. Empty array (default) renders nothing even if `commentary_requested` is true (effectively still OFF).\n\n**Amended \u00a76.1 workflow trigger:**\n\n```yaml\n# AMENDED \u00a76.1 per Round 2 convergent finding\nname: compliance-commentary\n\non:\n  workflow_run:\n    workflows: [\"compliance-enforce\"]\n    types: [completed]\n\njobs:\n  check_opt_in:\n    name: check_opt_in\n    runs-on: ubuntu-latest\n    timeout-minutes: 1\n    outputs:\n      commentary_requested: ${{ steps.read.outputs.requested }}\n    steps:\n      - name: Read attestation commentary_requested field\n        id: read\n        run: |\n          # ... reads .attestations/.json predicate.commentary_requested ...\n          # Outputs requested=true|false\n\n  commentary:\n    name: commentary\n    needs: [check_opt_in]\n    if: ${{ needs.check_opt_in.outputs.commentary_requested == 'true' }}\n    runs-on: ubuntu-latest\n    timeout-minutes: 3\n    continue-on-error: true\n    permissions:\n      pull-requests: write   # opt-in only; not always-on\n      issues: write\n      contents: read\n    steps: # ... same render + post steps as v3.0 \u00a76.1 ...\n```\n\n**Operational consequence:** on a routine commit (most commits), no commentary runs; no extra workflow minutes consumed; no permission-scope risk surfaced; no email-flood failure mode possible. When Zachary wants commentary on a specific commit (e.g., a high-stakes governance amendment), the attestation generator (\u00a73.4) is invoked with `--commentary-requested --commentary-targets pr_comment,pushover` and the commentary workflow fires.\n\n**Retracts:** v3.0 \u00a76's \"default ON\" framing for the commentary plane (the workflow file exists + runs every push by default). **Supersedes:** v3.0 \u00a76.1's workflow trigger (now gated on the attestation field). **Does NOT retract:** v3.0 \u00a76.2's preapproved-fields-only schema for the digest output \u2014 that defense survives; the amendment is to RUN vs NOT-RUN, not to the rendering safety. **Derives from:** Magna Carta P6 (Zachary's attention is the scarce resource \u2014 always-on commentary on routine commits IS attention-spend) + P5 (process errors compound; permission-scope drift over time is an architecture-layer pattern; default-OFF eliminates the drift surface) + Reviewer 3 + Reviewer 4 convergent finding.\n\n### \u00a713.4 \u2014 Collapse to 2-plane design (CHANGE 4; supersedes \u00a72 + \u00a7\u00a75-6 verbatim formulation)\n\n**Convergent reviewer finding (Round 2):** v3.0 \u00a72's 4-plane formulation (Evidence / Policy / Enforcement / Output) was useful for THINKING through the trust-isolation requirements but ships as **2 workflow files** (compliance-enforce.yml + compliance-commentary.yml) + **2 conceptual layers within enforce.yml** (Evidence-plane attestation generation + Policy-plane OPA evaluation). Reviewer 4 specifically: the 4-plane name is over-architected; the actual structural separation that delivers trust isolation is between (a) the enforcement workflow (read-only contents + id-token write, no outbound) and (b) the commentary workflow (which is now \u00a713.3 OPTIONAL). Reviewer 3 framing: the Output plane is not architecturally distinct from the Evidence plane verifier rendering its own result \u2014 it's a presentation layer of the same data, not a separate plane in the trust-isolation sense.\n\n**Amendment (binding):**\n\nThe \u00a72 architecture is amended from \"4 planes\" to **\"2 planes with optional commentary\"**:\n\n```\n\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n\u2502      Framework v3.1 \u2014 2-Plane Architecture (with optional commentary)            \u2502\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n\n  \u250c\u2500 \u00a73 EVIDENCE PLANE \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n  \u2502                                                                          \u2502\n  \u2502  in-toto Statement + Sigstore signature + .attestations/.{json,    \u2502\n  \u2502  sig,bundle} per \u00a73 (v3.0) + \u00a713.1 closed-schema amendments              \u2502\n  \u2502                                                                          \u2502\n  \u2514\u2500 + \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n        \u2502\n        \u25bc\n  \u250c\u2500 \u00a74 + \u00a75 POLICY + ENFORCEMENT PLANE (merged) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n  \u2502                                                                          \u2502\n  \u2502  .github/workflows/compliance-enforce.yml                                \u2502\n  \u2502    permissions: contents: read + id-token: write                         \u2502\n  \u2502    jobs.enforce:                                                         \u2502\n  \u2502      - cosign verify-blob (per \u00a713.2 tight identity binding)             \u2502\n  \u2502      - opa test policy/  (precondition)                                  \u2502\n  \u2502      - opa eval against attestation                                      \u2502\n  \u2502      - exit 0/1                                                          \u2502\n  \u2502    ZERO outbound surface.                                                \u2502\n  \u2502    Branch protection requires this status check to pass.                 \u2502\n  \u2514\u2500 (optional output) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n        \u2502\n        \u25bc\n  \u250c\u2500 \u00a76 OPTIONAL COMMENTARY (only if predicate.commentary_requested == true) \u2510\n  \u2502                                                                          \u2502\n  \u2502  .github/workflows/compliance-commentary.yml                             \u2502\n  \u2502  Gated on attestation field per \u00a713.3.                                   \u2502\n  \u2502  Renders from \u00a76.2 preapproved fields only.                              \u2502\n  \u2502  continue-on-error: true; failure does NOT trigger email.                \u2502\n  \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n```\n\nThe trust-isolation invariants of \u00a75.2 are preserved: the enforcement workflow has zero outbound surface; the commentary workflow (when it runs at all) is non-blocking with separate permissions. The conceptual reduction from 4 to 2 (+ optional) planes does NOT loosen any security boundary; it tightens the design vocabulary so reviewers + future contributors don't get confused about what's load-bearing.\n\n**\u00a74 Policy plane content survives unchanged:** the Rego rule pack at `policy/rules/` + tests at `policy/tests/` + fixtures at `policy/fixtures/` per \u00a74.2 still exist as separate ARTIFACTS \u2014 they're not collapsed into the workflow file. The \"merging\" in this amendment is in the conceptual architecture diagram, not in the file structure. `policy/` directory and its contents survive 1:1 from v3.0 \u00a74.\n\n**Retracts:** v3.0 \u00a72's \"4 planes\" naming + the \u00a76 framing as a separate Output Plane parallel to Evidence + Policy + Enforcement. **Supersedes:** v3.0 \u00a72 architecture diagram + \u00a76's \"default ON separate workflow\" formulation. **Does NOT retract:** the underlying trust-isolation invariants (zero outbound from enforcement; preapproved-fields-only from commentary when it runs) \u2014 those survive intact. **Derives from:** Reviewer 3 + Reviewer 4 convergent finding + Magna Carta P10 (volume \u2260 verification; 4 planes is more design surface than 2 + optional commentary which delivers the same isolation) + P14 (purpose is fact; the purpose of the architecture diagram is to make reviewers + future contributors understand the trust boundaries, not to maximize plane count).\n\n### \u00a713.5 \u2014 Non-keyless Sigstore default (CHANGE 5; supersedes \u00a73.6 verbatim recommendation)\n\n**Convergent reviewer finding (Round 2):** v3.0 \u00a73.6's default recommendation of Sigstore keyless signing has **two structural risks** for this project's deployment context that Round 1 did not surface:\n\n1. **Sigstore Fulcio CA + Rekor transparency log are public infrastructure.** Every signing event publishes the OIDC identity + a timestamped log entry to the public Rekor log. For a project with D1 Primary Clinical Purpose, this means the timing pattern of attestations becomes public information \u2014 a passive observer of Rekor can deduce when Zachary's clinical-record commits happen, even without seeing the content. This is a privacy correlation risk that's intrinsic to the Sigstore public-infra model.\n\n2. **Sigstore outage = deadlock.** v3.0 \u00a73.6 admits Sigstore has &lt;1% outage rate but treats this as acceptable risk because \"CI is down anyway\". The convergent reviewer concern: when Sigstore is down, Claude main cannot generate signed attestations, which means substantive commits cannot land via the v3 path. The fallback path (defer commit until Sigstore is up) is fine for routine commits but bad for time-critical commits (e.g., a Halper-delivery-day push at hour-23 of the delivery window).\n\n**Amendment (binding):**\n\nThe default Sigstore signing mode flips from keyless to **traditional public-key signing with a repo-checked-in public key**. Keyless signing becomes an OPTIONAL per-commit flag for high-public-verifiability deployments.\n\n**Amended default flow:**\n\n1. Zachary generates a long-lived signing key pair at v3 deployment time: `cosign generate-key-pair --output-key-prefix attestation-signer-v3` (produces `attestation-signer-v3.pub` + `attestation-signer-v3.key`). The `.pub` is committed to the repo at `policy/keys/attestation-signer-v3.pub`. The `.key` is stored as a GitHub Actions secret `ATTESTATION_SIGNER_KEY` (NOT committed; never echoed to logs).\n\n2. Claude main signs attestations via `cosign sign-blob --key ${{ secrets.ATTESTATION_SIGNER_KEY }} ...` \u2014 this runs INSIDE the GitHub Actions runner during the attestation-generation workflow (per \u00a710 point 5 + Q-F in \u00a711). The secret is scoped to the attestation-generation workflow only; the enforcement workflow has read-only access to the `.pub` key.\n\n3. The enforcement workflow verifies via `cosign verify-blob --key policy/keys/attestation-signer-v3.pub ...` \u2014 no Fulcio CA + no Rekor lookup + no internet round-trip during verification. Verification is fully offline-capable.\n\n**Keyless mode as opt-in (per-commit flag):**\n\nThe attestation predicate (\u00a713.1 schema) gets an additional field:\n\n```json\n{\n  \"predicate\": {\n    \"signing_mode\": \"static_key\"  // default; OR \"sigstore_keyless\"\n  }\n}\n```\n\nWhen `signing_mode == \"sigstore_keyless\"`, the cosign sign-blob step uses the OIDC-rooted flow per v3.0 \u00a73.4; verification per \u00a713.2's tight identity binding rules. This mode is opt-in for commits where Zachary wants public verifiability of the signing event (e.g., a Magna Carta v2.0 ratification commit that Zachary wants a public Rekor log entry for).\n\n**Default static-key mode advantages:**\n\n- No Fulcio + no Rekor dependency (Sigstore-outage tolerant)\n- No public timing-correlation surface (Rekor public log not touched)\n- Zero internet round-trip during verification (fully offline-verifiable from a fresh repo clone)\n- One key generated once at v3 deployment; rotation policy decided per Zachary direction (recommended: rotate annually + on any compromise indicator)\n\n**Static-key mode disadvantages (acknowledged):**\n\n- The key is a long-lived secret; if compromised, all attestations made with it are forgeable until rotation. Mitigation: key stored as GitHub Actions secret (encrypted at rest by GitHub; only decrypted into the runner during workflow execution); key rotation cadence (annual + on-compromise) limits compromise blast radius\n- Verification depends on the `.pub` key in the repo being uncompromised; an attacker with repo-write access could swap the `.pub` and forge attestations with their own key. Mitigation: branch protection on `policy/keys/**` requires Zachary review for any change; the policy hot-swap defense from \u00a713.6 below provides additional structural barrier\n\n**Retracts:** v3.0 \u00a73.6's \"Default recommendation: keyless\" framing. **Supersedes:** v3.0 \u00a73.4 signing flow's Sigstore Cosign keyless step as the default path. **Does NOT retract:** the v3.0 \u00a73.6 analysis of keyless vs traditional trade-offs (the analysis itself is preserved for audit trail; the DEFAULT recommendation flips). **Derives from:** D1 (Primary Clinical Purpose \u2014 Rekor public-log timing correlation is a privacy risk worth defending against) + Magna Carta P6 (Zachary's attention is the scarce resource \u2014 Sigstore-outage-deferred commits spend that attention to track) + P14 (purpose is fact; the purpose of attestation signing is integrity binding, not public verifiability; integrity binding works equally well with static keys) + Reviewer 3 + Reviewer 4 convergent finding.\n\n### \u00a713.6 \u2014 Reviewer 4 specifics (adopted vs deferred with rationale)\n\nRound 2 Reviewer 4 (GPT-5.4 RECONSIDER-REBUILD) supplied 5 additional specific recommendations beyond the 5 convergent changes. Each is evaluated below for adoption or deferral.\n\n**ADOPTED (binding amendments to relevant v3.0 sections):**\n\n#### \u00a713.6.1 \u2014 sha256 (not sha1) as primary subject digest [ADOPTED \u2014 already integrated into \u00a713.1]\n\nPer \u00a713.1 rule 4 above: subject.digest uses sha256 as the primary field. The in-toto digest set spec supports both; sha256 is the convergent recommended primary for new attestations. sha1 MAY appear in legacy v3.0-pre-amendment attestations and the policy evaluator's compatibility layer; for v3.1+ attestations the policy evaluator requires sha256.\n\n**Rationale:** sha1 has known collision attacks (SHAttered 2017, Shambles 2020); for new cryptographic bindings, sha256 is the modern default. Adoption cost is zero (cosign + jq + git all support sha256 natively); rejection cost would be future migration if sha1 acceptance broadens in attack surface.\n\n#### \u00a713.6.2 \u2014 Tight checkout of policy from PROTECTED BASE (not candidate PR HEAD) [ADOPTED \u2014 new \u00a713.6.2.A binding rule]\n\n**The policy hot-swap attack:** a malicious commit on a feature branch could include policy/ directory changes alongside substantive changes. If the enforcement workflow checks out the candidate PR HEAD (default GitHub Actions behavior) and runs OPA against the PR-HEAD policy/, the attacker has SWAPPED the policy to one that approves their own attestation. Defeat: the enforcement workflow checks out the PROTECTED BASE (main branch's policy/ directory) and runs OPA against THAT policy, regardless of what policy/ changes appear on the candidate PR HEAD.\n\n**Binding rule:** The \u00a75.1 enforcement workflow's checkout step is amended to perform a two-checkout:\n\n```yaml\n# AMENDED \u00a75.1 checkout step per Reviewer 4 \u00a713.6.2\n- name: Checkout candidate PR HEAD (for attestation file access)\n  uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11  # v4.1.1\n  with:\n    fetch-depth: 0\n    path: candidate\n\n- name: Checkout PROTECTED BASE policy\n  uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11  # v4.1.1\n  with:\n    ref: refs/heads/main   # always main; never the PR HEAD\n    sparse-checkout: |\n      policy/\n      .attestations/\n    path: protected_base\n\n# OPA evaluation uses protected_base/policy/ (not candidate/policy/)\n# Attestation files come from candidate/.attestations/ (the PR's own attestations)\n- name: Run OPA tests against PROTECTED BASE policy\n  run: |\n    opa test protected_base/policy/ --verbose --explain=fails\n    opa test protected_base/policy/ --coverage --threshold=80\n\n- name: Evaluate attestation against PROTECTED BASE policy\n  run: |\n    opa eval --data protected_base/policy/rules/ \\\n      --input \"candidate/.attestations/${SHA}.json\" \\\n      --format json \\\n      'data.compliance.allow' &gt; eval-result.json\n```\n\n**Rationale:** the policy hot-swap is one of the highest-likelihood attack patterns against policy-as-code systems; the defense is structural (checkout strategy) and free (one extra checkout step adds ~2s of CI runtime; well within the \u00a75.2 5-minute budget).\n\n**Composition with \u00a713.5:** the public key at `policy/keys/attestation-signer-v3.pub` is ALSO checked out from PROTECTED BASE, not candidate PR HEAD. This means a PR that swaps the public key AND signs an attestation with its own private key would fail verification \u2014 the verify step uses the BASE's public key, not the PR's.\n\n#### \u00a713.6.3 \u2014 NFKC normalization on every string field before policy evaluation [ADOPTED \u2014 new \u00a713.6.3.A binding rule]\n\n**The bypass pattern:** Unicode has multiple ways to encode \"the same\" string. ZWSP (zero-width space U+200B) inside a status enum value (`PASS`) reads as \"PASS\" to humans + breaks regex/equality checks unless the comparison normalizes. Homoglyph attacks (Cyrillic '\u0430' U+0430 vs Latin 'a' U+0061) similarly. Compatibility forms (full-width '\uff30' vs half-width 'P') similarly. v2 Wave 5 had a ZWSP bypass finding; v3 must defend.\n\n**Binding rule:** every string field in the attestation predicate, before being passed to OPA's `input.*`, gets `String.prototype.normalize('NFKC')` applied. The evaluator plumbing step:\n\n```javascript\n// AMENDED plumbing step per Reviewer 4 \u00a713.6.3\nfunction normalizeAttestation(att) {\n  const traverse = (v) =&gt; {\n    if (typeof v === 'string') return v.normalize('NFKC');\n    if (Array.isArray(v)) return v.map(traverse);\n    if (v &amp;&amp; typeof v === 'object') {\n      const out = {};\n      for (const [k, val] of Object.entries(v)) out[k.normalize('NFKC')] = traverse(val);\n      return out;\n    }\n    return v;\n  };\n  return traverse(att);\n}\n```\n\nThe normalized attestation is the input to `opa eval`. The non-normalized raw attestation is preserved for audit logging only.\n\n**Rationale:** NFKC is the strongest of the four Unicode normalization forms (NFC, NFD, NFKC, NFKD); it folds compatibility forms + canonical forms. Adoption cost is one helper function (~10 lines); rejection cost would be a Wave-5-style bypass via ZWSP that no one notices for months.\n\n**ADOPTED with modification:**\n\n#### \u00a713.6.4 \u2014 Conftest vs OPA: stays as OPA, with Conftest as a fallback option [ADOPTED-WITH-MODIFICATION]\n\nReviewer 4 proposed Conftest as a lighter-weight alternative to pure OPA for 1-person-team maintainability. Conftest is a thin OPA wrapper targeted at config-file validation. For this project's policy needs (J11-J16 + D1-D3 + Rule 3.X rules), Conftest CAN do the work, with some loss of OPA's full Rego expressiveness (e.g., complex partial evaluation features that we don't currently use).\n\n**Decision:** v3.1 stays on **pure OPA** as the default for policy plane plumbing, NOT Conftest. Rationale: (a) the projected growth path includes rules that may need full Rego expressiveness (e.g., a future rule that does cross-attestation reasoning over multiple commits in a PR); (b) the OPA-vs-Conftest cost differential at this project's scale is marginal (~0 vs ~0); (c) Reviewer 4's concern was \"1-person team should have simpler tooling\" but the tooling complexity at this scale is in the rule LOGIC, not in the OPA vs Conftest choice.\n\n**Conftest available as a fallback option per Q-B variant (b4):** if Zachary direction at any point in the v3.1+ lifecycle says \"the Rego pack is getting too complex for me to review,\" the migration path to Conftest is straightforward (rename `policy/rules/*.rego` \u2192 `policy/policy/*.rego`; replace `opa eval` with `conftest test`; the rules themselves are bytewise-compatible). This option is documented but not the default.\n\n**Small-TypeScript-validator alternative (Reviewer 4 b3-variant):** explicitly NOT adopted. The convergent verdict from Round 1 was that custom Node.js policy logic is the wrong substrate. Reverting to a Node.js validator (TypeScript or not) re-introduces the v2 failure mode. The intent is OFFLOAD policy logic to declarative tooling (OPA / Rego), not to re-skin the v2 substrate.\n\n#### \u00a713.6.5 \u2014 Per-PR attestation vs per-commit attestation [DEFERRED-WITH-RATIONALE]\n\nReviewer 4 proposed per-PR attestation as operational-sanity preference: one attestation covering N commits in a PR, rather than one attestation per commit. This reduces attestation churn from ~1000/year to ~100-200/year at typical project velocity.\n\n**Decision:** v3.1 stays on **per-commit attestation** as the default; per-PR attestation deferred to a future v3.2 amendment after operational experience.\n\n**Rationale for deferral (not rejection):**\n\n- The TDD discipline in \u00a73.5 + \u00a74.5 relies on per-commit attestation: each of the 3 commits in the TDD sequence (failing test \u2192 passing rule \u2192 attestation) gets its own attestation; the merge gate enforces all three present\n- The TOCTOU defense in \u00a75.1 + \u00a713.2 binds the attestation's subject digest to a specific commit SHA; per-PR attestation would need to bind to a range of SHAs (more complex; new failure modes to design against)\n- The per-commit pattern matches the granularity of the J11-J16 audit row (which is per-prompt/per-commit, not per-PR)\n- The ~1000-attestations-per-year volume estimate is manageable (~3 MB/year storage; ~3s/commit signing overhead)\n- Per-PR attestation IS attractive at scale (1000+ commits/year); revisit in v3.2 when operational data confirms it\n\n**Tracked debt:** add to Governance Debt Ledger as GD-38 \"Per-PR attestation amendment evaluation\" with status DEFERRED-pending-operational-data; review after v3.1 has been operational for 30 days post-Round-3-ratification.\n\n### \u00a713.7 \u2014 Conflicts between the 5 changes (audited)\n\nPer Mandatory Coverage Gap discipline + the \u00a710 v3.0 coverage gap structural acknowledgment, the 5 changes are audited for internal conflicts:\n\n| Conflict candidate | Resolution |\n|---|---|\n| \u00a713.3 commentary-OPTIONAL vs \u00a713.4 2-plane collapse | NO CONFLICT. \u00a713.4 keeps the commentary workflow file as a separate (optional) plane; \u00a713.3 governs WHEN it runs. The 2-plane diagram in \u00a713.4 explicitly shows commentary as \"optional output\" parallel to enforcement; this is consistent with \u00a713.3's default-OFF gating. |\n| \u00a713.5 static-key default vs \u00a713.2 tight OIDC binding | RESOLVED. The static-key path does NOT use Sigstore Fulcio OIDC; the \u00a713.2 tight binding applies ONLY to the keyless path (when `signing_mode == \"sigstore_keyless\"`). For static-key mode, verification is `cosign verify-blob --key policy/keys/attestation-signer-v3.pub ...` with no OIDC claims to bind. \u00a713.2's amended `--certificate-identity` + workflow-trigger + workflow-ref + workflow-sha + workflow-repository flags are inapplicable to static-key mode and the verification step is conditional on signing_mode. |\n| \u00a713.1 sha256 subject digest vs \u00a713.5 static-key signature algorithm | NO CONFLICT. The subject digest (what's being signed about) and the signature algorithm (how it's signed) are independent. cosign default signature algorithm is ECDSA-P256-SHA256 (or RSA-PSS); both support sha256 subject digests. |\n| \u00a713.6.2 PROTECTED BASE policy checkout vs \u00a73.5 TDD discipline (rule added in PR) | EXPLICIT TENSION; RESOLVED VIA SEPARATE LANE. The \u00a73.5 TDD pattern adds a rule via 3 commits ON a feature branch. The \u00a713.6.2 PROTECTED BASE checkout means the enforcement workflow uses MAIN'S policy/, not the feature branch's. **Resolution:** the feature branch's policy/ changes are NOT applied to enforcement until the PR is merged to main. The 3-commit TDD sequence on the feature branch is verifiable LOCALLY via `opa test policy/` against the feature branch's policy/, and is verifiable via the PR's CI status check (a separate `policy-test` workflow that DOES checkout feature-branch policy/ for testing-only purposes \u2014 explicitly not for enforcement). The enforcement gate is \"merge to main triggers re-evaluation against new main policy/\" \u2014 pattern is the same as the Conftest \"policy-as-code merged before enforcement\" idiom. **NEW workflow file to add:** `.github/workflows/policy-test.yml` runs `opa test` against feature-branch policy/ for PR validation (non-merge-blocking informational check); merge to main re-runs enforcement against new main policy/. |\n| \u00a713.6.3 NFKC normalization vs \u00a713.1 closed enum status values | NO CONFLICT. NFKC normalization is the LAYER 1 defense; the closed enum (status \u2208 {PASS, FAIL, PARTIAL, N_A, PASS_CARVE_OUT}) is the LAYER 2 defense. NFKC ensures `P\u200bASS` normalizes to `PASS`; the enum check then accepts it. If NFKC alone produced a string not in the enum (e.g., `PA SS` with a regular space), the enum check rejects it. Defense in depth. |\n| \u00a713.6.4 OPA-stays vs \u00a713.6.5 per-PR deferred | NO CONFLICT. OPA vs Conftest is the policy engine choice; per-PR vs per-commit is the attestation granularity choice. Independent dimensions. |\n\nThe cross-cutting conflict acknowledged is \u00a713.6.2 vs \u00a73.5 TDD, resolved by adding a separate non-merge-blocking `policy-test.yml` workflow that exercises feature-branch policy for local validation. This is a **new artifact** (`.github/workflows/policy-test.yml`) added by the amendment; it follows the Mandatory Pre-Build Search gate header convention at authoring time per \u00a713.8 below.\n\n### \u00a713.8 \u2014 Implementation impact on \u00a77 + \u00a78 (Migration path + Phase plan)\n\nThe amendment modifies the \u00a78 phase plan as follows:\n\n- **P1 (External review of v3.0):** ALREADY COMPLETED via Round 2. Status flips DONE.\n- **P1.5 (NEW \u2014 External review of v3.1 amendment):** Round 3 dispatch of the AMENDED spec by 1+ external reviewer; binding precondition for P2-P7. Recommended dispatch: same `template: B-premortem`; new reviewer pool member (e.g., Claude Sonnet 4.7 acting as Reviewer 5) OR re-dispatch one of Round 2 reviewers on the AMENDED spec (test for cross-version convergence). Effort: ~2-3h dispatch + 0.5h Zachary review.\n- **P2 (Policy plane authoring):** unchanged in scope but ADDS files per amendment: `policy/catalogs/tier_classification_patterns.json` + `policy/catalogs/panel_framings.json` (per \u00a713.1 rules 1 + 2) + `policy/keys/attestation-signer-v3.pub` (per \u00a713.5 default static-key) + `policy/rules/panel_framings_valid.rego` (per \u00a713.1 rule 2 enforcement). Effort estimate revised: ~7-9h (was ~6-8h).\n- **P3 (Evidence plane authoring):** unchanged in scope but `scripts/generate-attestation-v3.mjs` must implement the \u00a713.1 closed schema + \u00a713.6.3 NFKC normalization + \u00a713.5 static-key signing by default + \u00a713.3 commentary_requested field. Effort: ~5-7h (was ~4-6h).\n- **P4 (Enforcement plane authoring):** unchanged in scope but `compliance-enforce.yml` adds \u00a713.2 tight OIDC binding (for the keyless opt-in path) + \u00a713.5 static-key verification (for the default path) + \u00a713.6.2 PROTECTED BASE checkout strategy. Effort: ~4-6h (was ~3-5h).\n- **P5 (Output plane authoring):** REPLACED. New scope: ship the commentary workflow as DEFAULT-OFF per \u00a713.3 with the opt-in gating job. The \u00a76.2 preapproved-fields schema for digest output survives 1:1. Effort: ~3h (was ~3-4h; slight reduction because the default-OFF case has less to test).\n- **P5.5 (NEW \u2014 Policy-test workflow):** add `.github/workflows/policy-test.yml` per \u00a713.7 conflict resolution. Effort: ~1h.\n- **P6 (Wave-5 regression suite):** unchanged in scope; ADD \u00a713.x-specific regressions: PHI-in-tier-classification-evidence test (asserts free-text rejected), PHI-in-panel-framings test (asserts unregistered values rejected), PHI-in-subject-name test (asserts cleartext branch rejected), OIDC token confusion test (asserts a token from a different workflow rejected by \u00a713.2 tight binding), policy hot-swap test (asserts \u00a713.6.2 PROTECTED BASE checkout defeats malicious policy/ in PR), ZWSP bypass test (asserts \u00a713.6.3 NFKC normalization defeats Unicode tricks). Effort: ~5-7h (was ~4-6h).\n- **P7 (Archive v2 + Magna Carta amendments):** unchanged.\n- **P8 (External NON-Claude review of v3 deployment):** unchanged; remains binding pre-CI-re-enable.\n- **P9 (Branch protection + first live commits):** unchanged.\n- **P10 (Quarterly review):** unchanged.\n\n**Revised total estimated effort to v3.1 operational:** ~30-40h Claude main work + Zachary configuration (~1-1.5h total; key-pair generation + branch protection wiring + commentary opt-in selection adds ~30 min).\n\n### \u00a713.9 \u2014 Open questions for Zachary (additive to \u00a711)\n\nIn addition to the 7 v3.0 open questions in \u00a711, the v3.1 amendment surfaces:\n\n8. **Q-H \u2014 Round 3 external review reviewer choice?** Options: (h1) re-dispatch one of Round 2 reviewers on the AMENDED spec (tests for cross-version convergence); (h2) dispatch a fresh reviewer (Claude Sonnet 4.7 or similar) for independence from prior verdicts; (h3) dispatch BOTH (h1 + h2 in parallel). Default recommendation: (h3) \u2014 same effort as (h1) or (h2) alone given the parallel-dispatch pattern; provides the strongest convergence signal. Token cost is not a factor per CLAUDE.md Document Review Gate Amendment 2026-05-30.\n\n9. **Q-I \u2014 Static-key vs keyless signing \u2014 confirm default flip?** \u00a713.5 flips the default from keyless to static-key. Zachary confirmation: do you accept this flip? If you prefer keeping keyless as default (despite the Rekor public-log timing-correlation risk), say so and \u00a713.5 amends to opposite-default with static-key as the opt-in mode.\n\n10. **Q-J \u2014 Long-lived signing key rotation cadence?** \u00a713.5 default static-key mode introduces a long-lived signing key. Rotation cadence options: (j1) annual rotation + on-compromise (default recommended); (j2) quarterly rotation + on-compromise (more conservative; more rotation churn); (j3) on-compromise only (less conservative; relies on Zachary detecting compromise). Default: (j1).\n\n11. **Q-K \u2014 Policy-test workflow as non-merge-blocking vs merge-blocking?** \u00a713.7 conflict resolution introduces `policy-test.yml` as a non-merge-blocking informational workflow. Alternative: make it merge-blocking (a PR with broken policy tests cannot merge to main even if `compliance-enforce` passes against the protected base policy/). Default: non-merge-blocking (the \u00a713.6.2 PROTECTED BASE checkout already provides the structural defense; making policy-test merge-blocking adds enforcement-of-feature-branch-policy which is conceptually wrong per the protect-the-base discipline). Zachary confirmation requested.\n\n12. **Q-L \u2014 Commentary opt-in default for governance amendments?** \u00a713.3 makes commentary OFF-by-default per commit. For high-stakes commits (e.g., Magna Carta amendments, Rule 3.X additions, governance debt ledger updates), is the opt-in burden too high? Alternative: AUTO-opt-in for commits whose subject matches a regex (e.g., `^(magna-carta|rule-3\\\\.|governance-debt)`). Default: pure-opt-in per commit (no auto-detection magic; consistent with the \"no free-text policy\" discipline); Zachary explicitly flags `--commentary-requested` when wanted.\n\n13. **Q-M \u2014 Per-PR attestation v3.2 review timing?** \u00a713.6.5 defers per-PR attestation to v3.2 pending operational data. After v3.1 has been operational for 30 days, the per-PR review fires. Is 30 days the right interval? Options: (m1) 30 days (default; per GD-27 high-frequency-gate tier first-cycle re-tuning); (m2) 14 days (faster signal); (m3) 90 days (more data). Default: (m1).\n\n### \u00a713.10 \u2014 Coverage gap (per Rule 3.7; amendment surface)\n\nSurfaces NOT checked by this amendment:\n\n- **Rego rule audit for \u00a713.1 closed schema enforcement** \u2014 the amendment specifies the closed shapes but the actual Rego rules that enforce them (panel_framings_valid.rego, tier_classification_evidence_valid.rego, status_enum_valid.rego, etc.) are not yet authored in this amendment. P2 phase authoring will catch this; the amendment specifies INTENT not IMPLEMENTATION.\n- **CI testing of \u00a713.6.2 PROTECTED BASE checkout strategy in remote-container** \u2014 the amendment specifies the GitHub Actions checkout strategy but does not test it from the remote-container environment. This is a Stress Test Gate Remote-Container Clause situation: substantively unverified until the desktop session runs against actual CI. Tracked as a debt to close on next desktop session.\n- **Operational testing of static-key vs keyless signing latency** \u2014 the amendment specifies the default flip but does not benchmark the signing latency for either mode. Sigstore keyless can have ~5-10s latency per signing event; static-key is ~0.5s. The amendment's effort estimates assume static-key default; if keyless turns out to be required for any reason, the \u00a78 P3 effort estimate may need adjustment.\n- **Round 3 reviewer alignment with Round 1 + Round 2 frames** \u2014 the amendment assumes Round 3 will use a similar premortem framing. If Round 3 reviewer interprets the spec differently (e.g., constitutional vs operational vs cost-benefit framing), the convergence-pattern analysis differs.\n- **Schema_version 3.1 vs cosign + opa version compatibility** \u2014 the amendment specifies schema_version 3.1 in \u00a713.1 but does not pin specific cosign or opa versions known to support the new schema. Implementation may surface version constraints; if so, \u00a78 P3 + P4 add a version-pin clarification step.\n\nPossible rules residing in unchecked surfaces:\n- Conftest semantic subtleties (deferred per \u00a713.6.4; the OPA-stays decision may need revisit if Rego features get unexpected)\n- Sigstore + cosign tooling evolution (Sigstore is rapidly evolving; the \u00a713.2 binding flag names may rename in a future cosign version)\n- in-toto v1 spec future-versioning (in-toto's predicate type registry may add a \"compliance-row\" subtype that conflicts with the project-custom URI)\n- Sub-agent panel framing catalog growth (the \u00a713.1 rule 2 catalog will need ongoing maintenance as new panel framings get added; cadence unclear)\n\nCoverage gap line for this amendment: surfaces NOT checked this amendment \u2014 Rego rule authoring for closed-schema enforcement, CI runtime testing of PROTECTED BASE checkout strategy, signing latency benchmarks, Round 3 reviewer framing alignment, Sigstore + cosign tooling version-pinning. Possible rules residing there: Conftest semantic subtleties, Sigstore tooling evolution surface, in-toto registry evolution, sub-agent panel framing catalog cadence.\n\n### \u00a713.11 \u2014 Reference + cross-link surface (amendment-specific)\n\n- `scripts/external-review/queue.jsonl` line 9 \u2014 Round 2 Reviewer 3 (Sonnet 2) verdict + response_summary\n- `scripts/external-review/queue.jsonl` line 10 \u2014 Round 2 Reviewer 4 (GPT-5.4) verdict + response_summary\n- `scripts/FRAMEWORK-v3-OPA-INTOTO-2026-06-02.md` \u00a7\u00a73-6 (this same file, sections above) \u2014 preserved verbatim per OP-6; superseded in part by \u00a713 above\n- `CLAUDE.md` \u00a7Mandatory Document Review Gate \u2014 the gate this amendment passes through (inline display + synopsis below)\n- `CLAUDE.md` \u00a7Mandatory Plain-Language Communication \u2014 the gate this amendment passes through (glossary additions at \u00a713 header; first-mention spell-outs throughout)\n- `CLAUDE.md` \u00a7Mandatory Archive Policy + OP-6 (audit-trail preservation) \u2014 the operating procedure this amendment follows (v3.0 sections preserved verbatim; \u00a713 appended)\n- `CLAUDE.md` \u00a7Governance Debt Ledger \u2014 GD-38 to be added per \u00a713.6.5 deferred per-PR attestation evaluation\n- `CLAUDE.md` \u00a7Codified Rule 3.7 \u2014 the coverage-gap discipline followed in \u00a713.10\n- Convergent reviewer Round 2 verdict pattern \u2014 Reviewer 3 SHIP-WITH-CHANGES + Reviewer 4 RECONSIDER-REBUILD architecturally converged on the same 5 changes despite divergent verdict labels; this convergence is the load-bearing evidence for binding the amendment now (vs deferring to a Round 3 verdict before authoring)\n\n---\n\n**End of \u00a713 v3.1 AMENDMENT block.** Authored 2026-06-02 UTC by Claude main; binding upon Round 3 external review of THIS AMENDED spec returning RECONSIDER-or-better convergence per the M\u00fcnchhausen-trilemma recursive pattern established in v3.0 \u00a710 coverage gap item 1. v3.0 \u00a7\u00a73-6 preserved verbatim above per OP-6. Where \u00a713 conflicts with v3.0 \u00a7\u00a73-6, \u00a713 controls per the AMENDMENT NOTICE at the top of this file.\n\n---\n\n**End of framework v3 architecture spec.** Status: v3.0 DRAFT-PROPOSAL + v3.1 amendment per Round 2 external review (see \u00a713). Path: `/home/user/health-dashboard/scripts/FRAMEWORK-v3-OPA-INTOTO-2026-06-02.md`. Supersedes (substrate only): `scripts/FRAMEWORK-v2-CI-CENTERED-2026-06-01.md`. Governance content survives unchanged. Next action: P1.5 external review of THIS AMENDED v3.1 doc per \u00a713.8 (Round 3; recommended dispatch: same `template: B-premortem` via `scripts/external-review/queue.jsonl` append + Reviewer 5 or re-Round 2 reviewer per Q-H). Per Mandatory Document Review Gate: inline content above; no path-only references. Per Mandatory Plain-Language Communication: glossary at \u00a7Glossary + \u00a713 header glossary additions; first-mention spell-outs throughout. Per Magna Carta P3: this doc is a CLAIM; the Phase-2-onward shipping artifacts are the implementation evidence still owed; the v3.1 amendment is itself a CLAIM that the 5 convergent Round 2 changes correctly address the v3.0 architectural weaknesses; Round 3 verdict is the ratification.\n\n\n\n---\n\n**End of bundle.** All artifacts above are embedded verbatim from the source paths. No external fetches required. Reviewer may paste this entire file into a fresh non-Claude LLM thread; the Round 3 prompt + the full v3.1 architecture spec (v3.0 \u00a7\u00a71-12 preserved verbatim per OP-6 + v3.1 \u00a713 amendment block) are all present.\n", "creation_timestamp": "2026-06-03T01:52:04.000000Z"}