feat!: docs/ sorted into tutorials, how-to, reference, explanation plus unshipped docs/dev/; explanation pages and developer guide moved, human docs English (#187)
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:
1 parent
0e15972ee7
commit
d66a3f65f4
43 files changed
+756
-324
No files matched your search
@@ -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).
|
||||
@@ -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 -->
|
||||
@@ -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.
|
||||
@@ -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>`.
|
||||
@@ -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.
|
||||
Reference in new issue
Block a user