feat(rsr): standards RSR compliance pass — Bronze (58% → 86%)#390
Merged
Conversation
hyperpolymath
pushed a commit
that referenced
this pull request
Jun 18, 2026
Editing rhodium-standard-repositories/rsr-audit.sh changed that spec home's content-addressed source_hash; regenerated REGISTRY.a2ml via the sanctioned generator (bash scripts/build-registry.sh) to clear the "Registry + topology in sync" drift on PR #390. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019awZjBD1qx61tvmEuEKNpn
🔍 Hypatia Security ScanFindings: 148 issues detected
View findings[
{
"reason": "Issue in scorecard.yml",
"type": "missing_workflow",
"file": "scorecard.yml",
"action": "create",
"rule_module": "workflow_audit",
"severity": "high"
},
{
"reason": "Issue in scorecard-enforcer.yml",
"type": "scorecard_publish_with_run_step",
"file": "scorecard-enforcer.yml",
"action": "split_scorecard_publish_job",
"rule_module": "workflow_audit",
"severity": "high"
},
{
"reason": "Issue in instant-sync.yml",
"type": "secret_action_without_presence_gate",
"file": "instant-sync.yml",
"action": "peter-evans/repository-dispatch",
"rule_module": "workflow_audit",
"severity": "high"
},
{
"reason": "Required file missing (condition: public_repo)",
"type": "missing_requirement",
"file": ".github/workflows/scorecard.yml",
"action": "create",
"rule_module": "cicd_rules",
"severity": "high"
},
{
"reason": "TypeScript file detected -- banned language",
"type": "banned_language_file",
"file": "/home/runner/work/standards/standards/scripts/check-ts-allowlist.ts",
"action": "flag",
"rule_module": "cicd_rules",
"severity": "critical"
},
{
"reason": "Agda postulate assumes without proof -- potential soundness hole (4 occurrences, CWE-704)",
"type": "agda_postulate",
"file": "/home/runner/work/standards/standards/lol/proofs/theories/information_theory.agda",
"action": "flag",
"rule_module": "code_safety",
"severity": "critical"
},
{
"reason": "innerHTML assignment -- XSS risk, use textContent or SafeDOM (5 occurrences, CWE-79)",
"type": "js_innerhtml",
"file": "/home/runner/work/standards/standards/avow-protocol/public/demo.js",
"action": "flag",
"rule_module": "code_safety",
"severity": "high"
},
{
"reason": "innerHTML assignment -- XSS risk, use textContent or SafeDOM (1 occurrences, CWE-79)",
"type": "js_innerhtml",
"file": "/home/runner/work/standards/standards/axel-protocol/src/Tea.res.js",
"action": "flag",
"rule_module": "code_safety",
"severity": "high"
},
{
"reason": "Wildcard CORS -- restrict to specific origins or use env var (1 occurrences, CWE-942)",
"type": "js_wildcard_cors",
"file": "/home/runner/work/standards/standards/consent-aware-http/examples/reference-implementations/deno/aibdp_middleware.js",
"action": "flag",
"rule_module": "code_safety",
"severity": "high"
},
{
"reason": "HTTP URL in Nickel config -- must use HTTPS (1 occurrences, CWE-319)",
"type": "ncl_http_url",
"file": "/home/runner/work/standards/standards/k9-svc/register.ncl",
"action": "flag",
"rule_module": "code_safety",
"severity": "high"
}
]Powered by Hypatia Neurosymbolic CI/CD Intelligence |
hyperpolymath
pushed a commit
that referenced
this pull request
Jun 18, 2026
Editing rhodium-standard-repositories/rsr-audit.sh changed that spec home's content-addressed source_hash; regenerated REGISTRY.a2ml via the sanctioned generator (bash scripts/build-registry.sh) to clear the "Registry + topology in sync" drift on PR #390. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019awZjBD1qx61tvmEuEKNpn
hyperpolymath
force-pushed
the
claude/hopeful-babbage-pn0l4o
branch
from
June 18, 2026 11:47
a377b29 to
29cf386
Compare
hyperpolymath
marked this pull request as ready for review
June 18, 2026 11:47
hyperpolymath
enabled auto-merge (squash)
June 18, 2026 11:47
hyperpolymath
disabled auto-merge
June 18, 2026 11:48
🔍 Hypatia Security ScanFindings: 148 issues detected
View findings[
{
"reason": "Issue in scorecard.yml",
"type": "missing_workflow",
"file": "scorecard.yml",
"action": "create",
"rule_module": "workflow_audit",
"severity": "high"
},
{
"reason": "Issue in scorecard-enforcer.yml",
"type": "scorecard_publish_with_run_step",
"file": "scorecard-enforcer.yml",
"action": "split_scorecard_publish_job",
"rule_module": "workflow_audit",
"severity": "high"
},
{
"reason": "Issue in instant-sync.yml",
"type": "secret_action_without_presence_gate",
"file": "instant-sync.yml",
"action": "peter-evans/repository-dispatch",
"rule_module": "workflow_audit",
"severity": "high"
},
{
"reason": "Required file missing (condition: public_repo)",
"type": "missing_requirement",
"file": ".github/workflows/scorecard.yml",
"action": "create",
"rule_module": "cicd_rules",
"severity": "high"
},
{
"reason": "TypeScript file detected -- banned language",
"type": "banned_language_file",
"file": "/home/runner/work/standards/standards/scripts/check-ts-allowlist.ts",
"action": "flag",
"rule_module": "cicd_rules",
"severity": "critical"
},
{
"reason": "Agda postulate assumes without proof -- potential soundness hole (4 occurrences, CWE-704)",
"type": "agda_postulate",
"file": "/home/runner/work/standards/standards/lol/proofs/theories/information_theory.agda",
"action": "flag",
"rule_module": "code_safety",
"severity": "critical"
},
{
"reason": "innerHTML assignment -- XSS risk, use textContent or SafeDOM (5 occurrences, CWE-79)",
"type": "js_innerhtml",
"file": "/home/runner/work/standards/standards/avow-protocol/public/demo.js",
"action": "flag",
"rule_module": "code_safety",
"severity": "high"
},
{
"reason": "innerHTML assignment -- XSS risk, use textContent or SafeDOM (1 occurrences, CWE-79)",
"type": "js_innerhtml",
"file": "/home/runner/work/standards/standards/axel-protocol/src/Tea.res.js",
"action": "flag",
"rule_module": "code_safety",
"severity": "high"
},
{
"reason": "Wildcard CORS -- restrict to specific origins or use env var (1 occurrences, CWE-942)",
"type": "js_wildcard_cors",
"file": "/home/runner/work/standards/standards/consent-aware-http/examples/reference-implementations/deno/aibdp_middleware.js",
"action": "flag",
"rule_module": "code_safety",
"severity": "high"
},
{
"reason": "HTTP URL in Nickel config -- must use HTTPS (1 occurrences, CWE-319)",
"type": "ncl_http_url",
"file": "/home/runner/work/standards/standards/k9-svc/register.ncl",
"action": "flag",
"rule_module": "code_safety",
"severity": "high"
}
]Powered by Hypatia Neurosymbolic CI/CD Intelligence |
hyperpolymath
enabled auto-merge (squash)
June 18, 2026 11:49
hyperpolymath
disabled auto-merge
June 18, 2026 11:51
hyperpolymath
enabled auto-merge (squash)
June 18, 2026 11:51
🔍 Hypatia Security ScanFindings: 148 issues detected
View findings[
{
"reason": "Issue in scorecard.yml",
"type": "missing_workflow",
"file": "scorecard.yml",
"action": "create",
"rule_module": "workflow_audit",
"severity": "high"
},
{
"reason": "Issue in scorecard-enforcer.yml",
"type": "scorecard_publish_with_run_step",
"file": "scorecard-enforcer.yml",
"action": "split_scorecard_publish_job",
"rule_module": "workflow_audit",
"severity": "high"
},
{
"reason": "Issue in instant-sync.yml",
"type": "secret_action_without_presence_gate",
"file": "instant-sync.yml",
"action": "peter-evans/repository-dispatch",
"rule_module": "workflow_audit",
"severity": "high"
},
{
"reason": "Required file missing (condition: public_repo)",
"type": "missing_requirement",
"file": ".github/workflows/scorecard.yml",
"action": "create",
"rule_module": "cicd_rules",
"severity": "high"
},
{
"reason": "TypeScript file detected -- banned language",
"type": "banned_language_file",
"file": "/home/runner/work/standards/standards/scripts/check-ts-allowlist.ts",
"action": "flag",
"rule_module": "cicd_rules",
"severity": "critical"
},
{
"reason": "Agda postulate assumes without proof -- potential soundness hole (4 occurrences, CWE-704)",
"type": "agda_postulate",
"file": "/home/runner/work/standards/standards/lol/proofs/theories/information_theory.agda",
"action": "flag",
"rule_module": "code_safety",
"severity": "critical"
},
{
"reason": "innerHTML assignment -- XSS risk, use textContent or SafeDOM (5 occurrences, CWE-79)",
"type": "js_innerhtml",
"file": "/home/runner/work/standards/standards/avow-protocol/public/demo.js",
"action": "flag",
"rule_module": "code_safety",
"severity": "high"
},
{
"reason": "innerHTML assignment -- XSS risk, use textContent or SafeDOM (1 occurrences, CWE-79)",
"type": "js_innerhtml",
"file": "/home/runner/work/standards/standards/axel-protocol/src/Tea.res.js",
"action": "flag",
"rule_module": "code_safety",
"severity": "high"
},
{
"reason": "Wildcard CORS -- restrict to specific origins or use env var (1 occurrences, CWE-942)",
"type": "js_wildcard_cors",
"file": "/home/runner/work/standards/standards/consent-aware-http/examples/reference-implementations/deno/aibdp_middleware.js",
"action": "flag",
"rule_module": "code_safety",
"severity": "high"
},
{
"reason": "HTTP URL in Nickel config -- must use HTTPS (1 occurrences, CWE-319)",
"type": "ncl_http_url",
"file": "/home/runner/work/standards/standards/k9-svc/register.ncl",
"action": "flag",
"rule_module": "code_safety",
"severity": "high"
}
]Powered by Hypatia Neurosymbolic CI/CD Intelligence |
hyperpolymath
pushed a commit
that referenced
this pull request
Jun 18, 2026
The merge of main into the PR branch changed a spec-home content hash; regenerated REGISTRY.a2ml via the sanctioned generator to clear the "Registry + topology in sync" check on #390. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019awZjBD1qx61tvmEuEKNpn
🔍 Hypatia Security ScanFindings: 148 issues detected
View findings[
{
"reason": "Issue in scorecard.yml",
"type": "missing_workflow",
"file": "scorecard.yml",
"action": "create",
"rule_module": "workflow_audit",
"severity": "high"
},
{
"reason": "Issue in scorecard-enforcer.yml",
"type": "scorecard_publish_with_run_step",
"file": "scorecard-enforcer.yml",
"action": "split_scorecard_publish_job",
"rule_module": "workflow_audit",
"severity": "high"
},
{
"reason": "Issue in instant-sync.yml",
"type": "secret_action_without_presence_gate",
"file": "instant-sync.yml",
"action": "peter-evans/repository-dispatch",
"rule_module": "workflow_audit",
"severity": "high"
},
{
"reason": "Required file missing (condition: public_repo)",
"type": "missing_requirement",
"file": ".github/workflows/scorecard.yml",
"action": "create",
"rule_module": "cicd_rules",
"severity": "high"
},
{
"reason": "TypeScript file detected -- banned language",
"type": "banned_language_file",
"file": "/home/runner/work/standards/standards/scripts/check-ts-allowlist.ts",
"action": "flag",
"rule_module": "cicd_rules",
"severity": "critical"
},
{
"reason": "Agda postulate assumes without proof -- potential soundness hole (4 occurrences, CWE-704)",
"type": "agda_postulate",
"file": "/home/runner/work/standards/standards/lol/proofs/theories/information_theory.agda",
"action": "flag",
"rule_module": "code_safety",
"severity": "critical"
},
{
"reason": "innerHTML assignment -- XSS risk, use textContent or SafeDOM (5 occurrences, CWE-79)",
"type": "js_innerhtml",
"file": "/home/runner/work/standards/standards/avow-protocol/public/demo.js",
"action": "flag",
"rule_module": "code_safety",
"severity": "high"
},
{
"reason": "innerHTML assignment -- XSS risk, use textContent or SafeDOM (1 occurrences, CWE-79)",
"type": "js_innerhtml",
"file": "/home/runner/work/standards/standards/axel-protocol/src/Tea.res.js",
"action": "flag",
"rule_module": "code_safety",
"severity": "high"
},
{
"reason": "Wildcard CORS -- restrict to specific origins or use env var (1 occurrences, CWE-942)",
"type": "js_wildcard_cors",
"file": "/home/runner/work/standards/standards/consent-aware-http/examples/reference-implementations/deno/aibdp_middleware.js",
"action": "flag",
"rule_module": "code_safety",
"severity": "high"
},
{
"reason": "HTTP URL in Nickel config -- must use HTTPS (1 occurrences, CWE-319)",
"type": "ncl_http_url",
"file": "/home/runner/work/standards/standards/k9-svc/register.ncl",
"action": "flag",
"rule_module": "code_safety",
"severity": "high"
}
]Powered by Hypatia Neurosymbolic CI/CD Intelligence |
hyperpolymath
disabled auto-merge
June 18, 2026 12:07
hyperpolymath
enabled auto-merge (squash)
June 18, 2026 13:16
hyperpolymath
disabled auto-merge
June 18, 2026 13:19
hyperpolymath
enabled auto-merge (squash)
June 18, 2026 13:34
hyperpolymath
disabled auto-merge
June 18, 2026 13:34
hyperpolymath
force-pushed
the
claude/hopeful-babbage-pn0l4o
branch
from
June 18, 2026 13:47
fad601b to
388f3fe
Compare
🔍 Hypatia Security ScanFindings: 148 issues detected
View findings[
{
"reason": "Issue in scorecard.yml",
"type": "missing_workflow",
"file": "scorecard.yml",
"action": "create",
"rule_module": "workflow_audit",
"severity": "high"
},
{
"reason": "Issue in scorecard-enforcer.yml",
"type": "scorecard_publish_with_run_step",
"file": "scorecard-enforcer.yml",
"action": "split_scorecard_publish_job",
"rule_module": "workflow_audit",
"severity": "high"
},
{
"reason": "Issue in instant-sync.yml",
"type": "secret_action_without_presence_gate",
"file": "instant-sync.yml",
"action": "peter-evans/repository-dispatch",
"rule_module": "workflow_audit",
"severity": "high"
},
{
"reason": "Required file missing (condition: public_repo)",
"type": "missing_requirement",
"file": ".github/workflows/scorecard.yml",
"action": "create",
"rule_module": "cicd_rules",
"severity": "high"
},
{
"reason": "TypeScript file detected -- banned language",
"type": "banned_language_file",
"file": "/home/runner/work/standards/standards/scripts/check-ts-allowlist.ts",
"action": "flag",
"rule_module": "cicd_rules",
"severity": "critical"
},
{
"reason": "Agda postulate assumes without proof -- potential soundness hole (4 occurrences, CWE-704)",
"type": "agda_postulate",
"file": "/home/runner/work/standards/standards/lol/proofs/theories/information_theory.agda",
"action": "flag",
"rule_module": "code_safety",
"severity": "critical"
},
{
"reason": "innerHTML assignment -- XSS risk, use textContent or SafeDOM (5 occurrences, CWE-79)",
"type": "js_innerhtml",
"file": "/home/runner/work/standards/standards/avow-protocol/public/demo.js",
"action": "flag",
"rule_module": "code_safety",
"severity": "high"
},
{
"reason": "innerHTML assignment -- XSS risk, use textContent or SafeDOM (1 occurrences, CWE-79)",
"type": "js_innerhtml",
"file": "/home/runner/work/standards/standards/axel-protocol/src/Tea.res.js",
"action": "flag",
"rule_module": "code_safety",
"severity": "high"
},
{
"reason": "Wildcard CORS -- restrict to specific origins or use env var (1 occurrences, CWE-942)",
"type": "js_wildcard_cors",
"file": "/home/runner/work/standards/standards/consent-aware-http/examples/reference-implementations/deno/aibdp_middleware.js",
"action": "flag",
"rule_module": "code_safety",
"severity": "high"
},
{
"reason": "HTTP URL in Nickel config -- must use HTTPS (1 occurrences, CWE-319)",
"type": "ncl_http_url",
"file": "/home/runner/work/standards/standards/k9-svc/register.ncl",
"action": "flag",
"rule_module": "code_safety",
"severity": "high"
}
]Powered by Hypatia Neurosymbolic CI/CD Intelligence |
hyperpolymath
added a commit
that referenced
this pull request
Jun 27, 2026
…up to #390) (#433) ## Summary Discharges the licence-guardrail flag that **#390** raised and explicitly left for the owner: > 🔒 Flagged for owner (NOT changed — licence guardrail): `rsr-audit.sh` > hardcodes `MIT AND Palimpsest` as the required LICENSE content, which > contradicts the estate's MPL-2.0-for-sole-owner policy. Updating what > licence the standard mandates is an owner decision — left as-is. The owner has now approved the change (MPL-2.0 for code, CC-BY-SA-4.0 for prose docs, per estate policy). This PR makes only that one owner-gated edit. ## Change `rsr-audit.sh` Category-2 (documentation) and Category-7 (licensing) checks previously required every **audited** repo's LICENSE to contain `MIT` + `Palimpsest` with `SPDX-License-Identifier: MIT AND Palimpsest`. Under the estate's five-way licence policy, sole-owner repos are **MPL-2.0** and the Palimpsest carve-out is reserved for exactly three repos (`palimpsest-license`, `palimpsest-plasma`, `consent-aware-http`). So every correctly-MPL-2.0 repo was failing two licensing criteria. Both checks now: - expect **`Mozilla Public License`** + **`SPDX-License-Identifier: MPL-2.0`**; - accept either **`LICENSE`** or **`LICENSE.txt`** (matching #390's bare-`LICENSE` tolerance). ## Not touched (deliberate) - The RSR toolkit's **own** header `# SPDX-License-Identifier: MPL-2.0 AND Palimpsest-0.8` (line 2) is the framework's intentional dual-licence — it is the auditing tool's licence, not an audited target. Unchanged. - No SPDX header was swept anywhere; this is a single logic edit to the audit script's expectations, per the per-file / no-bulk-sweep mandate. ## Effect Removes two false-negative licensing failures from the self-audit of every correctly-MPL-2.0 estate repo, nudging Bronze scores upward across the board without changing any audited repo's actual licence. 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_019awZjBD1qx61tvmEuEKNpn --- _Generated by [Claude Code](https://claude.ai/code/session_019awZjBD1qx61tvmEuEKNpn)_ --------- Co-authored-by: Claude <noreply@anthropic.com>
hyperpolymath
added a commit
that referenced
this pull request
Jun 27, 2026
…meline check (#440) Two related licence-/RSR-housekeeping changes, both owner-requested. ## 1. `docs/migrations/pmpl-to-mpl-sweep-runbook.adoc` (new) A durable home for the estate-wide **PMPL → MPL-2.0 sweep runbook** — the delegation brief produced during this licence-cleanup pass, so a future (desktop / scope-expanded) agent can execute the actual flips correctly. Contents: - **Complete classified inventory** of stray `SPDX-License-Identifier: PMPL-1.0[-or-later]` headers across the org (248+ matches, 9 repos, deduplicated), mapped onto the estate's 5-way licence policy. - **Net actionable surface = 22 files / 4 repos:** `developer-ecosystem`, `email-octad-experiment`, `nextgen-databases` → MPL-2.0 (code) / CC-BY-SA-4.0 (prose); **`idaptik` → AGPL-3.0-or-later** (son-shared — explicitly *not* MPL). - **Bulk is legitimate or must-not-touch:** 200 files in the `palimpsest-*` carve-outs, 5 in `007` (ARR), ~60 in vendored `rescript/` forks, plus licence-exhibit text. - **`nextgen-databases` resolved** (its `rescript/` dirs are estate-authored VeriSimDB/Lithoglyph *clients*, not the vendored compiler → in scope). - **Phase-2 inventory:** 236 template-propagated body-text `License: PMPL` declarations (fix at the scaffold source, not 236× by hand) + 25 banned `MPL-2.0-or-later`. - **Flags `panll`'s governance conflict** (body-text PMPL + a `CLAUDE.md` that still mandates PMPL) for owner decision. - **Per-file discipline + capabilities/access spec** for the delegated agent. This doc is **FLAG-AND-PLAN only** — it performs no licence change. CC-BY-SA-4.0 from birth (prose), per the estate code/prose split. ## 2. `rsr-audit.sh` — de-brittle the SECURITY response-timeline check Category-2's check required the exact literal substring **"24 hours"** in `SECURITY.md`, failing repos that document the same SLA differently (a "Response Timeline" heading, "48 hours", "business day", …). Broadened to a basic-grep alternation covering the common phrasings, mirroring the format/case de-brittling #390 already did elsewhere. **Licence-content checks untouched.** `standards`' own `SECURITY.md` (Response Timeline / 48 hours) now passes where it previously failed — one of the 3 residual fails #390 flagged. Registry regenerated (`rhodium-standard-repositories/` is a registered spec home, so editing `rsr-audit.sh` changes its content-addressed `source_hash`). --- Note: as on #430–#433, the pre-existing `governance / Validate Hypatia Baseline` red is repo-wide and token-degraded — not introduced by this diff. 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_019awZjBD1qx61tvmEuEKNpn --- _Generated by [Claude Code](https://claude.ai/code/session_019awZjBD1qx61tvmEuEKNpn)_ --------- Co-authored-by: Claude <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
The standards RSR compliance pass — continuation of the standards end-to-end (the Idris ABI fix landed separately in #389). Takes the standards self-audit from 58.46% → 85.92% (🥉 BRONZE).
1. Real gaps (additive) —
feat(rsr).well-known/security.txt(RFC 9116: Contact/Expires/Preferred-Languages → GitHub Security Advisory + SECURITY.md).well-known/ai.txt(AI usage/training policy; summary of the estate bot-exclusion registry +0-ai-gatekeeper-protocol).well-known/humans.txt(humanstxt.org attribution)validaterecipe (registry-check hard-dep + RSR self-audit)2. Audit-script de-brittle —
fix(rsr-audit)rsr-audit.shwas mis-calibrated for this GitHub/.adocestate, failing repos on deliberate, policy-correct choices. De-brittled format/case only in the two core helpers + the CI check — licence content checks untouched:.adocdocs (estate docs policy mandates AsciiDoc),Justfilecase, bareLICENSE.github/workflows/*.y*ml) as first-class (not just GitLab CI / a hardcodedci.yml) — the estate runs on GitHub; the RSR satelliteCLAUDE.mditself notes the old GitLab guidance is superseded.Improves scoring for all 10 estate repos, not just standards.
🔒 Flagged for owner (NOT changed — licence guardrail)
rsr-audit.shhardcodesMIT AND Palimpsestas the required LICENSE content (≈ lines 194/424/430), which contradicts the estate's MPL-2.0-for-sole-owner policy. Updating what licence the standard mandates is an owner decision — left as-is.Residual (honest)
3 checks still fail, all content-pattern brittleness for content the estate phrases differently: SECURITY "24 hours" literal (standards has a Response Timeline section), the exact TPCF perimeter strings, and "fork workflow" (standards uses the TPCF perimeter model, not a fork workflow). BRONZE (≥75%) is achieved; these can be de-brittled in a follow-up.
🤖 Generated with Claude Code
https://claude.ai/code/session_019awZjBD1qx61tvmEuEKNpn
Generated by Claude Code