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
@@ -13,6 +13,9 @@ written by hand.
|
||||
start it, generated from their `SKILL.md`.
|
||||
- [Page types](page-types.md) - every page type the stack ships for `kb/`, its subtypes, where
|
||||
its pages are written and its required fields, generated from the type-specs.
|
||||
- [Configuration](configuration.md) - the environment variables `wikitool` reads and the
|
||||
per-checkout files an operator may create. Written by hand: it has no source to be generated
|
||||
from yet.
|
||||
|
||||
The last two describe the stack's shipped defaults, which an instance may change or extend;
|
||||
`tools/wikitool instructions list` and `tools/wikitool types describe <type>` show what one
|
||||
|
||||
@@ -55,7 +55,7 @@ tools/wikitool dist export ../my-wiki
|
||||
**Behaviour**
|
||||
|
||||
- Writes a contentless, distributable copy of this repo's machinery into an empty or new `<target>` directory.
|
||||
- Ships `AGENTS.md`/`README.md`/`EVALS.md` with any `dist:strip-start`...`dist:strip-end` marker region removed, `instructions/` (minus `instructions/dev/`), `types/` (the `root: kb` page type-specs, their schemas and their subtype templates `types/<type>.<value>.md` re-keyed as `.template`, the stack's own verbatim), `docs/` verbatim (minus `docs/dev/`), `tools/` (no venv/caches, and not the dev-only test suite `tools/chemenu/tests/` with its `pytest.ini`/`.coveragerc`), the `.github/hooks/`+`.vibe/` session-tracing config plus `.claude/settings.json`, `kb/CONTRACT.md` (no pages, no areas) and `VERSION`.
|
||||
- Ships `AGENTS.md`/`README.md`/`INSTALL.md` with any `dist:strip-start`...`dist:strip-end` marker region removed, `instructions/` (minus `instructions/dev/`), `types/` (the `root: kb` page type-specs, their schemas and their subtype templates `types/<type>.<value>.md` re-keyed as `.template`, the stack's own verbatim), `docs/` verbatim (minus `docs/dev/`), `tools/` (no venv/caches, and not the dev-only test suite `tools/chemenu/tests/` with its `pytest.ini`/`.coveragerc`), the `.github/hooks/`+`.vibe/` session-tracing config plus `.claude/settings.json`, `kb/CONTRACT.md` (no pages, no areas) and `VERSION`.
|
||||
- Ships `raw/` and `incoming/` as flat roots, each with a `.gitkeep` and no subdirectories. `incoming/.gitkeep` is trackable and survives becoming a git repository, so a plain clone gets the directory without any bootstrap step.
|
||||
- Ships templates, never the filled files: `USER.md.template`/`SOUL.md.template`, `kb/CONVENTIONS.md.template`, and each collection's contract re-keyed as `kb/<name>/COLLECTION.md.template`. The filled `USER.md`/`SOUL.md`/`kb/CONVENTIONS.md`/`kb/<name>/COLLECTION.md`/`types/<page-type>.md`/`types/<page-type>.<value>.md` bind their instance; `find_leaks` refuses a plan carrying one.
|
||||
- Writes a generated `.wikitool-release.json` stamp: version, export date, origin, and a sha256 per exported file - the base a later upgrade compares against.
|
||||
@@ -242,7 +242,7 @@ tools/wikitool dist upgrade --latest --expect 8.0.0 --dry-run
|
||||
- `wikitool version check` - finds out whether an update exists
|
||||
- `wikitool version notes` - the notes of the release `--expect` should name
|
||||
- `instructions/upgrade-instance.md` - the order after the swap
|
||||
- `INSTALL.md` § "Version und Updates" - which release, whether to take it, where the tarball comes from
|
||||
- `docs/how-to/update-an-instance.md` - which release, whether to take it, where the tarball comes from
|
||||
- `wikitool migrate status` - the migrations the report names
|
||||
|
||||
## `version show`
|
||||
@@ -323,7 +323,7 @@ tools/wikitool version check --json
|
||||
- The only command whose whole job is the network call - `version notes` reaches the same feed too, but only as a fallback on a distributed instance, and `dist upgrade --latest` asks it which release to download.
|
||||
- Never reached implicitly from another command (`dist upgrade` asks only when passed `--latest`), needs no key, and times out after `--timeout` seconds (default 10).
|
||||
- The feed is `--url`, else `$WIKITOOL_UPDATE_URL`, else the release stamp's, else the built-in origin. `$WIKITOOL_UPDATE_TOKEN` is only needed if that feed is not readable anonymously.
|
||||
- For `update` or `migration` it prints that applying the release is a separate, manual step (`INSTALL.md` § "Eine Instanz aktualisieren").
|
||||
- For `update` or `migration` it prints that applying the release is a separate, manual step (`docs/how-to/update-an-instance.md`).
|
||||
- Read-only; exempt from the Iteration Budget Gate.
|
||||
|
||||
**Properties**
|
||||
@@ -344,7 +344,7 @@ tools/wikitool version check --json
|
||||
|
||||
- `wikitool dist upgrade` - applies the update this reports
|
||||
- `wikitool version notes` - prints the release notes
|
||||
- `INSTALL.md` § "Version und Updates" - what the operator decides before an update
|
||||
- `docs/how-to/update-an-instance.md` - what the operator decides before an update
|
||||
|
||||
## `version notes`
|
||||
|
||||
|
||||
@@ -60,7 +60,7 @@ tools/wikitool doctor --json
|
||||
|
||||
- `instructions/setup-instance.md` - the setup steps most findings point back to
|
||||
- `instructions/preflight.md` - what `tool-paths` and `install-dir` point back to
|
||||
- `INSTALL.md` § "Konfiguration" - the per-checkout configuration files
|
||||
- `EVALS.md` - telemetry state and caps
|
||||
- `docs/reference/configuration.md` - the per-checkout configuration files
|
||||
- `docs/explanation/telemetry-and-evaluation.md` - telemetry state and caps
|
||||
- `instructions/session-setup.md` - setting `WIKITOOL_SESSION_ID`
|
||||
<!-- /wikitool:reference-commands -->
|
||||
@@ -401,7 +401,7 @@ tools/wikitool upload list --json
|
||||
**See also**
|
||||
|
||||
- `wikitool upload show` - one submission's manifest
|
||||
- `INSTALL-MCP.md` § "Schritt 7: Optional - den `submit`-Pfad freischalten"
|
||||
- `docs/how-to/set-up-the-mcp-server.md` § "Optional: the submit path"
|
||||
|
||||
## `upload show`
|
||||
|
||||
|
||||
@@ -53,7 +53,7 @@ tools/wikitool eval sessions --json
|
||||
**See also**
|
||||
|
||||
- `wikitool eval score` - scores one of them
|
||||
- `EVALS.md` - how telemetry and evaluation work
|
||||
- `docs/explanation/telemetry-and-evaluation.md` - how telemetry and evaluation work
|
||||
|
||||
## `eval score`
|
||||
|
||||
@@ -110,5 +110,5 @@ tools/wikitool eval score --session wiki-1727330000 --save
|
||||
**See also**
|
||||
|
||||
- `wikitool eval sessions` - which session ids exist
|
||||
- `EVALS.md` - the scoring levels
|
||||
- `docs/explanation/telemetry-and-evaluation.md` - the scoring levels
|
||||
<!-- /wikitool:reference-commands -->
|
||||
@@ -355,7 +355,7 @@ tools/wikitool docs toc --apply
|
||||
|
||||
- Creates, refreshes or removes the generated table-of-contents region on every reference file over 100 lines: `AGENTS.md`, every stage contract, `kb/CONVENTIONS.md`, every `kb/*/COLLECTION.md`, every flat `instructions/**.md` file, every `types/*.md` type-spec, and every `docs/` page - each together with the `<name>.template` it ships as, where one exists.
|
||||
- The scope is computed from those categories rather than listed, so a file added later is in scope without a code change.
|
||||
- Out of scope: every `SKILL.md`, the human docs (`README.md`, `CHANGES.md`, `EVALS.md`, `INSTALL.md`, `tools/README.md`), and every subtype template `types/<type>.<value>.md` - `new` copies it into a page, so it never carries a region whatever its length.
|
||||
- Out of scope: every `SKILL.md`, the human docs at the root and beside the code (`README.md`, `CHANGES.md`, `INSTALL.md`, `tools/README.md`), and every subtype template `types/<type>.<value>.md` - `new` copies it into a page, so it never carries a region whatever its length.
|
||||
- Dry-run by default (prints which files would change); `--apply` writes. Idempotent: a re-run after an interruption converges rather than doubling a region.
|
||||
- If `docs verify` still reports a stale region after `--apply`, the file's `##` headings changed in between; run it again.
|
||||
|
||||
|
||||
@@ -0,0 +1,203 @@
|
||||
# Configuration
|
||||
|
||||
The environment variables `wikitool` reads, and the per-checkout files an operator may create at the
|
||||
root of an instance. None of them is needed for an instance to work: an instance installed from a
|
||||
release runs against the origin's public release feed with no configuration at all.
|
||||
|
||||
This page is written by hand. Unlike the command reference, it has no single source in the code it
|
||||
could be generated from yet, so a change to one of these files' shape has to be carried here
|
||||
by whoever makes it.
|
||||
|
||||
<!-- wikitool:toc -->
|
||||
## Contents
|
||||
|
||||
- [Environment variables](#environment-variables)
|
||||
- [Telemetry](#telemetry)
|
||||
- [Tool paths](#tool-paths)
|
||||
- [Allowed push URLs](#allowed-push-urls)
|
||||
- [Task tracker](#task-tracker)
|
||||
- [Super Productivity](#super-productivity)
|
||||
- [CalDAV](#caldav)
|
||||
- [MCP submissions](#mcp-submissions)
|
||||
<!-- /wikitool:toc -->
|
||||
|
||||
## Environment variables
|
||||
|
||||
| Variable | Purpose | Fallback |
|
||||
|----------|---------|----------|
|
||||
| `WIKI_AUTHOR` | Overrides the author name of new source pages | `git config user.name`. Without either, `new` stops with an `ERROR` |
|
||||
| `WIKITOOL_SESSION_ID` | Scopes the Iteration Budget Gate to a task rather than a terminal, and names the directory a trace lands in | A session variable the harness sets itself, where one is known (for example `CLAUDE_CODE_SESSION_ID`), else the parent process id ([instructions/session-setup.md](../../instructions/session-setup.md)) |
|
||||
| `WIKITOOL_UPDATE_URL` | The release feed `version check`, `version notes` and `dist upgrade --latest` ask | The value in `.wikitool-release.json`, else the origin's feed |
|
||||
| `WIKITOOL_UPDATE_TOKEN` | A Gitea token for the release feed, sent only to downloads on the feed's own host | None. Not needed against the origin, only against a feed in a private repository |
|
||||
| `WIKITOOL_TASKS_CONFIG` | Path to a tracker configuration that `task`, `review` and `doctor` read instead of `.wikitool-tasks.json`, for running one checkout against several trackers in turn | `.wikitool-tasks.json` at the root. A path to a file that does not exist is an error, never "no tracker configured" |
|
||||
| `CHEMENU_ROOT` | Which corpus the package works on, for a caller outside the checkout itself | The checkout the package sits in. `tools/wikitool` behaves the same without it |
|
||||
| `WIKI_TRACE` | `0`/`1` turns telemetry off or on, beating both the default and `.wikitool-telemetry.json` | The installation-form default ([below](#telemetry)) |
|
||||
| `WIKI_TRACE_DIR` | Writes traces somewhere other than `reports/telemetry/` | `reports/telemetry/` |
|
||||
| `WIKI_TRACE_CONTENT` | `0` keeps only lengths and digests of prompts and replies instead of their text | Text is kept |
|
||||
| `WIKI_TRACE_MAX_CONTENT` | Per-attribute content cap in characters | 60 KiB |
|
||||
| `WIKI_TRACE_MAX_SESSION_BYTES` | Byte cap per session trace; beats the file's `max_session_bytes` | 5 MiB |
|
||||
| `WIKI_TRACE_KEEP_SESSIONS` | How many session directories retention keeps; beats the file's `keep_sessions` | 250 |
|
||||
|
||||
## Telemetry
|
||||
|
||||
**Telemetry is off in an instance.** Every instance carries the `.wikitool-release.json` of its
|
||||
release, and that is how `chemenu.telemetry.policy` recognises that nobody asked for telemetry. The
|
||||
same holds for every further clone of the instance, because the file is committed with the first
|
||||
publish. Only a clone of the origin repository, used to develop the stack, has no stamp. There the
|
||||
traces are the instrument the stack measures itself with, and they are **on**.
|
||||
|
||||
To turn the default around, create `.wikitool-telemetry.json` at the root. It is per checkout and
|
||||
gitignored, with no `.template`, like `.wikitool-remotes.json`:
|
||||
|
||||
```json
|
||||
{ "enabled": true, "max_session_bytes": 5242880, "keep_sessions": 250 }
|
||||
```
|
||||
|
||||
All three keys are optional. `WIKI_TRACE` still overrides `enabled` in both directions and beats
|
||||
this file. `wikitool doctor` reports the current state: on or off, why, and how much has been
|
||||
recorded against both caps. What the caps do and what never reaches a trace:
|
||||
[telemetry-and-evaluation.md](../explanation/telemetry-and-evaluation.md).
|
||||
|
||||
## Tool paths
|
||||
|
||||
**The preflight writes this file, not you.** `.wikitool-tools.json` at the root holds the absolute
|
||||
paths of Python, git and ripgrep, as the preflight found them on this machine. `wikitool` starts git
|
||||
and rg from there instead of from `PATH`. It is per checkout and gitignored, because a path on one
|
||||
machine says nothing about the next.
|
||||
|
||||
If the file is missing or incomplete, `tools/wikitool` does not start (exit 42) and names the
|
||||
preflight. If a tool sits somewhere the preflight does not look, name it:
|
||||
`tools/preflight.sh --set rg=<path>`, or in PowerShell
|
||||
`pwsh -NoProfile -ExecutionPolicy Bypass -File tools/preflight.ps1 --set rg=<path>`. Never edit the
|
||||
file by hand. `doctor` reports under `tool-paths` whether every path still works.
|
||||
|
||||
## Allowed push URLs
|
||||
|
||||
`.wikitool-remotes.json` at the root restricts where `publish` may push, per checkout and
|
||||
gitignored:
|
||||
|
||||
```json
|
||||
{ "allowed_push_urls": ["git@example.org:me/my-wiki.git"] }
|
||||
```
|
||||
|
||||
Without the file, any remote is allowed. With it, `publish` refuses with exit 42 (the Publish-Remote
|
||||
Gate) before pushing to a URL not on the list. A malformed file is an error, not permission. Only you
|
||||
edit this file. The gate has no token and no flag, and an agent that edits the list to get past a
|
||||
refusal is opening a gate on its own initiative.
|
||||
|
||||
## Task tracker
|
||||
|
||||
**Optional.** The weekly review (`tools/wikitool review`, skill `gtd-weekly-review`) checks the
|
||||
project pages under `kb/gtd/` against a task tracker. Which tracker that is goes in
|
||||
`.wikitool-tasks.json` at the root. Like the telemetry and remotes files, it is per checkout and has
|
||||
no `.template`, and it is **gitignored as soon as a token is in it**. Without the file, no tracker is
|
||||
configured, which is a valid state, not an error. A broken file, on the other hand, is a `FAIL`: an
|
||||
unreadable configuration must never pass as "no tracker".
|
||||
|
||||
```json
|
||||
{
|
||||
"schema": 1,
|
||||
"provider": "superproductivity",
|
||||
"thresholds": {
|
||||
"stalled_waiting_days": 14,
|
||||
"unpaged_project_weeks": 3,
|
||||
"someday_stale_months": 5
|
||||
},
|
||||
"superproductivity": {
|
||||
"access": "api",
|
||||
"api_base_url": "http://127.0.0.1:3876",
|
||||
"api_token": "<token from the SP settings>"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
`provider` picks the adapter. The stack ships `superproductivity` and `caldav`.
|
||||
|
||||
The `thresholds` block holds the review's three thresholds (configuration, not schema): when a
|
||||
waiting-for counts as overdue, how old a tracker project without a `kb/` page has to be before it is
|
||||
reported, and when a someday item counts as stale. A value the provider cannot supply at all - a
|
||||
waiting item with no follow-up date, a tracker project with no creation date - is not skipped silently
|
||||
but reported as its own finding (`waiting_no_follow_up`/`project_age_unknown`).
|
||||
|
||||
The provider block of the same name holds the connection details.
|
||||
|
||||
### Super Productivity
|
||||
|
||||
`access` is **mandatory and has no fallback**. It chooses between two mutually exclusive ways in:
|
||||
|
||||
- **`access: "snapshot"`** for an instance run headless: it reads only the newest backup snapshot
|
||||
under `backups_dir`. That works without the app running, but only reads. The tracker cannot be
|
||||
written from there.
|
||||
|
||||
```json
|
||||
"superproductivity": {
|
||||
"access": "snapshot",
|
||||
"backups_dir": "~/.config/superProductivity/backups"
|
||||
}
|
||||
```
|
||||
|
||||
- **`access: "api"`** for a desktop instance: it talks only to the local REST API. That answers only
|
||||
while the app runs, but it gives the current state and carries the write path. `api_token` is
|
||||
required, because every endpoint except `GET /health` demands `Authorization: Bearer <token>`.
|
||||
|
||||
The block names only the fields of its own way in. A `backups_dir` beside `access: "api"`, or an
|
||||
`api_token` beside `access: "snapshot"`, is refused when the configuration is read, not ignored.
|
||||
|
||||
What can write:
|
||||
|
||||
- `tools/wikitool new project` creates a tracker project of the same name only with `access: "api"`,
|
||||
and even there not automatically. The command stops (exit 42) and asks a human to create it, then
|
||||
continues with `--resume`.
|
||||
- `tools/wikitool task new` creates a single item without a `kb/` page.
|
||||
- `tools/wikitool task close --id` marks an item done. It never deletes one.
|
||||
|
||||
With `access: "snapshot"`, all three refuse completely with exit 1, because the tracker is read-only
|
||||
from there. `tools/wikitool task list --project` only reads, so it answers with either `access`.
|
||||
|
||||
### CalDAV
|
||||
|
||||
`caldav` is the standards-based second adapter (RFC 4791/5545). It is verified against Nextcloud
|
||||
Tasks, with iOS *Reminders* as the mobile client, and built for that split: tick items off on the
|
||||
phone, maintain them at the desk. Unlike Super Productivity, there is only one way in. CalDAV is
|
||||
always a network access, so no `access` field is needed:
|
||||
|
||||
```json
|
||||
"caldav": {
|
||||
"url": "https://<host>/remote.php/dav/calendars/<user>/",
|
||||
"username": "<login>",
|
||||
"app_password": "<Nextcloud app password>",
|
||||
"inbox_list": "Inbox",
|
||||
"someday_list": "Someday",
|
||||
"exclude_lists": ["<an existing list that is not a project>"]
|
||||
}
|
||||
```
|
||||
|
||||
- `url` points at the account's CalDAV calendar home set. It may be an alias - Nextcloud accepts a
|
||||
short name there - because every later address comes only from the `href`s the server returns,
|
||||
never from this URL joined with a name.
|
||||
- `username` is the login name, which can differ from the user id in the URL. A Nextcloud app
|
||||
password is recommended, not the account password.
|
||||
- `inbox_list` and `someday_list` name the two fixed lists, exactly one of each per instance.
|
||||
- `exclude_lists` leaves out existing plain task lists that are not projects. A list with a
|
||||
`VEVENT` component never counts as a project anyway.
|
||||
|
||||
A project is a list whose only supported component is `VTODO`. `tools/wikitool new project` creates
|
||||
it automatically with `MKCALENDAR` - without asking, unlike Super Productivity, because CalDAV has a
|
||||
real create command for lists. The uniqueness check runs against **every** list in the account,
|
||||
including excluded lists, the inbox, someday and mixed calendars. If a new name collides with any of
|
||||
them, nothing is created and the collision is named. Renaming the existing list in Nextcloud stays a
|
||||
manual step.
|
||||
|
||||
`task new` and `task close` work without restriction on `caldav`, which has no read-only mode like
|
||||
`access: "snapshot"`. When ticking an item off, `task close` changes only `STATUS`, `COMPLETED`,
|
||||
`PERCENT-COMPLETE`, `LAST-MODIFIED` and `DTSTAMP` on the existing `.ics` resource. Every other
|
||||
property, including an unknown `X-` property or an alarm, is kept unchanged. A resource that changed
|
||||
since it was read (an ETag conflict) is not written, and the command stops with exit 1. Nothing is
|
||||
ever deleted. The lists of finished projects stay after archiving, because the adapter never deletes
|
||||
a list. Remove them by hand in Nextcloud when you want to.
|
||||
|
||||
## MCP submissions
|
||||
|
||||
`.wikitool-upload.json` in the served corpus turns on the MCP read server's optional `submit` tool.
|
||||
Its shape, and what the authentication in front of the server has to guarantee before you create
|
||||
it, are in [Set up the MCP read server](../how-to/set-up-the-mcp-server.md#optional-the-submit-path).
|
||||
Reference in new issue
Block a user