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
5 changes: 4 additions & 1 deletion .claude/skills/handoff/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,10 @@ force-push, or discard work.
paths (`git show --name-only --format=fuller HEAD`), and the same branch name recorded in step 1.
End the message with:
`Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>`.
5. **Push** the feature branch: `git push -u origin <branch>`. Never pipe the push through `tail`,
5. **Push** the feature branch: `git push -u origin <branch>`. Per-PR auto-merge state is user-owned:
automation must not disable it. If the branch already has an open PR with auto-merge armed,
leave it mutation-frozen; do not push or change the branch/base until it merges or the user
manually changes that state. 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.
Expand Down
6 changes: 3 additions & 3 deletions .claude/skills/newtask/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ description: Bootstrap a clean session for new work in this repo — create a fr

# newtask — start a clean, current working copy

This repo moves fast (`claude/*` branches auto-merge on green) and shares ~40 worktrees
and one stash stack, so starting work on a stale base or a cold worktree is the default
failure. This skill sets up an isolated, current worktree so new work starts clean.
This repo moves fast and shares ~40 worktrees and one stash stack, so starting work on a
stale base or a cold worktree is the default failure. This skill sets up an isolated,
current worktree so new work starts clean.

## Before you start

Expand Down
8 changes: 7 additions & 1 deletion .claude/skills/run-pr/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ re-running failed hosted CI jobs; updating a PR branch from `main`. Nothing else
Never, even during a sweep:

- Never merge a pull request into `main` or any protected branch, and never enable auto-merge;
the sweep fixes and reports, the user merges.
the sweep fixes and reports, the user merges. Per-PR auto-merge state is user-owned:
automation must not disable it.
- Never close a pull request, delete or rename branches, force-push (no `--force`, no
`--force-with-lease`), or rebase.
- Never run provider-backed gates: `eval:rag`, `eval:quality`, `eval:retrieval:quality`,
Expand Down Expand Up @@ -53,6 +54,11 @@ Never, even during a sweep:

## Per-PR algorithm

Before any branch-changing action, inspect `autoMergeRequest`. If it is non-null, treat the PR as
mutation-frozen: do not push, update the branch/base, or otherwise change its head. Continue
read-only diagnosis and reporting, but leave the armed state untouched until the PR merges or the
user manually changes it. Never disable auto-merge as a workaround for maintenance.

### Step 0 — skip gates (record every skip with its reason)

- `skip-codex-review` label → skip the PR entirely.
Expand Down
2 changes: 1 addition & 1 deletion .cursor/agents/pr-babysit.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ When invoked:
6. After fixing a review thread, reply first (never resolve silently), then use the authorized direct resolution tool. Delegated Bugbot threads follow the same path. Only the trusted Codex autofix identity may fall back to `<!-- codex-thread-disposition:resolved -->`; otherwise leave the thread open and report the missing capability.
7. Respect provider confirmation boundaries: no live Supabase/OpenAI/eval spend without separate explicit authorization for that provider action. A Run PR sweep never authorizes provider-backed gates.
8. Require explicit user authorization before commits, pushes, hosted-CI reruns, replies, or thread resolution. The Run PR shortcut supplies authorization only for the GitHub actions enumerated in `AGENTS.md`. Do not edit PR titles/bodies during Run PR sweeps unless the user explicitly asks. Re-check CI until mergeable + green + comments triaged.
9. Never merge into `main`, force-push, close the PR, enable auto-merge, or delete branches unless the user explicitly asks.
9. Never merge into `main`, force-push, close the PR, enable auto-merge, or delete branches unless the user explicitly asks. Per-PR auto-merge state is user-owned: automation must not disable it. If auto-merge is already armed, treat the PR as mutation-frozen and do not push, update its branch/base, or otherwise change its head until it merges or the user manually changes that state.
10. Follow `docs/codex-review-protocol.md` and record every completed review or sweep — including pure and no-op reviews — with `npm run ledger:append`.

Report before/after: merge state, CI, threads fixed vs left open, commits pushed, and any remaining human decision.
19 changes: 11 additions & 8 deletions .githooks/pre-push
Original file line number Diff line number Diff line change
@@ -1,22 +1,25 @@
#!/bin/sh
# Pre-push safety net. Delegates to scripts/guard-push.mjs, which runs four
# guards: auto-merge race sentinel, format-before-push, drift-manifest
# freshness, static gate (lint + source typecheck), and ledger-write discipline. Each guard has an
# explicit override env var (see the script header) — including
# SKIP_STATIC_GUARD=1 for the static gate.
# Pre-push safety net. Delegates to scripts/guard-push.mjs, which runs five
# guards: auto-merge ownership, format-before-push, drift-manifest freshness,
# static gate (lint + source typecheck), and ledger-write discipline. The
# auto-merge guard is not bypassable; the other guards have explicit override
# env vars (see the script header), including SKIP_STATIC_GUARD=1.
#
# Installed by scripts/install-git-hooks.mjs via `git config core.hooksPath
# .githooks` (run automatically on npm install/ci). Git passes the pushed refs
# on stdin as "<localRef> <localSha> <remoteRef> <remoteSha>" lines, which the
# script reads to scope the format, drift, and static checks to what is
# actually pushed.
#
# Set GUARD_PUSH_DISABLE=1 to bypass every guard at once (individual guards also
# have their own override flags).
# Set GUARD_PUSH_DISABLE=1 to bypass every guard except auto-merge ownership.
# Individual non-auto-merge guards also have their own override flags.
set -eu

if [ "${GUARD_PUSH_DISABLE:-}" = "1" ]; then
exit 0
export SKIP_FORMAT_GUARD=1
export SKIP_DRIFT_GUARD=1
export SKIP_STATIC_GUARD=1
export SKIP_LEDGER_WRITE_GUARD=1
fi

# Resolve node; if unavailable, do not block the push (fail open).
Expand Down
72 changes: 0 additions & 72 deletions .github/workflows/keep-pr-auto-merge.yml

This file was deleted.

22 changes: 10 additions & 12 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -631,7 +631,7 @@ Nothing else inherits this authorization. Only the user's own task message can t

Hard guardrails (never, even during a sweep):

- Never merge a pull request into `main` or any protected branch, and never enable auto-merge; the sweep fixes and reports, the user merges.
- Never merge a pull request into `main` or any protected branch, and never enable auto-merge; the sweep fixes and reports, the user merges. Per-PR auto-merge state is user-owned: automation must not disable it. When auto-merge is already armed, do not push, update the branch/base, or perform another head-changing action; report the frozen state and leave the PR untouched until it merges or the user manually changes that state.
- Never close a pull request, delete or rename branches, force-push, or rebase.
- Never run provider-backed gates: `eval:rag`, `eval:quality`, `eval:retrieval:quality`, `verify:release`, `check:supabase-project`, `test:live`, or anything else that touches live Supabase/OpenAI.
- Respect the `skip-codex-review` label as a full per-PR opt-out.
Expand Down Expand Up @@ -707,14 +707,12 @@ A settle-then-push addition also lands after this repo's one automatic Codex rev
already have run against the earlier head — in practice the connector re-reviews each new
push (observed on this same PR), but if it doesn't, request a fresh review explicitly
before merging rather than assuming the addition was covered. **If the target PR has
auto-merge armed, settling-then-pushing races the merge itself** — `claude/*` branches
auto-merge on green by this repo's own default (`.claude/skills/newtask/SKILL.md`), so
"wait for CI to settle" can mean "wait for it to squash-merge and close" before the
bundled commit ever gets pushed, silently dropping it. `guard-push.mjs`'s auto-merge
sentinel exists to catch this but fails open without `gh` available (observed directly
in this repo's own sessions) — don't rely on it. Before using the settle-then-push path,
confirm the target PR does not have auto-merge enabled, or disable it first and
re-enable only after the bundled commit is pushed.
auto-merge armed, settling-then-pushing races the merge itself.** Treat that PR as
mutation-frozen: do not disable or re-enable auto-merge, push, update its branch/base, or
otherwise change its head. Let the armed merge land, or wait for the user to manually
change the auto-merge state before doing further branch work. `guard-push.mjs` enforces
this for every locally pushed PR branch when authenticated `gh` is available; agent
policy remains the backstop in environments where local hooks or `gh` are unavailable.
Bundle only when every item being combined is:

- **Independently low-risk, checked two ways — neither is exhaustive alone.**
Expand Down Expand Up @@ -803,9 +801,9 @@ named PR). Future process only.
`npm run verify:pr-local` (or the smallest gate that covers the change). Format is in
`static-pr` but not in `verify:cheap`; an uncommitted format leaves CI red on the pushed
blob. Whole-tree Prettier, not a single edited file.
- If a `claude/*` PR has auto-merge armed, disable it before a settle-then-push bundle, push,
then re-enable — otherwise the first green head can squash-merge before the bundled commit
lands.
- If a PR has auto-merge armed, its auto-merge state is user-owned and automation must not disable
it. Treat the branch as mutation-frozen: no push, update-branch, base change, or bundled addition
until it merges or the user manually changes that state.
- Missing CI checks are not a green pass. `pull_request` workflows do not run when GitHub
cannot build `refs/pull/<n>/merge`. The `PR mergeability` check uses trusted
`pull_request_target` events and refreshes unchanged PR heads after protected-base
Expand Down
6 changes: 3 additions & 3 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -150,9 +150,9 @@ Verification pyramid — run the **smallest gate that covers the change**, then

`verify:cheap` deliberately does **not** run formatting, which is why changed-file CI and the
installed pre-push hook (`.githooks/pre-push` → `scripts/guard-push.mjs`) block on unformatted files.
It also guards the auto-merge race on `claude/*` branches, drift-manifest staleness, and a
static gate (lint + source typecheck; override `SKIP_STATIC_GUARD=1`). Each guard has a
documented override env var.
It also guards user-owned auto-merge state on every PR branch, drift-manifest staleness, and a
static gate (lint + source typecheck; override `SKIP_STATIC_GUARD=1`). The auto-merge guard has no
automation override; the other guards retain their documented override env vars.

Domain changes (auth, Supabase, ingestion, answer generation, search/ranking, clinical
output, source governance) additionally want the smallest relevant domain check plus
Expand Down
2 changes: 1 addition & 1 deletion docs/codebase-index.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ Smaller top-level directories that are easy to miss:
| `.codex/` | Trusted Desktop/CLI config; tracked `config.toml` has disabled, secret-free Figma, Supabase, Railway, and Sentry MCP templates. Hosted ChatGPT/Codex apps are installed and authenticated separately; OAuth stays in the host credential store. |
| `.cursor/` | Cursor project rules and local-agent configuration |
| `.design-sync/` | Generated design-system package metadata, validation notes, and project-sync artifacts |
| `.githooks/` | Installed by `npm install`; `pre-push` runs `scripts/guard-push.mjs` (format, auto-merge race, drift staleness, static lint+typecheck) |
| `.githooks/` | Installed by `npm install`; `pre-push` runs `scripts/guard-push.mjs` (user-owned auto-merge preservation, format, drift staleness, static lint+typecheck, ledger write discipline) |
| `.vscode/` | Shared VS Code workspace recommendations and settings |

**Do not commit:** `.next/`, `node_modules/`, `coverage/`, `.env*`, `sample-documents/`, logs.
Expand Down
6 changes: 3 additions & 3 deletions docs/process-hardening.md
Original file line number Diff line number Diff line change
Expand Up @@ -636,9 +636,9 @@ Machinery added to retire repeated traps and surface live-product signal proacti
the durable index for the tooling; `docs/operator-backlog.md` tracks the human-only enablement steps.

- **Pre-push guards** (`.githooks/pre-push` → `scripts/guard-push.mjs`, auto-installed by the
`postinstall` → `scripts/install-git-hooks.mjs`, which sets `core.hooksPath=.githooks`): four guards,
each with an explicit override env var — auto-merge race sentinel (`claude/*`, blocks a push when the
PR's auto-merge is armed; `ALLOW_AUTOMERGE_PUSH=1`), format-before-push (closes the `verify:cheap` vs
`postinstall` → `scripts/install-git-hooks.mjs`, which sets `core.hooksPath=.githooks`): five guards.
The non-bypassable auto-merge ownership guard blocks a push on every PR branch when the PR's
auto-merge is armed. The other guards retain explicit overrides: format-before-push (closes the `verify:cheap` vs
CI `format:check` gap; it reuses only an exact-lock worktree dependency tree and otherwise blocks
with `npm ci --include=dev`; `SKIP_FORMAT_GUARD=1`), drift-manifest freshness
(`SKIP_DRIFT_GUARD=1`), and static gate (changed-file lint + source-only typecheck through the run
Expand Down
Loading
Loading