ci: enforce prettier format:check + stop tracking hook cache - #180
Merged
Conversation
Root-cause fixes for chronic format drift on main: - Add a "Format check" step to the CI verify job (a required status check), so unformatted code can no longer merge. Previously verify ran lint/typecheck/test/build but not format:check, letting drift accumulate every merge. - Reformat the 17 files that had already drifted, so the new gate passes on a clean tree (whitespace only; prettier is deterministic so this is conflict-safe with the standalone cleanup in #177). - Stop tracking .impeccable/hook.cache.json (a machine-local hook cache): gitignore the dir, add it to .prettierignore, and git rm --cached the file so it stops churning diffs. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…test) tests/worker-visual-capture.test.ts asserts on the exact source text of worker/main.ts (line-level guards on redaction/normalization order). Prettier wraps a long line there, which broke the test's .toContain and failed the new format gate's own verify run. Prettier-ignore the file and restore it to main's layout so both the test and format:check pass. This is the same wall the standalone cleanup in #177 hits. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This was referenced Jul 2, 2026
BigSimmo
added a commit
that referenced
this pull request
Jul 2, 2026
docs/source-review-priority-2026-07-02.md predates #180's format:check enforcement and failed the verify Format check step. No content change. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
3 tasks
BigSimmo
added a commit
that referenced
this pull request
Jul 2, 2026
#180 excluded worker/main.ts from prettier because tests/worker-visual-capture.test.ts asserts on its exact source text, and prettier line-wrapping broke one assertion. Instead of a permanent carve-out, format the file and make that one assertion formatting-agnostic (match two stable substrings), so worker/main.ts is covered by the format gate like every other source file. Only 3 lines reformat (prettier is deterministic, whitespace only); only the structuredProfile source-guard assertion needed loosening. The file's other source guards are unaffected. Full worker-visual-capture suite passes. Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
4 tasks
2 tasks
BigSimmo
added a commit
that referenced
this pull request
Jul 31, 2026
#179: the full catalogue silently went from a single minified line to 18,400 pretty-printed ones when the modality scrub routed it through syncTarget. Measured +123 KB raw but only +3.4 KB gzipped, so the real cost is ~37,000 lines of git churn per data revision — set against reviewable diffs on a 205-record clinical dataset, which is probably the better trade. Recorded so the format is a decision rather than a side effect. #180: that same change made the generator write its curated output back over the file it reads as source. It is stable only because curatedModality is a fixed point, and it matters because #175 asks someone to hand-curate modality values in exactly that file — an edit the next run could discard with no gate to catch it, since --check compares against what the generator would produce. Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
BigSimmo
pushed a commit
that referenced
this pull request
Aug 12, 2026
…e-local rows Archived: #179 (compact catalogue restored AND gated at build-therapies-index .mjs:240-244). Re-measured: #213 (only 3 empty catches left), #180 (re-confirmed live with exact source/target lines), #275. Annotated four machine-local rows (#152, #169, #236, #260) so a cloud session cannot mistake a fresh container for evidence and close them wrongly. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017paT42ZVMf8jaLtkjFxdy5
BigSimmo
added a commit
that referenced
this pull request
Aug 13, 2026
…#180) and serve aliases by rewrite (#177) (#1886) * fix(therapies): stop the catalogue generator consuming its own output build-therapies-index.mjs read public/therapy-compass-data/therapies.json as its source and also wrote that same path as legacyFullTarget. Source and target were one file, so every run consumed its own output. That was not merely untidy. curatedFull nulls every tag-echo modality (curatedModality), so the first run overwrote the author's raw modality values with the scrubbed ones, and every later run re-read the scrubbed copy. It survived only because the scrub happens to be idempotent — the raw input was still destroyed, recoverable from git history alone. Move the hand-edited catalogue to src/data/therapies-source.json, outside the directory this generator writes, and read only from there. The file in public/therapy-compass-data/ is now output, never input. Also add the new path to .prettierignore. At its old path it was covered by the public/therapy-compass-data/ entry; without an entry Prettier pretty-prints the compact single-line catalogue into ~17k lines, which is the churn #179 fixed on the generated side. Verified: regenerated output is byte-identical to the previous alias (hashed filenames unchanged), the source stays byte-identical to its original across two further re-runs, check:therapy-data-index passes, and the 28 therapy contract tests pass. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01STG6AU5J4gxrFJagP4pRti * perf(therapies): serve catalogue aliases by rewrite instead of duplicating bytes public/therapy-compass-data/ shipped each catalogue twice: therapies.json, therapies-index.json and therapies-home.json were written byte-identical to their content-addressed twin. Git stores one blob per identical pair, so history was unaffected, but the working tree and every Docker image carried both — 2.81 MB, and 5.34 MB while the one-deploy grace generation is retained. The alias URLs themselves are load-bearing: useTherapyData falls back to them when a bundle older than the grace generation names a hashed file that no longer exists, so they cannot simply be dropped. Serve them from next.config.ts rewrites onto the current hashed filename instead, and stop writing the files. afterFiles rather than beforeFiles: no file exists at the alias paths now, so the rewrite is reached once the static handler finds nothing, and nothing legitimate is shadowed. build-therapies-index.mjs --check now fails if an alias file reappears, since a real file would win over an afterFiles rewrite and then go stale at the next regeneration. The generator writes content-addressed assets directly from the generated bytes rather than copying a just-written alias, so projectionBytes/fullCatalogueBytes are now the single definition of each payload's exact bytes. Verified against a running server: all three alias URLs return 200 with content byte-identical to their hashed asset; aliases keep Cache-Control max-age=0, must-revalidate while the hashed asset keeps max-age=31536000, immutable, so the alias does not inherit the destination's immutable policy; the retained grace generation still returns 200. Hashed filenames are unchanged by this refactor, proving the direct-write path is byte-identical. public/therapy-compass-data/ drops from 8.0M to 5.3M. npm run build succeeds and the stray-alias guard fires. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01STG6AU5J4gxrFJagP4pRti * docs(issues): close #180 and #177, and correct the paths they moved Both rows are resolved by the two preceding commits. Also corrects three rows that cited the catalogue paths this work moved — docs:check-links caught them. #175 mattered most: it instructed a future reader to curate modality values in public/therapy-compass-data/therapies.json, which no longer exists. It now names src/data/therapies-source.json, the only hand-edited catalogue file. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01STG6AU5J4gxrFJagP4pRti * docs(ledger): record the review for this branch Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01STG6AU5J4gxrFJagP4pRti * fix: ship generated therapy assets with app runner * test: cover every next config runner import * fix(docs): update therapy catalogue references * fix(ci): reconcile therapy docs with ledger inbox --------- Co-authored-by: Claude <noreply@anthropic.com>
8 tasks
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
Durable fixes for two recurring hygiene issues on main.
1. Format drift can no longer merge. The CI
verifyjob ran lint/typecheck/test/build but neverformat:check, andformat:checkwas not a required status check — so every merge could reintroduce prettier drift (which is why the repo kept needing manual cleanup passes). This adds a Format check step to theverifyjob. Sinceverifyis already a required check, formatting is now enforced at the gate, not chased after the fact.To make the new gate pass on a clean tree, the 17 files that had already drifted are reformatted here (whitespace only). Prettier is deterministic, so this is byte-identical to — and therefore conflict-safe with — the standalone cleanup in #177. If this merges, #177 becomes redundant and can be closed; if #177 merges first, the reformat here no-ops.
2.
.impeccable/hook.cache.jsonno longer tracked. It's a machine-local hook-tool cache that was accidentally committed (same class as thescratch/debris removed in #148) and churned diffs — prettier even tried to reformat it during a merge. Now gitignored, prettier-ignored, andgit rm --cached.Verification
npm run format:check— passes on the cleaned tree (failed on main before)npm run typecheck— cleanverifyjob now includes theFormat checkstep;.github/workflows/ci.ymlvalidated as YAMLverify:ui— N/A: reformats are whitespace-only, no UI/routing/styling behavior changeClinical Governance Preflight
N/A — no ingestion, answer-generation, search/ranking, source-rendering, document-access, privacy, or clinical-output behavior changes. Source edits are prettier whitespace only; the functional changes are CI config and
.gitignore/.prettierignore.Notes
allow_auto_merge/allow_update_branch) is already enabled; the required-status-checks strict-up-to-date policy is being flipped on ruleset 18011271 separately.🤖 Generated with Claude Code