Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
15 commits
Select commit Hold shift + click to select a range
52e2f0c
docs: remediate documentation audit findings and add automated docs:m…
BigSimmo Oct 14, 2026
520ed92
chore(docs): sync generated snapshots, inventory, and organisation pins
BigSimmo Oct 14, 2026
428ee40
fix: 9 findings — Use the real snapshot checker in check mode; Fail when
qodo-code-review[bot] Oct 14, 2026
e117c12
fix: Catalogue only explicitly linked documentation files
qodo-code-review[bot] Oct 14, 2026
e2e2b97
fix: Remove crisis contacts absent from the fixture
qodo-code-review[bot] Oct 14, 2026
155e258
fix: 3 findings — Stabilize hazard snapshot generation dates; Use the so
qodo-code-review[bot] Oct 14, 2026
ea85045
Merge origin/main and resolve PR #3544 review comments
BigSimmo Oct 14, 2026
f7b003a
fix(ci): bounded rmSync retries in docs-maintain test; refresh repo-a…
claude Oct 14, 2026
4712138
Merge branch 'main' into docs/audit-remediation-20261014
BigSimmo Oct 14, 2026
ba6dfa6
fix: correct hazard review expiry and documentation cataloguing, writ…
coderabbitai[bot] Oct 14, 2026
95b0db4
fix: make hazard snapshot consistency tests expiry-independent and cl…
coderabbitai[bot] Oct 14, 2026
a0ac67b
docs: restore privacy attestation expiry; correct CME route count
claude Oct 14, 2026
9377f1d
docs(care-plan): state precisely what the crisis-contact tests pin
claude Oct 14, 2026
bf486df
docs(process-hardening): list the five real push-guard overrides
claude Oct 14, 2026
f519ae9
docs(design-system): state that adoption 'passed' proof is a recorded…
claude Oct 14, 2026
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
27 changes: 14 additions & 13 deletions .claude/skills/gates/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,10 @@ Check these before believing any result.

- **`verify:ui` under heavy-lock contention waits, then fails — it does not soft-skip green.** When
another worktree holds the exclusive lease, `acquireHeavyRunLock` queues Playwright admission for
up to 15 minutes and throws on timeout; `run-playwright.mjs` catches that error and exits `1`. Do
not treat a long wait or a red contention timeout as a false-green soft-skip. When the gate does
run, grep the output for the `N passed` line — exit `0` alone is never proof.
up to 15 minutes and throws on timeout; `scripts/run-playwright.mjs` catches that error and exits
**`75`** (`DATABASE_HEAVY_RUN_ADMISSION_BUSY`), not `1`. Do not treat a long wait or a contention
timeout (`75`) as a false-green soft-skip or a product test failure. When the gate does run, grep
the output for the `N passed` line — exit `0` alone is never proof.
- **A stale worktree makes every downstream gate a lie.** `check:installed-lock-parity` fails closed
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.
Expand All @@ -41,16 +42,16 @@ Match the gate to what actually changed. Running a broader gate is not more rigo
observe the change; running a narrower one is not sloppy if it can. Add a second gate only when it
covers a distinct plausible regression and the incremental confidence justifies its cost.

| Change | Gate that can actually fail |
| --------------------------- | --------------------------------------------------------------------------------------------------- |
| Markdown / docs only | `prettier --check`, `docs:check-links`, `docs:check-index` |
| Localised source behavior | `test:focused -- --files <paths>` |
| Ordinary pre-PR check | `verify:cheap` — lock parity + lint + typecheck + unit tests |
| Cross-module/unknown scope | `verify:full` — 42 static gates then lint + typecheck + test (does not invoke cheap; check 2 of 45) |
| Before PR handoff | `verify:pr-local` (risk-routed; inspect with `--dry-run`) |
| UI, styling, routing, a11y | `npm run ensure`, affected journey, broad UI only when shared |
| Phone chrome | `verify:phone-chrome` (narrower than `verify:ui`; run it first) |
| Explicit release confidence | `verify:release` (provider approval still required) |
| Change | Gate that can actually fail |
| --------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- |
| Markdown / docs only | `prettier --check`, `docs:check-links`, `docs:check-index` |
| Localised source behavior | `test:focused -- --files <paths>` |
| Ordinary pre-PR check | `verify:cheap` — `check:installed-lock-parity` + `check:diff-integrity` + `lint` + `typecheck` + `test` |
| Cross-module/unknown scope | `verify:full` — 42 static gates (`check:runtime` through `check:offline-pack` terminal static gate) then `lint` + `typecheck` + unit `test` |
| Before PR handoff | `verify:pr-local` (risk-routed; inspect with `--dry-run`) |
| UI, styling, routing, a11y | `npm run ensure`, affected journey, broad UI only when shared |
| Phone chrome | `verify:phone-chrome` (narrower than `verify:ui`; run it first) |
| Explicit release confidence | `verify:release` (includes `build` + full Playwright + governance/eval; provider approval required) |

`lint`, `typecheck`, and `test` cannot observe a markdown-only change. Say so rather than running
them for appearance.
Expand Down
16 changes: 10 additions & 6 deletions .claude/skills/handoff/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,11 @@ force-push, or discard work.
blindly. Do not stage `.env*`, secrets, build output, logs, or unrelated WIP; if you
see a possible secret, report the path (never the value) and stop.
3. **Format and verify.** From a fully owned feature worktree, run `npm run format`, inspect the
complete formatter diff, and include only intended formatting. Then invoke
`verification-router` (or the `gates` skill when scope is already clear) and run the one
smallest sufficient gate it selects. Default PR-ready work uses
complete formatter diff, and include only intended formatting. Then invoke the `gates` / `plan`
skills and run the one smallest sufficient gate they select. Default PR-ready work uses
`npm run verify:pr-local`; inspect its selection with `--dry-run` when uncertain. For
UI/routing/styling, prove the affected journey first and add `verify:ui` only for shared UI
foundations or when the router says its distinct coverage is necessary. Never stack
foundations or when the planner says its distinct coverage is necessary. Never stack
`verify:cheap` + `verify:ui` + `verify:release` by default.
- Touched `src/app/`, `src/components/`, or `tests/` (or design-system adoption
inputs): run `npm run design-system:adoption:update` and stage any regenerated
Expand All @@ -61,8 +60,13 @@ force-push, or discard work.
a force-push or base change is not ([Merge authority](../../../docs/agents/pull-request-workflow.md#merge-authority)).
Never pipe the push through `tail`,
`head`, or another command that can mask its status. Confirm the remote tip equals local HEAD
with `git ls-remote` before reporting success. The pre-push guards run
(auto-merge sentinel, format, drift) — heed a block rather than overriding blindly.
with `git ls-remote` before reporting success. This provider-touching verification requires
explicit user confirmation; push authorization alone does not cover it. If confirmation is
absent, report the push result and remote-tip verification as pending. The pre-push guards in `scripts/guard-push.mjs` run
(non-bypassable `autoMergeGuard` sentinel, plus five scoped overrides `SKIP_STATIC_GUARD=1`,
`SKIP_DRIFT_GUARD=1`, `SKIP_FORMAT_GUARD=1`,
`SKIP_IN_FLIGHT_CI_GUARD=1`, and `SKIP_LEDGER_WRITE_GUARD=1`) — heed a block rather than
overriding blindly.

**Restarting a branch whose PR already merged:** GitHub deletes the remote branch on merge,
so the local `origin/<branch>` ref is stale and `--force-with-lease` fails with `stale info`
Expand Down
24 changes: 15 additions & 9 deletions .claude/skills/issues/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@ description: Track and recall all outstanding tasks, recommendations, and issues

# issues — the outstanding-work memory

`docs/outstanding-issues.md` is the single universal, durable, cross-session ledger for recommended
execution order, open **tasks**, **recommendations**, **issues**, provider/operator work, and archive
history. Chat context resets; that file does not. This skill reads it back and keeps it current.
`docs/outstanding-issues.md` is the repository outstanding-issues ledger — the single universal,
durable, cross-session register for recommended execution order, open **tasks**, **recommendations**,
**issues**, provider/operator work, and archive history (while `docs/task-receipts.md` governs
canonical task lifecycle and receipt handoff). Chat context resets; `docs/outstanding-issues.md`
does not. This skill reads it back and keeps it current.

**The ledger on the remote `main` branch is the source of truth, not chat memory or a stale
worktree.** Never answer `/issues` from conversation recall or by reading the checkout file
Expand Down Expand Up @@ -60,8 +62,10 @@ read-only `/issues` needs no such check. Recorded as `#292`.
Parse the intent from natural language too — the exact syntax is a convenience, not a requirement.

- **`/issues add <text>`** — queue an immutable `add` request. Infer `Pri`/`Type` from the text
(ask only if genuinely ambiguous; default `P2`/`task`). The serial reconciler allocates the
numeric issue ID later; a feature branch must never read or bump the `issues:next-id` marker.
(ask only if genuinely ambiguous; default `P2`/`task`). `scripts/outstanding-issues.mjs` and the
serial reconciler allocate ULID-backed Crockford Base32 `#XXXXXX` IDs (six characters by default, growing
when needed to avoid collisions); a feature
branch must never hand-allocate IDs or edit canonical rows directly.
- **`/issues done <id> [outcome]`** — queue an immutable `done` request for the existing canonical
ID and its one-line outcome. Reconciliation moves the row to **Resolved / archive** and updates
any recommended-queue references.
Expand Down Expand Up @@ -91,14 +95,16 @@ paragraph; put the smallest next action in **Detail / next action**.

```bash
npm run issues:add -- --pri P2 --type issue --summary "…" --detail "…" --source "…"
npm run issues:done -- '#151' --outcome "Resolved 2026-07-31 by PR #1494. …"
npm run issues:update -- '#151' --detail "…"
npm run issues:queue -- '#151' --acuity A3 --when "After the next release"
npm run issues:done -- '#M6JNR8' --outcome "Resolved 2026-07-31 by PR #1494. …"
npm run issues:update -- '#M6JNR8' --detail "…"
npm run issues:queue -- '#M6JNR8' --acuity A3 --when "After the next release"
```

Each command creates one validated UUID JSON file under `docs/outstanding-issues-inbox/`; it does
not edit `docs/outstanding-issues.md`. Requests are immutable and merge independently. Only a
dedicated fresh-base ledger branch may run `npm run issues:reconcile`, which allocates IDs, applies
dedicated fresh-base ledger branch may run `npm run issues:reconcile`, which allocates ULID-backed
Crockford Base32 `#XXXXXX` IDs (six characters by default, growing when needed to avoid
collisions) via `scripts/outstanding-issues.mjs`, applies
requests serially, and moves them to `docs/outstanding-issues-inbox/applied/`. Never reconcile as
part of an ordinary product PR.

Expand Down
21 changes: 16 additions & 5 deletions .claude/skills/newtask/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ almost always has a pushed branch named after it. Report which check you used. O
under `C:\Users\…`:

```bash
git worktree add -b claude/<task-slug> D:/Repos/Database/.claude/worktrees/<task-slug> origin/main
git worktree add -b claude/<task-slug> D:/Repos/PsychSift/.claude/worktrees/<task-slug> origin/main
```

Use a short, descriptive `<task-slug>`.
Expand All @@ -73,12 +73,23 @@ almost always has a pushed branch named after it. Report which check you used. O
and `C:\Users\joshs\.gemini\` belong to Codex and Antigravity sessions — leave them
alone and do not count them.

3. **Install deps in the new worktree** (worktrees do NOT share `node_modules`; a cold
worktree fails `vitest`/`tsc`). `npm ci` keeps the lockfile untouched:
3. **Install deps in the new worktree** (a cold worktree fails `vitest`/`tsc`). Prefer
`node scripts/setup-codex-worktree.mjs`, which reuses a byte-identical donor `node_modules`
before falling back to `npm ci --include=dev --prefer-offline --no-audit --no-fund`:

```bash
cd D:/Repos/Database/.claude/worktrees/<task-slug> && npm ci --no-audit --no-fund
cd D:/Repos/PsychSift/.claude/worktrees/<task-slug>
node scripts/setup-codex-worktree.mjs
```
`postinstall` installs the pre-push guards automatically.

**Fallback — direct install when the setup helper cannot be used:**

```bash
npm ci --include=dev --prefer-offline --no-audit --no-fund
```

`postinstall` writes the lock-parity stamp and installs the pre-push guards automatically.

4. **Confirm the base is current:** `node scripts/check-base-freshness.mjs` — expect
`behind 0`. If it reports behind, the fetch/worktree base is stale; recreate.
5. **Warm routes before any browser/UI work** (fresh worktrees can hash onto a
Expand Down
34 changes: 13 additions & 21 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ HEALTH_DEEP_PROBE_SECRET=your-long-random-health-deep-probe-secret
# only by `npm run test:cross-tenant:staging`; never point them at production.
# The two accounts must be distinct, non-human staging test users. The staging
# app must use the same Supabase project and RAG_PROVIDER_MODE=offline.
#CROSS_TENANT_STAGING_APP_URL=https://clinical-kb-staging.example.org
#CROSS_TENANT_STAGING_APP_URL=https://psychsift-staging.example.org
#CROSS_TENANT_SUPABASE_URL=https://your-staging-project-ref.supabase.co
#CROSS_TENANT_PROJECT_REF=your-staging-project-ref
#CROSS_TENANT_PUBLISHABLE_KEY=your-staging-publishable-key
Expand Down Expand Up @@ -148,22 +148,29 @@ OPENAI_TEXT_VERBOSITY=low
# offline: never call OpenAI; lexical retrieval + deterministic source-only answers only.
RAG_PROVIDER_MODE=auto

# Optional server-only production error tracking. When SENTRY_DSN is absent the
# integration is inert. Events exclude request URLs/headers/bodies, user data,
# breadcrumbs, free-form context, and exception messages; browser replay stays off.
# Optional server-only production error tracking (see docs/error-tracking.md).
# When SENTRY_DSN is absent the integration is inert. Events exclude request
# URLs/headers/bodies, user data, breadcrumbs, free-form context, and exception
# messages; browser replay stays off.
# Performance tracing defaults to 10% sampling for privacy-safe Supabase DB spans
# (table/operation only — no query filters or mutation bodies). Set
# SENTRY_TRACES_SAMPLE_RATE=0 to disable tracing while keeping error capture.
# Structured Sentry Logs default on when DSN is set (allowlisted messages +
# attributes only; no console capture). Set SENTRY_ENABLE_LOGS=false to disable.
# Choose and document region, retention, access, and alert routing before enabling.
# Never expose this value as NEXT_PUBLIC_*.
# Never expose SENTRY_DSN as NEXT_PUBLIC_*.
SENTRY_DSN=
SENTRY_ENVIRONMENT=production
# SENTRY_TRACES_SAMPLE_RATE=0.1
# SENTRY_ENABLE_LOGS=false
# One-shot Sentry Logs wizard verify (emits "User triggered test log" at Node boot).
# SENTRY_SEND_TEST_LOG=true
# Optional source-map upload (build/CI only). Set all three together, or leave all unset.
#SENTRY_ORG=
#SENTRY_PROJECT=
#SENTRY_AUTH_TOKEN=
# Optional explicit release tag for Sentry events; if blank, commit SHA is used.
#NEXT_PUBLIC_SENTRY_RELEASE=
# Optional JSON override for app-layer ranking weights (see src/lib/ranking-config.ts).
# Omit for current defaults. Example (enable diversity demotion + linear freshness):
# RAG_RANKING_CONFIG={"documentDiversityPenalty":0.03,"freshness":{"mode":"linear"}}
Expand Down Expand Up @@ -215,7 +222,7 @@ RAG_AWAIT_QUERY_LOGS=false
# signed-in user whose Supabase app_metadata.site_role is "administrator".
# Assign that claim only through the approval-gated auth:set-administrator script.
# Optional canonical public origin for generated metadata, for example
# https://clinical-kb.example.org. Railway deployments otherwise use the
# https://psychsift.example.org. Railway deployments otherwise use the
# provider-supplied RAILWAY_PUBLIC_DOMAIN; request hosts are only used in dev.
#NEXT_PUBLIC_SITE_URL=
# Persist raw clinical query text in logs. Default off; blocked in production readiness.
Expand Down Expand Up @@ -336,21 +343,6 @@ TESSERACT_CMD=C:\Program Files\Tesseract-OCR\tesseract.exe
#RAILWAY_TOKEN=
#RAILWAY_API_TOKEN=

# Optional privacy-safe production server error tracking (see docs/error-tracking.md).
# Server-side DSN only — leave unset to keep tracking inert. Do not set a browser
# NEXT_PUBLIC_SENTRY_DSN; browser telemetry and replay stay disabled. Server
# tracing defaults on at 10% with redacted Supabase DB spans when SENTRY_DSN is set.
# Structured Logs also default on with DSN (disable with SENTRY_ENABLE_LOGS=false).
#SENTRY_DSN=
#SENTRY_TRACES_SAMPLE_RATE=0.1
#SENTRY_ENABLE_LOGS=false
# Optional source-map upload (build/CI only). Set all three together, or leave all unset.
#SENTRY_ORG=
#SENTRY_PROJECT=
#SENTRY_AUTH_TOKEN=
# Optional explicit release tag for Sentry events; if blank, commit SHA is used.
#NEXT_PUBLIC_SENTRY_RELEASE=

# --- Agent tooling only (not read by Next.js / env.ts) ---
# Context7 MCP — versioned library docs for agents (Tailwind 4, Zod 4, Playwright,
# Vitest, React 19, @supabase/supabase-js, …). Wired in `.cursor/mcp.json` as
Expand Down
Loading
Loading