feat: docs/ carries the operator's how-to guides, a configuration reference and the architecture and telemetry explanations carved out of README.md, INSTALL.md, INSTALL-MCP.md and EVALS.md; the last two retired (#190)
Files changed: - .gitea/workflows/ci.yml - .gitignore - .vibe/hooks.toml - AGENTS.md - CHANGES.md - EVALS.md - INSTALL-MCP.md - INSTALL.md - README.md - VERSION - docs/dev/development.md - docs/explanation/README.md - docs/explanation/architecture.md - docs/explanation/language-boundaries.md - docs/explanation/telemetry-and-evaluation.md - docs/how-to/README.md - docs/how-to/browse-with-obsidian.md - docs/how-to/capture-repository-docs.md - docs/how-to/export-guidelines.md - docs/how-to/ingest-a-source.md - docs/how-to/maintain-the-wiki.md - docs/how-to/query-the-wiki.md - docs/how-to/run-the-weekly-review.md - docs/how-to/set-up-the-mcp-server.md - docs/how-to/trace-and-score-sessions.md - docs/how-to/troubleshoot.md - docs/how-to/update-an-instance.md - docs/reference/README.md - docs/reference/commands/distribution-and-versioning.md - docs/reference/commands/instance-health.md - docs/reference/commands/raw-material-and-uploads.md - docs/reference/commands/telemetry.md - docs/reference/commands/types-instructions-and-docs.md - docs/reference/configuration.md - instructions/dev/dev-setup.md - instructions/dev/doc-pull-through.md - instructions/dev/stack-build/SKILL.md - instructions/dev/testing-conventions.md - instructions/dev/version-parts.md - instructions/setup-instance.md - instructions/upgrade-instance.md - reports/CONTRACT.md - tools/.coveragerc - 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/eval_cmd.py - tools/chemenu/commands/git_publish.py - tools/chemenu/commands/upload_cmd.py - tools/chemenu/commands/version_cmd.py - tools/chemenu/evals/__init__.py - tools/chemenu/evals/scorecard.py - tools/chemenu/evals/trajectory.py - tools/chemenu/telemetry/policy.py - tools/chemenu/tests/test_dist_cmd.py - tools/chemenu/tests/test_git_publish.py - tools/chemenu/tests/test_instructions_shell.py - tools/chemenu/tests/test_pipeline_l0.py - tools/chemenu/toc.py Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SnAJ7Z3CpVD3PRbN73QtU2
This commit is contained in:
1 parent
cff7df4ffa
commit
f9056c04f7
61 files changed
+2169
-1772
No files matched your search
@@ -2,27 +2,10 @@
|
||||
|
||||
A structured, LLM-maintained knowledge base for your personal IT work.
|
||||
|
||||
## What is this?
|
||||
|
||||
This is **Chemenu** - a pattern for building a personal knowledge base using LLMs.
|
||||
Instead of just retrieving from raw documents on every query, the LLM **incrementally builds
|
||||
and maintains a persistent wiki** that compounds over time.
|
||||
|
||||
**The key insight:** Knowledge is compiled once and kept current, not re-derived on every question.
|
||||
|
||||
**The pages are written in German.** Source material in `raw/` is never touched and is usually
|
||||
English; the compiled pages under `kb/` are not. What stays English inside them is everything that
|
||||
is an *identifier* rather than prose - page titles, section headings, wikilink targets, citation
|
||||
ids, schema enum values, tags, commands, paths and code - so `GitOps Ownership Model` and
|
||||
`## Beziehungen` sit in the same page without contradiction. Which lines are identifiers is
|
||||
[kb/CONTRACT.md § Language and identifiers](kb/CONTRACT.md#language-and-identifiers); *which
|
||||
language* the prose is in, and what the tool-owned headings are called, is this instance's own
|
||||
[kb/CONVENTIONS.md](kb/CONVENTIONS.md), and the vocabulary behind it is
|
||||
[instructions/german-terminology.md](instructions/german-terminology.md).
|
||||
|
||||
This is a per-instance decision, not a property of the pattern - which is why it lives in a file
|
||||
the instance owns rather than in one the stack ships. A new instance installed from a release
|
||||
starts empty and picks any language by filling in `kb/CONVENTIONS.md` before the first ingest.
|
||||
Chemenu is a pattern for a personal knowledge base maintained by an LLM. Instead of going back
|
||||
to the raw documents for every question, the LLM **incrementally builds and maintains a
|
||||
persistent wiki** that compounds over time: knowledge is compiled once and kept current, not
|
||||
re-derived on every question.
|
||||
|
||||
## Getting started
|
||||
|
||||
@@ -52,7 +35,7 @@ Two starting points, depending on what you're doing:
|
||||
|
||||
<!-- dist:strip-start -->
|
||||
- **Working on the stack itself.** A clone of this repository is a development checkout, with
|
||||
the demo corpus described below; it is never an instance. Setting it up, and `dist export` as
|
||||
a demo corpus; it is never an instance. Setting it up, and `dist export` as
|
||||
the build and test tool it is, are in `docs/dev/development.md` (for you) and
|
||||
`instructions/dev/dev-setup.md` (for the agent).
|
||||
<!-- dist:strip-end -->
|
||||
@@ -66,288 +49,15 @@ The human documentation lives under `docs/`, sorted by what you want from it:
|
||||
- [docs/how-to/](docs/how-to/README.md) - doing: one task per page, for the operator of an
|
||||
instance.
|
||||
- [docs/reference/](docs/reference/README.md) - looking up: commands, exit codes, skills, page
|
||||
types. The command reference is [docs/reference/commands/](docs/reference/commands/README.md);
|
||||
agents use the same records in [tools/CONTRACT.md](tools/CONTRACT.md).
|
||||
types, configuration. The command reference is
|
||||
[docs/reference/commands/](docs/reference/commands/README.md); agents use the same records in
|
||||
[tools/CONTRACT.md](tools/CONTRACT.md).
|
||||
- [docs/explanation/](docs/explanation/README.md) - understanding: why the stack is built the way
|
||||
it is.
|
||||
|
||||
The areas are filling up gradually; until a page exists there, the sections below still carry
|
||||
its material.
|
||||
|
||||
## Architecture
|
||||
|
||||
```
|
||||
chemenu/
|
||||
├── AGENTS.md # Control plane: invariants, file naming, routing, gates
|
||||
├── CLAUDE.md # Claude Code only: imports AGENTS.md, links the one Claude-Code-only decision (model/effort). No rules of its own
|
||||
├── README.md # This file: human-readable overview of the whole repo
|
||||
├── INSTALL.md # Human-readable install: one release, one sentence to the agent
|
||||
├── INSTALL-MCP.md # Human-readable setup for the optional MCP read server
|
||||
├── EVALS.md # Human-readable overview of telemetry and evaluation
|
||||
├── CHANGES.md # Changelog for the stack itself
|
||||
├── USER.md # Who operates this instance - context, never instructions
|
||||
├── SOUL.md # How this instance sounds. AGENTS.md always wins over it
|
||||
├── ENVIRONMENT.md # Optional, gitignored: this checkout's harness, MCP servers, remotes
|
||||
├── *.md.template # Unfilled USER/SOUL/ENVIRONMENT - what a distribution ships instead
|
||||
├── .gitignore # Anchored so nothing under raw/, kb/ or work/ is ever excluded;
|
||||
│ # incoming/ is the one directory excluded the other way round
|
||||
├── .github/hooks/ # Copilot CLI hooks - session tracing
|
||||
├── .vibe/ # Mistral Vibe hooks + the repo's telemetry policy
|
||||
├── docs/ # Human documentation: tutorials/, how-to/, reference/, explanation/
|
||||
├── instructions/ # CONTROL: everything an agent is told to do
|
||||
│ ├── CONTRACT.md # Instruction vs. skill, publishing, writing standard
|
||||
│ ├── bootstrap.md # Prepare a further checkout of an instance
|
||||
│ ├── gates.md # What to do when a gate refuses a call
|
||||
│ ├── german-terminology.md # Which words stay English in German prose; register
|
||||
│ ├── session-setup.md
|
||||
│ ├── page-lifecycle.md
|
||||
│ ├── publish-cycle.md
|
||||
│ ├── ingest-large-tree.md
|
||||
│ ├── ingest-queue.md # Reviewing a submission before wikitool upload accept promotes it
|
||||
│ └── wiki-*/SKILL.md # Skills - copied into .agents/skills/ and .claude/skills/
|
||||
├── mcp-upload/ # QUARANTINE (optional): the MCP `submit` tool's write path, gitignored -
|
||||
│ # read by no command in the ordinary pipeline; a human reviews it with
|
||||
│ # `wikitool upload list/show/accept/reject`
|
||||
├── incoming/ # INBOX: content gitignored - drop a file or one folder per source here, `raw accept` promotes it
|
||||
├── raw/ # INPUT: immutable, untrusted source material
|
||||
│ ├── CONTRACT.md # Date shard, capture fields, immutability, untrusted content
|
||||
│ ├── 2026/09/ # Where `raw accept` puts a file: the month it was accepted
|
||||
│ ├── articles/ # The old type directories: still valid paths, never moved,
|
||||
│ ├── documents/ # but nothing new is ever routed into them again
|
||||
│ ├── notes/
|
||||
│ └── assets/
|
||||
├── types/ # SCHEMA: the global type surface. Not a collection
|
||||
│ ├── type-spec.md # Root contract: anatomy, placement, adding a type
|
||||
│ ├── type-guidance.md # Contract for the *.guidance.md files below
|
||||
│ ├── entity.md # Entity type config + template (+ .schema.yaml)
|
||||
│ ├── entity.guidance.md # Its stack-owned authoring prose, shipped verbatim
|
||||
│ ├── entity.person.md # Subtype template: what `new` scaffolds for entity_type=person
|
||||
│ ├── concept.md # Concept type config + template (+ .guidance.md, + concept.decision.md)
|
||||
│ ├── source.md # Source type config + template (+ .guidance.md)
|
||||
│ ├── comparison.md # Comparison type config + template (+ .guidance.md)
|
||||
│ ├── project.md # Project (Vorhaben) type config + template, no guidance file
|
||||
│ ├── instruction.md # Instruction type - lives outside kb/ via `root: repo`
|
||||
│ └── lint-report.md # Contract-only: describes reports/, owns no directory
|
||||
├── kb/ # OUTPUT: compiled knowledge. A namespace, not a collection
|
||||
│ ├── CONTRACT.md # Collections, naming, tone, linking, provenance
|
||||
│ ├── index.md # Generated catalog *map*: counts and pointers
|
||||
│ ├── log.md # Generated chronological audit log
|
||||
│ ├── provenance.md # Generated raw-file reverse index
|
||||
│ ├── entities/ # COLLECTION.md + INDEX.md + areas below
|
||||
│ │ ├── codebases/
|
||||
│ │ ├── systems/
|
||||
│ │ ├── tools/ # own INDEX.md once past 50 pages
|
||||
│ │ ├── technologies/
|
||||
│ │ ├── people/
|
||||
│ │ └── organizations/
|
||||
│ ├── concepts/ # COLLECTION.md + INDEX.md + areas below
|
||||
│ │ ├── architectures/
|
||||
│ │ ├── patterns/
|
||||
│ │ ├── protocols/
|
||||
│ │ ├── workflows/
|
||||
│ │ ├── decisions/
|
||||
│ │ └── problems/
|
||||
│ ├── sources/ # COLLECTION.md + INDEX.md + areas below
|
||||
│ │ ├── transcripts/
|
||||
│ │ ├── analyses/
|
||||
│ │ ├── articles/
|
||||
│ │ ├── documents/
|
||||
│ │ ├── notes/
|
||||
│ │ ├── trackers/
|
||||
│ │ └── unclassified/
|
||||
│ ├── comparisons/ # COLLECTION.md - comparison pages, no subtype axis
|
||||
│ └── gtd/ # COLLECTION.md + INDEX.md + areas below
|
||||
│ ├── haus/
|
||||
│ ├── finanzen/
|
||||
│ └── technik/
|
||||
├── work/ # WORKSHOP: one directory per multi-session run, tracked
|
||||
│ └── CONTRACT.md # Run keys, required files, how a run closes
|
||||
├── reports/ # DERIVED: lint reports, traces, eval scores. Gitignored
|
||||
│ └── CONTRACT.md
|
||||
└── tools/ # COMPILER: the wikitool CLI
|
||||
├── CONTRACT.md # Command records (generated) and index, maintenance schedule
|
||||
└── README.md # How wikitool is built and how to change it
|
||||
```
|
||||
|
||||
<!-- dist:strip-start -->
|
||||
Dev-instance-only (see `tools/CONTRACT.md` for how it got here):
|
||||
|
||||
```
|
||||
├── docs/dev/ # Human-readable: development environment and release workflow
|
||||
└── commonplace/ # Vendored, read-only knowledge base
|
||||
```
|
||||
<!-- dist:strip-end -->
|
||||
|
||||
A directory under `kb/` is a **collection** exactly when it holds a `COLLECTION.md`; a
|
||||
subdirectory inside one is an **area** that inherits it, and that is as deep as a page goes -
|
||||
nothing nests below an area, because the generated catalog reads exactly two path segments
|
||||
under `kb/` and would fold a deeper page into the area silently (`kb/CONTRACT.md` § Collections
|
||||
has the rule; `wikitool lint` reports a violation as a hard error).
|
||||
|
||||
Which areas a collection has is not chosen per page: a type-spec's `layout:` maps its subtype
|
||||
field onto directories, and `wikitool new` writes the page straight into the one its subtype
|
||||
names. That is also what makes the catalog's shard threshold do anything - `index rebuild`
|
||||
splits **per area**, so a collection with no areas keeps one table however large it grows.
|
||||
`wikitool lint` reports such a collection once it is past the threshold, as a recommendation
|
||||
rather than an error, together with the split its subtype field would produce; it stays quiet
|
||||
when the split would not actually help. `kb/comparisons/` is the worked example of a collection
|
||||
that stays flat - it has no subtype field for a `layout:` to key on at all. A *lopsided* subtype
|
||||
field is a different case and is fixed rather than left flat: `kb/sources/` looked lopsided only
|
||||
because `source_type` had a schema `default:` that the compiler applied whenever nobody chose a
|
||||
value, and once that was removed and the pages reclassified it split into six real areas.
|
||||
|
||||
`COLLECTION.md` never appears outside `kb/` - the other layers carry a `CONTRACT.md` or a root
|
||||
type-spec instead. A stage may carry both a `README.md` and a `CONTRACT.md`: they have different
|
||||
readers. The README is for humans working *on* that layer, the contract is what binds an agent
|
||||
working *with* it.
|
||||
|
||||
## How to Use
|
||||
|
||||
### Adding Knowledge (Ingest)
|
||||
|
||||
1. Drop a file into `incoming/` - directly, no classification to make. Files that belong
|
||||
together go into one folder there instead: a folder is one source, accepted whole with
|
||||
its structure kept. Everything past that (the destination in `raw/`, which is a `YYYY/MM`
|
||||
shard of the day it was accepted, and whether several files of one source get bundled)
|
||||
is computed by `tools/wikitool raw accept`, never chosen by hand
|
||||
2. Tell the LLM: `Ingest incoming/my-article.md` - or just `Ingest`, which takes the oldest
|
||||
entry waiting in `incoming/` (`tools/wikitool raw pending` lists them). It will ask you
|
||||
two things before promoting: how faithful the capture is (`fidelity`) and what the material may claim
|
||||
about its subject (`authority`). Both are recorded once and never guessed - they are
|
||||
knowable now and unrecoverable later
|
||||
3. The LLM will:
|
||||
- Promote it into `raw/` with `raw accept`
|
||||
- Read and summarize the source
|
||||
- Create a source page in `kb/sources/`
|
||||
- Create or update relevant entity pages
|
||||
- Create or update relevant concept pages
|
||||
- Add cross-references between everything
|
||||
- Rebuild the catalog and append to `kb/log.md`
|
||||
|
||||
A document can also arrive from outside, through the MCP server's optional `submit` tool
|
||||
(see [INSTALL-MCP.md](INSTALL-MCP.md)): it lands in `mcp-upload/`, not `incoming/`, and a human
|
||||
reviews and promotes it with `wikitool upload accept` before step 1 above applies - see
|
||||
[instructions/ingest-queue.md](instructions/ingest-queue.md).
|
||||
|
||||
A web page needs no download of your own: tell the LLM `Ingest https://example.org/post`, and
|
||||
`tools/wikitool raw fetch` puts the page into `incoming/` - the HTML exactly as received, plus a
|
||||
text derived from it with a header recording where and when it was fetched. Behind a paywall or a
|
||||
login, save the page from your browser into `incoming/` (HTML only) instead; the LLM derives the
|
||||
same text from that file with `raw fetch --html`. See [raw/CONTRACT.md](raw/CONTRACT.md).
|
||||
|
||||
Documentation that lives in a git repository is captured, not copied: `tools/wikitool raw capture
|
||||
<repo-url> --ref main --path 'docs/**/*.md' --name <bundle> ...` writes the matching files, byte
|
||||
for byte, into `incoming/<bundle>/` together with a `_capture.json` manifest naming the repository,
|
||||
the ref rule and the commit. Later, `tools/wikitool raw status` tells you which captured bundles
|
||||
have fallen behind their repository, file by file; `raw capture --update` and `raw accept
|
||||
--replaces-bundle` take the new edition in as a whole. You need not run any of that yourself:
|
||||
tell the LLM `Update the captured repositories`, and it checks them, takes one changed bundle per
|
||||
run into the wiki and says how many are still behind. Git uses your own keys and credential
|
||||
helpers - nothing is stored in the repository.
|
||||
|
||||
The same repositories can get something back: the wiki's guidelines, as one generated
|
||||
`GUIDELINES.md` in their root. Which pages count as guidelines is your decision, written down in
|
||||
`kb/CONVENTIONS.md` (§ Guidelines for other repositories); `tools/wikitool export guidelines
|
||||
--tag guideline` prints the file as it would be written. A repository takes part by carrying a
|
||||
`GUIDELINES.md` whose first line is `<!-- wikitool:export kind=guidelines -->` - commit that one
|
||||
line there, and point the repository's own `AGENTS.md` at the file (Claude Code:
|
||||
`@GUIDELINES.md`). A hand-written `GUIDELINES.md` is never touched. Then tell the LLM
|
||||
`Roll out the guidelines to the captured repositories`: it runs `export guidelines --push`, which
|
||||
stops before pushing anything (the **Guideline Push Gate**) and shows you, per repository, what
|
||||
would change - the LLM puts every diff in front of you, and only your approval pushes one commit
|
||||
per repository, changing only that file, straight onto its branch.
|
||||
|
||||
### Querying Knowledge
|
||||
|
||||
Ask questions naturally:
|
||||
- "What projects use MQTT?"
|
||||
- "Show me the architecture of HA Integration"
|
||||
- "Compare gdeploy and plugnburn-edl"
|
||||
- "What decisions were made about E3DC integration?"
|
||||
|
||||
The LLM will search the wiki, synthesize an answer, and cite sources.
|
||||
|
||||
### Maintaining Knowledge (Lint)
|
||||
|
||||
Periodically run: `Lint the wiki`
|
||||
|
||||
The LLM will:
|
||||
- Run `tools/wikitool lint` for a deterministic structural + provenance scan
|
||||
(broken wikilinks, orphan pages, index drift, schema gaps, uncovered raw
|
||||
files, citation/frontmatter drift)
|
||||
- Check for contradictions (semantic judgment)
|
||||
- Find stale claims
|
||||
- Identify orphan pages and missing cross-references
|
||||
- Rebuild `kb/index.md` and `kb/provenance.md`, append to `kb/log.md`
|
||||
- Generate a report
|
||||
|
||||
See the [Maintenance](#maintenance) section below for the full schedule and
|
||||
command reference.
|
||||
|
||||
### Reviewing Commitments (Weekly Review)
|
||||
|
||||
Say: `Run the weekly review`
|
||||
|
||||
Knowledge and commitments keep different clocks, so they live in different
|
||||
places. A page under `kb/gtd/` is one committed initiative's durable memory -
|
||||
its goal, who is involved, where it stands, why it is worth doing - and it never
|
||||
summarizes the task list. The open items live in a task tracker that owns them,
|
||||
configured per checkout in `.wikitool-tasks.json` (see
|
||||
[INSTALL.md](INSTALL.md) § Konfiguration; no tracker configured is a valid
|
||||
state, and the pages work without one).
|
||||
|
||||
Nothing syncs between the two. `tools/wikitool review` joins them at read time
|
||||
over the project name and prints what needs a decision: initiatives with no next
|
||||
action, waiting-fors past their follow-up date, tracker projects with no page,
|
||||
active pages with no open loop, someday items gone stale. It stores nothing -
|
||||
not even a report file. The `gtd-weekly-review` skill then walks the findings with
|
||||
you and turns each one into a decision; `tools/wikitool new project` is what
|
||||
gives a new initiative its page and its tracker project under one name, and
|
||||
`tools/wikitool task new` files a single open item into the tracker - the
|
||||
commitment half of a source that carries both something to know and something
|
||||
to do, with no page of its own. `tools/wikitool task list` reads a project's
|
||||
open items back with their tracker id, and `tools/wikitool task close --id`
|
||||
marks one done - never deletes it - closing the loop the same source-driven
|
||||
way `task new` opened it, or the way the weekly review proposes it for a
|
||||
`waiting_overdue`/`someday_stale` finding once you confirm.
|
||||
|
||||
Why the split runs this way, rather than syncing the two:
|
||||
[docs/explanation/knowledge-and-commitment.md](docs/explanation/knowledge-and-commitment.md).
|
||||
|
||||
## Page Types
|
||||
|
||||
Every page type the stack ships - entity, concept, source, comparison, project - with its
|
||||
subtypes, the directory each is written to and its required fields, is listed in
|
||||
[docs/reference/page-types.md](docs/reference/page-types.md), generated from the type-specs. An
|
||||
instance adopts those type-specs and may change them, so for the types *this* instance has, ask
|
||||
the tool:
|
||||
|
||||
```bash
|
||||
tools/wikitool types list
|
||||
tools/wikitool types describe entity
|
||||
```
|
||||
|
||||
## Workflows
|
||||
|
||||
### For You (Human)
|
||||
|
||||
1. **Curate sources** - Drop files you want processed into `incoming/` - directly, or one folder
|
||||
per source
|
||||
2. **Ask questions** - Query the wiki naturally
|
||||
3. **Review changes** - Check `kb/log.md` and `kb/index.md`
|
||||
4. **Direct the LLM** - Guide it on what to emphasize or investigate
|
||||
5. **Browse in Obsidian** - Open the wiki directory in Obsidian for visualization
|
||||
|
||||
### For the LLM
|
||||
|
||||
`AGENTS.md` is the cross-cutting schema/policy; the step-by-step procedures
|
||||
themselves live as independently-discoverable skills under `.agents/skills/`
|
||||
(mirrored to `.claude/skills/` for Claude Code via `tools/wikitool instructions sync`).
|
||||
Which skills ship, what each does and which requests start it:
|
||||
[docs/reference/skills.md](docs/reference/skills.md), generated from the skills themselves.
|
||||
|
||||
Each skill's underlying mechanical work (frontmatter, cross-references, index/log,
|
||||
decay math, publishing) is delegated to `tools/wikitool` - never hand-edited.
|
||||
Most days you need three of the how-to guides: [ingest a source](docs/how-to/ingest-a-source.md),
|
||||
[query the wiki](docs/how-to/query-the-wiki.md) and [maintain it](docs/how-to/maintain-the-wiki.md).
|
||||
How the parts fit together is [docs/explanation/architecture.md](docs/explanation/architecture.md).
|
||||
|
||||
## Your first ingestion
|
||||
|
||||
@@ -372,213 +82,6 @@ cp ~/Downloads/my-notes.md incoming/my-notes.md
|
||||
Ingest incoming/my-notes.md
|
||||
```
|
||||
|
||||
## Tips
|
||||
|
||||
### Naming
|
||||
|
||||
- Use human-readable titles with spaces for files: `Hybrid Search.md`, not kebab-case
|
||||
- Use singular for entities: `HA Integration.md` (not `HA Integrations.md`)
|
||||
- Use wikilinks matching the file name exactly: `[[Entity Name]]`
|
||||
- A title is a file name, so it has to work on Windows and macOS as well: no `< > : " / \ | ? *`,
|
||||
no reserved names such as `CON` or `Index`, no trailing dot, and no second page whose title
|
||||
differs only by case. `wikitool new` and `wikitool rename` refuse such titles, `wikitool lint`
|
||||
reports existing ones, and `kb/CONTRACT.md` § Titles are identifiers has the full rule
|
||||
- A file's whole path below the instance root stays at 160 characters or fewer, so a Windows
|
||||
checkout works without long paths: `new`, `rename`, `move` and `raw accept` refuse a longer
|
||||
one, and `lint` reports existing ones as Long Paths (advisory; `wikitool rename` is the fix)
|
||||
- **Titles follow the subject's own established name, not the wiki's language.** `Act Runner` and
|
||||
`GitOps Ownership Model` keep theirs. A title is the only identifier a page has - it also lives
|
||||
in every wikilink and citation id pointing at it - so translating one is a rename, never an
|
||||
edit: `tools/wikitool rename`, per `instructions/page-lifecycle.md`
|
||||
|
||||
### Organization
|
||||
|
||||
- Start with a few broad categories, refine as needed
|
||||
- Don't over-organize early - let structure emerge
|
||||
- Use tags for cross-cutting concerns
|
||||
|
||||
### Quality
|
||||
|
||||
- The LLM will maintain quality standards from `AGENTS.md`
|
||||
- Review changes periodically
|
||||
- Flag issues to the LLM
|
||||
|
||||
## Maintenance
|
||||
|
||||
The wiki is kept healthy by deterministic `tools/wikitool` commands, run by the
|
||||
LLM (via the skills above). The schedule - which task runs how often, and with
|
||||
which command - lives in [`tools/CONTRACT.md`](tools/CONTRACT.md#maintenance-schedule),
|
||||
next to the command reference it depends on, so the two cannot drift apart.
|
||||
The notes below explain the three parts of it that need more than one line.
|
||||
|
||||
**Provenance.** Every fact should trace back to a raw file. Source pages
|
||||
declare their backing `raw_files:`; entity/concept pages declare `provenance:`
|
||||
(`sourced`/`general`/`mixed`) and cite specific claims inline with a
|
||||
`[^cite-id]` footnote (`tools/wikitool cite add` mints the id and definition;
|
||||
placing the marker in the prose is still manual). `tools/wikitool sources
|
||||
coverage` finds raw files with no source page yet, `sources trace` answers
|
||||
"where did this come from?" in either direction, and `sources rebuild-index`
|
||||
regenerates the reverse index at `kb/provenance.md`. `lint` cross-checks that
|
||||
citations and frontmatter `sources:` lists agree, and hard-errors on any
|
||||
leftover pre-migration `^[[...]]` marker.
|
||||
|
||||
**Git automation.** `tools/wikitool publish` stages everything, commits with
|
||||
an auto-generated changed-file list, and pushes to `origin/main` in one step -
|
||||
never run raw `git commit`/`git push` for wiki changes. Without `--no-push` it stops with
|
||||
exit 1 before committing when the remote is not configured or cannot be reached; a local-only
|
||||
instance passes `--no-push` on every call. Publishes touching
|
||||
≥10 files exit **42** (the **Mass-Update Gate**) - a distinct "a human must see
|
||||
this" code, not an error - printing the full file list and the
|
||||
`--confirm <token>` line that publishes it. The token digests that file list,
|
||||
so a clearance never carries to a changeset the user did not see.
|
||||
|
||||
**Guideline push.** `tools/wikitool export guidelines --push` exits **42** the same way (the
|
||||
**Guideline Push Gate**) before it writes `GUIDELINES.md` into any captured repository, printing
|
||||
every target's status and diff and the `--confirm <token>` line. The token digests each target's
|
||||
branch tip and the file, so a moved branch or an edited guideline asks again.
|
||||
|
||||
**Iteration/cost limits.** Every `tools/wikitool` call is checked against a
|
||||
hard, code-enforced per-session budget before it runs (default: 60 calls, or
|
||||
3 identical calls in a row) - not just a prompt instruction to stop. Past the
|
||||
limit, the command refuses to run until a human approves continuing with
|
||||
`--override-budget`. `budget status` stays readable at all times; `budget
|
||||
reset` clears the counter and therefore needs `--yes` of its own. See
|
||||
AGENTS.md's "Gates" section.
|
||||
|
||||
## Telemetry and evaluation
|
||||
|
||||
In this checkout, every `wikitool` call appends an event to
|
||||
`reports/telemetry/<session>/trace.jsonl`, and the hook files under `.github/hooks/` and
|
||||
`.vibe/` add what the agent did between those calls. Nothing leaves the machine: `reports/` is
|
||||
gitignored and no exporter is configured.
|
||||
|
||||
**A distributed instance records nothing unless it asks to.** The default follows the
|
||||
installation form - on for a git clone of this repo, where the traces are the stack's own
|
||||
measuring instrument, off for an instance installed from a release, where nobody ordered
|
||||
telemetry. Two
|
||||
quantity caps apply either way: 5 MiB per session trace, and 250 session directories.
|
||||
`wikitool doctor` reports which state a checkout is in and why; EVALS.md § "Whether it runs at
|
||||
all" has the precedence rules and the opt-in file.
|
||||
|
||||
That record is what makes it possible to ask how a session *worked*, not just what it left
|
||||
behind:
|
||||
|
||||
```bash
|
||||
tools/wikitool eval sessions # which sessions have a trace
|
||||
tools/wikitool eval score # score this session
|
||||
```
|
||||
|
||||
A score has two halves - the structural state of the tree, from lint's own checks, and
|
||||
trajectory rules over the trace, which catch things no unit test can: a refused call repeated
|
||||
unchanged, a gate flag passed without that gate having refused anything.
|
||||
|
||||
[`EVALS.md`](EVALS.md) is the full picture: the event contract, what each agent harness can and
|
||||
cannot report, what is redacted, and why there is deliberately no LLM judge yet.
|
||||
|
||||
## Tools Integration
|
||||
|
||||
### wikitool (deterministic CLI)
|
||||
|
||||
Mechanical wiki operations - never hand-edited by the LLM - are handled by
|
||||
`tools/wikitool`: scaffolding pages, renaming and deleting them, cross-references,
|
||||
index/log/provenance regeneration, structural linting, and publishing.
|
||||
|
||||
Every command carries one data record - synopsis, properties, copyable examples,
|
||||
each exit cause with what to do about it, prohibitions, and notes on its
|
||||
behaviour - kept next to its code. `tools/wikitool <command> -h` prints it,
|
||||
`tools/wikitool -h` prints a one-line index of all of them, a command that fails with
|
||||
exit 1 prints the record's reactions on stderr right under its `ERROR` line, and
|
||||
[`tools/CONTRACT.md`](tools/CONTRACT.md) holds a generated copy together with the
|
||||
maintenance schedule; `tools/wikitool docs verify` checks that copy and every
|
||||
command's flags against the CLI in both directions. [`tools/README.md`](tools/README.md)
|
||||
is the other half: how the CLI is built and how to add a command. `AGENTS.md`
|
||||
holds the invariants that say when each command is mandatory.
|
||||
|
||||
```bash
|
||||
tools/wikitool -h
|
||||
tools/wikitool <command> -h
|
||||
```
|
||||
|
||||
<!-- dist:strip-start -->
|
||||
Dev-instance-only: extending `tools/wikitool`, the type schema, or the instruction/skill layer
|
||||
itself is a separate session type with its own rules, covered by the `stack-dev`,
|
||||
`stack-build` and `stack-close` skills nested under `instructions/dev/` (never present in a
|
||||
distributed instance - `tools/CONTRACT.md` explains why).
|
||||
<!-- dist:strip-end -->
|
||||
|
||||
### MCP read server (optional)
|
||||
|
||||
The terminal is not the only way in. `tools/chemenu/mcp/` serves the same wiki read-only over
|
||||
MCP - `search`, `types`, `describe_type`, `lint` and `status` - so a consumer that is not a
|
||||
shell on this machine can ask the same questions and get the same answers. Literally the same:
|
||||
the CLI and the server are two adapters over one core, and a golden test holds their output
|
||||
together rather than trusting that it agrees.
|
||||
|
||||
There is no tool that writes, and not because one is filtered out of a list: the server imports
|
||||
nothing under `chemenu/commands/`, so `new`, `publish` and the rest are unreachable from it.
|
||||
Every answer carries the commit it was computed from, so a checkout that has fallen behind
|
||||
produces a visibly stale answer instead of a confident wrong one.
|
||||
|
||||
```bash
|
||||
tools/.venv/bin/pip install -r tools/requirements-mcp.txt
|
||||
WIKI_TRACE=0 tools/.venv/bin/python -m chemenu.mcp # stdio
|
||||
WIKI_TRACE=0 tools/.venv/bin/python -m chemenu.mcp \
|
||||
--transport streamable-http --host 0.0.0.0 --port 8000 # deployed
|
||||
```
|
||||
|
||||
The dependency is deliberately not in `requirements.txt`: an instance that only uses the CLI
|
||||
should not have to install a web stack to do it.
|
||||
|
||||
Installing it, wiring a client to it, and putting authentication in front of it:
|
||||
[`INSTALL-MCP.md`](INSTALL-MCP.md), for humans. The agent-side operating procedure - keeping the
|
||||
checkout current, and what a stale answer looks like - is
|
||||
[`instructions/mcp-read-server.md`](instructions/mcp-read-server.md).
|
||||
|
||||
### Obsidian
|
||||
|
||||
Open this directory in Obsidian for:
|
||||
- Graph view of connections
|
||||
- Easy navigation with wikilinks
|
||||
- Plugins: Dataview, Marp, etc.
|
||||
|
||||
### Git
|
||||
|
||||
This is a git repo. Use it for:
|
||||
- Version history
|
||||
- Branching for experiments
|
||||
- Collaboration
|
||||
|
||||
### Search
|
||||
|
||||
`tools/wikitool search "<text>"` searches `kb/` directly - by text, or by frontmatter with
|
||||
`--field entity_type=system` or `--field '!sources'`. It is read-only and is the one
|
||||
command not counted against the session budget, because looking before acting is the habit
|
||||
worth encouraging.
|
||||
|
||||
For browsing rather than searching, `kb/index.md` is the catalog map and each collection
|
||||
carries its own `INDEX.md`.
|
||||
|
||||
## IT-Specific Features
|
||||
|
||||
This wiki is tailored for IT work with:
|
||||
|
||||
- **Entity types** specific to software development and systems
|
||||
- **Relationship types** like `hängt ab von`, `verwendet`, `implementiert` - the vocabulary is in
|
||||
[kb/CONVENTIONS.md](kb/CONVENTIONS.md), because it is this instance's rather than the stack's
|
||||
- **Templates** per page type, and per subtype where its pages need a shape of their own - a person, a decision record (ADR)
|
||||
- **Guidelines** for documenting technical decisions
|
||||
- **Cross-reference patterns** for code and architecture
|
||||
|
||||
## Files Created Automatically
|
||||
|
||||
The LLM will create and maintain:
|
||||
- `kb/index.md` - Always up-to-date catalog
|
||||
- `kb/log.md` - Complete audit trail
|
||||
- `kb/provenance.md` - Raw-file reverse index
|
||||
- Pages of every page type, each in the directory
|
||||
[docs/reference/page-types.md](docs/reference/page-types.md) names for it
|
||||
- Lint reports, session traces and eval scores in `reports/` (gitignored)
|
||||
|
||||
## Changelog
|
||||
|
||||
Changes to the wiki stack (schema, skills, `wikitool`, READMEs) are tracked in
|
||||
@@ -614,4 +117,3 @@ Affero variant.
|
||||
If you set up an instance and later publish it, keep `LICENSE`, `LICENSE-CONTENT`
|
||||
and `NOTICE` in the tree. `dist export` puts them there and refuses to build a
|
||||
distribution without them, so under normal use this takes no effort.
|
||||
|
||||
Reference in new issue
Block a user