feat: export guidelines - the guideline pages as a generated GUIDELINES.md, pushed into the captured repositories behind the Guideline Push Gate (#179)
Files changed: - AGENTS.md - CHANGES.md - README.md - VERSION - docs/why-gates-are-code.md - instructions/gates.md - instructions/kb-profiles.md - kb/CONTRACT.md - kb/CONVENTIONS.md - kb/CONVENTIONS.md.template - raw/CONTRACT.md - tools/CONTRACT.md - tools/README.md - tools/chemenu/cli.py - tools/chemenu/cli_contract.py - tools/chemenu/commands/export_cmd.py - tools/chemenu/commands/page_ops.py - tools/chemenu/commands/raw_cmd.py - tools/chemenu/commands/search.py - tools/chemenu/guideline_export.py - tools/chemenu/kb_scan.py - tools/chemenu/repo_capture.py - tools/chemenu/search/filters.py - tools/chemenu/tests/test_cli.py - tools/chemenu/tests/test_export_guidelines.py Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SnAJ7Z3CpVD3PRbN73QtU2
This commit is contained in:
1 parent
ccede04b97
commit
283cdae8be
25 files changed
+1753
-68
No files matched your search
+41
-6
@@ -1,7 +1,7 @@
|
||||
---
|
||||
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.
|
||||
description: What to do when wikitool refuses a call - exit 42 (user clearance required) on publish, upload accept and export guidelines --push, and the Iteration Budget Gate and loop-breaker on every command.
|
||||
---
|
||||
|
||||
# When a gate refuses a call
|
||||
@@ -25,6 +25,7 @@ Read the exit code first - it says which of these applies:
|
||||
- [Exit 42: user clearance required](#exit-42-user-clearance-required)
|
||||
- [Publish-Remote Gate](#publish-remote-gate)
|
||||
- [Upload Review Gate](#upload-review-gate)
|
||||
- [Guideline Push Gate](#guideline-push-gate)
|
||||
- [Iteration Budget Gate and loop-breaker](#iteration-budget-gate-and-loop-breaker)
|
||||
- [Taking a new session id](#taking-a-new-session-id)
|
||||
- [Scope](#scope)
|
||||
@@ -33,12 +34,13 @@ Read the exit code first - it says which of these applies:
|
||||
## 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*. Four gates use it today - the Mass-Update Gate (`publish`, on a
|
||||
human has *read its output*. Five gates use it today - the Mass-Update Gate (`publish`, on a
|
||||
change touching 10 or more counted files), the rebase-review gate (`sync` and `publish`, on
|
||||
a rebase whose incoming commits touch a file this session is also changing), the
|
||||
Publish-Remote Gate (`publish`, on a push to a target this checkout has not declared), and the
|
||||
Upload Review Gate (`upload accept`, on a submission nobody has cleared yet) - but the
|
||||
rule is about the exit code, not the command:
|
||||
Publish-Remote Gate (`publish`, on a push to a target this checkout has not declared), the
|
||||
Upload Review Gate (`upload accept`, on a submission nobody has cleared yet), and the Guideline
|
||||
Push Gate (`export guidelines --push`, before a generated `GUIDELINES.md` goes into any captured
|
||||
repository) - 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.
|
||||
@@ -104,7 +106,7 @@ checkout is in, WARNing only when there is more than one remote and no allowlist
|
||||
file is an error rather than "no restriction": a corrupted safeguard must not read as a disabled
|
||||
one.
|
||||
|
||||
**This gate has no `--confirm` token, on purpose.** The other three clear with a token because the
|
||||
**This gate has no `--confirm` token, on purpose.** The others clear with a token because the
|
||||
question they ask ("is this change right?") is one the agent can put to the user and the user can
|
||||
answer for that one changeset. This one asks "does this content belong to that repository?", which
|
||||
is a standing property of the checkout, not a per-push judgment. The way past it is for the user
|
||||
@@ -133,6 +135,39 @@ Mass-Update Gate's review report versus this file's exit-42 procedure.
|
||||
all** - rejecting needs no clearance, only accepting a stranger's file into the pipeline does. It
|
||||
deletes the material and keeps only the reason and a sha256 in `mcp-upload/ledger.jsonl`.
|
||||
|
||||
### Guideline Push Gate
|
||||
|
||||
`wikitool export guidelines --push` writes this instance's guideline pages, rendered into one
|
||||
generated `GUIDELINES.md`, straight onto the branch of every captured repository that opted in -
|
||||
no pull request, no review on the other side. That is the one write this stack makes into a
|
||||
repository it does not own, and on a public target the content is public the moment it lands. So
|
||||
the first run fetches and builds everything, pushes nothing, and exits 42.
|
||||
|
||||
Its substance, which your reply reproduces in full:
|
||||
|
||||
- **Every target and its status** - `new`, `changed`, `unchanged`, or `skipped` with the reason
|
||||
(a tag rule, not reachable, not opted in, a hand-written file, another instance's file). A
|
||||
skipped line is part of the answer: the user may have expected that repository to be written.
|
||||
- **The diff of `GUIDELINES.md` for every target it would write**, against what that repository
|
||||
carries now. This is what the user approves - the text that will appear there, not a count of
|
||||
repositories.
|
||||
- **The re-run line** with `--confirm <token>`, which you run only after the user approved this
|
||||
exact set.
|
||||
|
||||
The token digests each target's URL, branch, the tip the commit builds on, and the file's
|
||||
content, so a branch that moved, a guideline edited since, or a newly captured repository makes
|
||||
it stale: the next run is gated again with the current state. A run with nothing to write ends
|
||||
with exit 0 and no gate.
|
||||
|
||||
**Not the Publish-Remote Gate.** That one stays on `publish`. The targets here are declared by
|
||||
the committed `_capture.json` manifests under `raw/`; asking for the same URLs in
|
||||
`.wikitool-remotes.json` as well would be a second declaration of the same thing. What this gate
|
||||
asks instead is the per-run question - whether this content belongs in these repositories now -
|
||||
which is the kind a token answers.
|
||||
|
||||
A push the branch moved under is rejected, never forced, and reported as `rejected`; running the
|
||||
whole command again (and clearing it again) serves that repository.
|
||||
|
||||
## Iteration Budget Gate and loop-breaker
|
||||
|
||||
Every `wikitool` call is counted per session. Calls are refused past **60 in a session**, or
|
||||
|
||||
@@ -55,7 +55,7 @@ is not a profile.
|
||||
|
||||
| File | Holds | Profiles below |
|
||||
|---|---|---|
|
||||
| `kb/CONVENTIONS.md` | Language, section headings, naming forms, tone, relationship labels, the hedging rule - once per instance | [Language profiles](#language-profiles) |
|
||||
| `kb/CONVENTIONS.md` | Language, section headings, naming forms, tone, relationship labels, the hedging rule, which pages leave as guidelines - once per instance | [Language profiles](#language-profiles) |
|
||||
| `kb/<name>/COLLECTION.md` | What one collection holds, its quality goal, its local linking and naming rules | [Collection profiles](#collection-profiles) |
|
||||
|
||||
2. **Copy the entry's text into the file**, then edit it until it is true of this instance.
|
||||
|
||||
Reference in new issue
Block a user