tools: command records, Private instances group - one line per cause, examples, prohibitions (#142)
CI / verify (push) Successful in 1m13s
Release / release (push) Successful in 38s

Files changed:
- CHANGES.md
- VERSION
- tools/CONTRACT.md
- tools/chemenu/commands/upstream_cmd.py
This commit is contained in:
torben committed 2026-09-26 09:29:09 +02:00
1 parent 243db66134
commit b83a3982c5
4 files changed
+168 -55

No files matched your search

+58 -6
View File
@@ -3039,18 +3039,51 @@ Take a stack update into a private instance's branch, machinery only.
- budget: counted
- network: no
**EXAMPLES**
- `tools/wikitool upstream merge`
- `tools/wikitool upstream merge --remote upstream --branch main --no-fetch`
**EXIT STATUS**
- 0 success
- 1 Dirty working tree, a merge already in progress, the remote does not resolve, git refused to open the merge at all (unrelated histories), or a real conflict remains in `tools/`/`types/`/`instructions/` after the content stages and stack-owned paths were restored
- 1 Dirty working tree, or a merge already in progress
- 1 The remote does not resolve, the fetch failed, or `HEAD` does not resolve
- 1 git refused to open the merge at all (unrelated histories); nothing was touched
- 1 A real conflict remains in `tools/`/`types/`/`instructions/` after the content stages and stack-owned paths were restored; the merge is left open
- 1 A git step failed inside the open merge (`git checkout MERGE_HEAD -- <path>` or `git commit --no-edit`)
- 1 The postcheck after the commit found a leak; the merge commit already exists
**ON FAILURE**
- Dirty working tree, a merge already in progress, the remote does not resolve, git refused to open the merge at all (unrelated histories), or a real conflict remains in `tools/`/`types/`/`instructions/` after the content stages and stack-owned paths were restored -> **Not idempotent, and not safe to retry unchanged.** For a dirty tree or an in-progress merge: fix the named precondition and retry once. For a real conflict: **do not retry, do not force** - resolve the named paths by hand (take the upstream side, or re-file the local change as an issue against the public repo per `instructions/private-instance.md`) and either `git commit --no-edit` yourself or `git merge --abort`. If the postcheck after commit finds a leak, the merge commit already exists and is **not** rolled back automatically - inspect it by hand; this is a bug report, not a retry
- Dirty working tree, or a merge already in progress -> Fix the named precondition and retry once
- The remote does not resolve, the fetch failed, or `HEAD` does not resolve -> Fix `--remote`/`--branch` or the repository state, then retry once
- git refused to open the merge at all (unrelated histories); nothing was touched -> Do not retry unchanged - report it to the user
- A real conflict remains in `tools/`/`types/`/`instructions/` after the content stages and stack-owned paths were restored; the merge is left open -> **Do not retry, do not force** - resolve the named paths by hand (take the upstream side, or re-file the local change as an issue against the public repo per `instructions/private-instance.md`) and either `git commit --no-edit` yourself or `git merge --abort`
- A git step failed inside the open merge (`git checkout MERGE_HEAD -- <path>` or `git commit --no-edit`) -> Do not retry unchanged - inspect the open merge by hand
- The postcheck after the commit found a leak; the merge commit already exists -> It is **not** rolled back automatically - inspect it by hand; this is a bug report, not a retry
**NEVER**
- Never retry a failed merge unchanged, and never force.
**NOTES**
The code procedure behind `instructions/private-instance.md` § "Taking a stack update". Refuses on a dirty working tree, a merge already in progress, or a remote that does not resolve; WARNs (does not block) when `.wikitool-remotes.json` is absent, pointing at the setup step that arms it. Fetches `<remote>/<branch>` (unless `--no-fetch`) and reports "already up to date" if nothing new exists. Otherwise opens `git merge --no-commit --no-ff <remote>/<branch>` - and stops, untouched, if git refused to open a merge at all (unrelated histories), since without a `MERGE_HEAD` every stack path would read as "the upstream deleted it". Then forces every content stage (`kb/`, `raw/`, `work/`, `reports/`) back to the local side by removing **only the paths tracked in either tree** and checking `HEAD`'s back out - never the stage directory wholesale, because `reports/` is gitignored apart from its contract and holds local, non-recomputable data (telemetry traces `eval score` reads, saved eval and lint reports) that no merge has business deleting. Then restores from the upstream side exactly the paths `chemenu.ownership.is_stack_owned` recognises as machinery (`<stage>/CONTRACT.md`, and anything ending `.template` under a content stage) - including a deletion, if the upstream removed one. A real conflict left in `tools/`, `types/` or `instructions/` after that leaves the merge open, uncommitted, and exits 1 rather than guessing. Commits with `git commit --no-edit`, then re-checks the resulting range with the same logic as `upstream verify`; a finding there is a loud, uncommitted-nothing-rolled-back error, because the merge commit already exists and needs a human's eyes, not an automatic repair. Never pushes. Not idempotent - see the tool error contract below
- Refuses on a dirty working tree, a merge already in progress, or a remote that does not resolve. WARNs (does not block) when `.wikitool-remotes.json` is absent, pointing at the setup step that arms it.
- Fetches `<remote>/<branch>` (unless `--no-fetch`) and reports "already up to date" if nothing new exists.
- Otherwise opens `git merge --no-commit --no-ff <remote>/<branch>`, and stops, untouched, if git refused to open a merge at all (unrelated histories).
- Forces every content stage (`kb/`, `raw/`, `work/`, `reports/`) back to the local side by removing **only the paths tracked in either tree** and checking `HEAD`'s back out - never the stage directory wholesale, so untracked and ignored local data under a stage (telemetry traces, saved eval and lint reports) is never deleted.
- Then restores from the upstream side exactly the machinery paths - `<stage>/CONTRACT.md` and anything ending `.template` under a content stage - including a deletion, if the upstream removed one.
- A real conflict left in `tools/`, `types/` or `instructions/` after that leaves the merge open, uncommitted, and exits 1 rather than guessing.
- Commits with `git commit --no-edit`, then re-checks the resulting range with the `upstream verify` check; a finding there is a loud error, and the merge commit is not rolled back.
- Never pushes.
- Not idempotent, and not safe to retry unchanged.
**SEE ALSO**
- `instructions/private-instance.md` § "Taking a stack update" - the procedure this implements
- `wikitool upstream verify` - the same check on any revision range
- `wikitool publish` - pushes the merge afterwards
#### `upstream verify`
@@ -3068,18 +3101,37 @@ Compare two revisions: did anything under a content stage change except through
- budget: exempt
- network: no
**EXAMPLES**
- `tools/wikitool upstream verify --since HEAD~1`
- `tools/wikitool upstream verify --since v7.0.0 --until HEAD`
**EXIT STATUS**
- 0 success
- 1 A leak was found (content changed under a content stage through a path that is not stack-owned), or `--since`/`--until` is not a revision in this repository
- 1 A leak: content changed under a content stage through a path that is not stack-owned
- 1 `--since`/`--until` is not a revision in this repository
**ON FAILURE**
- A leak was found (content changed under a content stage through a path that is not stack-owned), or `--since`/`--until` is not a revision in this repository -> A finding is not fixed by re-running - it names the paths that leaked. Fix the revision argument and retry for the second case
- A leak: content changed under a content stage through a path that is not stack-owned -> A finding is not fixed by re-running - it names the paths that leaked
- `--since`/`--until` is not a revision in this repository -> Fix the revision argument and retry
**NEVER**
- Never re-run to make a leak finding go away.
**NOTES**
Shares its check with `upstream merge`'s own postcheck, so a hand-resolved merge conflict, or a `dist upgrade`, can be verified the same way. Exit 1 with the offending paths if anything leaked; otherwise reports which stack-owned paths legitimately moved. Read-only and exempt from the Iteration Budget Gate, like `migrate verify`
- Compares `--since` with `--until` (default `HEAD`): did anything under a content stage change except through a stack-owned path?
- The same check `upstream merge` runs after its commit, so a hand-resolved merge conflict, or a `dist upgrade`, can be verified the same way.
- Exits 1 with the offending paths if anything leaked; otherwise reports which stack-owned paths legitimately moved.
- Read-only and exempt from the Iteration Budget Gate.
**SEE ALSO**
- `wikitool upstream merge` - runs this check after its commit
- `instructions/private-instance.md` - the private-instance workflow
### Instance health