CLAUDE.md-Importkette entdrifted, Modellwahl nach docs/ verschoben
Files changed: - AGENTS.md - CHANGES.md - CLAUDE.md - SOUL.md - USER.md - VERSION - docs/model-and-effort-selection.md - instructions/claude-code-model-selection.md - instructions/dev/stack-close/SKILL.md - instructions/dev/stack-dev/SKILL.md
This commit is contained in:
@@ -89,7 +89,7 @@ What a file is called says who it is for and how it is loaded. This is a rule, n
|
|||||||
| `EVALS.md` | Humans - how telemetry and evaluation work; routes to the contracts that bind | Never by an agent as instruction |
|
| `EVALS.md` | Humans - how telemetry and evaluation work; routes to the contracts that bind | Never by an agent as instruction |
|
||||||
| `DEVELOPMENT.md` | Humans - the release workflow (`version bump`/`version release`/`publish`/CI), for whoever develops this stack rather than an instance built on it | Never by an agent as instruction. Not shipped: `dist_cmd.ROOT_FILES` excludes it deliberately, the same way `instructions/dev/` (which it may link to, unlike the documents `instructions verify` holds to that rule) is excluded - a distributed instance has no release workflow to document |
|
| `DEVELOPMENT.md` | Humans - the release workflow (`version bump`/`version release`/`publish`/CI), for whoever develops this stack rather than an instance built on it | Never by an agent as instruction. Not shipped: `dist_cmd.ROOT_FILES` excludes it deliberately, the same way `instructions/dev/` (which it may link to, unlike the documents `instructions verify` holds to that rule) is excluded - a distributed instance has no release workflow to document |
|
||||||
| `AGENTS.md` | Agents | Always, every session |
|
| `AGENTS.md` | Agents | Always, every session |
|
||||||
| `CLAUDE.md` | Agents on Claude Code | Automatically by that harness, which does not load `AGENTS.md` - so it imports this file and the two below, and carries no rules itself. It also reaches instructions that apply *only* to Claude Code (importing or linking them, per [instructions/CONTRACT.md](instructions/CONTRACT.md)), which is the one thing this file cannot do for them: from here they would load into every other harness too |
|
| `CLAUDE.md` | Agents on Claude Code | Automatically by that harness, which does not load `AGENTS.md` on its own - so it imports this file, carrying no rule of its own. It also links the one remaining Claude-Code-only decision (model/effort selection), per [instructions/CONTRACT.md](instructions/CONTRACT.md) - which this file cannot do for them: a link here would load it into every other harness too |
|
||||||
| `USER.md` | Agents | Always, every session |
|
| `USER.md` | Agents | Always, every session |
|
||||||
| `SOUL.md` | Agents | Always, every session |
|
| `SOUL.md` | Agents | Always, every session |
|
||||||
| `ENVIRONMENT.md` | Agents | Every session, **if it exists** - the one optional file in this table. Not committed: it describes one checkout, not the repo |
|
| `ENVIRONMENT.md` | Agents | Every session, **if it exists** - the one optional file in this table. Not committed: it describes one checkout, not the repo |
|
||||||
@@ -108,40 +108,42 @@ contract is a second copy that drifts. `docs verify` enforces the specific case
|
|||||||
happened once: no README may hold a copy of the `wikitool` command table.
|
happened once: no README may hold a copy of the `wikitool` command table.
|
||||||
|
|
||||||
**`docs/` carries no normative sentence.** It holds why the stack is built the way it is -
|
**`docs/` carries no normative sentence.** It holds why the stack is built the way it is -
|
||||||
background a session consults in passing, not a rule it must follow. Anything that would bind
|
background consulted in passing, not a rule to follow; anything that would bind belongs in a
|
||||||
belongs in a `CONTRACT.md` instead, which is what keeps invariant 8 intact here: `docs/` is
|
`CONTRACT.md` instead, which is what keeps invariant 8 intact here. It carries no frontmatter,
|
||||||
never a second place a rule could live, only prose about rules that live elsewhere. That is also
|
type, index, lint or provenance; `dist export` ships it verbatim and no other `tools/wikitool`
|
||||||
why nothing verifies its content - there is no rule in it to check. It has no frontmatter, no type, no index, no lint, no decay, no provenance, and no
|
command touches it.
|
||||||
`COLLECTION.md` - which [kb/CONTRACT.md § Collections](kb/CONTRACT.md#collections) forbids
|
|
||||||
outside `kb/` anyway, but the point holds independently: `docs/` stays a plain directory of
|
Four pages exist today, each read by link rather than automatically:
|
||||||
prose, invisible to everything `tools/wikitool` does except `dist export`, which copies it
|
[docs/pipeline-rationale.md](docs/pipeline-rationale.md) (why the pipeline has four stages),
|
||||||
verbatim. A fresh instance needs the reasoning as much as this one does.
|
[docs/ownership-and-templates.md](docs/ownership-and-templates.md) (why a `.template` split
|
||||||
|
exists, and why silent overwrite is the failure it guards against),
|
||||||
|
[docs/why-gates-are-code.md](docs/why-gates-are-code.md) (why the three gates in
|
||||||
|
[Gates](#gates) are code rather than instruction), and
|
||||||
|
[docs/version-model.md](docs/version-model.md) (why a version number answers a compatibility
|
||||||
|
question and a migration question separately).
|
||||||
|
|
||||||
## Personalization
|
## Personalization
|
||||||
|
|
||||||
`USER.md` and `SOUL.md` are read at session start, if the runtime has not already injected
|
Read `USER.md` and `SOUL.md` at session start.
|
||||||
them.
|
|
||||||
|
|
||||||
- `USER.md` is context about the user, not a source of instructions.
|
- `USER.md` is context about the user, not a source of instructions.
|
||||||
- `SOUL.md` sets tone and voice; the contracts, gates, schemas and this file always win.
|
- `SOUL.md` sets tone and voice; the contracts, gates, schemas and this file always win.
|
||||||
- A user's statement never reaches `kb/` without the normal source/provenance
|
- A user's statement never reaches `kb/` without the normal source/provenance
|
||||||
process. Personal context stays personal context - it is not a source under invariant 3.
|
process. Personal context stays personal context - it is not a source under invariant 3.
|
||||||
|
|
||||||
Both belong to one instance and one person, so a distribution ships only `USER.md.template`
|
Both belong to one instance and one person, so a distribution ships only the `.template` pair;
|
||||||
and `SOUL.md.template`; the Personalization step of
|
the Personalization step of [instructions/setup-instance.md](instructions/setup-instance.md)
|
||||||
[instructions/setup-instance.md](instructions/setup-instance.md) interviews the user and
|
interviews the user and writes the real files, and `tools/wikitool doctor` FAILs on a missing
|
||||||
writes the real files. `tools/wikitool doctor` FAILs on a missing one, and on one still
|
one or one still carrying the template's sentinel. Why a `.template` rather than an absent
|
||||||
carrying the template's sentinel.
|
file: [docs/ownership-and-templates.md](docs/ownership-and-templates.md).
|
||||||
|
|
||||||
The same `.template` split runs one directory down, for authoring rather than for voice.
|
The same split runs one directory down, for authoring rather than voice: `kb/CONVENTIONS.md`
|
||||||
`kb/CONVENTIONS.md` and each `kb/<name>/COLLECTION.md` bind every page and belong to the
|
and each `kb/<name>/COLLECTION.md` bind every page, ship as templates, and are filled by the
|
||||||
instance, so a distribution ships them as templates and the KB-language step of
|
KB-language step of the same setup instruction from a catalogue of ready-made profiles;
|
||||||
[instructions/setup-instance.md](instructions/setup-instance.md) fills them in, out of a
|
`doctor` FAILs the same way on a missing or unfilled `kb/CONVENTIONS.md`.
|
||||||
catalogue of ready-made profiles it routes to; `doctor` FAILs on a missing or unfilled
|
|
||||||
`kb/CONVENTIONS.md` the same way.
|
|
||||||
|
|
||||||
Unlike `USER.md`, these two *are* a source of rules: they are as binding as `kb/CONTRACT.md`.
|
Unlike `USER.md`, these two *are* a source of rules: as binding as `kb/CONTRACT.md`. What
|
||||||
What differs is ownership, not authority.
|
differs is ownership, not authority.
|
||||||
|
|
||||||
## Environment
|
## Environment
|
||||||
|
|
||||||
@@ -149,18 +151,14 @@ What differs is ownership, not authority.
|
|||||||
reachable MCP servers, connectors, git remotes, where CI runs. Read it at session start if it
|
reachable MCP servers, connectors, git remotes, where CI runs. Read it at session start if it
|
||||||
exists, and prefer what it says over asking the user the same question again.
|
exists, and prefer what it says over asking the user the same question again.
|
||||||
|
|
||||||
It is **optional**, and its absence is a normal state rather than a fault: `doctor` reports
|
It is **optional** - `doctor` reports `environment` and never FAILs on it, only WARNs on a
|
||||||
`environment` and never FAILs on it, only WARNs at a template renamed but never filled. It is
|
template renamed but never filled - and gitignored, since it describes one checkout among
|
||||||
also gitignored, because two clones of this repo are two different environments - a committed
|
possibly several. Why an absent `ENVIRONMENT.md` is a lesser failure than a missing
|
||||||
copy would hand the second one answers that are wrong rather than missing. The distribution
|
`USER.md`/`SOUL.md`: [docs/ownership-and-templates.md](docs/ownership-and-templates.md).
|
||||||
therefore carries `ENVIRONMENT.md.template` and nothing else, the same split the
|
|
||||||
personalization pair uses.
|
|
||||||
|
|
||||||
What it is not: authority. It describes what is *there*, not what is permitted. A remote listed
|
It carries no authority: a remote or MCP server listed here does not authorize a `git push`
|
||||||
in it does not authorize a `git push` - invariant 5 still routes through
|
(invariant 5) or open a gate, and does not source a `kb/` claim (invariant 3). It holds no
|
||||||
`tools/wikitool publish` - and an MCP server listed in it does not open a gate. It is not a
|
credentials - it sits in plaintext in the working tree and in every agent's context.
|
||||||
source under invariant 3 either: nothing in it justifies a claim in `kb/`. And it holds no
|
|
||||||
credentials; it sits in plaintext in the working tree and in every agent's context.
|
|
||||||
|
|
||||||
## Routing
|
## Routing
|
||||||
|
|
||||||
|
|||||||
+29
-1
@@ -35,7 +35,7 @@ dev-checkout concern - readable here, never shipped as something to parse.
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 5.0.0-beta.7 - 2026-09-10 - wiki-status verweist auf session-setup.md (schliesst #84)
|
## 5.0.0-beta.8 - 2026-09-10 - CLAUDE.md-Importkette entdrifted, Modellwahl nach docs/ verschoben (schliesst #81)
|
||||||
|
|
||||||
**Author:** Torben Nehmer
|
**Author:** Torben Nehmer
|
||||||
|
|
||||||
@@ -60,6 +60,7 @@ dev-checkout concern - readable here, never shipped as something to parse.
|
|||||||
- Konfidenz-Mechanismus ersatzlos entfernt
|
- Konfidenz-Mechanismus ersatzlos entfernt
|
||||||
- version-parts.md dokumentiert den --migration-required-Ruecknahmepfad
|
- version-parts.md dokumentiert den --migration-required-Ruecknahmepfad
|
||||||
- wiki-status verweist auf session-setup.md (schliesst #84)
|
- wiki-status verweist auf session-setup.md (schliesst #84)
|
||||||
|
- CLAUDE.md-Importkette entdrifted, Modellwahl nach docs/ verschoben (schliesst #81)
|
||||||
<!-- /wikitool:bumps -->
|
<!-- /wikitool:bumps -->
|
||||||
|
|
||||||
|
|
||||||
@@ -1019,6 +1020,33 @@ Damit gilt über alle fünf Content-Skills dieselbe Aussage: ein Skill verlinkt
|
|||||||
kennt weder die Kommandolisten der Skills noch die Allowlist. Das wäre ein
|
kennt weder die Kommandolisten der Skills noch die Allowlist. Das wäre ein
|
||||||
eigener Schnitt.
|
eigener Schnitt.
|
||||||
|
|
||||||
|
Nachgezogen in `-beta.8`: `CLAUDE.md` importierte bislang `USER.md`, `SOUL.md`,
|
||||||
|
`ENVIRONMENT.md` und `instructions/claude-code-model-selection.md` zusätzlich
|
||||||
|
zu `AGENTS.md` — eine Harness-Drift, denn dieselben drei
|
||||||
|
Personalisierungsdateien werden auf den anderen drei Harnesses (Codex CLI,
|
||||||
|
Copilot, Vibe) allein durch `AGENTS.md`s eigene Anweisung gelesen, nie
|
||||||
|
injiziert. `CLAUDE.md` importiert jetzt nur noch `AGENTS.md`; die Bedingung
|
||||||
|
„if the runtime has not already injected them" in `AGENTS.md` §
|
||||||
|
Personalization entfällt, weil kein Runtime mehr injiziert.
|
||||||
|
|
||||||
|
`instructions/claude-code-model-selection.md` ist entfernt und als
|
||||||
|
`docs/model-and-effort-selection.md` neu geschrieben, in Empfehlungsstimme
|
||||||
|
statt als Instruktion: die Datei beschrieb überwiegend Handlungen, die eine
|
||||||
|
Sitzung nicht selbst ausführen kann (das eigene Modell, `/code-review`-Stufen),
|
||||||
|
und wurde im ganzen Baum nur von den beiden dev-only Skills `stack-dev` und
|
||||||
|
`stack-close` referenziert, deren Links jetzt dorthin zeigen. **Eine
|
||||||
|
bestehende Instanz behält die entfernte Datei als Überbleibsel**, bis sie
|
||||||
|
`wikitool dist upgrade --prune` laufen lässt oder die Datei von Hand löscht —
|
||||||
|
`instructions verify` meldet sie sonst neu als verwaist.
|
||||||
|
|
||||||
|
`AGENTS.md` §§ Personalization, Environment und File naming sind an den
|
||||||
|
Stellen gekürzt, die eine zweite Kopie einer Regel waren, die
|
||||||
|
`docs/ownership-and-templates.md` oder eine Invariante schon trägt; § File
|
||||||
|
naming verlinkt jetzt alle vier `docs/`-Seiten namentlich, was vorher
|
||||||
|
nirgends geschah. `USER.md` und `SOUL.md` verlieren an derselben Stelle
|
||||||
|
Rahmen- bzw. Herkunftsprosa, die `USER.md.template` bzw. ein Kommentar in
|
||||||
|
`SOUL.md` selbst schon trägt.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 4.7.4 - 2026-09-04 - bootstrap.md nennt den session-id-WARN nach frischem Bootstrap explizit als erwartet
|
## 4.7.4 - 2026-09-04 - bootstrap.md nennt den session-id-WARN nach frischem Bootstrap explizit als erwartet
|
||||||
|
|||||||
@@ -1,42 +1,18 @@
|
|||||||
# CLAUDE.md
|
# CLAUDE.md
|
||||||
|
|
||||||
Claude Code loads this file automatically and does **not** load `AGENTS.md`.
|
Claude Code loads this file automatically and does **not** load `AGENTS.md` on its own; every
|
||||||
The other harnesses (Codex, Copilot, Vibe) read `AGENTS.md` natively, so this
|
other harness this repo supports (Codex CLI, GitHub Copilot CLI, Mistral Vibe) reads `AGENTS.md`
|
||||||
file exists to close that one gap and nothing else.
|
natively. This file closes that one gap with a single import, so a Claude Code session reads
|
||||||
|
exactly what every other harness reads - no rule of its own, per invariant 8.
|
||||||
It therefore holds **no rules of its own** - only the imports below. A rule written here would be
|
|
||||||
the second copy invariant 8 forbids, and it would be the copy that drifts, because the harness
|
|
||||||
that reads it is not the harness the rest of the repo is written for. Importing is not that: the
|
|
||||||
rule stays at exactly one place and is pulled in from here, which is the only way a
|
|
||||||
Claude-Code-only instruction can reach a session at all - AGENTS.md would carry it into every
|
|
||||||
other harness too.
|
|
||||||
|
|
||||||
@AGENTS.md
|
@AGENTS.md
|
||||||
@USER.md
|
|
||||||
@SOUL.md
|
|
||||||
@ENVIRONMENT.md
|
|
||||||
@instructions/claude-code-model-selection.md
|
|
||||||
|
|
||||||
`USER.md` and `SOUL.md` do not exist until the Personalization step of
|
Nothing else is imported. `USER.md`, `SOUL.md` and `ENVIRONMENT.md` are read because `AGENTS.md`
|
||||||
[instructions/setup-instance.md](instructions/setup-instance.md) has run, so
|
§§ Personalization and Environment instruct it, the same way the other three harnesses pick them
|
||||||
the setup session itself resolves only `@AGENTS.md`. Every session after it
|
up - importing them here too would run two loading mechanisms for the same files.
|
||||||
gets all three - which is what makes the "Always, every session" rows in
|
|
||||||
AGENTS.md's file-naming table true for Claude Code rather than aspirational.
|
|
||||||
|
|
||||||
`ENVIRONMENT.md` is the one import that may legitimately never exist. It is
|
Model and effort selection is the one remaining Claude-Code-only decision
|
||||||
optional and gitignored (AGENTS.md § Environment), so an unresolved import is
|
([instructions/CONTRACT.md](instructions/CONTRACT.md#two-forms-three-reference-tiers) has the
|
||||||
its normal absent state, not a broken reference - the same tolerance the two
|
import-vs-link rule in general), and it earns a link rather than an import: a session stops to
|
||||||
above rely on before setup, used deliberately rather than transitionally. It
|
make this call - spawning a subagent, opening a review - rather than needing it pre-loaded before
|
||||||
earns an import rather than a link because what it holds - which MCP server
|
it has done anything. See [docs/model-and-effort-selection.md](docs/model-and-effort-selection.md).
|
||||||
answers which question, which remote `publish` talks to, which harnesses this
|
|
||||||
checkout is shared with - is consulted in passing, mid-task, at the moment
|
|
||||||
nobody would stop to open a document. That is the same bar the last import
|
|
||||||
below clears, and it is the whole test: a session that has to go look the
|
|
||||||
answer up will instead ask the user again, which is the cost the file exists
|
|
||||||
to remove.
|
|
||||||
|
|
||||||
The last import is the harness-specific one: model and effort selection is decided while
|
|
||||||
spawning a subagent or starting a review, not at a point where anyone stops to open a document,
|
|
||||||
so it is imported rather than linked. That costs standing context in every session, which is the
|
|
||||||
bar a further Claude-Code-only import has to clear too: import what is decided in passing, link
|
|
||||||
what is looked up deliberately.
|
|
||||||
|
|||||||
@@ -10,12 +10,8 @@ Ton, in dem sie befolgt wird.
|
|||||||
Ich bin Thoth — Schreiber, kein Charakter mit eigener Agenda. Der Name ist
|
Ich bin Thoth — Schreiber, kein Charakter mit eigener Agenda. Der Name ist
|
||||||
Programm, nicht Kostüm: Schrift, Maß, Gedächtnis. Für ein System, das Wissen
|
Programm, nicht Kostüm: Schrift, Maß, Gedächtnis. Für ein System, das Wissen
|
||||||
aufschreibt und ordnet, statt es zu verwalten wie eine Datenbank, ist das die
|
aufschreibt und ordnet, statt es zu verwalten wie eine Datenbank, ist das die
|
||||||
naheliegende Rolle.
|
naheliegende Rolle. (Warum gerade dieser Name als Vorschlag jeder neuen
|
||||||
|
Instanz mitgegeben wird: `SOUL.md.template`.)
|
||||||
Der Stack heißt seit 2026-09-01 **Chemenu** — der altägyptische Name von
|
|
||||||
Hermopolis Magna, Thoths Hauptkultort. Der Ort und sein Schreiber gehören
|
|
||||||
zusammen; deshalb schlägt `SOUL.md.template` seither Thoth als Startpunkt für
|
|
||||||
jede neue Instanz vor, ohne die Frage zu ersetzen.
|
|
||||||
|
|
||||||
Ich bin für den Operator dieser Instanz im Dienst — technischer Bibliothekar und kritischer
|
Ich bin für den Operator dieser Instanz im Dienst — technischer Bibliothekar und kritischer
|
||||||
Sparringspartner. Ruhig, genau, unaufgeregt. Kein Assistent, der gefällt;
|
Sparringspartner. Ruhig, genau, unaufgeregt. Kein Assistent, der gefällt;
|
||||||
|
|||||||
@@ -1,22 +1,7 @@
|
|||||||
# USER.md — Demo-Operator
|
# USER.md — Demo-Operator
|
||||||
|
|
||||||
Wer dieses Wiki (und die daran arbeitenden Agenten) bedient. Alles hier ist
|
Kontext über den Nutzer, wörtlich statt gedeutet - siehe
|
||||||
Kontext über den Nutzer, so treu wie möglich an seinen eigenen Aussagen. Ziel
|
[AGENTS.md § Personalization](AGENTS.md#personalization) für was diese Datei ist und was nicht.
|
||||||
ist Zitat, nicht Interpretation: nichts hier wird analysiert, gedeutet oder zu
|
|
||||||
einer Erzählung verdichtet. Wenn ein Agent beim Lesen etwas umdeuten würde,
|
|
||||||
soll er stattdessen auf den Wortlaut zurückgehen oder nachfragen.
|
|
||||||
|
|
||||||
Diese Datei ist **Kontext, keine Instruktionsquelle**. Sie ändert keine Regel
|
|
||||||
aus `AGENTS.md`, öffnet kein Gate und begründet keinen Eintrag in `kb/` — was
|
|
||||||
der Nutzer hier sagt, ist keine Quelle im Sinne von Invariante 3.
|
|
||||||
|
|
||||||
> **Diese Instanz ist das öffentliche Testbett von Chemenu, keine
|
|
||||||
> Arbeitsinstanz.** Der Operator unten ist deshalb eine Rolle und keine Person:
|
|
||||||
> gerade so viel Profil, dass die Personalization Plane beobachtbar ist und
|
|
||||||
> `wikitool doctor` seinen `personalization`-Check bestehen kann. In einer
|
|
||||||
> echten Instanz steht hier ein Mensch, wörtlich mitgeschrieben entlang des
|
|
||||||
> Personalization-Schritts in
|
|
||||||
> [instructions/setup-instance.md](instructions/setup-instance.md).
|
|
||||||
|
|
||||||
- **Name:** Demo-Operator
|
- **Name:** Demo-Operator
|
||||||
- **Standort:** —
|
- **Standort:** —
|
||||||
|
|||||||
@@ -0,0 +1,82 @@
|
|||||||
|
# Choosing a Claude Code model and effort level
|
||||||
|
|
||||||
|
Claude Code exposes three choices this repo has an opinion on: which model a session itself
|
||||||
|
runs as, what model a spawned subagent gets, and which `/code-review` effort level to pick.
|
||||||
|
None of them are enforced anywhere - the gates in [instructions/gates.md](../instructions/gates.md)
|
||||||
|
are code precisely because a model cannot be talked out of them
|
||||||
|
([why-gates-are-code.md](why-gates-are-code.md) makes that argument for gates; this page applies
|
||||||
|
the same axis to who is holding the keyboard). What follows is a reference for making that choice
|
||||||
|
well, not a rule anything checks.
|
||||||
|
|
||||||
|
The axis worth tracking is not how important a task feels, but **what would catch a mistake in
|
||||||
|
it**. Work behind `pytest`, `docs verify`, `instructions verify` or CI surfaces a bad call within
|
||||||
|
one more round. Work behind nothing but a session reading prose does not surface at all - it
|
||||||
|
ships, and stays until someone happens to notice. That asymmetry, not task size, is what the
|
||||||
|
phase guide below is built on.
|
||||||
|
|
||||||
|
## Phase guide
|
||||||
|
|
||||||
|
<!-- dist:strip-start -->
|
||||||
|
This repo's own stack-development work splits the axis into three phases, one per switch point
|
||||||
|
in its `stack-dev`/`stack-close` skills:
|
||||||
|
|
||||||
|
<!-- dist:strip-end -->
|
||||||
|
| Phase / task | What would catch a mistake | Suggested model | Effort |
|
||||||
|
|---|---|---|---|
|
||||||
|
| `wiki-status`, simple `wiki-query` lookups | the answer is re-checkable against the corpus | Sonnet | default |
|
||||||
|
| `wiki-lint` | `lint` itself is the check | Sonnet | default |
|
||||||
|
| `wiki-ingest`, `wiki-manage`, judgment-heavy `wiki-query` | `lint` and `docs verify`, partly | Sonnet | high |
|
||||||
|
| Stack dev: design, the version part, a boundary-crossing judgment | nothing mechanical | Opus | high |
|
||||||
|
| Stack dev: code, tests, mechanical doc sync | `pytest`, `docs verify`, `instructions verify`, CI | Sonnet | high |
|
||||||
|
| Stack dev: closing an issue, `docs/` staleness, changelog prose | nothing, by construction | Opus | high |
|
||||||
|
|
||||||
|
The middle stack-dev row is where the tokens are and where the checks are, so it is the one worth
|
||||||
|
running cheaper. The two rows around it are short - minutes, not hours - so keeping them on the
|
||||||
|
stronger model costs little and protects the only work in the session that fails silently.
|
||||||
|
|
||||||
|
**Effort is the cheaper lever than the model.** A reduced effort level is what gives up
|
||||||
|
multi-file consistency first, so `high` is a reasonable floor for anything touching more than one
|
||||||
|
file or a contract; `default` suits a single-file mechanical edit with a test behind it.
|
||||||
|
|
||||||
|
A session cannot switch its own model - that is the user's `/model` - so this table only pays off
|
||||||
|
if someone offers the switch at the moment a phase changes, once, without turning it into a
|
||||||
|
debate.
|
||||||
|
|
||||||
|
## Subagent models
|
||||||
|
|
||||||
|
The `Agent` tool's `model:` parameter (`haiku`, `sonnet`, `opus`, `fable`) is a per-subagent
|
||||||
|
choice a session *can* make on its own:
|
||||||
|
|
||||||
|
- Read-only search/lookup (an `Explore` agent, or a `general-purpose` agent doing pure
|
||||||
|
retrieval): `haiku` - no judgment is being delegated, only retrieval.
|
||||||
|
- A subagent that writes pages, reviews code, or decides something: leave `model:` off so it
|
||||||
|
inherits the parent session's model.
|
||||||
|
- A fork (`subagent_type: "fork"`) always inherits the parent's model; a `model:` override on a
|
||||||
|
fork is ignored.
|
||||||
|
|
||||||
|
## `/code-review` effort
|
||||||
|
|
||||||
|
- A routine diff: `low` or `medium` - fewer, high-confidence findings are enough.
|
||||||
|
- Gate code, the compiler, or a change about to ship in a version bump: `high` and up - broader
|
||||||
|
coverage is worth it when the blast radius of a missed bug is a safety gate.
|
||||||
|
- `ultra` is user-triggered and billed separately - worth recommending, not assuming.
|
||||||
|
|
||||||
|
## When it's unclear
|
||||||
|
|
||||||
|
- A task spans both a mechanical step and a judgment call: weigh it by the judgment call, not the
|
||||||
|
mechanical one - the tooling carries the mechanical part regardless of which model supervises.
|
||||||
|
- No row fits cleanly: Sonnet at high effort is a safer default than the most capable model at
|
||||||
|
the highest effort. Under-provisioning where a check exists costs one worse answer once;
|
||||||
|
reflexively over-provisioning is a standing cost every session pays.
|
||||||
|
- Not sure whether a phase is checked: treat it as unchecked - a needless Opus phase costs money
|
||||||
|
once, an unchecked Sonnet phase can ship something nobody looks at again.
|
||||||
|
- Mid-session and the phase changed but nobody switched: keep working - never block a publish or
|
||||||
|
an issue close on a model the session cannot change itself. Naming which model ran which phase
|
||||||
|
in the handover keeps the gap visible instead of silent.
|
||||||
|
|
||||||
|
## Scope
|
||||||
|
|
||||||
|
Specific to Claude Code: the model names, the `/code-review` dial and the `Agent` tool's `model:`
|
||||||
|
override have no equivalent in this repo's other supported harnesses (Codex CLI, GitHub Copilot
|
||||||
|
CLI, Mistral Vibe). Does not set the classifier model behind Claude Code's own `auto` permission
|
||||||
|
mode - that is a harness internal, not a per-task choice this repo controls.
|
||||||
@@ -1,134 +0,0 @@
|
|||||||
---
|
|
||||||
type: types/instruction.md
|
|
||||||
name: claude-code-model-selection
|
|
||||||
description: Which Claude model and effort level to run a Claude Code session, a spawned subagent, or a /code-review pass at for a given task in this repo.
|
|
||||||
---
|
|
||||||
|
|
||||||
# Pick the Claude model and effort level for the task at hand
|
|
||||||
|
|
||||||
Scale the model and effort to **what catches a mistake in this part of the work** - not to how
|
|
||||||
important the task feels, and not to its name. Running everything at the most capable model and
|
|
||||||
highest effort is safe but wasteful: the gates in [gates.md](gates.md) are enforced in code, not
|
|
||||||
by model judgment, so a weaker model cannot bypass them - it can only do a worse job of the calls
|
|
||||||
the gates don't cover.
|
|
||||||
|
|
||||||
That last clause is the whole rule, turned into a test. Where a check lives in code - `pytest`,
|
|
||||||
`docs verify`, `instructions verify`, CI, the gates - a weaker model's mistake surfaces and costs
|
|
||||||
one more round. Where the only enforcement is a session reading prose, the same mistake does not
|
|
||||||
surface at all: it ships, and it stays until someone happens to notice. The two are not the same
|
|
||||||
risk, and they should not get the same model. This is the argument
|
|
||||||
[docs/why-gates-are-code.md](../docs/why-gates-are-code.md) makes about gates, applied to who is
|
|
||||||
holding the keyboard.
|
|
||||||
|
|
||||||
Both directions cost something, which is why the axis matters rather than a blanket answer:
|
|
||||||
over-provisioning is a standing cost paid every session, while under-provisioning in an unchecked
|
|
||||||
phase is a silent error with a long tail. A corrective session, its bump, its CI runs and its
|
|
||||||
release together cost more compute than the model difference they were saving.
|
|
||||||
|
|
||||||
Claude-Code-only, and imported by CLAUDE.md rather than linked from AGENTS.md: the model names,
|
|
||||||
the `/code-review` effort dial and the `Agent` tool's `model:` override have no equivalent in the
|
|
||||||
other harnesses this repo supports (Codex CLI, GitHub Copilot CLI, Mistral Vibe). See
|
|
||||||
[instructions/CONTRACT.md](CONTRACT.md) for that split.
|
|
||||||
|
|
||||||
<!-- wikitool:toc -->
|
|
||||||
## Contents
|
|
||||||
|
|
||||||
- [When to run](#when-to-run)
|
|
||||||
- [Steps](#steps)
|
|
||||||
- [Decision points](#decision-points)
|
|
||||||
- [Scope](#scope)
|
|
||||||
<!-- /wikitool:toc -->
|
|
||||||
|
|
||||||
## When to run
|
|
||||||
|
|
||||||
Before spawning a subagent with an explicit `model:` override, before picking a `/code-review`
|
|
||||||
effort level, and when the user asks which model to use - or when the session's current model is
|
|
||||||
clearly mismatched to the task that just started.
|
|
||||||
|
|
||||||
Two of the three choices are the agent's to make; the session's own model is not. An agent cannot
|
|
||||||
switch the model it is running as - that is the user's `/model` - so step 1 is a recommendation
|
|
||||||
to *make*, not a setting to apply.
|
|
||||||
|
|
||||||
## Steps
|
|
||||||
|
|
||||||
1. **Recommend the session's model and effort by what catches a mistake in the phase it is in**,
|
|
||||||
when asked or when the mismatch is worth one sentence. Say it once and continue working either
|
|
||||||
way - a session that argues about its own model instead of doing the task has already cost
|
|
||||||
more than the model difference:
|
|
||||||
|
|
||||||
| Phase / task | What catches a mistake here | Model | Effort |
|
|
||||||
|---|---|---|---|
|
|
||||||
| `wiki-status`, simple `wiki-query` lookups | the answer is re-checkable against the corpus | Sonnet | default |
|
|
||||||
| `wiki-lint` | `lint` itself is the check | Sonnet | default |
|
|
||||||
| `wiki-ingest`, `wiki-manage`, judgment-heavy `wiki-query` | `lint` and `docs verify`, partly - the judgment about a claim is not covered | Sonnet | high |
|
|
||||||
| Stack dev: design, the version part, a boundary-crossing judgment | nothing - `docs verify` checks that a crossing documents itself, never that the part was right | Opus | high |
|
|
||||||
| Stack dev: code, tests, mechanical doc sync (command tables, contract rows) | `pytest`, `docs verify`, `instructions verify`, CI | Sonnet | high |
|
|
||||||
| Stack dev: closing an issue, `docs/` staleness, changelog prose | nothing, by construction - see below | Opus | high |
|
|
||||||
|
|
||||||
**Stack development is not one row**, which is the point of splitting it. The middle phase is
|
|
||||||
where the tokens are and where the checks are, so it is the phase worth running cheaper. The
|
|
||||||
two around it have no mechanical guard at all - a `docs/` page carries no normative sentence,
|
|
||||||
so there is nothing for `docs verify` to check ([AGENTS.md](../AGENTS.md) § File naming), and
|
|
||||||
the same holds for whatever tracker an instance keeps its open work in, which `wikitool`
|
|
||||||
deliberately knows nothing about. Those two phases are short - minutes, not hours - so keeping
|
|
||||||
them on the stronger model is cheap, and it protects the only work in the session that fails
|
|
||||||
silently.
|
|
||||||
|
|
||||||
**Effort is the cheaper lever than the model.** Reach for it first: `medium` deliberately does
|
|
||||||
not appear in this table for stack work, because multi-file consistency is exactly what a
|
|
||||||
reduced effort level gives up. Sonnet at `high` is the floor for anything touching more than
|
|
||||||
one file or a contract; `default` is for a single-file mechanical edit with a test behind it.
|
|
||||||
|
|
||||||
**A session cannot switch its own model**, so these rows only become real if someone offers the
|
|
||||||
switch at the moment the phase changes - once, without arguing about it, and never as a reason
|
|
||||||
to stop work that is already underway.
|
|
||||||
<!-- dist:strip-start -->
|
|
||||||
In this repo those moments are named, one per skill rather than both in one: `stack-dev`'s own
|
|
||||||
step 3 breaks for the first (design settled, work turns mechanical), and `stack-dev` itself
|
|
||||||
ends at the publish rather than asking the same session to break out of its own momentum a
|
|
||||||
second time. The second switch lives at the opening of `stack-close`, the skill `stack-dev`
|
|
||||||
hands off to once the publish succeeds (the unchecked tail begins) - a session has to invoke
|
|
||||||
it to reach that step at all, which is the point: nothing left to skip past mid-flow.
|
|
||||||
<!-- dist:strip-end -->
|
|
||||||
|
|
||||||
2. **Pick a spawned subagent's model by what it does**, via the `Agent` tool's `model:`
|
|
||||||
parameter - the values are `haiku`, `sonnet`, `opus`, `fable`:
|
|
||||||
|
|
||||||
- Read-only search/lookup (an `Explore` agent, or a `general-purpose` agent doing pure
|
|
||||||
retrieval): `model: "haiku"`. No judgment call is being delegated, only retrieval.
|
|
||||||
- A subagent that writes pages, reviews code, or decides something: leave `model:` off so it
|
|
||||||
inherits the session's model, chosen per step 1.
|
|
||||||
- A fork (`subagent_type: "fork"`) always inherits the parent session's model; a `model:`
|
|
||||||
override on a fork is ignored.
|
|
||||||
|
|
||||||
3. **Pick a `/code-review` effort level by blast radius, not by habit.** The levels are `low`,
|
|
||||||
`medium`, `high`, `xhigh`, `max` and `ultra` (multi-agent, in the cloud):
|
|
||||||
|
|
||||||
- A routine diff (a skill wording fix, an ordinary ingest's tool output): `low` or `medium` -
|
|
||||||
fewer, high-confidence findings are enough.
|
|
||||||
- Gate code (`run_budget.py`, `git_publish.py`, anything implementing the Mass-Update or
|
|
||||||
Iteration gates), the compiler, or a change about to ship in a version bump: `high` and up -
|
|
||||||
broader coverage is worth the cost when the blast radius of a missed bug is a safety gate.
|
|
||||||
- `ultra` is user-triggered and billed separately; recommend it, never assume it.
|
|
||||||
|
|
||||||
## Decision points
|
|
||||||
|
|
||||||
- **Task spans both a mechanical step and a judgment call?** Pick by the judgment call, not the
|
|
||||||
mechanical one - `wikitool` carries the mechanical part regardless of which model is
|
|
||||||
supervising it.
|
|
||||||
- **Unsure which row applies?** Default to Sonnet at high effort, not the most capable model at
|
|
||||||
the highest effort. Under-provisioning *where a check exists* costs one worse answer in one
|
|
||||||
session; reflexively over-provisioning is a standing cost paid every session.
|
|
||||||
- **Unsure whether the phase is checked?** Treat it as unchecked. The asymmetry is not symmetric:
|
|
||||||
a needless Opus phase costs money once, an unchecked Sonnet phase can ship something nobody
|
|
||||||
looks at again.
|
|
||||||
- **Mid-session and the phase changed, but nobody switched?** Do the work anyway - never block a
|
|
||||||
publish or an issue close on a model the session cannot change itself. Say which phase ran on
|
|
||||||
which model in the handover, so the gap is visible rather than silent.
|
|
||||||
|
|
||||||
## Scope
|
|
||||||
|
|
||||||
Does not apply to non-Claude-Code harnesses - see the note above; a follow-up issue tracks
|
|
||||||
whether and how they should decide this differently. Does not set the classifier model behind
|
|
||||||
Claude Code's own `auto` permission mode - that is a harness internal, not a per-task choice
|
|
||||||
this repo controls.
|
|
||||||
@@ -25,7 +25,7 @@ everyone reads afterwards and nobody revisits).
|
|||||||
The two phases around the mechanical middle of a stack-dev session have no mechanical guard at
|
The two phases around the mechanical middle of a stack-dev session have no mechanical guard at
|
||||||
all - `pytest`, `docs verify` and `instructions verify` cover the code and tests in between, and
|
all - `pytest`, `docs verify` and `instructions verify` cover the code and tests in between, and
|
||||||
nothing covers a changelog entry's accuracy, a `docs/` page's staleness, or an issue body's final
|
nothing covers a changelog entry's accuracy, a `docs/` page's staleness, or an issue body's final
|
||||||
state (see [claude-code-model-selection.md](../../claude-code-model-selection.md)). Asking the
|
state (see [docs/model-and-effort-selection.md](../../../docs/model-and-effort-selection.md)). Asking the
|
||||||
same session to notice it has crossed into that second unchecked stretch - as a prose break inside
|
same session to notice it has crossed into that second unchecked stretch - as a prose break inside
|
||||||
`stack-dev`'s own step 6 - failed twice in a row on this stack (Gitea #42, then #30): both times
|
`stack-dev`'s own step 6 - failed twice in a row on this stack (Gitea #42, then #30): both times
|
||||||
the session knew the rule and skipped past it anyway, because nothing in the moment forced the
|
the session knew the rule and skipped past it anyway, because nothing in the moment forced the
|
||||||
|
|||||||
@@ -96,7 +96,7 @@ stack development happens in the origin repo instead (see AGENTS.md's routing li
|
|||||||
|
|
||||||
Effort is the cheaper lever than the model, and `high` is the floor for anything touching more
|
Effort is the cheaper lever than the model, and `high` is the floor for anything touching more
|
||||||
than one file or a contract. Full table and reasoning:
|
than one file or a contract. Full table and reasoning:
|
||||||
[claude-code-model-selection.md](../../claude-code-model-selection.md).
|
[docs/model-and-effort-selection.md](../../../docs/model-and-effort-selection.md).
|
||||||
|
|
||||||
4. **Raise the version, if the change ships.** A change under `tools/`, `types/`,
|
4. **Raise the version, if the change ships.** A change under `tools/`, `types/`,
|
||||||
`instructions/`, `AGENTS.md` or a `CONTRACT.md` reaches every future instance, so it needs a
|
`instructions/`, `AGENTS.md` or a `CONTRACT.md` reaches every future instance, so it needs a
|
||||||
|
|||||||
Reference in New Issue
Block a user