Files
chemenu/instructions/CONTRACT.md
T
torben 502971d147
CI / verify (push) Successful in 53s
Release / release (push) Successful in 38s
feat: Autorenkonventionen nach Eigentum geschnitten - kb/CONVENTIONS.md, deklarierte Collections (3.0.0)
Files changed:
- .gitea/workflows/ci.yml
- .wikitool-kb.json
- AGENTS.md
- CHANGES.md
- INSTALL.md
- README.md
- VERSION
- instructions/CONTRACT.md
- instructions/dev/testing-conventions.md
- instructions/german-terminology.md
- instructions/kb-profiles.md
- instructions/migrations/3.0.0-authoring-conventions.md
- instructions/private-instance.md
- instructions/setup-instance.md
- instructions/wiki-ingest/SKILL.md
- instructions/wiki-manage/SKILL.md
- kb/CONTRACT.md
- kb/CONVENTIONS.md
- kb/CONVENTIONS.md.template
- kb/comparisons/COLLECTION.md
- kb/concepts/COLLECTION.md
- kb/entities/COLLECTION.md
- kb/sources/COLLECTION.md
- tools/CONTRACT.md
- tools/README.md
- tools/chemenu/commands/dist_cmd.py
- tools/chemenu/commands/docs_verify.py
- tools/chemenu/commands/doctor.py
- tools/chemenu/commands/new_page.py
- tools/chemenu/conventions.py
- tools/chemenu/kb_collections.py
- tools/chemenu/kb_scan.py
- tools/chemenu/provenance.py
- tools/chemenu/sections.py
- tools/chemenu/tests/conftest.py
- tools/chemenu/tests/test_conventions.py
- tools/chemenu/tests/test_dist_cmd.py
- tools/chemenu/tests/test_doctor.py
- tools/chemenu/tests/test_new_page.py
- tools/chemenu/tests/test_types_cmd.py
- types/comparison.md
- types/concept.md
- types/entity.md
- types/source.md
- types/type-spec.md
2026-09-02 15:02:10 +02:00

10 KiB

instructions/ - Instruction Layer Contract

Agent-directed procedure. Everything an agent is told to do lives here, and nowhere else.

Quality goal: executability + precision - every step actionable, every decision point explicit, ambiguity eliminated. A vague prescription spends bounded context on interpretation instead of action.

instructions/ is not a pipeline stage and not a collection. It is part of the control plane, alongside AGENTS.md.

Two forms, three reference tiers

Form File Loaded by
Instruction instructions/<name>.md A link from a skill, a contract, AGENTS.md, or CLAUDE.md - or run explicitly on request
Skill instructions/<name>/SKILL.md The agent harness, automatically, once published

The Instruction/Skill split is structural, not editorial: a subdirectory containing a SKILL.md is published; a flat .md file never is. Nothing else decides it, and no frontmatter flag controls it.

The split exists because publication is not free. Every published skill's description sits in the agent's context for the whole session, whether or not it is used. A procedure that runs once a quarter earns a link, not a permanent slot.

Within the flat instructions/<name>.md form, tools/wikitool instructions verify's reference rule (below) has two further tiers, told apart by frontmatter manual: true:

Tier manual: Referenced from AGENTS.md/CLAUDE.md/a contract/a skill/... Linked from AGENTS.md, CLAUDE.md, or a skill When
Linked absent (default) Required - verify reports it as dead otherwise Allowed The normal case: every instruction most agents will run
Manual true Not required, and a CONTRACT.md/COLLECTION.md/other-instruction mention is fine Forbidden - verify reports it if it IS linked there Rare, deliberate, or still experimental - must never be picked up implicitly. Named directly by the user, or mentioned as documentation, never followed as an automatic step

AGENTS.md and CLAUDE.md are both "automatically loaded" for this purpose, but for disjoint harnesses: AGENTS.md is read natively by every harness except Claude Code, and CLAUDE.md exists because Claude Code does not read AGENTS.md on its own (see AGENTS.md's file-naming table). A Claude-Code-only instruction is therefore reached from CLAUDE.md, not AGENTS.md - a link from AGENTS.md would load it into every other harness's session too, where it may not even apply.

CLAUDE.md can reach it two ways, and the choice is about when the decision is made:

From CLAUDE.md Effect Use for
@instructions/<name>.md The whole file is in context for every session on this harness A decision made in passing - while spawning a subagent, while picking a review level - where nobody would stop to open a document
A markdown link Only the link line is in context; the body is read on demand A procedure looked up deliberately, when its trigger is recognisable from the link alone

An import is the strongest load in this layer - stronger than a skill, which puts only its description in context - so it is also the most expensive. It is charged to every session on that harness whether or not the session ever makes the decision, which is the bar each further import has to clear. tools/wikitool instructions verify counts either form as a reference: both put the filename in CLAUDE.md.

A mention in README.md or CHANGES.md is not a reference. Both describe the stack to a human

  • the file-naming table makes README.md "never by an agent as instruction" - so a mention there documents an instruction without deploying it to anyone. verify scans neither when asking whether an instruction is still reachable, which is exactly why the answer means something. The instructions/dev/ boundary check below asks the opposite question - what would dangle in a distributed instance - and does scan README.md, because dist export ships it verbatim.

Three kinds of file use the Manual tier today: german-terminology.md, a vocabulary consulted on demand rather than a procedure; kb-profiles.md, the catalogue of authoring profiles an instance may adopt into its own kb/CONVENTIONS.md and COLLECTION.md files; and every migration document (below).

instructions/migrations/

A content migration is a Manual instruction with two extra frontmatter fields (types/instruction.schema.yaml): migrates_to:, the stack version whose content shape it produces, and migration_kind: (mechanical | assisted). It lives at instructions/migrations/<version>-<slug>.md.

The tier fits exactly: a migration must never be picked up implicitly - it rewrites the corpus - and it is referenced by nothing, because tools/wikitool migrate status finds it by reading the directory and comparing migrates_to: against this instance's kb_version. That is also why these files are ordinary instructions rather than a new stage: dist export already ships instructions/, so a migration reaches every distributed instance without a second export path.

Writing one is migrate-corpus.md, which also holds the procedure for carrying a migration out. The baseline is 1.0.0 - nothing older has a document.

instructions/dev/

A fourth, orthogonal split: material relevant only to developing the tool stack - procedures for extending tools/wikitool, the type schema, or this layer itself, rather than operating on wiki content - lives under instructions/dev/, one level in. tools/wikitool dist export prunes that whole directory, unconditionally and one-way: there is no command that adds it back to a distributed instance. This is a whole-directory exclusion, distinct from the <!-- dist:strip-start/end --> marker convention (tools/CONTRACT.md), which removes marked content from an otherwise-shipped file rather than excluding a file outright.

This is orthogonal to the Linked/Manual split above, not a third value of the same field: a instructions/dev/*.md file still carries manual: or not, exactly like any other instruction, and still needs a reference from somewhere for verify's ordinary orphan check. What instructions/dev/ adds on top is a hard boundary in the other direction - tools/wikitool instructions verify also reports anything under it that is referenced from outside it, because such a reference would dangle the moment dist export runs. A skill switching a session into this mode is nested under instructions/dev/ too, for the same reason: it must never reach a distributed instance either.

The one sanctioned crossing is a routing line from AGENTS.md into instructions/dev/, and it uses the marker convention to stay honest: wrapped in <!-- dist:strip-start/end -->, so dist export removes the line and the directory it points at together, and verify's boundary check skips marker-block content before scanning, exempting exactly that line and nothing else.

Publishing

tools/wikitool instructions sync copies each skill directory into .agents/skills/ (read natively by GitHub Copilot, Codex CLI and Mistral Vibe) and .claude/skills/ (Claude Code reads nothing else).

Both targets are generated and gitignored. A fresh clone therefore has no skills until sync runs - see bootstrap.md.

Copies, not symlinks: a symlink cannot go stale but is unreliable on Windows checkouts and does not survive being archived or copied. The price of a copy is drift, and drift is what tools/wikitool instructions verify checks - byte for byte against the source.

Writing an instruction

Scaffold with tools/wikitool new instruction --name "<name>"; the contract is tools/wikitool types describe instruction.

  • Imperative title. It answers "what does this tell me to do?".
  • description is the retrieval wire. Write it to match the question an agent would ask when it needs this procedure, not as a label for the file.
  • Frontload. Self-contained enough for an agent with no prior context: define terms inline, do not assume other documents are loaded.
  • Keep reasoning out of the body. Cut the explanation of why each step exists. If it is worth preserving, it is a concept page under kb/concepts/, linked from here. Keep only enough reasoning to decide edge cases.
  • State scope boundaries. When does this not apply, and what to do instead.

Instruction duality

These files are both content and running system. Changing one changes agent behaviour immediately: the edit is live for the next agent that loads the text, with no release step. Treat edits as deployments, not documentation updates.

The same duality runs the other way. An instruction nothing loads is inert - it deploys to no one. tools/wikitool instructions verify reports a file here that nothing references, because otherwise nothing would - unless it is manual: true (see "Two forms, three reference tiers" above), where the same duality flips the check: being loadable from somewhere IS the fault.

Single source

A rule belongs in exactly one place; everywhere else links to it. This is an authoring rule, not a checked one - prose duplication is a judgment call, so it is reviewed during a wiki-lint pass rather than enforced by a validator.

What lives where:

Layer Owns
AGENTS.md Invariants and routing - what must always hold
instructions/ How the tooling is operated
kb/CONTRACT.md What the stack enforces about a page, in every instance
kb/CONVENTIONS.md + each COLLECTION.md What this instance decided about authoring - owned by the instance, shipped only as a .template
types/ What a page structurally is
tools/CONTRACT.md What each command does and how it fails

What does not belong here

  • Knowledge. A fact about a system is a page under kb/.
  • The reasoning behind a procedure - that is a concept page, linked from the instruction.
  • Anything under .agents/skills/ or .claude/skills/: those are generated copies.