Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .claude/skills/gates/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ Check these before believing any result.
for exactly this reason — if installed packages do not match `package-lock.json`, treat any test,
lint, or typecheck result as void until `npm ci` has run. Its own failure message says as much.
- **`verify:cheap` stops at the first failing check.** Everything after that point never ran. Do not
describe the change as broadly verified when the gate died at check 2 of 38.
describe the change as broadly verified when the gate died at check 2 of 39.
- **Changed-file formatting is required in CI but is not part of `verify:cheap`.** A locally green
`verify:cheap` can still fail CI on formatting. During iteration, format only task-owned files.
Before a push, follow `AGENTS.md`: from an isolated or otherwise fully owned worktree run
Expand Down
7 changes: 7 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -399,6 +399,13 @@ jobs:
if: needs.changes.outputs.static_heavy_changed == 'true'
run: npm run check:mha-act-sections

# Derives sha256/bytes/passwordProtected from the committed form PDFs. The badge a
# clinician reads before relying on a statutory form must match the file on disk;
# a hand-maintained flag had nothing checking it against the bytes.
- name: Forms PDF manifest drift
if: needs.changes.outputs.static_heavy_changed == 'true'
run: npm run check:forms-pdf-manifest

- name: Design-system contract
if: needs.changes.outputs.static_heavy_changed == 'true'
run: npm run check:design-system-contract
Expand Down
2 changes: 1 addition & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ Verification pyramid — run the **smallest gate that covers the change**, then
| Gate | What it is |
| ----------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `npm run test:focused -- --files <paths>` | Source-only iteration. Fails closed for deleted files and test infrastructure — then run `npm run test`. |
| `npm run verify:cheap` | The broad local gate: 35 static/consistency gates + `lint` + `typecheck` + full offline unit suite; use for cross-module risk, not automatically |
| `npm run verify:cheap` | The broad local gate: 36 static/consistency gates + `lint` + `typecheck` + full offline unit suite; use for cross-module risk, not automatically |
| `npm run verify:pr-local` | Risk-routed PR mirror: focused docs/workflow contracts for recognised light scope, fail-closed heavy checks for executable or unknown scope. `-- --dry-run --files <paths>` shows selection. |
| `npm run verify:ui` | Chromium production journeys. Run `npm run ensure` first. |
| `npm run verify:phone-chrome` | Phone-chrome changes; selects affected owners/journeys before escalating to `verify:ui` |
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"version": 2,
"id": "e49dd511-974f-4f7e-af2c-e399b1c147ec",
"createdOn": "2026-09-02",
"action": "done",
"payload": {
"id": "#9P4XAE",
"outcome": "Resolved 2026-09-02 on branch claude/form-12a-warning. The 12A data defect was already corrected before this work: data/forms-pdf-manifest.json recorded passwordProtected false and tests/forms.test.ts pinned it. The outstanding half — a measured generation/validation workflow deriving the flag from committed PDF bytes — is what landed. scripts/build-forms-pdf-manifest.mjs derives sha256, bytes and passwordProtected offline from public/forms-pdf/, with a --check mode wired into verify:cheap:internal and CI as check:forms-pdf-manifest. The flag is derived by attempting to open each PDF with an empty user password, not by looking for an /Encrypt marker, because a PDF with an owner password and an empty user password carries /Encrypt yet opens freely. Every error path fails closed to passwordProtected true plus a hard non-zero exit. Regeneration reproduces the committed manifest byte for byte. tests/forms.test.ts now asserts the generated contract, keeps every prior assertion, and adds a synthetic owner-password-only fixture that is the only test which fails if the deriver is ever simplified to an /Encrypt grep.",
"baseRowFingerprint": "e85f7e6b68571acafd0cfe331ea7f28241e56a2c997cd8e52f5a8e503344fd5c"
}
}
4 changes: 3 additions & 1 deletion docs/scripts-index.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Scripts index

Curated map of `scripts/` (286 files) and the `package.json` script surface (291 entries),
Curated map of `scripts/` (287 files) and the `package.json` script surface (292 entries),
grouped by purpose. This is orientation, not an exhaustive per-file listing — the authoritative
command list is `package.json`, and `npm run docs:check-scripts` verifies every `npm run <x>`
referenced in docs resolves to a real script. `npm run docs:update` refreshes the exact counts above.
Expand Down Expand Up @@ -137,6 +137,8 @@ preserved, in which case generated assets return to their exact pre-review state

`build-worker.mjs`, `build-analyze.mjs`, `build-therapies-index.mjs`,
`build-cross-mode-differentials-index.mjs`, `build-ranking-snapshot.ts`,
`build-forms-pdf-manifest.mjs` (`check:forms-pdf-manifest` — derives each committed WA MHA form
PDF's sha256, size, and whether opening it needs a user password; offline, fails closed),
`generate-site-map.ts`, `generate-brand-assets.ts`, `generate-sample-documents.ts`,
`check-sample-extraction.ts`, `optimize-public-images.mjs`.

Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@
"clean:worktree": "npm run worktrees:report",
"verify:preflight": "npm run check:installed-lock-parity && npm run typecheck && npm run verify:cheap && npm run worktrees:report -- --self-test",
"verify:cheap": "npm run verify:cheap:internal",
"verify:cheap:internal": "npm run check:runtime && npm run check:installed-lock-parity && npm run check:upload-limit-parity && npm run check:github-actions && npm run check:ci-scope && npm run check:verification-plan && npm run check:gitleaks-pinned && npm run check:ci-triage && npm run check:pr-policy && npm run check:gate-manifest && npm run check:skills && npm run check:branch-review-ledger && npm run check:outstanding-issues && npm run check:ledger-write-discipline && npm run check:diff-integrity && npm run check:pr-mergeability && npm run sitemap:check && npm run check:repo-awareness-snapshot && npm run docs:check-index && npm run docs:check-inventory && npm run docs:check-scripts && npm run docs:check-links && npm run check:knip && npm run check:maintainability-budgets && npm run brand:check && npm run check:assets && npm run check:therapy-data-index && npm run check:cross-mode-index && npm run check:mha-act-sections && npm run check:type-scale && npm run check:icon-scale && npm run check:design-system-contract && npm run check:migration-role && npm run check:function-grants && npm run check:owner-scope && npm run lint && npm run typecheck && npm run test",
"verify:cheap:internal": "npm run check:runtime && npm run check:installed-lock-parity && npm run check:upload-limit-parity && npm run check:github-actions && npm run check:ci-scope && npm run check:verification-plan && npm run check:gitleaks-pinned && npm run check:ci-triage && npm run check:pr-policy && npm run check:gate-manifest && npm run check:skills && npm run check:branch-review-ledger && npm run check:outstanding-issues && npm run check:ledger-write-discipline && npm run check:diff-integrity && npm run check:pr-mergeability && npm run sitemap:check && npm run check:repo-awareness-snapshot && npm run docs:check-index && npm run docs:check-inventory && npm run docs:check-scripts && npm run docs:check-links && npm run check:knip && npm run check:maintainability-budgets && npm run brand:check && npm run check:assets && npm run check:therapy-data-index && npm run check:cross-mode-index && npm run check:mha-act-sections && npm run check:forms-pdf-manifest && npm run check:type-scale && npm run check:icon-scale && npm run check:design-system-contract && npm run check:migration-role && npm run check:function-grants && npm run check:owner-scope && npm run lint && npm run typecheck && npm run test",
"verify:pr-local": "node scripts/verify-pr-local.mjs",
"verify:phone-chrome": "node scripts/verify-phone-chrome.mjs",
"plan:browser": "node scripts/browser-test-plan.mjs",
Expand Down Expand Up @@ -147,6 +147,7 @@
"check:therapy-data-index": "node scripts/build-therapies-index.mjs --check",
"check:cross-mode-index": "node scripts/build-cross-mode-differentials-index.mjs --check",
"check:mha-act-sections": "node scripts/build-mha-act-sections.mjs --check",
"check:forms-pdf-manifest": "node scripts/build-forms-pdf-manifest.mjs --check",
"check:runtime": "node scripts/run-tsx.mjs scripts/check-runtime.ts",
"check:source-catalogue": "node scripts/run-tsx.mjs scripts/check-source-catalogue.ts",
"check:installed-lock-parity": "node scripts/check-installed-lock-parity.mjs",
Expand Down
Loading
Loading