feat(agent): ship gate — checks run at the push, not on request - #838
Merged
Merged
Conversation
patroza
marked this pull request as ready for review
August 3, 2026 18:19
Ports the agent ship gate from macs-scanner, minus everything that does not apply to a library monorepo. `.githooks/pre-push` is a no-op for humans and for draft / no-PR pushes, and runs the full gate on ready PRs. Drafts stay free so sharing early costs nothing. Publishing is gated rather than forbidden: `pnpm pr:ready` is the explicit path and plain `gh pr ready` reaches the same place, because `.tools/bin/gh` runs the gate first and passes the command through when it is green. Nothing to remember, and no way around it. The gate is `pnpm check` -> `pnpm lint` -> `pnpm test`: exactly what ci.yml runs, deliberately not a superset. There is no application to stand up and no browser suite here, so the unit run is the whole gate — `pnpm -r --no-bail test:run` is the closest analogue of the E2E stage the product repos gate on. The validated HEAD SHA is cached under `.run/`, so a commit is validated once however often it is pushed or published, and AGENTS.md now says plainly not to hand-run these checks as routine verification. Repeatedly re-proving one commit is the cost the gate exists to remove, not to add. Two details carried over from what the other ports taught: - The gate supplies its own PATH (node_modules/.bin). pnpm and the hook both provide it, so the dependency stays invisible until something runs the gate from a bare process — which the gh shim does — and it dies with "command not found". - The hook scrubs git's local env vars before running, so nested git commands discover their own repository instead of inheriting the outer push's GIT_DIR. Verified: the shim intercepts `gh pr ready`, runs the gate, and refuses on a dirty worktree. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
`pnpm exec` runs a dependency-status check before the command. When the lockfile
has moved — a rebase does it — pnpm decides node_modules must be purged and
reinstalled, then aborts because a git hook has no TTY:
ERR_PNPM_ABORTED_REMOVE_MODULES_DIR_NO_TTY
The push then fails with a pnpm error that says nothing about the gate, because
the gate never started. Invoke node directly instead; the gate already puts
node_modules/.bin on PATH itself, so pnpm was not providing anything still
needed.
Same class as the other headless failures this work surfaced: a tool changing
behaviour based on TTY or CI detection breaks in a hook, and does it
confusingly.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
patroza
force-pushed
the
feat/agent-ship-gate
branch
from
August 3, 2026 18:24
0a18f8a to
067f372
Compare
@effect-app/cli
effect-app
@effect-app/eslint-codegen-model
@effect-app/eslint-shared-config
@effect-app/infra
@effect-app/vue
@effect-app/vue-components
commit: |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
Validation that depends on an agent remembering to run it produces both failure modes at once: skipped when it matters, and re-run repeatedly through a task when it doesn't. Neither is what you want — the goal is reliability without burning cycles re-proving the same commit.
What
The
macs-scannership gate, minus everything that doesn't apply to a library monorepo..githooks/pre-push— no-op for humans, and for draft / no-PR pushes. Full gate on ready PRs, fail-closed when PR state can't be resolved. Drafts stay free so sharing early costs nothing.pnpm check→pnpm lint→pnpm test— exactly whatci.ymlruns, deliberately not a superset. No application to stand up, no browser suite: here the unit run (pnpm -r --no-bail test:run) is the whole gate, and is the closest analogue of the E2E stage the product repos gate on.pnpm pr:readyis explicit; plaingh pr readyreaches the same place because.tools/bin/ghruns the gate first and passes through when green..run/agent-ship-gate.json, so one commit is validated once however often it is pushed or published.AGENT_SHIP_GATE_FORCE=1overrides.AGENTS.md now says plainly not to hand-run these checks as routine verification, and that narrow targeted proof while iterating is the right tool instead.
How
Two details carried over from porting this to three other repos, each of which was a real bug there:
node_modules/.bin). pnpm and the hook both provide it, so the dependency stays invisible until something runs the gate from a bare process — which theghshim does — and it dies with "command not found".GIT_DIR.The shim is generated by
install-git-hooks.mjsrather than committed, because it embeds the checkout's absolute path;.envrcputs it onPATH, so it applies only inside this repository. Rundirenv allowonce after cloning.Remarks
Verified live: the shim intercepted
gh pr ready, ran the gate, and correctly refused on a dirty worktree.Same rule now stated in
macs-scanner,t3codeandmacs-configurator.🤖 Generated with Claude Code
Need help on this PR? Tag
@codesmith-botwith what you need. Autofix is disabled.