feat!: docs/ sorted into tutorials, how-to, reference, explanation plus unshipped docs/dev/; explanation pages and developer guide moved, human docs English (#187)
CI / verify (push) Successful in 6m1s
CI / pwsh (push) Successful in 2m0s
Release / release (push) Successful in 34s

The seven explanation pages move to docs/explanation/ without a stub, DEVELOPMENT.md becomes docs/dev/development.md (translated to English), dist export leaves docs/dev/ out, docs verify rejects a file outside the five areas, and AGENTS.md states that the stack's human documentation is English. Required migration 9.0.0-docs-diataxis rewrites the old path in an instance's own kb/CONVENTIONS.md.

Files changed:
- .wikitool-kb.json
- AGENTS.md
- CHANGES.md
- CLAUDE.md
- DEVELOPMENT.md
- INSTALL.md
- README.md
- VERSION
- docs/dev/development.md
- docs/explanation/README.md
- docs/explanation/knowledge-and-commitment.md
- docs/explanation/language-boundaries.md
- docs/explanation/model-and-effort-selection.md
- docs/explanation/ownership-and-templates.md
- docs/explanation/pipeline-rationale.md
- docs/explanation/version-model.md
- docs/explanation/why-gates-are-code.md
- docs/how-to/README.md
- docs/knowledge-and-commitment.md
- docs/language-boundaries.md
- docs/model-and-effort-selection.md
- docs/ownership-and-templates.md
- docs/pipeline-rationale.md
- docs/reference/README.md
- docs/tutorials/README.md
- docs/version-model.md
- docs/why-gates-are-code.md
- instructions/CONTRACT.md
- instructions/dev/dev-setup.md
- instructions/dev/doc-pull-through.md
- instructions/dev/stack-close/SKILL.md
- instructions/dev/stack-mode.md
- instructions/gtd-weekly-review/SKILL.md
- instructions/ingest-queue.md
- instructions/migrations/6.0.0-type-guidance-split.md
- instructions/migrations/9.0.0-docs-diataxis.md
- instructions/upgrade-instance.md
- kb/CONVENTIONS.md
- kb/CONVENTIONS.md.template
- tools/CONTRACT.md
- tools/chemenu/commands/dist_cmd.py
- tools/chemenu/commands/docs_verify.py
- tools/chemenu/commands/new_page.py
- tools/chemenu/commands/task_cmd.py
- tools/chemenu/tasks/protocol.py
- tools/chemenu/tests/test_dist_cmd.py
- tools/chemenu/tests/test_docs_verify.py
- tools/chemenu/tests/test_git_publish.py
- tools/chemenu/tests/test_toc.py
- types/type-guidance.md

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SnAJ7Z3CpVD3PRbN73QtU2
This commit is contained in:
torbenandClaude Opus 5.5 committed 2026-10-06 20:45:09 +02:00
1 parent 0e15972ee7
commit d66a3f65f4
43 files changed
+756 -324

No files matched your search

+196
View File
@@ -0,0 +1,196 @@
# Developing this stack
This document is for people working on `tools/wikitool`, the type schema or the
instruction/skill layer itself - not for the operators of an instance. For the other side
(installing, upgrading and running an instance) see [INSTALL.md](../../INSTALL.md).
**This file is not shipped.** It lives under `docs/dev/`, the human counterpart of
`instructions/dev/`, and `tools/wikitool dist export` excludes both directories wholesale: a
distributed instance has no release workflow, no CI and no issue board, so it needs no guide to
them. The reason is a comment at `dist_cmd.DOCS_DEV_ONLY`, so that a later session does not
"repair" the apparent gap. And because it is not shipped, this file may link into
`instructions/dev/` - unlike a shipped document such as `README.md`, which
`instructions verify` checks on exactly that point.
<!-- wikitool:toc -->
## Contents
- [Development environment](#development-environment)
- [`dist export` as a build and test tool](#dist-export-as-a-build-and-test-tool)
- [A release feed in a non-public repository](#a-release-feed-in-a-non-public-repository)
- [The release workflow](#the-release-workflow)
- [The CI half](#the-ci-half)
- [Stack development as a session type of its own](#stack-development-as-a-session-type-of-its-own)
<!-- /wikitool:toc -->
## Development environment
Work on the stack happens in a clone of this repository. Such a clone is **not an instance** and
never becomes one. Instances come only from releases - see [INSTALL.md](../../INSTALL.md).
```bash
git clone https://gitea.nehmer.net/torben/chemenu.git
cd chemenu
```
Then have the agent run `instructions/bootstrap.md`: the preflight, then
`tools/wikitool instructions sync`. The agent's side of it - what differs here from an instance,
and how `dist export` runs as a test tool - is
[instructions/dev/dev-setup.md](../../instructions/dev/dev-setup.md).
What a clone has and an instance does not:
- **The demo corpus.** Some 170 pages documenting the stack itself: gates, lint, versioning,
search, the wiki pattern. It is a testbed and a walkable example, not a productive knowledge
base. What may be changed in it is governed by
[instructions/dev/corpus-policy.md](../../instructions/dev/corpus-policy.md).
- **A demo persona** in `USER.md`/`SOUL.md`. `doctor` reports both as filled in. They describe
the demo setup, not you.
- **Telemetry on.** Without `.wikitool-release.json` the clone is the measuring station the stack
evaluates itself with ([EVALS.md](../../EVALS.md) § "Whether it runs at all").
- **`instructions/dev/`, `docs/dev/`, `commonplace/` and `.gitea/`.** `dist export` ships none
of them.
`ENVIRONMENT.md` is missing after every clone, because the file is gitignored: it describes a
checkout, not the repository. Creating it (template `ENVIRONMENT.md.template`, step 5 in
`instructions/bootstrap.md`) spares every stack session the questions about harness, `gitea-mcp`
and remote.
### `dist export` as a build and test tool
`tools/wikitool dist export <empty directory>` writes exactly the tree a release ships: the
machinery without wiki content, without git history, without `instructions/dev/` or `docs/dev/`.
That is how you check before a release what would ship (`--dry-run` only lists it). And it is
how you replay the installation path without waiting for a release: build a tarball from it the
way `.gitea/workflows/release.yml` does, then start the preflight script in an empty directory
with `--archive <tarball>`. The CI step "The distribution works as a fresh instance" in
`.gitea/workflows/ci.yml` does exactly that.
For a real instance such an export is not a way in. It lacks the release origin in its stamp,
and `dist upgrade --latest` later compares against a state that never existed as a release.
### A release feed in a non-public repository
Whoever runs the stack from a repository of their own that is not public, and upgrades instances
from there, points `WIKITOOL_UPDATE_URL` at its feed. There is one quirk: Gitea answers an
anonymous caller with the same `404` for an invisible repository as for one that does not exist
at all. A missing release and missing access then look identical - and "no update found" would
simply be wrong. A Gitea token with read access in `WIKITOOL_UPDATE_TOKEN` fixes that. It is sent
only to downloads on the same host as the feed.
## The release workflow
Between two releases the stack carries **one** running version candidate instead of a new
number per bump. The full model - where the state lives, how escalation works, why a number is
only consumed by a release - is in
[instructions/dev/version-parts.md](../../instructions/dev/version-parts.md) and
[docs/explanation/version-model.md](../explanation/version-model.md). Here only the sequence, in
the order a session actually goes through it:
1. **A bump opens or escalates the candidate, graded with `--impact`.**
```bash
tools/wikitool version bump --minor --title "What changed" --impact medium
```
Writes `VERSION` as `X.Y.Z-beta.N` and opens (or updates) the matching `CHANGES.md` entry.
Several bumps for the same change are normal - each one updates the same entry instead of
opening a new one. `--impact high|medium|low` (default `medium`) groups the entry;
`tools/wikitool version regrade` corrects a grade later, when the candidate's overall shape
changes the read on an earlier bump.
2. **The entry gets its prose - only where it is needed.** `bump` writes the skeleton (heading,
date, author, the machine-managed, grouped list of bump titles, and the breaking and migration
lines where they apply). A smaller change needs nothing beyond its bump title; a larger one
gets a paragraph for its topic, and a short summary is added before the release. The form, and
the size budget `docs verify` and `version release` check, are in
[instructions/dev/version-parts.md](../../instructions/dev/version-parts.md) § The candidate
model.
3. **Run the checks before anything is published:**
```bash
cd tools && .venv/bin/python -m pytest -q
tools/wikitool docs verify
tools/wikitool instructions verify
```
4. **`version release` fixes the candidate** once it is meant to ship:
```bash
tools/wikitool version release --title "Summarising title"
```
Strips the `-beta.N` suffix from `VERSION` and closes the changelog entry. `--title` is
optional - without it the last bump's title stays; with it, a candidate that collected several
bump titles gets a summarising heading. Refused when the candidate collected two or more bumps
and the summary from step 2 is still missing - a candidate with exactly one bump is exempt -
and likewise when the entry is over its size budget. Commits and pushes nothing (invariant 5
in [AGENTS.md](../../AGENTS.md)).
5. **Publish moves `VERSION` on `main`.**
```bash
tools/wikitool publish --message "..."
```
The Mass-Update Gate and the Publish-Remote Gate apply as on every other publish - see
[instructions/gates.md](../../instructions/gates.md).
6. **CI does the rest.** `.gitea/workflows/release.yml` reacts to every push that moves
`VERSION`: a `VERSION` with a suffix (a candidate) makes the job skip cleanly before it even
queries the releases API - betas are never published. A suffix-free `VERSION` builds the
distribution (`dist export`), creates the tag and the release, and uploads the tarball and its
checksum, along with the two preflight scripts and the instructions `setup-instance.md` and
`preflight.md` that the installation sentence in `INSTALL.md` points at. **CI sets the tag,
never a session** - that keeps invariant 5 intact.
The release note is the `CHANGES.md` entry; Gitea on MySQL stores at most 65535 bytes, and
the job refuses from 60000 on, before it creates a tag. That is only the last net: `docs
verify` already holds the topmost entry to at most 32000 bytes while it is a candidate (step
2). If the job fails after `VERSION` is already on `main`, neither a push (the version does
not rise again) nor a re-run (it takes the workflow file of the failed commit) helps: fix the
cause, publish, and start `release.yml` on `main` via `workflow_dispatch`. The check for an
existing release prevents a second one.
The three check commands are in step 3 above; what each of them checks is in
[tools/CONTRACT.md](../../tools/CONTRACT.md), where `docs verify` holds it against the actual
CLI. It is deliberately **not** repeated here: a second description of the same commands is
exactly the copy that drifts (AGENTS.md invariant 8), and this document lies outside the files
the command-record check of `docs verify` covers - so a drift here would go unnoticed. What
`pytest` expects of the developer at this point is in
[instructions/dev/testing-conventions.md](../../instructions/dev/testing-conventions.md).
## The CI half
`.gitea/workflows/ci.yml` runs on every push/PR against `main` (content paths excepted) and
runs the test suite, `docs verify`, `instructions verify` and a complete `setup-instance.md`
replay: a locally built release tarball, the preflight script with `--archive` in an empty
directory, then the instruction's steps - the same path a new user actually takes, just without
the download. `.gitea/workflows/nightly.yml` is the drift check against time rather than against
a commit. `.gitea/workflows/release.yml` is step 6 above.
Three more workflows carry the live tests of the tracker adapters (Super Productivity, CalDAV):
`ci.yml` runs the CalDAV half in a step of its own against Radicale as a process,
`tracker-live.yml` runs nightly and covers both providers, and `sp-live-image.yml` builds the
`chemenu-sp-live` image daily (when there is a new version) and monthly (always) with the current
Super Productivity version. The image follows the desktop clients' update channel, not a fixed
version. Once, after the very first push, the package has to be linked to the `torben/chemenu`
repository by hand. What the suite writes, how to run it against a tracker of your own, and what
a red run means is in
[instructions/dev/tracker-testing.md](../../instructions/dev/tracker-testing.md).
## Stack development as a session type of its own
Three skills (`instructions/dev/`, present only in this origin repository) carry a session that
works on the stack itself rather than on wiki content through three phases: `stack-dev` works
the issue out until its body is "ready", `stack-build` builds, publishes and waits for a green CI
run, `stack-close` checks the body's final state and stale `docs/` and contract prose, and closes
the issue. The handover goes through the state in the tracker, not through a session's context:
every phase change works in the same session or after `/clear`. `stack-dev` triggers
automatically; `stack-build` and `stack-close` are started only by the operator, by slash command
(`/stack-build #N`, `/stack-close`) - exactly where the choice falls whether to continue in the
same session or a new one, and on which model. None of the three offers a model switch in the
middle of a session. Rules and the phase table are in
[instructions/dev/stack-mode.md](../../instructions/dev/stack-mode.md), the issue tracker itself
in [instructions/dev/issue-tracking.md](../../instructions/dev/issue-tracking.md).
+18
View File
@@ -0,0 +1,18 @@
# Explanation
Why the stack is built the way it is. These pages are background for humans and agents alike:
read by link or on request, never as instruction, and they carry no normative sentence - a rule
lives in `AGENTS.md` or a `CONTRACT.md`, and a page here only gives its reasons.
- [pipeline-rationale.md](pipeline-rationale.md) - why the pipeline has four stages
- [ownership-and-templates.md](ownership-and-templates.md) - why a `.template` split exists, and
why an instance comes only from a release
- [language-boundaries.md](language-boundaries.md) - why the control plane is English everywhere
and the KB language is a value
- [why-gates-are-code.md](why-gates-are-code.md) - why the gates are code rather than instruction
- [version-model.md](version-model.md) - why a version number answers a compatibility question
and a migration question separately
- [knowledge-and-commitment.md](knowledge-and-commitment.md) - why commitments live in a task
tracker rather than in `kb/`
- [model-and-effort-selection.md](model-and-effort-selection.md) - which model and effort suit
which kind of session, for the harness that has to choose
@@ -4,8 +4,8 @@ Chemenu compiles knowledge into `kb/`, and it also tracks what its operator has
Those look like one subject - both are "things about my projects" - and the stack deliberately
keeps them apart: `kb/gtd/` holds one page per initiative, an external task tracker holds the
open items, and the only thing that crosses between them is a name. This page is about why that
line was drawn there. The rules that follow from it live in [kb/CONTRACT.md](../kb/CONTRACT.md)
and the `review`, `new` and `task new` records in [tools/CONTRACT.md](../tools/CONTRACT.md).
line was drawn there. The rules that follow from it live in [kb/CONTRACT.md](../../kb/CONTRACT.md)
and the `review`, `new` and `task new` records in [tools/CONTRACT.md](../../tools/CONTRACT.md).
<!-- wikitool:toc -->
## Contents
@@ -2,10 +2,12 @@
Two languages run through this repo at once. `kb/` is written in whatever language the instance
chose - German here, and the value lives in `kb/CONVENTIONS.md`'s `language:`. Everything that
tells an agent what to do - [AGENTS.md](../AGENTS.md), every `CONTRACT.md`, everything under
`instructions/` - is written in English, in every instance, whatever the first value says.
tells an agent what to do - [AGENTS.md](../../AGENTS.md), every `CONTRACT.md`, everything under
`instructions/` - is written in English, in every instance, whatever the first value says. So
is the stack's own documentation for humans, for a different reason (§ "The stack's human
documentation").
The rule itself is in [AGENTS.md § File naming](../AGENTS.md#file-naming). This page holds the
The rule itself is in [AGENTS.md § File naming](../../AGENTS.md#file-naming). This page holds the
part that is not a rule: why the line runs where it does, why the English half is not a setting,
and which argument for it turned out to be wrong.
@@ -17,6 +19,7 @@ and which argument for it turned out to be wrong.
- [Why it is not a parameter](#why-it-is-not-a-parameter)
- [What the KB language still decides](#what-the-kb-language-still-decides)
- [Where the line runs around a page type](#where-the-line-runs-around-a-page-type)
- [The stack's human documentation](#the-stacks-human-documentation)
- [What would put this back on the table](#what-would-put-this-back-on-the-table)
<!-- /wikitool:toc -->
@@ -35,7 +38,7 @@ guidance is still instruction addressed to an agent, and reads exactly like the
four types the stack ships. Ownership says "yours"; the audience has not moved at all.
So the question a line answers is not *whose file is this* but *who reads this line*, which is
the same cut [kb/CONTRACT.md](../kb/CONTRACT.md#language-and-identifiers) already makes inside a
the same cut [kb/CONTRACT.md](../../kb/CONTRACT.md#language-and-identifiers) already makes inside a
single page between prose and identifiers - applied one level up, to the halves of a document.
Ownership decides who may change a sentence. The reader decides what language it is in. The two
questions were answered together for as long as they happened to agree.
@@ -99,7 +102,8 @@ experiences:
language.
So an operator who reads no English gets German pages and German answers from an agent reading
English instructions. The English is what the machinery is written in, not what it says back.
English instructions. The English is what the machinery is written in, not what it says back -
with one exception, the stack's documentation for humans (§ "The stack's human documentation").
## Where the line runs around a page type
@@ -115,11 +119,28 @@ beside the template, but that split was made for ownership reasons - so an upgra
the guidance without overwriting what the instance chose - and it leaves this page's argument
untouched: each part is still written in the language its own reader needs, and a type-spec that
declares no `guidance:` keeps both halves in one file with exactly the same rule applying inside
it. [types/type-spec.md § Who owns a type-spec](../types/type-spec.md#who-owns-a-type-spec) has
it. [types/type-spec.md § Who owns a type-spec](../../types/type-spec.md#who-owns-a-type-spec) has
the split as a table, and [ownership-and-templates.md](ownership-and-templates.md) § "Where the
file boundary used to strain" has what it cost to keep two audiences in one file for as long as
it did.
## The stack's human documentation
`README.md`, `INSTALL*.md`, `EVALS.md` and everything under `docs/` are read by humans, and the
reader axis alone would put them in the operator's language. They are English anyway, and the
reason is not the reader but the fact that there is no single one. This documentation belongs to
the stack, not to an instance: it ships identically to every instance, whatever each one's
`language:` says, so there is no instance value it could follow - only a translation per language
to maintain beside it, each one a second copy that drifts. And a growing part of it is generated
from the code (the command reference from `cli_contract` records, for one), whose source is
English control-plane material; a translated frame around English generated text is the
half-done version of both.
The KB language keeps deciding what an operator reads *of their own*: pages and answers. What
the stack tells every operator about itself is the same text everywhere. `CHANGES.md` sits
outside the question - it is a log of what was true at a time, not documentation, and its older
entries are in the language they were written in.
## What would put this back on the table
A `docs/` page goes stale when the reasoning stops holding rather than when the code changes, so
@@ -135,3 +156,8 @@ it is worth naming what that would look like here. Two things would:
Neither is close. Both are cheaper to notice here than to rediscover in an argument about a
single file.
The human documentation has a trigger of its own: **translations the stack maintains itself,
with a check that holds each one to its English source.** Without such a check a translation is
exactly the drifting second copy the section above argues against; with one, the argument for a
single language weakens to cost alone.
@@ -2,7 +2,7 @@
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)
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
@@ -2,8 +2,8 @@
Chemenu ships two kinds of files side by side, and at a glance they look the same: both are
plain markdown, both sit in the repo root or under `kb/`, both get read at session start. But a
stack upgrade treats them completely differently. Some - [AGENTS.md](../AGENTS.md),
[kb/CONTRACT.md](../kb/CONTRACT.md), the per-stage contracts - are identical in every instance
stack upgrade treats them completely differently. Some - [AGENTS.md](../../AGENTS.md),
[kb/CONTRACT.md](../../kb/CONTRACT.md), the per-stage contracts - are identical in every instance
that runs this stack and are the next release's to replace (with one caveat about local edits,
below). Others - `USER.md`,
`SOUL.md`, `kb/CONVENTIONS.md`, `ENVIRONMENT.md` - describe one particular instance, and
@@ -25,7 +25,7 @@ overwriting them would silently erase a choice someone made on purpose.
The stack-owned files describe how the tool works. `kb/CONTRACT.md` opens by saying it holds
what `tools/wikitool` enforces or what follows mechanically from how it operates - see
[kb/CONTRACT.md](../kb/CONTRACT.md), lines 10-13. That kind of statement doesn't vary by
[kb/CONTRACT.md](../../kb/CONTRACT.md), lines 10-13. That kind of statement doesn't vary by
instance: the compiler behaves the same way regardless of who is running it, so the sentence
describing that behavior can be copied byte-for-byte into every checkout without becoming
wrong anywhere.
@@ -33,7 +33,7 @@ wrong anywhere.
The instance-owned files describe a choice: which language pages are written in, what tone the
agent takes, who the operator is, which git remote is authoritative, which MCP servers are
reachable. None of that follows from the tool's mechanics - two instances of the identical
stack can answer all of these differently and both be correct. [AGENTS.md § Personalization](../AGENTS.md#personalization)
stack can answer all of these differently and both be correct. [AGENTS.md § Personalization](../../AGENTS.md#personalization)
frames the split the same way for `kb/CONTRACT.md` versus `kb/CONVENTIONS.md`: "the split is by
who may change the sentence, not by what it is about." A rule about page structure could in
principle have been written per-instance too, but then every instance answering "not German" to
@@ -59,7 +59,7 @@ the file itself already answers that.
For a while the boundary was written down as a list of paths - once in `dist_cmd.py`, once in
the merge procedure a private instance was told to run by hand, and once in the check that
procedure ended with. Three copies of one fact, which is the shape [AGENTS.md](../AGENTS.md)
procedure ended with. Three copies of one fact, which is the shape [AGENTS.md](../../AGENTS.md)
invariant 8 exists to forbid, and they drifted exactly as predicted: the hand-run procedure was
still naming three paths after the collection contracts had moved to the instance's side of the
line, so it discarded upstream changes to files it had never heard of, while its own final check
@@ -81,7 +81,7 @@ The mechanism for instance-owned content is a `.template` file the distribution
of the real one - `USER.md.template`, `SOUL.md.template`, `kb/CONVENTIONS.md.template`,
`ENVIRONMENT.md.template`. An alternative would have been to ship nothing at all and let a
brand-new instance start from a blank page. The template exists because a blank page doesn't
tell [instructions/setup-instance.md](../instructions/setup-instance.md) what shape the answer
tell [instructions/setup-instance.md](../../instructions/setup-instance.md) what shape the answer
should take, and it gives nothing for a validator to check afterward.
A template carries a placeholder value - a sentinel - in the fields that need a real answer.
@@ -89,7 +89,7 @@ Setup interviews the operator and replaces the sentinel with what they actually
gives `doctor` a mechanical way to tell "personalized" from "not yet": a file that still
contains the sentinel hasn't been through setup, regardless of whether the file exists. That's
also why `ENVIRONMENT.md` only warrants a WARN rather than a FAIL when absent - see
[AGENTS.md § Environment](../AGENTS.md#environment) - while a missing or unfilled
[AGENTS.md § Environment](../../AGENTS.md#environment) - while a missing or unfilled
`USER.md`/`SOUL.md`/`kb/CONVENTIONS.md` is a harder failure: `ENVIRONMENT.md` describes one
checkout among possibly several and is gitignored for that reason, so its absence is a normal
state rather than a sign setup was skipped.
@@ -2,13 +2,13 @@
Chemenu could, in principle, be one directory: drop a file in, ask a question, get an answer
computed fresh each time. It isn't built that way. The pipeline in
[AGENTS.md](../AGENTS.md#routing) - `raw/` -> `[types/ + tools/]` -> `kb/` -> `reports/`, with
[AGENTS.md](../../AGENTS.md#routing) - `raw/` -> `[types/ + tools/]` -> `kb/` -> `reports/`, with
`work/` alongside rather than inside it - separates *material* from *meaning* from
*byproduct*, and each seam exists because collapsing it costs something specific.
## Why raw material stays untouched
[raw/CONTRACT.md](../raw/CONTRACT.md) keeps a source exactly as it arrived. The reasoning is
[raw/CONTRACT.md](../../raw/CONTRACT.md) keeps a source exactly as it arrived. The reasoning is
simple once stated: the moment someone "cleans up" or reformats a source on the way in, the
thing later claims get checked against is no longer the thing that was actually said. An
immutable `raw/` means a citation always resolves to the original, not to somebody's tidied
@@ -31,19 +31,19 @@ promotion into `raw/` quietly doubling as the review step it cannot perform.
## Why extraction happens once, through a schema
[types/type-spec.md](../types/type-spec.md) is what stands between a raw file and a `kb/` page:
[types/type-spec.md](../../types/type-spec.md) is what stands between a raw file and a `kb/` page:
a type-spec defines what a conforming instance of a page looks like, and the compiler
(`tools/wikitool`) applies it. The alternative - every query re-reading and re-interpreting the
source on demand - would mean paying the cost of understanding the material every single time,
and getting a slightly different answer each time depending on how the question was phrased.
Extracting once, against a fixed schema, turns "re-read and re-guess" into "look up what was
already compiled." That is the "never re-derive, always compile" principle from
[AGENTS.md](../AGENTS.md): understanding a source is expensive and worth doing exactly once,
[AGENTS.md](../../AGENTS.md): understanding a source is expensive and worth doing exactly once,
after which it becomes a cheap, stable lookup.
## Why a `kb/` page has to stand on its own
[kb/CONTRACT.md](../kb/CONTRACT.md) sets the bar for the compiled layer: a page should answer a
[kb/CONTRACT.md](../../kb/CONTRACT.md) sets the bar for the compiled layer: a page should answer a
future question without sending the reader back to the source it came from. That's the payoff
of compiling in the first place - if every answer still bottomed out in "go re-read the raw
file," the `kb/` layer would just be a pointer with extra steps, and the cost of extraction
@@ -52,7 +52,7 @@ consistent to query: the work of understanding is already sitting there, done.
## Why `reports/` doesn't need to be maintained
[reports/CONTRACT.md](../reports/CONTRACT.md) treats most of what lands in `reports/` -
[reports/CONTRACT.md](../../reports/CONTRACT.md) treats most of what lands in `reports/` -
lint output, telemetry traces - as disposable. The structural content of a lint report can be
recomputed from the tree at any commit, so keeping an old copy around would just be a second
version of something the tool can already answer on demand, and a second copy is exactly the
@@ -64,7 +64,7 @@ distinction between what's recomputable and what isn't.
## Where `work/` fits
[work/CONTRACT.md](../work/CONTRACT.md) describes a workshop, not a fifth pipeline stage: a
[work/CONTRACT.md](../../work/CONTRACT.md) describes a workshop, not a fifth pipeline stage: a
place for the notes, extracts and open decisions of a task that spans more than one session, on
its way toward becoming a `kb/` page. It sits beside the raw -> kb -> reports flow rather than
inside it - closer in spirit to a desk than to a conveyor belt.
File renamed without changes.
@@ -4,8 +4,8 @@ Chemenu has five hard limits - the Mass-Update Gate, the Publish-Remote Gate, th
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
[instructions/gates.md](../instructions/gates.md). This page is only about the design choice
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.
<!-- wikitool:toc -->
+11
View File
@@ -0,0 +1,11 @@
# How-to guides
Task-oriented pages for the operator of an instance: one goal per page - upgrade an instance,
set up the MCP read server, run a weekly review - with the steps a human takes and the sentence
handed to the agent. A how-to guide never retells an agent's procedure: the steps an agent runs
live in `instructions/`, and a guide here says what to prepare, what to ask for and where the
agent stops.
Nothing is here yet. Until the guides are written, the task-shaped parts of
[README.md](../../README.md), [INSTALL.md](../../INSTALL.md),
[INSTALL-MCP.md](../../INSTALL-MCP.md) and [EVALS.md](../../EVALS.md) still carry this material.
+10
View File
@@ -0,0 +1,10 @@
# Reference
Lookup pages: the command surface, exit codes and gates, the skill catalogue, the page types. A
reference page describes what is, not how to use it or why it is so - and wherever a source for
it exists in the code, it is generated from that source and checked against it rather than
written by hand.
Nothing is generated here yet. Until it is, the command reference is
[tools/CONTRACT.md](../../tools/CONTRACT.md) (and `tools/wikitool <command> -h`), and a page
type is described by `tools/wikitool types describe <type>`.
+8
View File
@@ -0,0 +1,8 @@
# Tutorials
Learning-oriented pages: a guided first walk through an instance, start to finish, for someone
who has not used one before. A tutorial shows one path that works; it does not list options or
explain why.
Nothing is here yet. The installation tutorial is still [INSTALL.md](../../INSTALL.md) at the
repository root, which stays there; a walk from the first source to the first answer is planned.