tools: command records, Workshop runs and session budget group - examples, prohibitions (#142)
Files changed: - CHANGES.md - VERSION - tools/CONTRACT.md - tools/chemenu/commands/run_budget.py - tools/chemenu/commands/work_cmd.py
This commit is contained in:
1 parent
964978a9c6
commit
b9c22f783f
5 files changed
+185
-36
No files matched your search
@@ -333,9 +333,18 @@ def refund() -> None:
|
||||
atomic="Read-only",
|
||||
budget=cli_contract.Budget.EXEMPT,
|
||||
),
|
||||
notes="Recent command history is never counted against the budget. Never fails. Safe to "
|
||||
"retry freely.",
|
||||
notes=(
|
||||
"Shows the current session's `wikitool` call count and its recent command history.",
|
||||
"Never counted against the budget; never fails; safe to retry freely.",
|
||||
),
|
||||
failures=(),
|
||||
examples=(
|
||||
"tools/wikitool budget status",
|
||||
),
|
||||
see_also=(
|
||||
"`instructions/session-setup.md` - scoping the budget to a task",
|
||||
"`instructions/gates.md` - what to do when the Iteration Budget Gate refuses",
|
||||
),
|
||||
))
|
||||
def status_command():
|
||||
"""Show the current session's call count and recent command history."""
|
||||
@@ -371,13 +380,26 @@ def reset_message() -> str:
|
||||
atomic="Read/rewrite of one JSON file (or its deletion, with `--all`)",
|
||||
budget=cli_contract.Budget.COUNTED,
|
||||
),
|
||||
notes="Requires `--yes`: clearing the counter is itself a way around the gate, so it needs "
|
||||
"the same explicit human approval",
|
||||
notes=(
|
||||
"Clears the current session's iteration budget state; `--all` deletes every session's.",
|
||||
"Requires `--yes`: clearing the counter is itself a way around the Iteration Budget "
|
||||
"Gate, so it needs the same explicit human approval.",
|
||||
"Counted against the budget like any other call.",
|
||||
),
|
||||
failures=(cli_contract.Failure(
|
||||
label="",
|
||||
cause="`--yes` not passed",
|
||||
reaction="Get the user's approval, then re-run with `--yes`",
|
||||
),),
|
||||
examples=(
|
||||
"tools/wikitool budget reset --yes # only after the user approved it",
|
||||
),
|
||||
never=(
|
||||
"Never run it on your own initiative to get past a budget or loop-breaker refusal.",
|
||||
),
|
||||
see_also=(
|
||||
"`wikitool budget status` - the current count",
|
||||
"`instructions/gates.md` - why `budget reset` is not the escape hatch",
|
||||
),
|
||||
))
|
||||
def reset_command(
|
||||
all_sessions: bool = typer.Option(
|
||||
|
||||
@@ -142,19 +142,48 @@ Cut the tree into units. One unit does one job and becomes one source page. A un
|
||||
atomic="Yes - one directory with two files",
|
||||
budget=cli_contract.Budget.COUNTED,
|
||||
),
|
||||
notes="Refuses a collision instead of suffixing it, and writes the required `README.md` + "
|
||||
"`plan.md`. `--input` derives the run key from the path below `raw/` (an ingest); `--key` "
|
||||
"names it outright for a run with no raw input - a migration or a sweep across `kb/` - and "
|
||||
"may not start with `ingest-`, which stays reserved for derived keys. Exactly one of the "
|
||||
"two. `--again` opens a dated second pass over a tree that has itself changed. See "
|
||||
"`work/CONTRACT.md`",
|
||||
failures=(cli_contract.Failure(
|
||||
label="",
|
||||
cause="Neither or both of `--input`/`--key` given, `--input` outside `raw/`, a "
|
||||
"`--key` that is empty or starts with `ingest-`, or the workshop already exists",
|
||||
reaction="A collision is not transient: resume the existing run instead, or pass "
|
||||
"`--again` if the tree itself changed. Never create a numbered variant by hand",
|
||||
),),
|
||||
notes=(
|
||||
"Creates `work/<runkey>/` with the required `README.md` and `plan.md`.",
|
||||
"`--input` derives the run key from the path below `raw/` (an ingest); `--key` names it "
|
||||
"outright for a run with no raw input - a migration or a sweep across `kb/` - and may "
|
||||
"not start with `ingest-`, which stays reserved for derived keys. Exactly one of the "
|
||||
"two.",
|
||||
"Refuses a collision instead of suffixing it.",
|
||||
"`--again` opens a dated second pass (`<runkey>-<date>`) over a tree that has itself "
|
||||
"changed.",
|
||||
"`--dry-run` reports the run key and files without writing.",
|
||||
),
|
||||
failures=(
|
||||
cli_contract.Failure(
|
||||
cause="Neither or both of `--input`/`--key` given, or a `--key` that is empty or "
|
||||
"starts with `ingest-`",
|
||||
reaction="Fix the argument and retry once",
|
||||
),
|
||||
cli_contract.Failure(
|
||||
cause="`--input` is outside `raw/`, does not exist, or is `raw/` itself (an empty "
|
||||
"run key)",
|
||||
reaction="Point `--input` at material under `raw/`, or use `--key` for a run with no "
|
||||
"raw input",
|
||||
),
|
||||
cli_contract.Failure(
|
||||
cause="The workshop already exists",
|
||||
reaction="A collision is not transient: resume the existing run instead, or pass "
|
||||
"`--again` if the tree itself changed",
|
||||
),
|
||||
),
|
||||
examples=(
|
||||
"tools/wikitool work new --input raw/2026/09/handbuch",
|
||||
"tools/wikitool work new --key migrate-7.0.0",
|
||||
"tools/wikitool work new --input raw/2026/09/handbuch --again",
|
||||
),
|
||||
never=(
|
||||
"Never create a numbered variant of a run key by hand.",
|
||||
),
|
||||
see_also=(
|
||||
"`work/CONTRACT.md` - run keys, required files, how a run closes",
|
||||
"`wikitool work close` - deletes the run when it is done",
|
||||
"`instructions/ingest-large-tree.md` - the ingest that opens a run",
|
||||
),
|
||||
))
|
||||
def new_command(
|
||||
input_path: Optional[str] = typer.Option(
|
||||
@@ -247,14 +276,36 @@ def new_command(
|
||||
atomic="No - a recursive delete",
|
||||
budget=cli_contract.Budget.COUNTED,
|
||||
),
|
||||
notes="Lists what would be lost and requires `--yes`, because nothing in it is recoverable "
|
||||
"from the rest of the repo - the durable conclusions must already be in `kb/`",
|
||||
failures=(cli_contract.Failure(
|
||||
label="",
|
||||
cause="Unknown run key, or `--yes` was not passed",
|
||||
reaction="For \"not confirmed\": check the listed files are no longer needed, confirm the "
|
||||
"conclusions are in `kb/`, then re-run with `--yes`",
|
||||
),),
|
||||
notes=(
|
||||
"Deletes `work/<run-key>/` recursively.",
|
||||
"Without `--yes` it lists what would be lost and refuses: nothing in a workshop is "
|
||||
"recoverable from the rest of the repo, so the durable conclusions must already be in "
|
||||
"`kb/`.",
|
||||
"`--dry-run` lists the files without deleting.",
|
||||
"Not idempotent: once deleted, the run key is unknown.",
|
||||
),
|
||||
failures=(
|
||||
cli_contract.Failure(
|
||||
cause="Unknown run key",
|
||||
reaction="Check `ls work/` for the open runs, then retry once",
|
||||
),
|
||||
cli_contract.Failure(
|
||||
cause="`--yes` was not passed - the output lists what would be lost",
|
||||
reaction="Check the listed files are no longer needed, confirm the conclusions are in "
|
||||
"`kb/`, then re-run with `--yes`",
|
||||
),
|
||||
),
|
||||
examples=(
|
||||
"tools/wikitool work close --run-key ingest-2026-09-handbuch --dry-run",
|
||||
"tools/wikitool work close --run-key ingest-2026-09-handbuch --yes",
|
||||
),
|
||||
never=(
|
||||
"Never pass `--yes` before the run's conclusions are in `kb/`.",
|
||||
),
|
||||
see_also=(
|
||||
"`work/CONTRACT.md` - how a run closes",
|
||||
"`wikitool work new` - opens a run",
|
||||
),
|
||||
))
|
||||
def close_command(
|
||||
run_key: str = typer.Option(..., "--run-key", help="The workshop directory name"),
|
||||
|
||||
Reference in new issue
Block a user