Files changed: - .gitignore - AGENTS.md - CHANGES.md - INSTALL.md - VERSION - docs/explanation/knowledge-and-commitment.md - docs/explanation/telemetry-and-evaluation.md - docs/explanation/why-gates-are-code.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/reference/commands/README.md - docs/reference/commands/configuration.md - docs/reference/commands/finding-and-checking.md - docs/reference/commands/git.md - docs/reference/commands/instance-health.md - docs/reference/commands/pages.md - docs/reference/commands/raw-material-and-uploads.md - docs/reference/configuration.md - docs/reference/exit-codes.md - instructions/dev/doc-pull-through.md - instructions/dev/tracker-testing.md - instructions/gates.md - instructions/ingest-queue.md - instructions/mcp-read-server.md - instructions/migrate-corpus.md - instructions/migrations/10.0.0-settings-tiers.md - instructions/setup-instance.md - raw/CONTRACT.md - reports/CONTRACT.md - tools/CONTRACT.md - tools/README.md - tools/bugreport.py - tools/chemenu/cli_contract.py - tools/chemenu/commands/_util.py - tools/chemenu/commands/config_cmd.py - tools/chemenu/commands/docs_verify.py - tools/chemenu/commands/doctor.py - tools/chemenu/commands/export_cmd.py - tools/chemenu/commands/git_publish.py - tools/chemenu/commands/new_page.py - tools/chemenu/commands/review_cmd.py - tools/chemenu/commands/task_cmd.py - tools/chemenu/commands/upload_cmd.py - tools/chemenu/config.py - tools/chemenu/config_shapes.py - tools/chemenu/legacy_settings.py - tools/chemenu/mcp/__main__.py - tools/chemenu/mcp/server.py - tools/chemenu/reference_doc.py - tools/chemenu/review.py - tools/chemenu/settings.py - tools/chemenu/tasks/__init__.py - tools/chemenu/tasks/caldav.py - tools/chemenu/tasks/config.py - tools/chemenu/tasks/superproductivity.py - tools/chemenu/telemetry/policy.py - tools/chemenu/tests/conftest.py - tools/chemenu/tests/record_sp_fixtures.py - tools/chemenu/tests/test_bugreport.py - tools/chemenu/tests/test_caldav.py - tools/chemenu/tests/test_config_shapes.py - tools/chemenu/tests/test_doctor.py - tools/chemenu/tests/test_git_publish.py - tools/chemenu/tests/test_legacy_settings.py - tools/chemenu/tests/test_mcp_server.py - tools/chemenu/tests/test_new_page.py - tools/chemenu/tests/test_review.py - tools/chemenu/tests/test_settings.py - tools/chemenu/tests/test_sp_recorded.py - tools/chemenu/tests/test_superproductivity.py - tools/chemenu/tests/test_task_cmd.py - tools/chemenu/tests/test_tasks_config.py - tools/chemenu/tests/test_telemetry_policy.py - tools/chemenu/tests/test_tracker_live.py - tools/chemenu/tests/test_upload.py - tools/chemenu/tests/tracker_live.py - tools/chemenu/upload.py Co-Authored-By: Claude Code <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SnAJ7Z3CpVD3PRbN73QtU2
12 KiB
12 KiB
Finding and checking
Searching the wiki, checking its health, and preparing the weekly review of projects and commitments.
Contents
lint
Run structural lint checks against kb/.
Synopsis
wikitool lint [--json] [--markdown out.md] [--full] [--fail-on-error]
Options
--json Print the raw findings as JSON and write no report
--markdown <path> Write the markdown report here instead of the default
reports/Lint Report <date>.md
--full Print the whole report instead of only the sections with
findings
--fail-on-error Exit non-zero if hard errors were found
-h, --help Show this message and exit.
Examples
tools/wikitool lint
tools/wikitool lint --json
tools/wikitool lint --fail-on-error
Behaviour
- Structural and provenance checks over
kb/: broken wikilinks, wikilinks wrapped across a line break, dangling frontmatter references, orphan pages, index drift, schema gaps, duplicate titles, title mismatches, uncovered raw files, brokenraw_files:refs, raw files claimed by more than one source page, unmarked provenance, citation/frontmatter drift, and unbalanced generated-region markers. - Unportable Titles is a hard finding, and hard at every
kb_version: a page whose title is not a valid file name on Windows and macOS (forbidden character, reserved name, trailing dot or space), or that collides with another page by case or Unicode normalization.wikitool renameis the fix. - Wrapped Wikilinks is a hard finding: a
[[...]]with a line break inside it. The link graph reads it as the title it folds to (the break and its indentation become one space), so it is not also a broken link unless that title is missing; the fix is to put it back on one line. - Broken Anchors is advisory: a
[[Page#Section]]whose page exists but has no heading the anchor names (any level, compared without case, inline-code backticks or extra whitespace; every segment of a nested[[Page#A#B]]). The link still reaches the page, so nothing else reports it - typically a section that was promoted to a page of its own or renamed. A missing page is Broken Wikilinks instead. - Pages nested more than one directory below their collection are a hard finding - the generated catalog folds these into their area silently rather than merely reading it.
- Edges whose label is missing or not authorised by the source collection's
outbound:are both hard oncekb_versionhas reached the release that introduced labelled edges, and advisory below it. - Advisory only:
see-alsoedges whose reverse direction already carries a specific label - never migration-gated. - Advisory only: a collection past the catalog's per-area shard threshold that has no areas to shard, reported with the split its subtype field would produce, and only when that split puts every resulting area at or under the threshold.
- Advisory only: source pages sitting in the
unclassifiedcatalog slot. - Advisory only: Long Paths - a file under
kb/orraw/whose path below the instance root is over 160 UTF-16 code units, the budget that keeps a Windows checkout without long paths working. Reported as{path, length}; a corpus over the budget breaks no lint run.wikitool renameis the fix for a page. - Advisory only: quote-limit overages (>2 blockquotes/page).
- Advisory only: Unfilled Template Sections - a page with at least one
##section whose non-blank lines are all template placeholders (content starting withTODO, after an optional list marker, checkbox, table cell or bold field label), reported as{page, sections}. Code, generated regions and footnote definitions do not count; an empty section, or one placeholder beside written lines, is no finding. Writing the section from the page's sources or retiring the page is the fix - not a mechanical one. - Prints only the sections that found something and always writes the full report to
reports/Lint Report <date>.md(or--markdown), naming the path.--fullprints everything;--jsonprints the findings and writes nothing. - Exits 0 whatever it finds unless
--fail-on-erroris passed.
Properties
- Changes files: yes
- Idempotent: yes
- Atomic: Writes one report file (single atomic write) unless
--json - Counts toward the session call budget: yes
- Can reach the network: no
Exit codes
0- success1- Only with--fail-on-error: hard findings exist
See also
wiki-lintskill - the procedure that runs thiswikitool move --reconcile- fixes Misplaced and Nested Pageswikitool rename- fixes Unportable Titles and, for a page, Long Pathswikitool log status- whether a full lint is due
search
Find pages in kb/ by text and/or frontmatter.
Synopsis
wikitool search ["<text>"] [--field <predicate> ...] [--kind/--subtype/--collection/--tag <v>] [--regex] [--limit N] [--sort [-]<field>] [--backend <name>] [--matches] [--json]
Options
Arguments:
text Text to search for. Omit it to run a pure frontmatter query.
Options:
-f, --field <str> Frontmatter predicate, repeatable (AND). Forms:
field=value, field~substring, 'field>=value', 'field:*'
(present), '!field' (absent).
--kind <str> Shorthand for --field kind=<value>.
--subtype <str> Shorthand for --field subtype=<value>.
--collection <str> Shorthand for --field collection=<value>.
--tag <str> Shorthand for --field tags=<value>.
--regex Treat the query as a regex. Off by default: terms are
literal.
--limit <int> Maximum number of results. 0 for no limit. A capped result
says so. [default: 50]
--sort <str> Sort by a result field; prefix with '-' to reverse, e.g.
-modified.
--backend <str> Search backend(s), comma-separated. Default 'rg' (or
$WIKITOOL_SEARCH_BACKEND).
--matches Print the matching lines under each result.
--json Print the results as JSON.
-h, --help Show this message and exit.
Examples
tools/wikitool search "act runner"
tools/wikitool search --field entity_type=system --field '!sources'
tools/wikitool search "docker" --collection entities --limit 10 --json
Behaviour
- Finds pages in
kb/without reading the catalog. Text search runs through a pluggable backend (rgtoday). --fieldpredicates are evaluated on frontmatter -f=v,f~substring,'f>=v','f:*'(present),'!f'(absent) - repeatable and ANDed. With no text this is a pure structured query.- One hit per line,
|-separated asscore | kind/subtype | title | path | summary. Title and path are never truncated - the title is the identifiertouch/xref/citetake. The summary, the one lossy field and the only one that may contain the separator, goes last, so splitting on" | "withmaxsplit=4is unambiguous. - Scope is pages: the backend walks
kb/but drops the kb-root meta files, everyCOLLECTION.mdand every generatedINDEX.md- a hand-run grep overkb/can add none of them but those. --limitdefaults to 50 (0for no limit), and a truncated result says so:50 of 182 result(s)in the table,total/truncated/limitbesidecountin--json, wherecountstays the number of results in the payload.api.searchand the MCPsearchtool carry the same default and the same fields.- A page whose frontmatter does not parse can match no positive predicate, so it is named rather than dropped:
--jsonalways carries anunreadablelist of{path, reason}(usually empty), and the table form writes the same lines to stderr. - An unknown field name is reported with the list of fields that do exist - never answered with an empty result, which would read as "no such pages".
--regexis applied byrgalone, whose engine is linear; the ranking boosts for title and summary are literal-containment only, so a non-literal pattern is ranked by match count.rgis killed after 30 s and reported as a failure.- Read-only, and exempt from the Iteration Budget Gate.
Properties
- Changes files: no
- Idempotent: yes
- Atomic: Read-only
- Counts toward the session call budget: no
- Can reach the network: no
Exit codes
0- success1-rgis not installed1-rgdid not finish within 30 s1- A malformed--fieldpredicate, or an unknown--backend1- An unknown field name; the error lists the fields that exist
See also
wikitool links show- the edges around a page once foundwiki-queryskill - answering a question from the wiki
review
The GTD weekly review.
Synopsis
wikitool review [--json]
Options
--json Print the findings as JSON.
-h, --help Show this message and exit.
Examples
tools/wikitool review
tools/wikitool review --json
Behaviour
- Joins the configured task-tracker provider against
kb/gtd/project pages over the case-normalized project name, at read time, storing nothing - not even areports/file. - stalled: a tracker project with zero open items whose
kb/page isstate: active;dormant/completed/abandonednever fire. - waiting-overdue: a
WAITINGitem whosefollow_up_atis older thanthresholds.stalled_waiting_days. - unpaged-project: a tracker project with no matching
kb/page, older thanthresholds.unpaged_project_weeks. - no-open-loop: a
kb/pagestate: activewith no matching tracker project, or one with zero open items - the reverse direction of unpaged-project, so a rename on either side surfaces on both. - someday-stale: a someday/maybe item untouched for longer than
thresholds.someday_stale_months. - A value a provider genuinely cannot supply - a
WAITINGitem with nofollow_up_at, a tracker project with no determinable creation date - is its own finding (waiting_no_follow_up/project_age_unknown) rather than a silent skip. - Thresholds come from the tracker configuration, never from the schema.
- The tracker configuration is read from the
tasks,superproductivityandcaldavsections of the settings, or from the profileWIKITOOL_TASKS_CONFIGnames when that variable is set (so one checkout can be run against several trackers in turn). A set variable that names no file is an error, never "no tracker configured". - The tracker settings file of an earlier version exits 42 and names
tools/wikitool config migrate; so does a secret source that needs unlocking. - Text output is one
[check] project: messageline per finding, preceded by aSource:line naming which access path answered and, forsuperproductivity'saccess: "snapshot", the snapshot's age.--jsoncarries the same findings pluschecks_run/checks_skipped/kb_project_count/complete/source({"kind": ..., "detail": ...}ornull). - A provider that cannot be reached mid-run degrades only the checks that needed the failing call; the report is printed in full, then exit 1 follows - never rendered as if it were complete.
- Re-reads everything fresh on every call, so nothing is ever stale to re-fetch.
- Read-only, and exempt from the Iteration Budget Gate.
Properties
- Changes files: no
- Idempotent: yes
- Atomic: Read-only
- Counts toward the session call budget: no
- Can reach the network: yes
Exit codes
0- success1- Notaskssection in the settings, or a malformed one - a clear "no tracker configured" message1-WIKITOOL_TASKS_CONFIGnames a profile that does not exist or is broken1- The provider was reachable at config-parse time but a read call failed mid-run; the full report (findings plus which checks ran) was printed first42- The tracker settings file of an earlier version is still there, or a secret source (1Password) needs unlocking
See also
gtd-weekly-reviewskill - turns the findings into decisionswikitool task list/wikitool task close- act on an itemwikitool new project- a project page and its tracker project