AGENTS.md § Gates is the one gate list; cli_contract.GATES and docs verify hold it
CI / verify (push) Successful in 6m17s
CI / pwsh (push) Successful in 1m59s
Release / release (push) Successful in 34s

The gate list contradicted itself across AGENTS.md, instructions/gates.md and the
command records' gate names. The Rebase-Review Gate is now listed, `new project`'s
exit 42 is no longer a pseudo-gate, gates.md and the explanation page link to the one
list instead of counting, and a register plus a docs verify check keep the three in step.

Files changed:
- AGENTS.md
- CHANGES.md
- VERSION
- docs/explanation/why-gates-are-code.md
- docs/reference/commands/pages.md
- docs/reference/commands/types-instructions-and-docs.md
- docs/reference/exit-codes.md
- instructions/gates.md
- tools/CONTRACT.md
- tools/chemenu/cli_contract.py
- tools/chemenu/commands/docs_verify.py
- tools/chemenu/commands/doctor.py
- tools/chemenu/commands/git_publish.py
- tools/chemenu/commands/new_page.py
- tools/chemenu/errors.py
- tools/chemenu/mcp/server.py
- tools/chemenu/tests/test_cli_contract.py
- tools/chemenu/tests/test_docs_verify.py
- tools/chemenu/tests/test_git_publish.py
- tools/chemenu/tests/test_reference_doc.py

Co-Authored-By: Claude Code <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SnAJ7Z3CpVD3PRbN73QtU2
This commit is contained in:
torbenandClaude Code committed 2026-10-07 10:10:48 +02:00
1 parent 1559f4b405
commit e9f4759727
20 files changed
+269 -52

No files matched your search

+18 -10
View File
@@ -1,10 +1,8 @@
# Why gates are code
Chemenu has five hard limits - the Mass-Update Gate, the Publish-Remote Gate, the Upload Review
Gate, the Guideline Push Gate, and the Iteration Budget Gate - and all five live inside
`tools/wikitool`, not in a
paragraph of instructions an agent reads and follows. The rules themselves, and what to do when
one trips, are in [AGENTS.md § Gates](../../AGENTS.md#gates) and
Chemenu's hard limits - the gates [AGENTS.md § Gates](../../AGENTS.md#gates) lists - live inside
`tools/wikitool`, not in a paragraph of instructions an agent reads and follows. The rules
themselves, and what to do when one trips, are in [AGENTS.md § Gates](../../AGENTS.md#gates) and
[instructions/gates.md](../../instructions/gates.md). This page is only about the design choice
underneath them: why code, and why these mechanisms in particular.
@@ -34,8 +32,8 @@ well-written instruction - it's that code doesn't get talked into anything.
## Why different mechanisms, not one
The five gates ask four different kinds of question, and each one's shape follows from what kind
of question it is.
The gates ask different kinds of question, and each one's shape follows from what kind of
question it is.
The Mass-Update Gate asks *is this change too large to publish unreviewed* - a judgment that
varies changeset by changeset, so it clears with a `--confirm` token tied to the specific
@@ -51,7 +49,7 @@ editing `.wikitool-remotes.json` directly, outside the gate's own flow.
The Upload Review Gate asks the Mass-Update Gate's own question - *is this change right?* - at
the opposite end of its size range: one file from a stranger instead of a changeset from the
session's own work. That similarity is exactly why it reuses the same shape (a `--confirm` token
digesting the thing being approved) rather than inventing a fourth one: the two gates differ in
digesting the thing being approved) rather than inventing a new one: the two differ in
*who* produced the change and *how much* of it there is, not in what kind of question either one
is answering, so nothing about the mechanism needed to change - only the boundary it sits behind
did, since the submission lives in a quarantine the ordinary pipeline never reads at all rather
@@ -68,14 +66,24 @@ standing, committed declaration - the capture manifests under `raw/` - and askin
URLs in an allowlist as well would be a second declaration of one fact. What is left to ask is
the per-run question, and that is the one a token answers.
The Iteration Budget Gate asks a fourth kind of question - not "is this instance correct" but
The Rebase-Review Gate asks the one question the others cannot: *does what is arriving collide
logically with what I am about to publish?* `sync` and `publish` reconcile with the remote by
rebasing, and when the incoming commits touch a file this session is also changing, git can
produce a clean textual result out of two changes that contradict each other. Whether they do is
a question of meaning, not of text, so the tool cannot answer it - it can only refuse, and show
the incoming commits, the overlapping files and their diff to whoever can. The answer is different
for every rebase, which is why it takes the token shape: the token digests the exact upstream
state and the overlapping files, so a remote that moved again before the re-run is a new
question, asked again.
The Iteration Budget Gate asks a different kind of question - not "is this instance correct" but
"has this session stopped making progress." That's read from the shape of the call history
itself (call count, repeated identical calls), not from anything about the content of any one
call.
## Exit 42 is a posture, and it outgrew the gates
Those five are the named gates, and they are not the only thing that exits 42 any more. When the
Those are the named gates, and they are not the only thing that exits 42 any more. When the
task-tracker provider layer arrived, it brought a case that looks like a gate from the outside and
is not one: a provider whose API cannot create a project (Super Productivity's local REST API
reads projects but does not write them) raises `HumanInterventionRequired`, and the command prints
-1
View File
@@ -85,7 +85,6 @@ tools/wikitool new project --name "Homelab migration" --set responsibility=infra
- Atomic: `new <type>`: Yes - single file write. `new project`: **No** for the tracker-configured case - a tracker-project write (or its human-clearance request) happens before the kb/ page write, so a failure between the two leaves a tracker project with no page (a state `review`'s check 3 already reports), never a page with no tracker project. Still a single file write when no tracker is configured
- Counts toward the session call budget: yes
- Can reach the network: no
- Gates: human-intervention-required (`new project` only) - see [exit codes and gates](../exit-codes.md)
**Exit codes**
@@ -288,6 +288,7 @@ tools/wikitool docs verify
- Every reference file `docs toc` covers carries the current table-of-contents region for its own headings - missing and stale are one check.
- Every relative markdown link in one of those reference files resolves to an existing file. A target's `#anchor` suffix is stripped first, and code fences and inline code spans are masked before scanning, so link syntax shown as an example is not mistaken for a real reference.
- Every file under `docs/` sits in one of its areas - `tutorials/`, `how-to/`, `reference/`, `explanation/` or `dev/` - never directly in `docs/` or in another directory.
- `AGENTS.md` § Gates names exactly the gates in `cli_contract.GATES` (the bold entry names, `- **<Name>.**`), and every gate in that register that ends in exit 42 is declared by at least one command record. A record naming a gate outside the register fails when `wikitool` starts, not here.
- If `docs/` exists: every generated region of the human reference under `docs/reference/` matches what `docs reference` would write, every `cli_contract.GROUPS` entry has its page under `docs/reference/commands/`, and no page there belongs to no group. That includes the four configuration regions in `docs/reference/configuration.md`. The skill catalogue and the page types are checked only in the origin repo (no `.wikitool-release.json`): they describe the stack's shipped defaults, which an instance's own type-specs and instructions may differ from.
- `INSTALL.md` carries one generated `<!-- wikitool:prerequisites -->` region per platform value of `tools/prerequisites.txt` (`prerequisites-<platform>` for a platform-specific one), each current; and the `<!-- setup-question: <key> -->` markers in `instructions/setup-instance.md` and `INSTALL.md` name the same set of keys, so a question the agent asks is never one the human guide leaves out, nor the reverse.
- `VERSION` parses and the newest versioned `CHANGES.md` entry names it. An entry that crosses the compatibility boundary from the last release carries `**Breaking Change:**`, has a migration document or `**Migration:** none required`, and its `**Migration:**` line names every required migration document targeting it.
@@ -316,6 +317,7 @@ tools/wikitool docs verify
- `1` - A page of the human reference is missing or lacks its marker pair, or a page under `docs/reference/commands/` belongs to no group
- `1` - A reference file's table-of-contents region is missing or stale
- `1` - A file sits directly in `docs/`, or in a directory there that is not one of its five areas
- `1` - `AGENTS.md` § Gates and `cli_contract.GATES` disagree, or a register gate that ends in exit 42 is declared by no command record
- `1` - A reference file's relative markdown link does not resolve to an existing file
- `1` - An `INSTALL.md` prerequisites region is stale
- `1` - An `INSTALL.md` prerequisites region is missing, or names a platform no tool has
-4
View File
@@ -12,10 +12,6 @@ What each exit code means, and how a caller reacts to it, is [AGENTS.md § Tool
- [`export guidelines`](commands/guideline-export.md#export-guidelines)
### human-intervention-required (`new project` only)
- [`new`](commands/pages.md#new)
### mass-update
- [`publish`](commands/git.md#publish)