diff --git a/CLAUDE.md b/CLAUDE.md index 4494ad1fab..46379fdad1 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -90,7 +90,7 @@ src/data/ Static clinical content (DSM, formulation, therapies indexes) data/ Generated clinical snapshot exports loaded at runtime — regenerate, never hand-edit supabase/ migrations/ (source of truth), schema.sql (mirror), functions/ worker/ Ingestion worker; worker/python/ is the OCR stack -scripts/ ~160 files backing 194 npm scripts: gates, eval, reindex, governance, dev +scripts/ gates, eval, reindex, governance, dev — counted and mapped in docs/scripts-index.md tests/ Vitest unit + Playwright E2E, side by side docs/ Runbooks, governance, plans; docs/README.md categorises them eslint-rules/ Repo-specific lint rules (see Conventions below) diff --git a/docs/branch-review-ledger.md b/docs/branch-review-ledger.md index 3b472b5a4e..cdb4b93382 100644 --- a/docs/branch-review-ledger.md +++ b/docs/branch-review-ledger.md @@ -253,6 +253,7 @@ Records before 2026-07-28 were written by hand and had drifted: 146 lines carrie | 2026-07-30 | PR #1477 | 20f795da2d9d0adafa6cb3117429ab3665129c0d | PR #1477 fork-safe Codex autofix routing | Refreshed onto current main after #1465; issue and ledger reconciliation remained clean and no new actionable defects were introduced. | check:outstanding-issues; check:branch-review-ledger; check:codex-autofix-workflow; focused Vitest 53 passed | | 2026-07-30 | PR #1480 | 6c1e76f53aee87be8408cebc295744fbdce05367 | PR #1480 bounded outstanding reliability fixes | Fixed both review findings: documented the dark accent role and added partial favourites retry without hiding valid counts; no other actionable defects found. | focused Vitest 119 passed; docs index; issue and ledger guards; Actions and Codex workflow guards; Prettier; diff check; typecheck coordinator-blocked | | 2026-07-30 | codex/close-pr1480-issues | bf8ac88b024642eb45d1fead86f4ee30fce3f98d | archive PR 1480 issue resolutions | approved: five resolved rows moved intact to archive | check:outstanding-issues; prettier check; diff check | +| 2026-07-30 | PR-1458 | 8c1975b178c67e4c54acffc395d85e38c43d39f5 | PR #1458 superseded root-gate reconciliation | PASS: retained only unique documentation corrections after PR #1480 landed the stronger tracked-root gate; archived resolved shared-hook issue #143 | docs index and links passed; outstanding-issues and branch-review-ledger guards passed; diff check passed | | 2026-07-30 | codex/close-issue-127 | 9bbb8486d399ed31b9bf43364579f466a4e66c67 | archive issue 127 after post-fix runs | approved: close condition satisfied with no post-fix recurrence | check:outstanding-issues; prettier check; diff check | | 2026-07-30 | codex/close-issue-127 | d5fd28f75b404046f13507aa3705d55898d7669c | review finding wording correction | approved: causal wording now matches PR 1427 implementation | check:outstanding-issues; prettier check; diff check | | 2026-07-30 | PR-1469 | 02108d5424f8a3ab50f45808a6cc3cbd872e7555 | PR #1469 component state matrix coverage | PASS after current-main sync; tests execute enabled and disabled popup transitions plus document search loading, empty, and fault states | focused Vitest 2 files, 10 tests passed; outstanding-issues and branch-review-ledger guards passed; no unresolved review threads | diff --git a/docs/outstanding-issues.md b/docs/outstanding-issues.md index 3ea8f0a3ef..f60009838e 100644 --- a/docs/outstanding-issues.md +++ b/docs/outstanding-issues.md @@ -149,7 +149,6 @@ removed after current-main verification; it is not missing recommended work. | #132 | P3 | issue | Both client-side push guards are inert for agent pushes | **Outcome:** the format and auto-merge guards protect every push, or their blind spot is explicit. **Detail:** `scripts/guard-push.mjs` printed `auto-merge: gh not available — auto-merge check skipped (fail-open)` for pushes from a remote agent environment, so the auto-merge race sentinel never evaluated; and `core.hooksPath` is set only by a local `npm install`, so an agent pushing from its own checkout bypasses `.githooks/pre-push` entirely. Both guards therefore protect exactly the environment least likely to break the rule, which is why the AGENTS.md format-before-push instruction is still load-bearing even though the tooling now exists. Observed directly on PR #1400: a push landed while auto-merge was armed with nothing to stop it. **Next:** provide `gh` (or a token-based equivalent) in agent environments so the sentinel can evaluate. **Do not move the format check into `pull_request_target`** — that context carries secrets and a write token, and a format check must execute PR-head code including this repo's now-loadable dynamic `prettier.config.*`, which is the classic privileged-context vector; `.github/workflows/pr-policy.yml` deliberately checks out only `github.workflow_sha` for exactly this reason. Formatting is already enforced server-side by `Static PR checks` running `format:check` on ordinary `pull_request` CI, so the guard's only unique value is failing fast before the push — nothing to duplicate. The auto-merge sentinel reads PR metadata only and could safely live in `pull_request_target` if it is ever worth moving. | PR #1400; session 2026-07-30 | 2026-07-30 | | #133 | P3 | rec | Ledger conflicts on nearly every `main` advance (union driver removed) | **Outcome:** two agents editing different rows of this ledger do not silently corrupt it. **Driver half RESOLVED 2026-07-30:** `merge=union` is removed from `.gitattributes` and `check:outstanding-issues` now requires that **no** driver is set, so a reappearance is a red gate (proved by reintroducing it: `must have NO merge driver (found merge=union)`). This row already recorded union as worse — "two sides each bumping the marker produce two `next-id` lines, corrupting the file silently where a conflict would fail loudly" — but the attribute stayed in place and the gate _mandated_ it, so the repo's own tested conclusion was contradicted by its own config. PR #1430 confirmed the cost at scale: four merges in one session, each reporting success while duplicating the **entire** open-items table (`#059 appears 2 times (lines 101, 166)` and so on), every one needing a manual rebuild from `origin/main`. Union also makes `git merge-tree` report a clean tree, so the pre-merge conflict check cannot warn. Unlike `docs/branch-review-ledger.md`, this file allocates IDs by read-modify-write, so concurrent appends need manual renumbering whatever the driver does — union bought nothing. `AGENTS.md`, `docs/process-hardening.md`, `.claude/skills/issues/SKILL.md` and `docs/scripts-index.md` are updated to match. **Still open — the conflict frequency itself:** the table is padded to fixed column widths, so one row's edit re-pads every open row and git sees the whole table as one changed hunk; on 2026-07-30 it conflicted twice within an hour on PR #1400, and each conflict silently stopped **all** CI on that PR (`#116`). **Next:** stop padding this table (Prettier still renders it readably, and one-row edits become one-line diffs), or split the open items into per-row files. **Re-confirmed 2026-07-30 (PR #1451):** removal did not reduce the pain — that PR conflicted on this file, its session resolved it (renumbering a colliding row), and `git merge-tree` showed it conflicting again within minutes, because four further `main` commits (#1455, #1446, #1445, and the X3 coverage record) each touched the table. Both sides had also allocated `#141` concurrently, so a duplicate id reached a pushed tip and failed `check:outstanding-issues` there (`#141 appears 2 times`) independently of the conflict — the read-modify-write allocation race this row already predicts. **Prerequisite for the un-pad fix:** Prettier enforces padded markdown tables under `docs/`, verified by checking identical ragged content in an ignored path (passes) and under `docs/` (fails) — so un-padding also needs `docs/outstanding-issues.md` added to `.prettierignore`, precisely as its sibling `docs/branch-review-ledger.md` already is at `.prettierignore:23`. Do that in one commit while the ledger queue is quiet: the un-pad rewrites every open row and will conflict with any in-flight ledger edit. **Stop:** do not reintroduce a merge driver here; if concurrent-append pain returns, write a dedupe driver like `merge=ledger`'s rather than stock union. | `.gitattributes`; `scripts/check-outstanding-issues.mjs`; PR #1400; PR #1430 | 2026-07-30 | | #142 | P3 | task | Four loose dated docs need source and migration edits before they can be filed | **Outcome:** every dated point-in-time doc lives in `docs/audit/` or `docs/archive/` as `docs/README.md` requires, not loose at the `docs/` top level. **Detail:** PR #1436 filed the five that were docs-only moves. These four are referenced from outside `docs/`, so relocating them means editing source, tests and migration SQL comments — a different risk class than a docs tidy, and not worth bundling into one: `capacity-review.md` (`scripts/soak-test.ts`), `tenancy-defense-in-depth-review.md` (`src/lib/owner-scope.ts`, `tests/owner-scope-guard.test.ts`, two migrations, `SECURITY.md`, `.claude/agents/clinical-governance-reviewer.md`), `operator-apply-july8-batch.md` (three migrations plus `supabase/schema.sql`), `scale-readiness-review.md` (one migration). Also note `forward-codify-retrieval-rpcs-workorder.md` is indexed as a completed workorder but live is still ahead of the repo on those RPCs, so archiving it would misrepresent open operator work. **Next:** treat as low priority — the docs are correctly indexed and reachable where they are; only file them if a pass is already editing those migrations. Editing applied migration SQL is subject to `npm run check:migration-role`'s immutability pin. | PR #1436; session 2026-07-30 | 2026-07-30 | -| #143 | P2 | issue | An uncommitted hook in the main checkout aborts commits in every worktree | **Outcome:** a worktree commit is not blocked by unfinished work sitting in a different checkout. **Detail:** `core.hooksPath` is an absolute path to the primary checkout's `.githooks` (`C:\Dev\Apps\Database\.githooks`), and it is shared by every linked worktree because `git config` writes to the common config file. That primary checkout currently has an **uncommitted** `.githooks/pre-commit` plus an `update-docs-inventory.mjs` under `scripts/`; neither is on `origin/main` (so that path deliberately appears un-linked here — it does not resolve in this repo). The hook therefore fires in worktrees whose branch does not contain the script and dies: `Error: Cannot find module '/scripts/update-docs-inventory.mjs'` — `[pre-commit] Synchronizing generated documentation...` then `MODULE_NOT_FOUND`, commit aborted. Hit directly on PR #1436, worked around per-command with `git -c core.hooksPath=/.githooks commit` (not `--no-verify`, and without touching the shared checkout). **Mitigated 2026-07-30, NOT closed:** the hook now fails open — if the inventory task is selected but its script is absent from the committing worktree it prints `skipping inventory sync`, drops that task, and re-checks the all-tasks-empty early exit (without that re-check an empty `docs_to_check` makes the trailing `git diff --name-only --` match every modified file in the tree). Proven by committing from a linked worktree with the shared `core.hooksPath` untouched: exit 0. **Why this is not a fix:** that hook file is _untracked in the primary checkout and committed on no branch_, so the mitigation is not version-controlled — it disappears on overwrite and is absent from any fresh clone or other machine. The script itself IS committed, on `codex/docs-sync-automation-pr` (3 commits ahead of `main`), so the durable fix is to commit `.githooks/pre-commit` alongside it on that branch and let `scripts/install-git-hooks.mjs` distribute it. Inverse blind spot to #132: there the hook never runs, here it runs from the wrong tree. | PR #1436 commit attempt; session 2026-07-30 | 2026-07-30 | | #135 | P2 | rec | UI scope overfires: `ui_changed` matches every `src/app` path | **Outcome:** a change that cannot alter a rendered journey stops paying the longest job in CI. **Detail:** `uiPatterns` in `scripts/ci-change-scope.mjs` matches all of `src/app`, so an edit confined to `src/app/api/**` sets `ui_changed` and runs the full Chromium gate — measured 2026-07-30 at 15m26 of an 18m36 run, the entire critical path. **Next:** decide whether API-only diffs can be excluded. **Not done blind, deliberately:** the journeys exercise a production build that serves those routes, so a naive exclusion can hide a real regression; this needs a decision plus a compensating check, not a quieter filter. Sharding `ui-critical` (PR #1427) cut the cost of over-firing but did not remove it. **VALIDATED 2026-07-30, and it is already implemented:** `isUiChangedPath` in `scripts/ci-change-scope.mjs` already excludes `src/app/api/**`. A naive grep suggested a coverage hole — 16 of 17 API route groups appear in Playwright specs — but 92 of those references are `page.route(` / `context.route(` **stubs**, not real calls: the journeys mock the API layer, so an API handler change genuinely cannot move them. The exclusion is correct and the measurement now says so. **Stop:** do not re-open on a bare grep for `/api/` in specs; check whether the reference is an interception before concluding anything. | `scripts/ci-change-scope.mjs`; CI runs 30520443076 / 30519912667; session 2026-07-30 | 2026-07-30 | | #137 | P3 | rec | Advisory UI spends ~3 min per UI PR on five mockup tests | **Outcome:** the advisory lane costs what its signal is worth. **Detail:** `ui-advisory` runs on every UI PR (3m14 measured 2026-07-30) to cover `@quarantine` plus `@mockup` journeys — but `tests/flake-ledger.json` is empty and there are **zero** `@quarantine` tests in the suite, so it executes 5 `@mockup` tests. It is `continue-on-error` and outside `pr-required`, so it can also rot unnoticed. **Next:** gate it on mockup-file scope, or accept the cost as the price of keeping the lane warm for future quarantines. Either is defensible; the current state is just unmeasured. **DONE 2026-07-30:** `advisory_ui_changed` gates the lane on a mockup surface having changed or the flake ledger being non-empty. Reading the ledger rather than hard-coding "no quarantines exist" makes it self-correcting — quarantining a test brings the lane straight back. Fails OPEN on an unreadable ledger. Five self-test cases cover both directions plus the fail-open path. | `.github/workflows/ci.yml` `ui-advisory`; `tests/flake-ledger.json`; session 2026-07-30 | 2026-07-30 | | #138 | P3 | task | CI Triage ships inert pending a repo variable | **Outcome:** a PR red that is really a main-side regression is labelled as such instead of costing an author a debugging session. **Detail:** `.github/workflows/ci-triage.yml` is complete and self-tested (`check:ci-triage` runs in `verify:cheap` and `static-pr`) but every run short-circuits on `vars.CI_TRIAGE_ENABLED == 'true'`, which is unset. Its purpose is the failure mode this doc records repeatedly: CI merges the PR branch with current `main`, so a main regression surfaces on every open PR. **Next:** operator sets the repository variable, then confirm one triage comment posts. Reads job metadata from a trusted default-branch checkout only; never runs PR code. | `.github/workflows/ci-triage.yml`; session 2026-07-30 | 2026-07-30 | @@ -167,13 +166,14 @@ Move resolved rows here with the resolution date and a one-line outcome. Keep th | ---- | ----- | --------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------- | | #127 | issue | Document-route phone header intermittently failed to hide | Resolved 2026-07-30 by PR #1427, which fixed the short/clamped drag mechanism. Its runway polling and delivered-travel assertions then passed across the four recorded post-fix runs and the later PR #1480 exact-head browser/PWA document-header journeys, with no recurrence. | 2026-07-30 | -| ID | Type | Summary | Outcome | Resolved | -| ---- | ----- | ------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------- | -| #091 | issue | Results band could not express a partial-source failure | Resolved by PR #1480. Favourites and shared result bands now retain only the honest loaded count, visibly report unavailable sources, and expose a tested Retry recovery path without masking partial failures as ready. | 2026-07-30 | -| #128 | issue | Draft-to-ready alone did not retrigger required CI | Resolved by PR #1480. The CI pull-request trigger now includes ready_for_review alongside opened, synchronize, and reopened, with the workflow contract and exact-head Actions runs passing. | 2026-07-30 | -| #134 | issue | Ledger merge driver could be absent when install was skipped | Resolved by PR #1480. The branch-review-ledger guard now fails loudly when merge=ledger is declared but merge.ledger.driver is not configured, and its self-test covers the missing-driver case. | 2026-07-30 | -| #141 | issue | Production --clinical-accent-strong token was undefined | Resolved by PR #1480. The token is defined for light, dark, and forced-colors themes, documented in the permanent colour direction, and protected by focused design-token tests. | 2026-07-30 | -| #144 | issue | check:docs-index lacked repository-root directory coverage | Resolved by PR #1480. The checker now discovers tracked top-level directories, applies an explicit infrastructure/output allowlist, verifies both orientation maps, and reports all 49 covered roots/modules/routes plus schema tables. | 2026-07-30 | +| ID | Type | Summary | Outcome | Resolved | +| ---- | ----- | -------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ---------- | +| #143 | issue | Shared pre-commit hook could abort commits in linked worktrees | Resolved by PR #1442. `.githooks/pre-commit` and `scripts/update-docs-inventory.mjs` are tracked on `main`; the installed shared hook now fails open when a committing worktree lacks the inventory script, so the mitigation is durable in fresh clones and linked worktrees. | 2026-07-30 | +| #091 | issue | Results band could not express a partial-source failure | Resolved by PR #1480. Favourites and shared result bands now retain only the honest loaded count, visibly report unavailable sources, and expose a tested Retry recovery path without masking partial failures as ready. | 2026-07-30 | +| #128 | issue | Draft-to-ready alone did not retrigger required CI | Resolved by PR #1480. The CI pull-request trigger now includes ready_for_review alongside opened, synchronize, and reopened, with the workflow contract and exact-head Actions runs passing. | 2026-07-30 | +| #134 | issue | Ledger merge driver could be absent when install was skipped | Resolved by PR #1480. The branch-review-ledger guard now fails loudly when merge=ledger is declared but merge.ledger.driver is not configured, and its self-test covers the missing-driver case. | 2026-07-30 | +| #141 | issue | Production --clinical-accent-strong token was undefined | Resolved by PR #1480. The token is defined for light, dark, and forced-colors themes, documented in the permanent colour direction, and protected by focused design-token tests. | 2026-07-30 | +| #144 | issue | check:docs-index lacked repository-root directory coverage | Resolved by PR #1480. The checker now discovers tracked top-level directories, applies an explicit infrastructure/output allowlist, verifies both orientation maps, and reports all 49 covered roots/modules/routes plus schema tables. | 2026-07-30 | | ID | Type | Summary | Outcome | Resolved | | ---- | ----- | ----------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------- |