Chemenu 2.1.0 - deterministischer Wissenskompiler
CI / verify (push) Failing after 32s
Release / release (push) Successful in 38s

Chemenu kompiliert Rohnotizen zu einem verlinkten, quellengebundenen Wiki:
raw/ -> types/ + tools/ -> kb/ -> reports/. Was mechanisch ist, macht
tools/wikitool; was Urteil braucht, macht ein Agent unter Contracts, deren
Grenzen in Code durchgesetzt sind statt im Prompt.

Dieser Commit ist der Startpunkt der oeffentlichen Historie. Die vorherige
Entwicklung fand in einer privaten Instanz statt und ist nicht Teil dieses
Repositorys; ihre Erzaehlung steht vollstaendig in CHANGES.md, das mit 44
Eintraegen von 0.1.0 bis 2.1.0 erhalten geblieben ist.

Der mitgelieferte Korpus ist ein Testbett und eine Demo: 170 Seiten ueber den
Stack selbst - Gates, Lint, Versionierung, Suche, das Wiki-Muster. Er
dokumentiert das Werkzeug mit den eigenen Mitteln des Werkzeugs.

Lizenz: AGPL-3.0 fuer den Stack (tools/, types/), CC-BY-4.0 fuer die Inhalte.
Die Grenze zwischen beiden ist der Dateiplan, den dist export berechnet -
siehe NOTICE.
This commit is contained in:
2026-09-01 16:24:34 +02:00
commit 18ae28f918
368 changed files with 50628 additions and 0 deletions
+120
View File
@@ -0,0 +1,120 @@
---
type: types/instruction.md
name: gates
description: What to do when wikitool refuses a call - exit 42 (user clearance required) on publish, and the Iteration Budget Gate and loop-breaker on every command.
---
# When a gate refuses a call
Two limits are enforced in code rather than by instruction, because a prompt-level limit is one
an agent can talk itself past.
**Never open a gate on your own initiative.** Not `--override-budget`, not `budget reset`, not a
`--confirm` token the user has not actually seen and approved.
Read the exit code first - it says which of these applies:
| Exit | Meaning | What to do |
|------|---------|------------|
| 42 | User clearance required | Reproduce the command's output in your reply, stop. See below. |
| 1 | Validation error, or a budget/loop refusal | Read the `ERROR` line; fix and retry once, or stop and escalate. |
## Exit 42: user clearance required
A `wikitool` command that exits **42** is not reporting an error. It is refusing to act until a
human has *read its output*. Two gates use it today - the Mass-Update Gate (`publish`, on a
change touching 10 or more counted files) and the rebase-review gate (`sync` and `publish`, on
a rebase whose incoming commits touch a file this session is also changing) - but the rule is
about the exit code, not the command:
> **Copy the command's output into your reply - the substance of it, not a description of it -
> and stop.** Run no further commands in that turn.
For the Mass-Update Gate that substance is the grouped file breakdown: the area headings, every
path, and the sizes. It is already ordered for a reader - what a bad publish damages most comes
first, and the mechanically-regenerated files come last - so reproducing it in order is both the
cheapest and the most useful thing to do with it.
For the rebase-review gate the substance is different: the commits arriving from the remote,
the files they touch that this session is also touching, and a diff of those files. Read it -
this is the check `sync`/`publish` cannot perform themselves, since a rebase between two commit
ranges that touch disjoint files never reaches this gate at all (no content collision is
possible by construction, so it rebases automatically). Judge whether the incoming change
conflicts logically with what you are about to publish, summarize *that judgment*, not just the
diff, to the user, and only then re-run with the `--confirm-rebase <token>` the refusal prints.
**A command's output is not visible to the user.** On most harnesses stdout goes to the agent's
context, not to the user's screen, so the tool having printed something and the user having seen
it are different events. "See the output above", a summary, a file count, or a description of the
change all leave the user approving something they never read. The one thing that discharges this
is the content itself, restated in the reply.
The output says what would change, lists the evidence, and carries the exact line that proceeds
once the user has approved. Nothing more about the procedure lives here on purpose: a recipe
written down in the instruction layer is one an agent can perform start-to-finish without a human
ever being involved, which is exactly the failure this replaced.
Paths under `work/` are committed but never counted - the gate protects published knowledge, and
a workshop is working state deleted when its run closes ([work/CONTRACT.md](../work/CONTRACT.md)).
Not a gate you may widen: the prefix list is a constant in the tool. `--path <dir>` (repeatable)
scopes a large change into reviewable batches, which is a legitimate alternative to one big
clearance.
Background: [[Mass-Update Gate]] (`kb/concepts/Mass-Update Gate.md`).
## Iteration Budget Gate and loop-breaker
Every `wikitool` call is counted per session. Calls are refused past **60 in a session**, or
after **3 identical calls in a row** - whichever trips first. The check runs before the command
dispatches, so the command never ran.
Calibration: roughly 5-15 calls for a simple task, **20-35** for a complex multi-tool workflow
such as an ingest or a full lint pass. The ceiling sits well clear of that band on purpose -
it is not a target but the point past which a session is presumed stuck, and a real workflow
carries overhead the band does not describe. A session that spends 60 calls on one task has a
decomposition problem regardless of what the individual calls were.
The upper band is measured here, not inherited. It read 15-25 until 2026-08-31, taken from an
industry rule of thumb; four consecutive real ingests then measured 24, 26, 29 and 30 calls,
every one at or above that ceiling while doing nothing unusual. A guideline the normal case
exceeds teaches an agent that the numbers are decorative, which is the opposite of what a
calibration is for. Re-measure it the same way when the workflows change:
`tools/.wikitool_session/budget.json` holds the per-session counts.
**A call that declined is refunded.** A rejected argument, or a read-only check reporting
findings, exits 1 having changed nothing - and the tool error contract answers a rejected
argument with "fix it and retry once", so charging for the rejection would make the prescribed
response cost two slots for one operation. The call still enters the loop-breaker's history:
repeating the same broken invocation is exactly what that instrument is for.
When it trips:
1. Stop. Retrying is the failure mode the gate exists to prevent.
2. Summarise progress and the blocker to the user. `tools/wikitool budget status` stays
readable at all times and is never counted.
3. Wait for explicit approval.
**`budget reset` is not the escape hatch.** It is deliberately counted like any other call, so
at exactly the limit it is refused too. The only way past is `--override-budget` on the
command you actually need to run, and only with the user's approval.
`wikitool search` is exempt from this budget entirely: retrieval is reading, not iterating.
### Taking a new session id
The budget is scoped by `WIKITOOL_SESSION_ID` ([session-setup.md](session-setup.md)), so a new
id is a new budget. That is legitimate for a task made of several planned units - a tree
ingest publishes one unit at a time - and is *not* legitimate as a way past a refusal.
**A new session id may only be taken at a unit boundary written down in the run's `plan.md`,
never in response to a gate refusal.** The plan is the human approval the gate would otherwise
have to ask for; a refusal means that approval has not been given yet. If you are tempted to
re-export the variable after an `ERROR` line, that is the gate working.
Background: [[Iteration and Cost Limits]] (`kb/concepts/Iteration and Cost Limits.md`).
## Scope
This covers refusals by *gates*. An ordinary validation error (a bad argument, a missing page,
a duplicate title) is not a gate: fix the input and retry once, per the error contract in
[tools/CONTRACT.md](../tools/CONTRACT.md).