diff --git a/.claude/cloud-profile/memory/MEMORY.md b/.claude/cloud-profile/memory/MEMORY.md index b44ee7978d..310f15a666 100644 --- a/.claude/cloud-profile/memory/MEMORY.md +++ b/.claude/cloud-profile/memory/MEMORY.md @@ -11,5 +11,5 @@ - [Plain, brief communication style](communication-style-plain-and-brief.md) — answer first, numbered steps, no internal detail unless asked; saved in user-level CLAUDE.md - [Ward Flow coordination state](ward-flow-coordination-state.md) — WA metro psychiatry patient flow: spec approved, Phase 1 executing, handoff lives in docs/ward-flow-phase-handoff.md - [Ward Flow verification lessons](ward-flow-verification-lessons.md) — green tests missed a wrong value on every screen; verify claims, watch regression tests fail, look at the screen -- [Token usage hygiene](token-usage-hygiene.md) — no .claudeignore exists; grep before reading big dirs, delegate broad searches to Explore, don't shrink AGENTS.md +- [Token usage hygiene](token-usage-hygiene.md) — no .claudeignore exists; grep before reading big dirs, delegate broad searches to Explore, never drop a rule to save tokens (AGENTS.md is a deliberately small core plus docs/agents/ reference files) - [Claude plugin native deps trap](claude-plugin-native-deps-trap.md) — `claude plugin install` skips npm deps; npm 11 blocks native builds; prove with stats+search, not the postinstall warning diff --git a/.claude/cloud-profile/memory/token-usage-hygiene.md b/.claude/cloud-profile/memory/token-usage-hygiene.md index 1bc5322005..a16bfd1c94 100644 --- a/.claude/cloud-profile/memory/token-usage-hygiene.md +++ b/.claude/cloud-profile/memory/token-usage-hygiene.md @@ -30,7 +30,13 @@ shape, so there was nothing to add there. [[dev-drive-project-location]] separat of the repo's disk footprint — the same directory is the main _token_ risk for reads, not just disk space. **How to apply:** Follow this automatically in every Database repo session; it needs no action or approval from -Josh each time. Do not shrink or restructure `AGENTS.md`/`CLAUDE.md` to save tokens even though they are large — -that size is deliberate (shared safety/process rules read by five different AI tooling systems, per the file's -own "AI tooling map"), and trimming it is a project decision for the team, not something to do unilaterally for -token savings. +Josh each time. Do not shrink `AGENTS.md`/`CLAUDE.md` by dropping or condensing rules to save tokens — those +rules are shared safety and process contracts read by five different AI tooling systems (per the file's own "AI +tooling map"), and cutting one is a project decision for the team, never something to do unilaterally for token +savings. + +Their current shape is the result of one such project decision, taken deliberately in 2026-09: `AGENTS.md` is a +small always-loaded core — the boundaries that prevent irreversible harm, plus the sections a gate parses by +exact text — and an index. Every other rule keeps its heading there and its full text, verbatim, in a named file +under `docs/agents/`. So a large `AGENTS.md` is no longer the expected state, and a rule that is not in the core +has not been dropped; open the file the core names for it. Restoring the old single wall would undo that work. diff --git a/.github/codex/prompts/run-pr-operator.md b/.github/codex/prompts/run-pr-operator.md index 061404b741..9c06ae82df 100644 --- a/.github/codex/prompts/run-pr-operator.md +++ b/.github/codex/prompts/run-pr-operator.md @@ -7,6 +7,7 @@ Read these files before acting: - `AGENTS.md` - `CLAUDE.md` +- `docs/agents/pull-request-workflow.md` - `docs/codex-review-protocol.md` - `.claude/skills/run-pr/SKILL.md` - `.codex-run-pr/context.json` diff --git a/AGENTS.md b/AGENTS.md index a1c519a7ef..1209da30ec 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -8,6 +8,37 @@ This block is written and re-added by `next dev` — verify at `node_modules/nex +# How these rules are organised + +This file is the always-loaded core. It carries the boundaries that prevent irreversible harm, and +the sections a committed gate parses by exact text. Every other rule keeps its heading here and its +full text — verbatim, nothing dropped — in a named reference file. Open the file before acting in +its area. + +**Read these first; they prevent damage that cannot be undone, and their full text is below:** +`# Supabase project safety` (merging a migration reaches the live clinical database within +seconds, with no deploy step in between), `# RAG ranking protection`, `# Railway project safety`, +`# API and provider confirmation boundary`, and `# Local server safety`. + +| Topic | Full text | +| ------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------- | +| Gate selection, the verification tier table, the gate arbiter | [`docs/agents/verification-gates.md`](docs/agents/verification-gates.md) | +| Open PR sync, the `Run PR` sweep, babysitting a PR, review coverage, PR bundling | [`docs/agents/pull-request-workflow.md`](docs/agents/pull-request-workflow.md) | +| The `upload` shortcut | [`docs/agents/upload-shortcut.md`](docs/agents/upload-shortcut.md) | +| Button and route wiring, the bundle budget | [`docs/agents/wiring-and-bundle-budget.md`](docs/agents/wiring-and-bundle-budget.md) | +| External skill precedence, evidence and calibration | [`docs/agents/external-skill-precedence.md`](docs/agents/external-skill-precedence.md) | +| Deleting code you believe is dead | [`docs/agents/dead-code-deletion.md`](docs/agents/dead-code-deletion.md) | +| Claude Code hook scripts | [`docs/agents/claude-hook-scripts.md`](docs/agents/claude-hook-scripts.md) | +| The `bug-hunter` shortcut | [`docs/agents/bug-hunter-shortcut.md`](docs/agents/bug-hunter-shortcut.md) | +| Repository skills, the `/issues` outstanding-work memory | [`docs/agents/repository-skills-and-issues.md`](docs/agents/repository-skills-and-issues.md) | +| Codex dependency, review throttling, desktop worktree, reasoning effort, productivity, GitHub review, Cloud; Cursor Cloud | the `docs/agents/codex-*.md` and `docs/agents/cursor-cloud.md` pointers below | + +Five sections stay here in full because a committed test or script reads their exact text: +`## Bare PR publication is not readiness work`, the format-before-push rule, +`# Search chrome behaviour`, `## Anti-conflict and CI-speed operating procedure`, and +`## Codex Cloud environment`. Their wording is code, not prose — moving or rewording it fails +`verify:cheap`. + ## Dependency shortcut @@ -20,22 +51,7 @@ For the full Codex dependency shortcut workflow, see [`docs/agents/codex-depende ## Bug-hunter shortcut -When the user types exactly `bug-hunter` as the entire task message, after trimming surrounding whitespace, treat it as a shortcut for targeted defect discovery. - -Execution rules: - -- Invoke the `bug-hunter` skill first. -- Prioritize reproducible defects over code style, naming, or formatting feedback. -- Trace realistic failure paths: invalid input, empty states, retries, race/concurrency issues, stale state/cache, network/auth failures, permissions, and boundary values. -- For each finding, include trigger, expected behavior, actual risk, and the smallest proof (or targeted test/check) that would catch it. -- If no high-confidence defect is found, explicitly state that and list the most likely residual risk area. - -Scope and safety: - -- Keep the hunt scoped to code touched by the user request unless the defect clearly crosses module boundaries. -- Do not make broad refactors while hunting; propose minimal fixes for confirmed issues. -- Run the smallest focused verification for each confirmed defect, then expand only if needed. - +For the `bug-hunter` targeted defect-discovery shortcut, its execution rules, and its scope and safety limits, see [`docs/agents/bug-hunter-shortcut.md`](docs/agents/bug-hunter-shortcut.md). @@ -63,36 +79,7 @@ For Codex review throttling, branch routing, review ledger append rules, and rev # Claude Code hook scripts -`.claude/hooks/*.sh` runs on Linux web containers as well as on the Windows workstation, and the -workstation cannot see the thing that breaks it. - -- **Pin the executable bit in the index, not on disk.** The primary workstation is a Windows ReFS - Dev Drive with `core.fileMode=false`, so git ignores filesystem permission bits entirely and a - local `chmod +x` is a silent no-op. A hook added there commits as `100644`. Fix it with - `git update-index --chmod=+x .claude/hooks/.sh` and confirm with `git ls-files -s`. - This is not hypothetical: `session-start.sh` shipped `100644` while both its siblings were - `100755` (found 2026-08-18). That script's body only runs when `CLAUDE_CODE_REMOTE=true`, so the - sole environment it does work in is the Linux container where a non-executable checkout cannot - be run — and it is the script that provisions the Node 24 the engine floor needs, after - `npm ci` EBADENGINE blocked PRs #1611, #1697, #1705 and #1740. -- **Register hooks as `bash "$CLAUDE_PROJECT_DIR/…"`, never as a bare path**, so the mode is never - load-bearing. `session-start.sh` was the only bare-path registration and the only one missing the - bit; that is not a coincidence worth repeating. -- **Line endings are LF.** `.gitattributes` sets `* text=auto eol=lf`; all hook blobs measure CR=0. - A CR in a shell blob fails on Linux as the near-unreadable `/bin/bash^M: bad interpreter`. -- **Hooks must not be able to fail a session.** Every hook here exits 0 on any parse problem and - makes no decision, so a malformed payload leaves the tool call exactly as it was. -- **Set an explicit `timeout`.** The default is 60s, which `session-start.sh` can exceed on a cold - container (Node tarball download plus `npm ci`) — a killed hook leaves dependencies half - installed. -- **SessionStart context comes from stdout, not stderr.** A hook that reports on stderr is invisible - to the model even though it ran and exited 0; `check-base-freshness.mjs` spent its life in that - state. Emit `{"hookSpecificOutput":{"hookEventName":"SessionStart","additionalContext":"…"}}` on - stdout, and only when the message is worth the context it costs. - -Enforced by the `claude hook scripts are checked in runnable` block in -`tests/session-start-hook.test.ts`, which fails on any hook that is not `100755` or that carries CR -bytes. Do not weaken it. +For the `.claude/hooks/*.sh` contract — the executable bit in the index, hook registration, line endings, failure behaviour, timeouts, and SessionStart output, see [`docs/agents/claude-hook-scripts.md`](docs/agents/claude-hook-scripts.md). # Codex Desktop worktree setup @@ -119,208 +106,32 @@ When the user says `open PR`, `create PR`, or `publish PR` without also requesti - If a local commit hook or a readiness-only push guard (format, drift, static, or ledger-write) is the only blocker, publish with `git commit --no-verify` and that guard's own scoped override (`SKIP_FORMAT_GUARD=1`, `SKIP_DRIFT_GUARD=1`, `SKIP_STATIC_GUARD=1`, or `SKIP_LEDGER_WRITE_GUARD=1`, as applicable) instead of `git push --no-verify`; do not spend time preparing dependencies or formatting solely to satisfy the hook. Never skip the push hook wholesale — the auto-merge ownership guard has no override and must never be bypassed, even for a bare-publication request. This exception is limited to the explicit bare-publication request and does not weaken normal-push safeguards. - Create the PR immediately after the push, using the repository PR template where its policy fields apply. Report the URL and identify all local and hosted checks as unrun by request. Do not babysit CI, amend, or perform follow-up readiness work unless the user asks. This route overrides generic branch-bundling, handover, review, and babysit instructions. -- **Verification principle:** run the smallest check capable of detecting a plausible regression introduced by the current diff. Before starting a check, identify the failure class it covers, whether a successful check already covered that class, whether a cheaper focused check offers comparable detection, and whether the incremental confidence justifies the runtime, resource use, and repository-lock contention. If there is no plausible changed failure path, do not run the check. - -| Tier | Use when | Default evidence | -| ----------------------- | ----------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------- | -| 0 — No test command | Explanation, planning, prompt writing, read-only inspection, or no repository change | No test, build, server, or baseline command | -| 1 — Static/focused | Documentation, comments, metadata, or narrow non-behavioural configuration | Relevant format, docs, syntax, generated-file, or diff check only | -| 2 — Focused behavioural | A localized helper, component, contract, or test change | Directly affected unit/DOM/contract test; add typecheck only when the edit can affect compilation or a type contract | -| 3 — Domain gate | Shared UI/routing, dependencies, security, privacy, RAG, clinical output, production configuration, or another cross-cutting domain | The smallest applicable repository/domain selector, focused journey, or contract gate | -| 4 — Broad handoff | The diff crosses multiple subsystems, cannot be bounded reliably, or the task explicitly requires PR/release confidence | One appropriate broad gate, selected rather than stacked by default | - -- Do not run a broad baseline routinely before localized work, and do not select `verify:cheap` merely because a change is described as “non-trivial.” Use `npm run verify:cheap` once when cross-module risk warrants a broad offline gate. Use `npm run verify:pr-local` when a change is ready for PR handoff: it now classifies the changed paths, runs focused documentation/workflow contracts for recognised low-risk scopes, and fails closed to lint, typecheck, the full unit suite, RAG fixture validation, and relevant build/domain gates for executable or unknown scope. If the diff has not changed, do not run `verify:cheap` first merely to repeat the same coverage. -- Do not stack focused tests, full tests, typecheck, lint, build, and browser checks unless each catches a distinct plausible regression. Do not rerun an unchanged successful gate. Since 2026-08-21 that last rule is enforced rather than remembered: `scripts/gate-receipts.mjs` memoises `lint`, `typecheck` and non-coverage Vitest runs against a content signature, so an identical re-run on unchanged content exits 0 immediately instead of repeating the work. A reused receipt must be reported as "reused receipt from