--- type: types/instruction.md name: session-setup description: Scope the wikitool iteration budget to the task by exporting a stable session id before the first tool call. --- # Scope the session budget Every `wikitool` call is counted against a per-session iteration budget. A "session" is keyed by `WIKITOOL_SESSION_ID`, falling back to the parent process id when that variable is unset. Without an explicit id, the budget is scoped to whichever shell happened to run the command, so a task spanning several terminals is counted as several sessions - and one that reuses a shell inherits an unrelated count. ## Steps Run this **once per working session**, before the first `wikitool` call that is not exempt from the budget (see ยง Scope for what that means): ```bash export WIKITOOL_SESSION_ID="wiki-$(date +%s)" tools/wikitool sync ``` Check the current state at any time with `tools/wikitool budget status`, which is never counted against the budget itself and prints the id it is counting under. **Why `sync` here, not just at publish time.** `publish` already pulls before it pushes, but a session that runs many `wikitool` calls before its first `publish` (an ingest, a multi-page update) would otherwise build all of that work against whatever the local clone happened to hold when the session started - stale by however long the previous sync was, on a repo more than one machine or session writes to. Running `sync` first shrinks that window to the start of the session instead of discovering the drift only at the very end. `sync` fetches the remote and fast-forwards or rebases automatically when that is safe; it never commits and never pushes. **Exit 42 (rebase-review)?** Same as any exit 42 - read the diff it prints, judge whether it conflicts with what you are about to do, summarize that to the user, then `tools/wikitool sync --confirm-rebase ` before continuing. See [gates.md](gates.md). ## Multi-unit runs A task planned as several units - a tree ingest, where each unit produces its own source page and its own `publish` - takes one id per unit, derived from the workshop's run key: ```bash export WIKITOOL_SESSION_ID="ingest-documents-handbook/u3" ``` The run key, the workshop directory name and the session id are then the same string, so the checklist in `work//README.md` and the budget state cannot disagree about where the run stands. A new id may only be taken at a unit boundary recorded in `plan.md` - never after a gate refusal. See [gates.md](gates.md). ## Scope **The exemption is an allowlist, not "read-only" or "does not change the wiki."** A command needs this setup unless it is one of the dozen `tools/CONTRACT.md` marks exempt in its command table (`search`, `doctor`, `links show`, `cite id`, `budget status`, the read-only forms of `eval`, `version`, `migrate` and `upstream verify`) - that table, not a rule of thumb here, is the single list. One entry on it, `version regrade`, is exempt only in its bare listing form and counted when it is given positions to regrade; every other entry is exempt however it is called. `lint` is the case that breaks the "changes the wiki" reading: it only writes to `reports/`, which is gitignored, so it looks side-effect-free - but it is not on the allowlist and is counted like any mutating command. A skill that calls only exempt commands needs no session id; a skill that calls `lint` alone still does. The limits themselves, and what to do when one trips, are in [gates.md](gates.md).