tools: command records, Provenance group - examples, exit lines per cause (#142)
CI / verify (push) Successful in 1m12s
Release / release (push) Successful in 36s

Files changed:
- CHANGES.md
- VERSION
- tools/CONTRACT.md
- tools/chemenu/commands/provenance_cmd.py
This commit is contained in:
torben committed 2026-09-26 08:51:53 +02:00
1 parent 0b2d93a4a4
commit be78ad20af
4 files changed
+112 -23

No files matched your search

+9 -1
View File
@@ -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 **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, Pages group: one line per cause, examples, prohibitions
- Command records, Links and citations 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, Finding and checking group: one line per cause, examples, prohibitions
- Command records, Provenance group: examples, exit lines per cause
<!-- /wikitool:bumps --> <!-- /wikitool:bumps -->
### CalDAV task-tracker provider (Nextcloud Tasks, iOS Reminders); review reports unknown-value findings instead of skipping them ### 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 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. 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 ## 7.0.0 - 2026-09-22 - Task-Tracker-Anbindung: Vorhaben als Seitenart, Verpflichtungsschicht, Weekly Review als Read-Time-Join
+1 -1
View File
@@ -1 +1 @@
7.1.0-beta.12 7.1.0-beta.13
+48 -7
View File
@@ -1242,13 +1242,25 @@ List raw files with no source page, broken `raw_files:` references, and legacy d
- budget: counted - budget: counted
- network: no - network: no
**EXAMPLES**
- `tools/wikitool sources coverage`
- `tools/wikitool sources coverage --json`
**EXIT STATUS** **EXIT STATUS**
- 0 success - 0 success
**NOTES** **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` #### `sources trace`
@@ -1266,18 +1278,32 @@ Trace provenance in either direction: raw file, or page.
- budget: counted - budget: counted
- network: no - network: no
**EXAMPLES**
- `tools/wikitool sources trace --page "Docker"`
- `tools/wikitool sources trace --raw "raw/articles/llm-wiki.md"`
**EXIT STATUS** **EXIT STATUS**
- 0 success - 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** **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** **NOTES**
Trace provenance in either direction: raw file -> source page(s) -> citing pages, or page -> its sources -> their raw files - `--raw <path>`: raw file -> the source page(s) covering it -> the pages citing those.
- `--page "<Title>"`: 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` #### `sources rebuild-index`
@@ -1295,18 +1321,33 @@ Regenerate the `kb/provenance.md` reverse index.
- budget: counted - budget: counted
- network: no - network: no
**EXAMPLES**
- `tools/wikitool sources rebuild-index`
- `tools/wikitool sources rebuild-index --dry-run`
**EXIT STATUS** **EXIT STATUS**
- 0 success - 0 success
- 1 Rare I/O error only - 1 An I/O error while writing `kb/provenance.md` (rare)
**ON FAILURE** **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** **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 ### Raw material and uploads
+54 -14
View File
@@ -60,9 +60,21 @@ def _normalize_raw_path(raw: str) -> str:
atomic="Read-only", atomic="Read-only",
budget=cli_contract.Budget.COUNTED, budget=cli_contract.Budget.COUNTED,
), ),
notes="List raw files with no source page, broken `raw_files:` references, and legacy " notes=(
"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.",
),
failures=(), 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")): 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 """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", atomic="Read-only",
budget=cli_contract.Budget.COUNTED, budget=cli_contract.Budget.COUNTED,
), ),
notes="Trace provenance in either direction: raw file -> source page(s) -> citing pages, or " notes=(
"page -> its sources -> their raw files", "`--raw <path>`: raw file -> the source page(s) covering it -> the pages citing those.",
failures=(cli_contract.Failure( "`--page \"<Title>\"`: page -> its sources -> their raw files.",
label="", "Read-only.",
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 " failures=(
"rejection), or `--page` names an unknown page", cli_contract.Failure(
cause="Neither or both of `--raw`/`--page` given, or `--page` names an unknown page",
reaction="Fix the argument and retry", 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( def trace(
raw: Optional[str] = typer.Option(None, "--raw", help="Raw file path to trace forward from"), 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", atomic="Yes - the single provenance file is regenerated from scratch",
budget=cli_contract.Budget.COUNTED, budget=cli_contract.Budget.COUNTED,
), ),
notes="Regenerate the `kb/provenance.md` reverse index (raw file -> source page -> citing " notes=(
"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`.",
),
failures=(cli_contract.Failure( failures=(cli_contract.Failure(
label="", cause="An I/O error while writing `kb/provenance.md` (rare)",
cause="Rare I/O error only",
reaction="Safe to retry freely", 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( def rebuild_index(
dry_run: bool = typer.Option(False, "--dry-run", help="Print the result instead of writing kb/provenance.md"), dry_run: bool = typer.Option(False, "--dry-run", help="Print the result instead of writing kb/provenance.md"),