Skip to content

feat(dx): Wave 1 session guards — retire repeated push-time traps#583

Merged
BigSimmo merged 1 commit into
mainfrom
claude/session-guards
Jul 13, 2026
Merged

feat(dx): Wave 1 session guards — retire repeated push-time traps#583
BigSimmo merged 1 commit into
mainfrom
claude/session-guards

Conversation

@BigSimmo

Copy link
Copy Markdown
Owner

What

First PR of the repo-productivity program. Encodes this repo's most-repeated traps into machinery.

  • scripts/guard-push.mjs — pre-push safety net, three guards each with an explicit override:
    • Auto-merge race sentinel (claude/* only): blocks a push when the branch's open PR has auto-merge armed, which has orphaned late commits before. Override ALLOW_AUTOMERGE_PUSH=1; fails open when gh is missing/unauthenticated.
    • Format-before-push: prettier --check on the pushed files, closing the verify:cheap (no format) vs CI (format required) gap. Override SKIP_FORMAT_GUARD=1.
    • Drift-manifest freshness: blocks when supabase/schema.sql changed without regenerating drift-manifest.json. Override SKIP_DRIFT_GUARD=1.
    • Includes --self-test.
  • .githooks/pre-push + scripts/install-git-hooks.mjs — auto-installed via a bulletproof postinstall (the SessionStart hook is remote-gated, so postinstall is the reliable local/CI/remote install point).
  • scripts/check-base-freshness.mjs — advisory stale-base tripwire, wired into a second SessionStart hook. Never blocks.
  • docs/operator-backlog.md — consolidates operator/provider-gated actions out of chat memory. Statuses seeded from runbooks; 🔎 verify rows must be confirmed against live state.
  • tests/guard-push.test.ts — 13 tests incl. a sha-parity lock keeping guard-push byte-identical to check-drift's normalizedSchemaSha256.

Verification

Local: --self-test, 13/13 vitest, eslint, tsc --noEmit, prettier, and a live pre-push smoke against real git — all green. No product/runtime code, no migrations; dev-tooling only.

🤖 Generated with Claude Code

Adds a committed pre-push safety net plus session/operator tooling that
encodes this repo's most-repeated traps into machinery:

- guard-push.mjs: auto-merge race sentinel (claude/* only; blocks when a
  PR's auto-merge is armed, ALLOW_AUTOMERGE_PUSH override, fails open when
  gh absent), format-before-push (closes verify:cheap vs CI gap,
  SKIP_FORMAT_GUARD override), drift-manifest freshness (SKIP_DRIFT_GUARD
  override). Includes --self-test.
- .githooks/pre-push + install-git-hooks.mjs, auto-installed via a
  bulletproof postinstall (session-start.sh is remote-gated, so postinstall
  is the reliable local/CI/remote install point).
- check-base-freshness.mjs: advisory stale-base tripwire wired into a
  second SessionStart hook (never blocks).
- docs/operator-backlog.md: consolidates operator/provider-gated actions
  out of chat memory (statuses seeded from runbooks — confirm before trust).
- tests/guard-push.test.ts: 13 tests incl. sha-parity lock vs check-drift.

Verified: self-test, 13/13 vitest, eslint, tsc --noEmit, prettier, and a
live pre-push smoke against real git all green.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@supabase

supabase Bot commented Jul 13, 2026

Copy link
Copy Markdown

This pull request has been ignored for the connected project sjrfecxgysukkwxsowpy because there are no changes detected in supabase directory. You can change this behaviour in Project Integrations Settings ↗︎.


Preview Branches by Supabase.
Learn more about Supabase Branching ↗︎.

@BigSimmo
BigSimmo enabled auto-merge (squash) July 13, 2026 13:43
@BigSimmo
BigSimmo merged commit b8b4843 into main Jul 13, 2026
14 of 17 checks passed

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 08a83b87d6

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread scripts/guard-push.mjs
if (process.env.SKIP_FORMAT_GUARD === "1") {
return { name: "format", ok: true, skipped: "SKIP_FORMAT_GUARD=1" };
}
const existing = changedFiles.filter((f) => existsSync(f));

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Check committed files instead of the worktree

When the worktree is dirty after the commit being pushed, this guard runs Prettier on the filesystem copy of each path rather than the localSha that the pre-push hook parsed from stdin. A committed unformatted change can pass if the developer ran npm run format but forgot to commit the result, and a clean pushed commit can be blocked by later unstaged edits; CI still checks the pushed tree. A small repro is to commit an unformatted file, format it without committing, then push—the guard passes while format:check on the pushed commit would fail.

Useful? React with 👍 / 👎.

Comment thread scripts/guard-push.mjs
} catch {
return { name: "drift", ok: true, note: "drift-manifest.json unreadable — drift check skipped" };
}
const verdict = driftVerdict(readFileSync(SCHEMA_PATH, "utf8"), manifest);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Compare the pushed schema and manifest

For the same dirty-worktree case, the drift guard compares the current filesystem schema.sql and drift-manifest.json, not the versions in the commit identified by the pre-push localSha. If someone changes supabase/schema.sql, commits it with a stale manifest, then regenerates the manifest but forgets to commit that file, this check reports fresh and allows a push that check:drift will reject in CI. Read both files from the pushed tree or require the relevant paths to be clean before accepting the guard result.

Useful? React with 👍 / 👎.

@coderabbitai

coderabbitai Bot commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: fded05e9-651a-4db3-8301-8de9efd20957

📥 Commits

Reviewing files that changed from the base of the PR and between a180fb2 and 08a83b8.

📒 Files selected for processing (8)
  • .claude/settings.json
  • .githooks/pre-push
  • docs/operator-backlog.md
  • package.json
  • scripts/check-base-freshness.mjs
  • scripts/guard-push.mjs
  • scripts/install-git-hooks.mjs
  • tests/guard-push.test.ts

📝 Walkthrough

Summary by CodeRabbit

  • New Features

    • Added pre-push safety checks for formatting, schema drift, and auto-merge conflicts.
    • Added automatic Git hook installation and commands for running guard and freshness checks.
    • Added advisory detection for branches that fall behind the main branch.
  • Documentation

    • Added an operator backlog with launch, deployment, configuration, and disaster-recovery checklists.
  • Tests

    • Added coverage for push-range parsing, formatting normalization, auto-merge protection, and schema freshness validation.

Walkthrough

Adds pre-push guards for auto-merge races, formatting, and schema drift; installs the committed hook; introduces advisory base-freshness reporting; wires related npm and session-start commands; and documents operator backlog actions.

Changes

Push Safety and Freshness

Layer / File(s) Summary
Push guard decisions and validation
scripts/guard-push.mjs, tests/guard-push.test.ts
Parses pushed ranges and evaluates auto-merge, Prettier, and schema-drift checks, with overrides, reporting, orchestration, exports, and self-tests.
Git hook installation and command wiring
.githooks/pre-push, scripts/install-git-hooks.mjs, package.json
Installs .githooks during post-install, exposes guard commands, and delegates pre-push execution to guard-push.mjs.
Base freshness reporting
scripts/check-base-freshness.mjs, .claude/settings.json, package.json
Checks origin/main ahead/behind counts with configurable output and strictness, and invokes the check during session start.
Operational action index
docs/operator-backlog.md
Documents launch, post-deploy, environment configuration, and disaster-recovery actions with statuses and verification details.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Developer
  participant SessionStart
  participant FreshnessCheck
  participant Git
  Developer->>SessionStart: start session
  SessionStart->>FreshnessCheck: run check-base-freshness.mjs
  FreshnessCheck->>Git: fetch and inspect origin/main...HEAD
  Git-->>FreshnessCheck: ahead/behind counts
  FreshnessCheck-->>Developer: print freshness status
Loading
sequenceDiagram
  participant PackageInstall
  participant GitConfig
  participant PrePushHook
  participant GuardPush
  PackageInstall->>GitConfig: set core.hooksPath to .githooks
  PrePushHook->>GuardPush: pass pre-push arguments and stdin
  GuardPush-->>PrePushHook: exit with push decision
Loading
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch claude/session-guards
✨ Simplify code
  • Create PR with simplified code
  • Commit simplified code in branch claude/session-guards

Comment @coderabbitai help to get the list of available commands.

BigSimmo added a commit that referenced this pull request Jul 13, 2026
…stinstall

- check-docs-links: markdown link targets now resolve relative to the
  containing file (and accept the repo-root-relative convention), are
  confined to the repository root, and docs/redesign + docs/superpowers
  are scanned by default while archive/audit/dated records stay behind
  --all (review findings from Codex and CodeRabbit)
- Dockerfile + Dockerfile.worker: copy scripts/install-git-hooks.mjs into
  the npm ci stages — main's #583 added it as the npm postinstall hook, so
  every image build failed at npm ci with the module missing

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
BigSimmo added a commit that referenced this pull request Jul 13, 2026
#584)

* docs: refresh README, add docs index and link checker, fix stale paths

- README: correct the verify:cheap chain, document verify:pr-local, and
  rewrite the CI paragraph to match the risk-scoped ci.yml jobs
  (changes/static-pr/pr-required aggregate, gated release-browser-matrix)
- Add docs/README.md: categorized index of all docs distinguishing
  maintained docs from point-in-time records and archive
- Rewrite docs/agents-guide.md as a non-duplicating pointer to AGENTS.md,
  codebase-index, and the new docs index
- Add scripts/check-docs-links.mjs + `npm run docs:check-links` (advisory;
  not wired into verify chains) to catch dead repo-path references
- Fix stale references it found: phantom favourites-home-page.tsx in the
  site-map generator (regenerated docs/site-map.md), ambiguous
  src/lib/supabase paths in codebase-index, archived phase-0 link in
  search-rag-master-context

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix: resolve doc links relative to their file; unbreak image-build postinstall

- check-docs-links: markdown link targets now resolve relative to the
  containing file (and accept the repo-root-relative convention), are
  confined to the repository root, and docs/redesign + docs/superpowers
  are scanned by default while archive/audit/dated records stay behind
  --all (review findings from Codex and CodeRabbit)
- Dockerfile + Dockerfile.worker: copy scripts/install-git-hooks.mjs into
  the npm ci stages — main's #583 added it as the npm postinstall hook, so
  every image build failed at npm ci with the module missing

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
@BigSimmo
BigSimmo deleted the claude/session-guards branch July 13, 2026 16:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant