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
204 lines
11 KiB
Markdown
204 lines
11 KiB
Markdown
# 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).
|