From be78ad20af521a2570fb9554e30146cad9ed4779 Mon Sep 17 00:00:00 2001 From: Torben Nehmer Date: Sat, 26 Sep 2026 08:51:53 +0200 Subject: [PATCH] tools: command records, Provenance group - examples, exit lines per cause (#142) Files changed: - CHANGES.md - VERSION - tools/CONTRACT.md - tools/chemenu/commands/provenance_cmd.py --- CHANGES.md | 10 +++- VERSION | 2 +- tools/CONTRACT.md | 55 ++++++++++++++++--- tools/chemenu/commands/provenance_cmd.py | 70 +++++++++++++++++++----- 4 files changed, 113 insertions(+), 24 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 5c1c88a..13971a3 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -59,7 +59,7 @@ concern - readable here, never shipped as something to parse. --- -## 7.1.0-beta.12 - 2026-09-26 - Command records, Finding and checking group: one line per cause, examples, prohibitions +## 7.1.0-beta.13 - 2026-09-26 - Command records, Provenance group: examples, exit lines per cause **Author:** Torben Nehmer @@ -81,6 +81,7 @@ concern - readable here, never shipped as something to parse. - Command records, Pages group: one line per cause, examples, prohibitions - Command records, Links and citations group: one line per cause, examples, prohibitions - Command records, Finding and checking group: one line per cause, examples, prohibitions +- Command records, Provenance group: examples, exit lines per cause ### CalDAV task-tracker provider (Nextcloud Tasks, iOS Reminders); review reports unknown-value findings instead of skipping them @@ -261,6 +262,13 @@ the scope rule that justifies it. One claim is deliberately left as it stood: `l still describes the quote limit in blockquoted lines while the code counts quotes - which of the two is meant is not this change's call to make. +### Command records, Provenance group: examples, exit lines per cause + +`sources coverage`, `sources trace` and `sources rebuild-index` rewritten the same way; text +only. `sources trace` separates an argument error from the uncovered-file finding it also exits +1 on, since the second is a result to act on rather than an argument to fix; +`sources rebuild-index` names `kb/provenance.md` as generated in NEVER. + --- ## 7.0.0 - 2026-09-22 - Task-Tracker-Anbindung: Vorhaben als Seitenart, Verpflichtungsschicht, Weekly Review als Read-Time-Join diff --git a/VERSION b/VERSION index 3713405..0b07751 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -7.1.0-beta.12 +7.1.0-beta.13 diff --git a/tools/CONTRACT.md b/tools/CONTRACT.md index fecd435..a254d08 100644 --- a/tools/CONTRACT.md +++ b/tools/CONTRACT.md @@ -1242,13 +1242,25 @@ List raw files with no source page, broken `raw_files:` references, and legacy d - budget: counted - network: no +**EXAMPLES** + +- `tools/wikitool sources coverage` +- `tools/wikitool sources coverage --json` + **EXIT STATUS** - 0 success **NOTES** -List raw files with no source page, broken `raw_files:` references, and legacy directory/URL-only source pages. Never fails. Safe to retry freely. +- Lists raw files with no source page, broken `raw_files:` references, and legacy directory/URL-only source pages. +- `--json` prints the same lists as JSON. +- Never fails; read-only and safe to retry freely. + +**SEE ALSO** + +- `wikitool sources trace` - follows one file or page +- `wiki-ingest` skill - turns an uncovered raw file into a source page #### `sources trace` @@ -1266,18 +1278,32 @@ Trace provenance in either direction: raw file, or page. - budget: counted - network: no +**EXAMPLES** + +- `tools/wikitool sources trace --page "Docker"` +- `tools/wikitool sources trace --raw "raw/articles/llm-wiki.md"` + **EXIT STATUS** - 0 success -- 1 Neither or both of `--raw`/`--page` given, `--raw` names a file no source page covers (reported as a plain finding plus exit 1, not the usual `ERROR`-prefixed rejection), or `--page` names an unknown page +- 1 Neither or both of `--raw`/`--page` given, or `--page` names an unknown page +- 1 `--raw` names a file no source page covers - reported as a plain finding plus exit 1, not the usual `ERROR`-prefixed rejection **ON FAILURE** -- Neither or both of `--raw`/`--page` given, `--raw` names a file no source page covers (reported as a plain finding plus exit 1, not the usual `ERROR`-prefixed rejection), or `--page` names an unknown page -> Fix the argument and retry +- Neither or both of `--raw`/`--page` given, or `--page` names an unknown page -> Fix the argument and retry +- `--raw` names a file no source page covers - reported as a plain finding plus exit 1, not the usual `ERROR`-prefixed rejection -> Nothing to retry: the file is uncovered. Ingest it, or check the path **NOTES** -Trace provenance in either direction: raw file -> source page(s) -> citing pages, or page -> its sources -> their raw files +- `--raw `: raw file -> the source page(s) covering it -> the pages citing those. +- `--page ""`: page -> its sources -> their raw files. +- Read-only. + +**SEE ALSO** + +- `wikitool sources coverage` - every uncovered raw file at once +- `wikitool xref link-source` - links a source page to what it mentions #### `sources rebuild-index` @@ -1295,18 +1321,33 @@ Regenerate the `kb/provenance.md` reverse index. - budget: counted - network: no +**EXAMPLES** + +- `tools/wikitool sources rebuild-index` +- `tools/wikitool sources rebuild-index --dry-run` + **EXIT STATUS** - 0 success -- 1 Rare I/O error only +- 1 An I/O error while writing `kb/provenance.md` (rare) **ON FAILURE** -- Rare I/O error only -> Safe to retry freely +- An I/O error while writing `kb/provenance.md` (rare) -> Safe to retry freely + +**NEVER** + +- Never hand-edit `kb/provenance.md` - re-run this command instead. **NOTES** -Regenerate the `kb/provenance.md` reverse index (raw file -> source page -> citing pages) +- Regenerates the `kb/provenance.md` reverse index (raw file -> source page -> citing pages) from scratch. +- `--dry-run` prints the result instead of writing `kb/provenance.md`. + +**SEE ALSO** + +- `wikitool index rebuild` - the page catalog, rebuilt alongside +- `instructions/publish-cycle.md` - where a write session runs this ### Raw material and uploads diff --git a/tools/chemenu/commands/provenance_cmd.py b/tools/chemenu/commands/provenance_cmd.py index c8d0d5f..6fca72e 100644 --- a/tools/chemenu/commands/provenance_cmd.py +++ b/tools/chemenu/commands/provenance_cmd.py @@ -60,9 +60,21 @@ def _normalize_raw_path(raw: str) -> str: atomic="Read-only", budget=cli_contract.Budget.COUNTED, ), - notes="List raw files with no source page, broken `raw_files:` references, and legacy " - "directory/URL-only source pages. Never fails. Safe to retry freely.", + notes=( + "Lists raw files with no source page, broken `raw_files:` references, and legacy " + "directory/URL-only source pages.", + "`--json` prints the same lists as JSON.", + "Never fails; read-only and safe to retry freely.", + ), failures=(), + examples=( + "tools/wikitool sources coverage", + "tools/wikitool sources coverage --json", + ), + see_also=( + "`wikitool sources trace` - follows one file or page", + "`wiki-ingest` skill - turns an uncovered raw file into a source page", + ), )) def coverage(json_out: bool = typer.Option(False, "--json", help="Print raw findings as JSON")): """Report raw files with no source page, broken raw_files: references, and @@ -99,15 +111,30 @@ def coverage(json_out: bool = typer.Option(False, "--json", help="Print raw find atomic="Read-only", budget=cli_contract.Budget.COUNTED, ), - notes="Trace provenance in either direction: raw file -> source page(s) -> citing pages, or " - "page -> its sources -> their raw files", - failures=(cli_contract.Failure( - label="", - cause="Neither or both of `--raw`/`--page` given, `--raw` names a file no source page " - "covers (reported as a plain finding plus exit 1, not the usual `ERROR`-prefixed " - "rejection), or `--page` names an unknown page", - reaction="Fix the argument and retry", - ),), + notes=( + "`--raw <path>`: raw file -> the source page(s) covering it -> the pages citing those.", + "`--page \"<Title>\"`: page -> its sources -> their raw files.", + "Read-only.", + ), + failures=( + cli_contract.Failure( + cause="Neither or both of `--raw`/`--page` given, or `--page` names an unknown page", + reaction="Fix the argument and retry", + ), + cli_contract.Failure( + cause="`--raw` names a file no source page covers - reported as a plain finding " + "plus exit 1, not the usual `ERROR`-prefixed rejection", + reaction="Nothing to retry: the file is uncovered. Ingest it, or check the path", + ), + ), + examples=( + 'tools/wikitool sources trace --page "Docker"', + 'tools/wikitool sources trace --raw "raw/articles/llm-wiki.md"', + ), + see_also=( + "`wikitool sources coverage` - every uncovered raw file at once", + "`wikitool xref link-source` - links a source page to what it mentions", + ), )) def trace( raw: Optional[str] = typer.Option(None, "--raw", help="Raw file path to trace forward from"), @@ -215,13 +242,26 @@ def build_provenance_index(kb_dir: Path, raw_dir: Path) -> str: atomic="Yes - the single provenance file is regenerated from scratch", budget=cli_contract.Budget.COUNTED, ), - notes="Regenerate the `kb/provenance.md` reverse index (raw file -> source page -> citing " - "pages)", + notes=( + "Regenerates the `kb/provenance.md` reverse index (raw file -> source page -> citing " + "pages) from scratch.", + "`--dry-run` prints the result instead of writing `kb/provenance.md`.", + ), failures=(cli_contract.Failure( - label="", - cause="Rare I/O error only", + cause="An I/O error while writing `kb/provenance.md` (rare)", reaction="Safe to retry freely", ),), + examples=( + "tools/wikitool sources rebuild-index", + "tools/wikitool sources rebuild-index --dry-run", + ), + never=( + "Never hand-edit `kb/provenance.md` - re-run this command instead.", + ), + see_also=( + "`wikitool index rebuild` - the page catalog, rebuilt alongside", + "`instructions/publish-cycle.md` - where a write session runs this", + ), )) def rebuild_index( dry_run: bool = typer.Option(False, "--dry-run", help="Print the result instead of writing kb/provenance.md"),