Done, shipped in 6.1.0-beta.7 (commit 24cd221), with a prose correction in 6.1.0-beta.8 (9a1be6a).
The reported symptom was real. The reported scope was not: it was one instance of a class.
The wiki/ → kb/ rename (2026-08-21, recorded in kb/concepts/architectures/Three-Layer Architecture.md) moved the directory but left the string wiki/ standing in 33 places across the tree. Nothing caught it for four weeks, because no check reads a path literal in source.
The scan itself was never wrong — run_lint(kb_dir) walks kb/ and page_count = len(pages) counts what it found. Only the labels lied.
What was fixed
User-facing output (13 of the 33):
lint_core.py:529 — the report header, Scanned N pages under `wiki/` (the originally reported line). Verified after the fix: Scanned 182 pages under kb/``.
Error messages: xref, cite (×2), touch, raw accept, move, rm, rename, log status
--help text: cite sync --all, provenance rebuild-index --dry-run, move --reconcile, and log's own Typer app help
Agent-facing: the four description: fields in types/type-spec.schema.yaml, which reach an agent through types describe and through every schema-validation message. base_dir's now reads "relative to the KB root (kb/)".
Control-plane prose:types/type-spec.md:181.
Comments and docstrings:frontmatter_io.py, type_resolver.py (×4), _util.py, log_append.py, tools/wikitool. Two were doubly wrong — git_publish.py and run_budget.py cited wiki/concepts/Mass-Update Gate.md, while the page lives at kb/concepts/workflows/Mass-Update Gate.md; the collection level was stale too.
Tests:test_log_append.py's assertion moved with the string; comments in test_type_resolver.py and test_touch.py.
Corpus:kb/entities/projects/Chemenu.md's "Architektur" line, pulled through with wikitool touch and logged to kb/log.md.
Deliberately not touched
raw/ — immutable by contract, whatever it says.
CHANGES.md's older entries — records of what was true at the time, not wayfinders. Same evidence/wayfinder split this repo applies to the tracker.
kb/concepts/architectures/Three-Layer Architecture.md — it documents the rename and is correct as written.
test_dist_cmd.py:456 — https://example/torben/wiki/releases/... is a fixture URL where wiki is a repository name.
"Dreilagig" on the Chemenu page stayed. An earlier revision of this body called it stale on the grounds that the pipeline has four stages. That was wrong: the corpus's own Three-Layer Architecture page carries reports/ as a fourth phase beside the three layers, so the wording is consistent and only the path was defective.
The guard
A pure string sweep would have left the identical trap for the next rename, so the fix carries one: tools/chemenu/tests/test_source_hygiene.py scans every .py file under tools/chemenu/ plus tools/wikitool against a table of retired stage paths. A future rename adds one row in the same change that does the renaming, and every forgotten site becomes a test failure instead of a string nobody reads for a year.
A docs verify sibling to check_no_issue_references() was considered and rejected: it reads shipped_prose(), which is markdown only, and the bulk of the defect sat in .py strings. A pytest guard covers exactly the surface the defect lives on.
Two exceptions are an explicit list with a reason rather than a cleverer regex — the fixture URL above, and the guard file itself, which necessarily declares the retired paths.
Acceptance criteria
grep -rn "wiki/" tools/ types/ returns nothing outside the out-of-scope list — verified after publish; the only remaining hits are the fixture URL and the guard's own declaration.
Every path a wikitool error message or --help string names resolves in a fresh checkout.
git_publish.py and run_budget.py cite kb/concepts/workflows/Mass-Update Gate.md, the path wikitool search "Mass-Update Gate" returns.
A test fails if any wiki/ literal is reintroduced under tools/chemenu/ — proved with a canary line in lint_core.py, which the guard reported as lint_core.py:842 names the retired path 'wiki/' (now 'kb/') before being reverted.
kb/entities/projects/Chemenu.md updated through wikitool touch, logged via log append --op update.
pytest (1314 passed, +2 from the new file), docs verify (56 commands, 73 shipped documents, 58 reference files) and instructions verify (23 instructions, 7 skills) all green before each publish.
VERSION at 6.1.0-beta.8, both bumps --patch --impact low, changelog prose written for each.
Doc pull-through
Nothing in docs/, in any CONTRACT.md, or in the README-shaped human docs went stale: no command behaviour, flag or reasoning moved, and none of those documents named wiki/. Checked rather than assumed.
One judgment made and worth recording: instructions/dev/issue-tracking.md § "Renames and other decay in the tracker" was considered as a home for a pointer to the new guard and deliberately left alone. That section is scoped to the tracker; the guard is scoped to source, and it is self-documenting at the point of failure — a failing run names the retired path and its replacement.
Two process notes
The published 6.1.0-beta.7 changelog entry first claimed "27 places" and "about half of them user-facing". Both were wrong — 27 came from a wc -l counting only tools/**/*.py. Corrected to 33 and thirteen in 6.1.0-beta.8, in the changelog and in the guard's docstring. The correction needed its own --patch bump because the docstring lives under tools/, and CI's version gate is scoped by path, not by intent.
During the guard's negative test, git checkout tools/chemenu/lint_core.py was used to revert a canary line and took the unstaged fix in the same file with it. Caught, restored, re-verified by grep and a full suite run before publishing.
**Done, shipped in 6.1.0-beta.7 (commit `24cd221`), with a prose correction in 6.1.0-beta.8 (`9a1be6a`).**
The reported symptom was real. The reported scope was not: it was one instance of a class.
The `wiki/` → `kb/` rename (2026-08-21, recorded in `kb/concepts/architectures/Three-Layer Architecture.md`) moved the directory but left the string `wiki/` standing in **33 places** across the tree. Nothing caught it for four weeks, because no check reads a path literal in source.
The scan itself was never wrong — `run_lint(kb_dir)` walks `kb/` and `page_count = len(pages)` counts what it found. Only the labels lied.
## What was fixed
**User-facing output (13 of the 33):**
- `lint_core.py:529` — the report header, ``Scanned N pages under `wiki/` `` (the originally reported line). Verified after the fix: `Scanned 182 pages under `kb/``.
- Error messages: `xref`, `cite` (×2), `touch`, `raw accept`, `move`, `rm`, `rename`, `log status`
- `--help` text: `cite sync --all`, `provenance rebuild-index --dry-run`, `move --reconcile`, and `log`'s own Typer app help
**Agent-facing:** the four `description:` fields in `types/type-spec.schema.yaml`, which reach an agent through `types describe` and through every schema-validation message. `base_dir`'s now reads "relative to the KB root (kb/)".
**Control-plane prose:** `types/type-spec.md:181`.
**Comments and docstrings:** `frontmatter_io.py`, `type_resolver.py` (×4), `_util.py`, `log_append.py`, `tools/wikitool`. Two were *doubly* wrong — `git_publish.py` and `run_budget.py` cited `wiki/concepts/Mass-Update Gate.md`, while the page lives at `kb/concepts/workflows/Mass-Update Gate.md`; the collection level was stale too.
**Tests:** `test_log_append.py`'s assertion moved with the string; comments in `test_type_resolver.py` and `test_touch.py`.
**Corpus:** `kb/entities/projects/Chemenu.md`'s "Architektur" line, pulled through with `wikitool touch` and logged to `kb/log.md`.
## Deliberately not touched
- `raw/` — immutable by contract, whatever it says.
- `CHANGES.md`'s older entries — records of what was true at the time, not wayfinders. Same evidence/wayfinder split this repo applies to the tracker.
- `kb/concepts/architectures/Three-Layer Architecture.md` — it documents the rename and is correct as written.
- `test_dist_cmd.py:456` — `https://example/torben/wiki/releases/...` is a fixture URL where `wiki` is a repository name.
- **"Dreilagig" on the `Chemenu` page stayed.** An earlier revision of this body called it stale on the grounds that the pipeline has four stages. That was wrong: the corpus's own `Three-Layer Architecture` page carries `reports/` as a fourth *phase* beside the three layers, so the wording is consistent and only the path was defective.
## The guard
A pure string sweep would have left the identical trap for the next rename, so the fix carries one: `tools/chemenu/tests/test_source_hygiene.py` scans every `.py` file under `tools/chemenu/` plus `tools/wikitool` against a table of retired stage paths. A future rename adds one row in the same change that does the renaming, and every forgotten site becomes a test failure instead of a string nobody reads for a year.
A `docs verify` sibling to `check_no_issue_references()` was considered and **rejected**: it reads `shipped_prose()`, which is markdown only, and the bulk of the defect sat in `.py` strings. A pytest guard covers exactly the surface the defect lives on.
Two exceptions are an explicit list with a reason rather than a cleverer regex — the fixture URL above, and the guard file itself, which necessarily declares the retired paths.
## Acceptance criteria
- [x] `grep -rn "wiki/" tools/ types/` returns nothing outside the out-of-scope list — verified after publish; the only remaining hits are the fixture URL and the guard's own declaration.
- [x] Every path a `wikitool` error message or `--help` string names resolves in a fresh checkout.
- [x] `git_publish.py` and `run_budget.py` cite `kb/concepts/workflows/Mass-Update Gate.md`, the path `wikitool search "Mass-Update Gate"` returns.
- [x] A test fails if any `wiki/` literal is reintroduced under `tools/chemenu/` — proved with a canary line in `lint_core.py`, which the guard reported as `lint_core.py:842 names the retired path 'wiki/' (now 'kb/')` before being reverted.
- [x] `kb/entities/projects/Chemenu.md` updated through `wikitool touch`, logged via `log append --op update`.
- [x] `pytest` (1314 passed, +2 from the new file), `docs verify` (56 commands, 73 shipped documents, 58 reference files) and `instructions verify` (23 instructions, 7 skills) all green before each publish.
- [x] `VERSION` at `6.1.0-beta.8`, both bumps `--patch --impact low`, changelog prose written for each.
## Doc pull-through
Nothing in `docs/`, in any `CONTRACT.md`, or in the README-shaped human docs went stale: no command behaviour, flag or reasoning moved, and none of those documents named `wiki/`. Checked rather than assumed.
One judgment made and worth recording: `instructions/dev/issue-tracking.md` § "Renames and other decay in the tracker" was considered as a home for a pointer to the new guard and deliberately left alone. That section is scoped to the *tracker*; the guard is scoped to *source*, and it is self-documenting at the point of failure — a failing run names the retired path and its replacement.
## Two process notes
- The published 6.1.0-beta.7 changelog entry first claimed "27 places" and "about half of them user-facing". Both were wrong — 27 came from a `wc -l` counting only `tools/**/*.py`. Corrected to 33 and thirteen in 6.1.0-beta.8, in the changelog and in the guard's docstring. The correction needed its own `--patch` bump because the docstring lives under `tools/`, and CI's version gate is scoped by path, not by intent.
- During the guard's negative test, `git checkout tools/chemenu/lint_core.py` was used to revert a canary line and took the unstaged fix in the same file with it. Caught, restored, re-verified by grep and a full suite run before publishing.
torben
changed title from lint report mislabels its scan root as wiki/ instead of kb/ to Stale `wiki/` path literals survive the kb/ rename across tools/, types/ and one kb/ page2026-09-17 06:51:47 +00:00
Changelog: Triaged against the tree, status/unconfirmed removed — the symptom is confirmed, but the original body's "cosmetic one-liner, fix the literal" diagnosis was wrong about scope: 27 stale wiki/ literals across tools/, types/ and one kb/ page, of which ~13 are user-facing error messages and --help text. Body rewritten from the one-line diagnosis to the full inventory, an explicit out-of-scope list (raw/, CHANGES.md, the page documenting the rename), the guard decision, and checkable acceptance criteria. Labelled area/kb / kind/defect / prio/planned / size/M.
Original stub, for the record:
Root cause found: tools/chemenu/lint_core.py:529 hardcodes f"Scanned {report['page_count']} pages under \wiki/. ...". It's a cosmetic string bug, not a functional one — the scan itself correctly walks kb/(32 pages matched exactly), only the printed label is wrong. Fix: change the literal to ``kb/ ``.
Two notes on that text: the page count it cites (32) no longer matches the corpus, and the docs verify route was considered and rejected — shipped_prose() does not read .py, where most of the defect sits.
**Changelog:** Triaged against the tree, `status/unconfirmed` removed — the symptom is confirmed, but the original body's "cosmetic one-liner, fix the literal" diagnosis was wrong about scope: 27 stale `wiki/` literals across `tools/`, `types/` and one `kb/` page, of which ~13 are user-facing error messages and `--help` text. Body rewritten from the one-line diagnosis to the full inventory, an explicit out-of-scope list (`raw/`, `CHANGES.md`, the page documenting the rename), the guard decision, and checkable acceptance criteria. Labelled `area/kb` / `kind/defect` / `prio/planned` / `size/M`.
Original stub, for the record:
> Root cause found: tools/chemenu/lint_core.py:529 hardcodes f"Scanned {report['page_count']} pages under \wiki/`. ...". It's a cosmetic string bug, not a functional one — the scan itself correctly walks kb/(32 pages matched exactly), only the printed label is wrong. Fix: change the literal to ``kb/` ``.
Two notes on that text: the page count it cites (32) no longer matches the corpus, and the `docs verify` route was considered and rejected — `shipped_prose()` does not read `.py`, where most of the defect sits.
Changelog: Closed. Body moved from spec to record — criteria ticked with what verified them, the count corrected from 27 to 33 (the earlier figure counted only tools/**/*.py), and the "Dreilagig is stale" claim withdrawn as wrong. Added the doc-pull-through result (nothing went stale, checked not assumed), the rejected-docs verify reasoning, and two process notes: the published changelog prose needed a follow-up bump to fix the same count, and a git checkout during the guard's negative test briefly reverted an unstaged fix.
Shipped as 24cd221 (6.1.0-beta.7) and 9a1be6a (6.1.0-beta.8).
**Changelog:** Closed. Body moved from spec to record — criteria ticked with what verified them, the count corrected from 27 to 33 (the earlier figure counted only `tools/**/*.py`), and the "Dreilagig is stale" claim withdrawn as wrong. Added the doc-pull-through result (nothing went stale, checked not assumed), the rejected-`docs verify` reasoning, and two process notes: the published changelog prose needed a follow-up bump to fix the same count, and a `git checkout` during the guard's negative test briefly reverted an unstaged fix.
Shipped as `24cd221` (6.1.0-beta.7) and `9a1be6a` (6.1.0-beta.8).
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Done, shipped in 6.1.0-beta.7 (commit
24cd221), with a prose correction in 6.1.0-beta.8 (9a1be6a).The reported symptom was real. The reported scope was not: it was one instance of a class.
The
wiki/→kb/rename (2026-08-21, recorded inkb/concepts/architectures/Three-Layer Architecture.md) moved the directory but left the stringwiki/standing in 33 places across the tree. Nothing caught it for four weeks, because no check reads a path literal in source.The scan itself was never wrong —
run_lint(kb_dir)walkskb/andpage_count = len(pages)counts what it found. Only the labels lied.What was fixed
User-facing output (13 of the 33):
lint_core.py:529— the report header,Scanned N pages under `wiki/`(the originally reported line). Verified after the fix:Scanned 182 pages underkb/``.xref,cite(×2),touch,raw accept,move,rm,rename,log status--helptext:cite sync --all,provenance rebuild-index --dry-run,move --reconcile, andlog's own Typer app helpAgent-facing: the four
description:fields intypes/type-spec.schema.yaml, which reach an agent throughtypes describeand through every schema-validation message.base_dir's now reads "relative to the KB root (kb/)".Control-plane prose:
types/type-spec.md:181.Comments and docstrings:
frontmatter_io.py,type_resolver.py(×4),_util.py,log_append.py,tools/wikitool. Two were doubly wrong —git_publish.pyandrun_budget.pycitedwiki/concepts/Mass-Update Gate.md, while the page lives atkb/concepts/workflows/Mass-Update Gate.md; the collection level was stale too.Tests:
test_log_append.py's assertion moved with the string; comments intest_type_resolver.pyandtest_touch.py.Corpus:
kb/entities/projects/Chemenu.md's "Architektur" line, pulled through withwikitool touchand logged tokb/log.md.Deliberately not touched
raw/— immutable by contract, whatever it says.CHANGES.md's older entries — records of what was true at the time, not wayfinders. Same evidence/wayfinder split this repo applies to the tracker.kb/concepts/architectures/Three-Layer Architecture.md— it documents the rename and is correct as written.test_dist_cmd.py:456—https://example/torben/wiki/releases/...is a fixture URL wherewikiis a repository name.Chemenupage stayed. An earlier revision of this body called it stale on the grounds that the pipeline has four stages. That was wrong: the corpus's ownThree-Layer Architecturepage carriesreports/as a fourth phase beside the three layers, so the wording is consistent and only the path was defective.The guard
A pure string sweep would have left the identical trap for the next rename, so the fix carries one:
tools/chemenu/tests/test_source_hygiene.pyscans every.pyfile undertools/chemenu/plustools/wikitoolagainst a table of retired stage paths. A future rename adds one row in the same change that does the renaming, and every forgotten site becomes a test failure instead of a string nobody reads for a year.A
docs verifysibling tocheck_no_issue_references()was considered and rejected: it readsshipped_prose(), which is markdown only, and the bulk of the defect sat in.pystrings. A pytest guard covers exactly the surface the defect lives on.Two exceptions are an explicit list with a reason rather than a cleverer regex — the fixture URL above, and the guard file itself, which necessarily declares the retired paths.
Acceptance criteria
grep -rn "wiki/" tools/ types/returns nothing outside the out-of-scope list — verified after publish; the only remaining hits are the fixture URL and the guard's own declaration.wikitoolerror message or--helpstring names resolves in a fresh checkout.git_publish.pyandrun_budget.pycitekb/concepts/workflows/Mass-Update Gate.md, the pathwikitool search "Mass-Update Gate"returns.wiki/literal is reintroduced undertools/chemenu/— proved with a canary line inlint_core.py, which the guard reported aslint_core.py:842 names the retired path 'wiki/' (now 'kb/')before being reverted.kb/entities/projects/Chemenu.mdupdated throughwikitool touch, logged vialog append --op update.pytest(1314 passed, +2 from the new file),docs verify(56 commands, 73 shipped documents, 58 reference files) andinstructions verify(23 instructions, 7 skills) all green before each publish.VERSIONat6.1.0-beta.8, both bumps--patch --impact low, changelog prose written for each.Doc pull-through
Nothing in
docs/, in anyCONTRACT.md, or in the README-shaped human docs went stale: no command behaviour, flag or reasoning moved, and none of those documents namedwiki/. Checked rather than assumed.One judgment made and worth recording:
instructions/dev/issue-tracking.md§ "Renames and other decay in the tracker" was considered as a home for a pointer to the new guard and deliberately left alone. That section is scoped to the tracker; the guard is scoped to source, and it is self-documenting at the point of failure — a failing run names the retired path and its replacement.Two process notes
wc -lcounting onlytools/**/*.py. Corrected to 33 and thirteen in 6.1.0-beta.8, in the changelog and in the guard's docstring. The correction needed its own--patchbump because the docstring lives undertools/, and CI's version gate is scoped by path, not by intent.git checkout tools/chemenu/lint_core.pywas used to revert a canary line and took the unstaged fix in the same file with it. Caught, restored, re-verified by grep and a full suite run before publishing.lint report mislabels its scan root as wiki/ instead of kb/to Stale `wiki/` path literals survive the kb/ rename across tools/, types/ and one kb/ pageChangelog: Triaged against the tree,
status/unconfirmedremoved — the symptom is confirmed, but the original body's "cosmetic one-liner, fix the literal" diagnosis was wrong about scope: 27 stalewiki/literals acrosstools/,types/and onekb/page, of which ~13 are user-facing error messages and--helptext. Body rewritten from the one-line diagnosis to the full inventory, an explicit out-of-scope list (raw/,CHANGES.md, the page documenting the rename), the guard decision, and checkable acceptance criteria. Labelledarea/kb/kind/defect/prio/planned/size/M.Original stub, for the record:
Two notes on that text: the page count it cites (32) no longer matches the corpus, and the
docs verifyroute was considered and rejected —shipped_prose()does not read.py, where most of the defect sits.Changelog: Closed. Body moved from spec to record — criteria ticked with what verified them, the count corrected from 27 to 33 (the earlier figure counted only
tools/**/*.py), and the "Dreilagig is stale" claim withdrawn as wrong. Added the doc-pull-through result (nothing went stale, checked not assumed), the rejected-docs verifyreasoning, and two process notes: the published changelog prose needed a follow-up bump to fix the same count, and agit checkoutduring the guard's negative test briefly reverted an unstaged fix.Shipped as
24cd221(6.1.0-beta.7) and9a1be6a(6.1.0-beta.8).