Rule 6 tells agents to tag unprompted at the end of a task, and the Inception Oath says the tag is "the machine-readable assertion that the Oath was kept". Nothing connects the two. On 2026-10-08 mathias/doodle was tagged v0.1.0 by an agent while G2, G3 and G4 did not hold and main had been red since birth. Both the process rule and the agent's own checklist said "tag", and no control said "not yet".
A repo can now ship a gate (mathias/doodle has scripts/oath-check.sh and task release:gate, which exits 1 while an Oath clause is open). A repo-local gate only binds whoever remembers to run it. This issue is about making the harness run it.
Why a hook, and why more than git tag
A tag can be created by at least four paths, and a hook on one leaves three open:
git tag ... in Bash (also git -C <dir> tag, git tag -a, a lightweight git tag v1).
git push of a tag (git push origin v1.2.3, git push --tags, git push --follow-tags, refs/tags/...).
The Gitea MCP tag_create tool.
The Gitea MCP tbd_ship tool, and release_create, which can create the tag as a side effect.
Proposed
A PreToolUse hook in this plugin (it already ships secret-guard and pre-task-ritual, see #48) that, when a tag-creating action is detected:
looks for a gate in the target repo: scripts/release-gate.sh, else task release:gate if the Taskfile defines it;
runs it and denies the tool call on a non-zero exit, with the gate's own output as the reason;
allows with a one-line warning when the repo has no gate. Failing closed here would block tagging in the ~56 repos that have none; whether that should change is a decision, see Open question.
Honest limits (write these into the hook's header)
It binds Claude Code only. Crush, Pi and OpenCode have no plugin hooks, so they stay unguarded.
A hook is a preventer for the paths it recognises. Anything it does not recognise (a script that calls git tag internally, an alias) passes. CI on tag push is the second layer and belongs in each repo's workflow.
The gate checks what the repo's gate checks. oath-check.sh verifies that the Oath table has no open clause; it does not verify that a locator such as a CI run id is true.
Acceptance Criteria
Each case is run by executing the hook with a crafted tool-call payload, not by reading the code:
Bash git tag -a v1.0.0 -m x in a repo whose gate exits 1: denied, reason contains the gate output.
Same repo, gate exits 0: allowed.
Repo with no gate: allowed, a warning line is emitted.
Each of these is recognised as tag creation and denied under a failing gate: git tag v1, git -C /path tag -a v1 -m x, git push origin v1.2.3, git push --tags, git push --follow-tags, git push origin refs/tags/v1.
MCP tag_create, tbd_ship and release_create payloads with a failing gate: denied.
git tag -l, git tag --list, git tag --sort=-v:refname (read-only) are not blocked. A gate that blocks git tag -l would break the "check live tags before tagging" footgun rule.
A gate that hangs is killed after a timeout and the call is denied (fail closed on the gate, open only when there is no gate).
The hook has its own test file in tests/, wired into task check, and each deny case above has a test that fails if the hook is removed.
Reviewed by skills:pr-gatekeeper with instructions to verify by execution (control code, rule 8). The verdict is recorded on this issue.
Risk: MEDIUM
Open question (not for the agent to decide)
Should a repo with no gate fail open (proposed) or closed? Closed is safer and forces every repo to grow a gate; open keeps the estate working today. Raise it as DECISION NEEDED when the first PR for this lands.
Source
mathias/doodle retro: docs/retro/2026-10-08-remotion-bootstrap.md. Related: #48 (shipping hooks from the plugin), brain a-green-gate-is-not-evidence-for-control-code.
## Problem
Rule 6 tells agents to tag unprompted at the end of a task, and the Inception Oath says the tag is "the machine-readable assertion that the Oath was kept". Nothing connects the two. On 2026-10-08 `mathias/doodle` was tagged `v0.1.0` by an agent while G2, G3 and G4 did not hold and `main` had been red since birth. Both the process rule and the agent's own checklist said "tag", and no control said "not yet".
A repo can now ship a gate (`mathias/doodle` has `scripts/oath-check.sh` and `task release:gate`, which exits 1 while an Oath clause is open). A repo-local gate only binds whoever remembers to run it. This issue is about making the harness run it.
## Why a hook, and why more than `git tag`
A tag can be created by at least four paths, and a hook on one leaves three open:
1. `git tag ...` in Bash (also `git -C <dir> tag`, `git tag -a`, a lightweight `git tag v1`).
2. `git push` of a tag (`git push origin v1.2.3`, `git push --tags`, `git push --follow-tags`, `refs/tags/...`).
3. The Gitea MCP `tag_create` tool.
4. The Gitea MCP `tbd_ship` tool, and `release_create`, which can create the tag as a side effect.
## Proposed
A `PreToolUse` hook in this plugin (it already ships `secret-guard` and `pre-task-ritual`, see #48) that, when a tag-creating action is detected:
- looks for a gate in the target repo: `scripts/release-gate.sh`, else `task release:gate` if the Taskfile defines it;
- runs it and **denies** the tool call on a non-zero exit, with the gate's own output as the reason;
- **allows with a one-line warning** when the repo has no gate. Failing closed here would block tagging in the ~56 repos that have none; whether that should change is a decision, see Open question.
## Honest limits (write these into the hook's header)
- It binds Claude Code only. Crush, Pi and OpenCode have no plugin hooks, so they stay unguarded.
- A hook is a preventer for the paths it recognises. Anything it does not recognise (a script that calls `git tag` internally, an alias) passes. CI on tag push is the second layer and belongs in each repo's workflow.
- The gate checks what the repo's gate checks. `oath-check.sh` verifies that the Oath table has no open clause; it does not verify that a locator such as a CI run id is true.
## Acceptance Criteria
Each case is run by executing the hook with a crafted tool-call payload, not by reading the code:
- [ ] Bash `git tag -a v1.0.0 -m x` in a repo whose gate exits 1: denied, reason contains the gate output.
- [ ] Same repo, gate exits 0: allowed.
- [ ] Repo with no gate: allowed, a warning line is emitted.
- [ ] Each of these is recognised as tag creation and denied under a failing gate: `git tag v1`, `git -C /path tag -a v1 -m x`, `git push origin v1.2.3`, `git push --tags`, `git push --follow-tags`, `git push origin refs/tags/v1`.
- [ ] MCP `tag_create`, `tbd_ship` and `release_create` payloads with a failing gate: denied.
- [ ] `git tag -l`, `git tag --list`, `git tag --sort=-v:refname` (read-only) are **not** blocked. A gate that blocks `git tag -l` would break the "check live tags before tagging" footgun rule.
- [ ] A gate that hangs is killed after a timeout and the call is denied (fail closed on the gate, open only when there is no gate).
- [ ] The hook has its own test file in `tests/`, wired into `task check`, and each deny case above has a test that fails if the hook is removed.
- [ ] Reviewed by `skills:pr-gatekeeper` with instructions to verify by execution (control code, rule 8). The verdict is recorded on this issue.
**Risk:** MEDIUM
## Open question (not for the agent to decide)
Should a repo with no gate fail open (proposed) or closed? Closed is safer and forces every repo to grow a gate; open keeps the estate working today. Raise it as `DECISION NEEDED` when the first PR for this lands.
## Source
`mathias/doodle` retro: `docs/retro/2026-10-08-remotion-bootstrap.md`. Related: #48 (shipping hooks from the plugin), brain `a-green-gate-is-not-evidence-for-control-code`.
---
_Created via git-mcp on behalf of @mathias_
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Problem
Rule 6 tells agents to tag unprompted at the end of a task, and the Inception Oath says the tag is "the machine-readable assertion that the Oath was kept". Nothing connects the two. On 2026-10-08
mathias/doodlewas taggedv0.1.0by an agent while G2, G3 and G4 did not hold andmainhad been red since birth. Both the process rule and the agent's own checklist said "tag", and no control said "not yet".A repo can now ship a gate (
mathias/doodlehasscripts/oath-check.shandtask release:gate, which exits 1 while an Oath clause is open). A repo-local gate only binds whoever remembers to run it. This issue is about making the harness run it.Why a hook, and why more than
git tagA tag can be created by at least four paths, and a hook on one leaves three open:
git tag ...in Bash (alsogit -C <dir> tag,git tag -a, a lightweightgit tag v1).git pushof a tag (git push origin v1.2.3,git push --tags,git push --follow-tags,refs/tags/...).tag_createtool.tbd_shiptool, andrelease_create, which can create the tag as a side effect.Proposed
A
PreToolUsehook in this plugin (it already shipssecret-guardandpre-task-ritual, see #48) that, when a tag-creating action is detected:scripts/release-gate.sh, elsetask release:gateif the Taskfile defines it;Honest limits (write these into the hook's header)
git taginternally, an alias) passes. CI on tag push is the second layer and belongs in each repo's workflow.oath-check.shverifies that the Oath table has no open clause; it does not verify that a locator such as a CI run id is true.Acceptance Criteria
Each case is run by executing the hook with a crafted tool-call payload, not by reading the code:
git tag -a v1.0.0 -m xin a repo whose gate exits 1: denied, reason contains the gate output.git tag v1,git -C /path tag -a v1 -m x,git push origin v1.2.3,git push --tags,git push --follow-tags,git push origin refs/tags/v1.tag_create,tbd_shipandrelease_createpayloads with a failing gate: denied.git tag -l,git tag --list,git tag --sort=-v:refname(read-only) are not blocked. A gate that blocksgit tag -lwould break the "check live tags before tagging" footgun rule.tests/, wired intotask check, and each deny case above has a test that fails if the hook is removed.skills:pr-gatekeeperwith instructions to verify by execution (control code, rule 8). The verdict is recorded on this issue.Risk: MEDIUM
Open question (not for the agent to decide)
Should a repo with no gate fail open (proposed) or closed? Closed is safer and forces every repo to grow a gate; open keeps the estate working today. Raise it as
DECISION NEEDEDwhen the first PR for this lands.Source
mathias/doodleretro:docs/retro/2026-10-08-remotion-bootstrap.md. Related: #48 (shipping hooks from the plugin), braina-green-gate-is-not-evidence-for-control-code.Created via git-mcp on behalf of @mathias