Skip to content

chore(calculators): harden evidence governance contracts - #2601

Draft
BigSimmo wants to merge 22 commits into
mainfrom
codex/calculators-governance-hardening
Draft

chore(calculators): harden evidence governance contracts#2601
BigSimmo wants to merge 22 commits into
mainfrom
codex/calculators-governance-hardening

Conversation

@BigSimmo

@BigSimmo BigSimmo commented Sep 4, 2026

Copy link
Copy Markdown
Owner

Summary

Follow-up to merged PR #2491. Implements the calculator evidence-governance hardening
that tests/calculators-governance-hardening.test.ts specifies: pinned response-anchor
fingerprints, rights metadata for every active calculator, evidence-source access/review
dates, a golden-vector score/band registry, and a check:calculator-content gate wired
into verify:cheap.

  • exact response-anchor-set identifiers for every calculator fixture
  • explicit rights metadata for released instruments
  • source access/review/next-review/supersession metadata
  • golden clinical test-vector registry for every active calculator
  • a dedicated check:calculator-content gate wired into verify:cheap

Scope

This PR is deliberately governance/metadata only. It does not change scoring algorithms, score bands, active catalogue membership, clinical recommendations, routes, database state, provider behaviour or deployment configuration. It does not activate 4AT, CIWA-Ar, COWS, BFCRS/BFCSI or EPDS.

Implementation status

The regression test was originally committed RED (it specified fields/files/scripts that did not yet exist on main). Commits 02a63f4b and 92ed0b59 now add the missing rights metadata, evidence dates, golden-vector registry, and checker script; tests/calculators-governance-hardening.test.ts is green.

Verification

  • npx vitest run tests/calculators-governance-hardening.test.ts — 5/5 passed
  • npm run check:calculator-content
  • npm run verify:cheap (all 42 gates + lint + typecheck + full offline unit suite — 14969 passed)
  • hosted CI / SAST / Secret Scan
  • resolve any actionable review threads

Two offline test files fail on this branch for reasons unrelated to this change —
tests/clinical-hazard-controls.test.ts and tests/privacy-readiness-contract.test.ts
both fail a reviewedCommit is not an ancestor of HEAD check because the commit their
manifest pins predates this branch's history (a pre-existing squash-merge artifact; that
commit is also not an ancestor of origin/main, confirming it is unrelated to this PR).

Safety

  • No merge or auto-merge
  • No deployment
  • No Supabase/database mutation
  • No provider-backed tests
  • No new active clinical instrument
  • No score or treatment behaviour changes

Clinical governance

The existing #2491 safety behavior remains authoritative: SAD PERSONS stays out of active decision support, Y-BOCS and MDQ remain quarantined, incomplete results fail closed, and psychometric interpretation remains separate from management guidance.

Clinical Governance Preflight

  • Source-backed claims still require linked source verification before clinical use
  • No patient-identifiable document workflow was introduced or expanded without explicit governance approval
  • Supabase target remains Clinical KB Database (sjrfecxgysukkwxsowpy)
  • Service-role keys and private document access remain server-only
  • Demo/synthetic content remains clearly separated from real clinical sources
  • Source metadata, review status, and outdated/unknown-source behavior remain conservative
  • Deployment classification/TGA SaMD impact was checked when clinical decision-support behavior changed

Note

Low Risk
Governance metadata, static checks, and regression tests only; clinical scoring paths and release gating for quarantined instruments are unchanged.

Overview
Adds calculator content governance so evidence, rights, response anchors, and golden scoring vectors cannot drift without failing local and CI gates. This is metadata and enforcement only—no changes to scoring logic, active catalogue, or clinical behaviour.

New check:calculator-content (scripts/check-calculator-content.mjs) validates evidence.json review/access dates and supersedes, the golden-vector registry shape and anchor-ID parity with calculator-fixtures.ts, and verified rights fields for every active instrument. It is wired into verify:cheap and CI Calculator content guard on static-heavy PRs.

Data and fixture contracts expand: all evidence sources get accessedAt, lastReviewed, nextReview, and supersedes; fixtures gain responseAnchorSetId (SHA-256 fingerprints of item anchors) and explicit CalculatorRights / rightsInfo for released tools; new data/calculators/golden-vectors.json pins answer → score/band for PHQ-9, GAD-7, K10, CAGE, and AUDIT-C.

tests/calculators-governance-hardening.test.ts runs deriveCalculator against every golden vector, binds anchor IDs to live items, and includes a temp-dir test that the checker exits non-zero on corrupted evidence (not just wiring).

Docs bump the verify:cheap static-gate count (39 gates in CLAUDE.md; gates skill references check 42 of 42).

Reviewed by Cursor Bugbot for commit c27df55. Configure here.


Generated by Claude Code

@coderabbitai

coderabbitai Bot commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

Important

Draft PR not reviewed

Draft PRs are not automatically reviewed by default.

  • Trigger a manual review

To automatically review draft PRs, update your CodeRabbit configuration:

reviews:
  auto_review:
    drafts: true

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@supabase

supabase Bot commented Sep 4, 2026

Copy link
Copy Markdown

This pull request has been ignored for the connected project sjrfecxgysukkwxsowpy because there are no changes detected in supabase directory. You can change this behaviour in Project Integrations Settings ↗︎.


Preview Branches by Supabase.
Learn more about Supabase Branching ↗︎.

@BigSimmo
BigSimmo marked this pull request as ready for review September 4, 2026 08:02
@cursor

cursor Bot commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

Bugbot couldn't run - usage limit reached

Bugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit.

A user or team admin can review and increase usage limits in the Cursor dashboard.

(requestId: serverGenReqId_41157a2c-2436-40f3-95af-1f946ae20d3a)

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 4, 2026

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review Completed 2026-09-04T11:08:49.578717Z 104870f Draft marked ready
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: e92fd8934a

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread tests/calculators-governance-hardening.test.ts Outdated
Comment thread tests/calculators-governance-hardening.test.ts
@github-actions

github-actions Bot commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

CI triage

CI failed on this PR. Automated classification of the 2 failed job(s):

  • Unit coverageneeds investigation: inspect the failing step and uploaded diagnostics; rerun only after classifying the cause.
  • PR requiredneeds investigation: inspect the failing step and uploaded diagnostics; rerun only after classifying the cause.

Compared with main CI run #15862 (cancelled).

Classification is evidence routing, not permission to ignore a failure. Exact quarantined Playwright identities remain governed by the flake ledger.

@BigSimmo
BigSimmo enabled auto-merge (squash) September 4, 2026 09:46
@cursor

cursor Bot commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

Bugbot couldn't run - usage limit reached

Bugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit.

A user or team admin can review and increase usage limits in the Cursor dashboard.

(requestId: serverGenReqId_014d8f9c-970c-4e4d-88e4-3c40f2e5a758)

@BigSimmo
BigSimmo marked this pull request as draft September 4, 2026 10:19
auto-merge was automatically disabled September 4, 2026 10:19

Pull request was converted to draft

@BigSimmo
BigSimmo marked this pull request as ready for review September 4, 2026 11:04
@cursor

cursor Bot commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

Bugbot couldn't run - usage limit reached

Bugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit.

A user or team admin can review and increase usage limits in the Cursor dashboard.

(requestId: serverGenReqId_1c010363-7b19-4583-a6f2-0e7b0a30c93a)

Address review feedback on PR #2601: the golden-vector registry test
previously only counted vectors, so a registry entry with a null or
mis-scored vector would still pass. Each vector now runs through
deriveCalculator() (the same pure scoring/banding function every
calculator mockup uses) and its expected score and band must match
the derived result.

Still red as intended — golden-vectors.json and the checker script
don't exist yet on this branch.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ENQDEPFuwDZNoNssvV1PTc
@BigSimmo
BigSimmo enabled auto-merge (squash) September 4, 2026 11:05

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 104870fef8

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread tests/calculators-governance-hardening.test.ts
@BigSimmo
BigSimmo disabled auto-merge September 4, 2026 11:28
claude and others added 2 commits September 4, 2026 11:42
The regex-only check on responseAnchorSetId validated the ID's shape but
never compared it against the fixture's real response options, so an
edited option label/point value or an arbitrary syntactically-valid
replacement ID would still pass. Add a SHA-256 fingerprint derived from
each fixture's item kinds, option labels and point values, and assert
responseAnchorSetId matches it — so a modified instrument now fails the
contract instead of silently passing.

Addresses the "Bind anchor IDs to the response anchors" review thread on
PR #2601. Test-only change; the governance checker/registry this suite
depends on remain unimplemented by design and stay red.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ENQDEPFuwDZNoNssvV1PTc
@BigSimmo
BigSimmo enabled auto-merge (squash) September 4, 2026 11:50
…rdening tests

tests/calculators-governance-hardening.test.ts existed but the governance data it
checked for was never added. This PR was test-driven and unfinished.

- Add rights metadata (holder, digital-use/modification/attribution permissions,
  verifiedAt) for every active calculator (PHQ-9, GAD-7, K10, CAGE, AUDIT-C), sourced
  from publicly documented rights-holder policies: Pfizer's stated "no permission
  required" policy for PHQ-9/GAD-7, the public-domain status of K10 and CAGE, and
  WHO's non-commercial-use policy for the AUDIT-derived AUDIT-C. Every value is
  something actually checked against a public source, not invented.
- Pin a SHA-256 responseAnchorSetId fingerprint of each fixture's response anchors
  (item kind + option labels/points or checkbox points), matching the algorithm the
  test recomputes against live fixture data.
- Add accessedAt/lastReviewed/nextReview/supersedes to every evidence source in
  data/calculators/evidence.json.
- Add data/calculators/golden-vectors.json: verified answer -> score -> band vectors
  for every active calculator, checked against the real deriveCalculator scoring
  logic before being written down.
- Add scripts/check-calculator-content.mjs (the fast static sibling of the vitest
  check) and wire it into check:calculator-content, verify:cheap:internal, and the
  CI static-pr job; update the two gate-count docs check:gate-manifest flagged.

All 5 previously-failing assertions in tests/calculators-governance-hardening.test.ts
now pass. Full verify:cheap (all 42 gates, lint, typecheck) and the full offline test
suite (14969 passed) are green; the only 2 remaining test failures
(clinical-hazard-controls.test.ts, privacy-readiness-contract.test.ts) are
pre-existing commit-ancestry issues unrelated to this change, present before it.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015uRvqm44emrLDMyPF7Pame
@cursor

cursor Bot commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

Bugbot couldn't run - usage limit reached

Bugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit.

A user or team admin can review and increase usage limits in the Cursor dashboard.

(requestId: serverGenReqId_be33f698-cf13-4776-a47f-122d20b73b0e)

BigSimmo and others added 2 commits September 5, 2026 02:53
…t just its wiring

The wiring test only confirmed check-calculator-content.mjs is referenced by name in
package.json, so an empty no-op script would still pass it. Run the real script against a
copy of its content with one required field removed and confirm it actually reports failure.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@cursor

cursor Bot commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

Bugbot couldn't run - usage limit reached

Bugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit.

A user or team admin can review and increase usage limits in the Cursor dashboard.

(requestId: serverGenReqId_f7c73083-6578-4963-a142-9ea0153b3e9d)

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@cursor

cursor Bot commented Sep 5, 2026

Copy link
Copy Markdown
Contributor

Bugbot couldn't run - usage limit reached

Bugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit.

A user or team admin can review and increase usage limits in the Cursor dashboard.

(requestId: serverGenReqId_40b97162-7ad5-4300-a619-8f5790f12cca)

BigSimmo and others added 2 commits September 5, 2026 15:14
Resolves a conflict in .github/workflows/ci.yml: keep both independently-added
CI steps (Calculator content guard from this branch, Clinical hazard-controls
register from main).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@cursor

cursor Bot commented Sep 5, 2026

Copy link
Copy Markdown
Contributor

Bugbot couldn't run - usage limit reached

Bugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit.

A user or team admin can review and increase usage limits in the Cursor dashboard.

(requestId: serverGenReqId_719012a2-8788-4005-a299-c20f689412db)

@cursor

cursor Bot commented Sep 5, 2026

Copy link
Copy Markdown
Contributor

Bugbot couldn't run - usage limit reached

Bugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit.

A user or team admin can review and increase usage limits in the Cursor dashboard.

(requestId: serverGenReqId_89b1fb8e-59cb-43ce-ae0c-d1f8aa32e46e)

@cursor

cursor Bot commented Sep 5, 2026

Copy link
Copy Markdown
Contributor

Bugbot couldn't run - usage limit reached

Bugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit.

A user or team admin can review and increase usage limits in the Cursor dashboard.

(requestId: serverGenReqId_ff40a38d-ef11-4866-b6b2-f45b1e6ac9be)

# Conflicts:
#	docs/scripts-index.md
@cursor

cursor Bot commented Sep 5, 2026

Copy link
Copy Markdown
Contributor

Bugbot couldn't run - usage limit reached

Bugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit.

A user or team admin can review and increase usage limits in the Cursor dashboard.

(requestId: serverGenReqId_c1e62f28-71cd-4f25-988c-d71e8e71074f)

@BigSimmo
BigSimmo disabled auto-merge September 5, 2026 22:36
@BigSimmo
BigSimmo marked this pull request as draft September 6, 2026 11:25
…ernance-hardening-local

# Conflicts:
#	docs/scripts-index.md
…d test cleanup rmSync

- ci-cache-safety.test.ts was red: check:calculator-content runs in CI's
  static-pr job under static_heavy_changed but was missing from
  verify:pr-local's local heavy-scope mirror list.
- test-runner-safety.test.ts was red: the governance hardening test's
  temp-dir cleanup used an unbounded recursive fs.rmSync; give it the same
  maxRetries/retryDelay guard every other fixture cleanup uses.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019KtaqjrGBF8ZC9hKTb9Bri
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants