sync and publish name the Rebase-Review Gate by its display name
CI / verify (push) Successful in 6m20s
CI / pwsh (push) Successful in 2m0s
Release / release (push) Successful in 35s

The help and exit-42 cause texts still said "rebase-review gate" after the display
name was settled; the generated reference and CONTRACT row follow.

Files changed:
- CHANGES.md
- VERSION
- docs/reference/commands/git.md
- docs/reference/exit-codes.md
- tools/CONTRACT.md
- tools/chemenu/commands/git_publish.py

Co-Authored-By: Claude Code <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SnAJ7Z3CpVD3PRbN73QtU2
This commit is contained in:
torbenandClaude Code committed 2026-10-07 10:30:49 +02:00
1 parent e9f4759727
commit 5915b07383
6 files changed
+26 -25

No files matched your search

+7 -7
View File
@@ -1910,13 +1910,13 @@ Fetch `<remote>/<branch>` and bring the local branch up to date with it.
- 0 The remote cannot be reached - reported and skipped, not a failure
- 1 The automatic rebase hit a real conflict outside the generated files (git failed), or `kb/log.md` was edited rather than appended to; it is aborted cleanly and the working tree restored
- 1 An uncommitted change - or an untracked file - sits on a path the incoming commits also change; nothing was changed
- 42 Rebase-review gate: `<remote>/<branch>` moved and both sides changed the same file, generated files aside; the output lists the upstream commits, the overlapping files and their diff
- 42 Rebase-Review Gate: `<remote>/<branch>` moved and both sides changed the same file, generated files aside; the output lists the upstream commits, the overlapping files and their diff
**ON FAILURE**
- The automatic rebase hit a real conflict outside the generated files (git failed), or `kb/log.md` was edited rather than appended to; it is aborted cleanly and the working tree restored -> Do not retry and do not force - resolve the conflict manually, then re-run
- An uncommitted change - or an untracked file - sits on a path the incoming commits also change; nothing was changed -> Show the user the file it names. Once that change is committed or moved out of the way, re-run once
- Rebase-review gate: `<remote>/<branch>` moved and both sides changed the same file, generated files aside; the output lists the upstream commits, the overlapping files and their diff -> Show the user the command's full output verbatim and stop. Once they have approved it, run the re-run line the output prints, which carries `--confirm-rebase <token>`. Without that token, or with a wrong, invented or superseded one, it exits 42 again with the current state
- Rebase-Review Gate: `<remote>/<branch>` moved and both sides changed the same file, generated files aside; the output lists the upstream commits, the overlapping files and their diff -> Show the user the command's full output verbatim and stop. Once they have approved it, run the re-run line the output prints, which carries `--confirm-rebase <token>`. Without that token, or with a wrong, invented or superseded one, it exits 42 again with the current state
**NEVER**
@@ -1925,7 +1925,7 @@ Fetch `<remote>/<branch>` and bring the local branch up to date with it.
**NOTES**
- Fetches `<remote>/<branch>`, then: fast-forwards when only the remote moved; rebases the local commits on top when both sides moved but touched disjoint files; exits 42 (rebase-review gate) when both sides touched the same file.
- Fetches `<remote>/<branch>`, then: fast-forwards when only the remote moved; rebases the local commits on top when both sides moved but touched disjoint files; exits 42 (Rebase-Review Gate) when both sides touched the same file.
- Files `wikitool` generates (`kb/index.md`, `kb/log.md`, `kb/provenance.md`, every `kb/**/INDEX.md`) never count as an overlap and never reach the gate. Where they are what stops git - uncommitted ones in the way of a fast-forward or rebase, or a rebase conflict in them - they are merged mechanically: `kb/log.md` becomes the incoming log plus the entries only this side appended, and the catalog and `kb/provenance.md` are regenerated from the merged pages and left as an uncommitted change. A reconcile git can do on its own is unchanged and regenerates nothing.
- Uncommitted changes that no incoming commit touches do not stop a rebase: they are carried through it (`git rebase --autostash`) and come back unchanged.
- Before anything is set aside, the working tree is stored as a commit under `refs/wikitool/reconcile-backup`. A successful reconcile drops it; a failed one restores the working tree and names the ref.
@@ -1953,7 +1953,7 @@ Reconcile with `<remote>/<branch>`, then stage all changes, commit, and push.
- effect: write
- idempotent: no
- atomic: No - sequential git operations. Every gate runs before staging, except on the one retry of a rejected push, where the rebase-review gate can exit 42 after the commit: nothing is pushed, and the re-run with `--confirm-rebase` pushes that commit
- atomic: No - sequential git operations. Every gate runs before staging, except on the one retry of a rejected push, where the Rebase-Review Gate can exit 42 after the commit: nothing is pushed, and the re-run with `--confirm-rebase` pushes that commit
- budget: counted
- network: yes
- gates: mass-update, publish-remote, rebase-review
@@ -1973,7 +1973,7 @@ Reconcile with `<remote>/<branch>`, then stage all changes, commit, and push.
- 1 `--yes`/`-y` was passed - the flag does not exist and fails with an explicit error
- 1 `.wikitool-remotes.json` is unreadable or has no usable `allowed_push_urls` list
- 42 Mass-Update Gate: `--threshold` (default 10) or more counted files would be committed, or the `--confirm` token does not match this changeset
- 42 Rebase-review gate: `<remote>/<branch>` moved and both sides changed the same file; the output lists the upstream commits, the overlapping files and their diff
- 42 Rebase-Review Gate: `<remote>/<branch>` moved and both sides changed the same file; the output lists the upstream commits, the overlapping files and their diff
- 42 Publish-Remote Gate: `.wikitool-remotes.json` exists and the push URL of `--remote` is not listed in it, or `--remote` resolves to no push URL
**ON FAILURE**
@@ -1984,7 +1984,7 @@ Reconcile with `<remote>/<branch>`, then stage all changes, commit, and push.
- `--yes`/`-y` was passed - the flag does not exist and fails with an explicit error -> Drop it. The Mass-Update Gate is cleared only with `--confirm <token>` from the gate's own refusal output
- `.wikitool-remotes.json` is unreadable or has no usable `allowed_push_urls` list -> Show the error to the user and stop - a malformed file is not permission, and fixing or deleting it is theirs to do
- Mass-Update Gate: `--threshold` (default 10) or more counted files would be committed, or the `--confirm` token does not match this changeset -> Show the user the command's full output verbatim and stop. Once they have approved it, run the re-run line the output prints, which carries `--confirm <token>`. Without that token, or with a wrong, invented or superseded one, it exits 42 again with the current state
- Rebase-review gate: `<remote>/<branch>` moved and both sides changed the same file; the output lists the upstream commits, the overlapping files and their diff -> Show the user the command's full output verbatim and stop. Once they have approved it, run the re-run line the output prints, which carries `--confirm-rebase <token>`. Without that token, or with a wrong, invented or superseded one, it exits 42 again with the current state
- Rebase-Review Gate: `<remote>/<branch>` moved and both sides changed the same file; the output lists the upstream commits, the overlapping files and their diff -> Show the user the command's full output verbatim and stop. Once they have approved it, run the re-run line the output prints, which carries `--confirm-rebase <token>`. Without that token, or with a wrong, invented or superseded one, it exits 42 again with the current state
- Publish-Remote Gate: `.wikitool-remotes.json` exists and the push URL of `--remote` is not listed in it, or `--remote` resolves to no push URL -> Show the user the push URL it names and the allowed ones, and stop. This gate has no token and no flag: only the user resolves it, by adding the URL to that file
**NEVER**
@@ -1997,7 +1997,7 @@ Reconcile with `<remote>/<branch>`, then stage all changes, commit, and push.
- Order: branch check and Publish-Remote Gate, then the reconcile with `<remote>/<branch>`, then the Mass-Update Gate, then `git add -A`, commit and push. `--no-push` skips all but the Mass-Update Gate and the commit.
- Without `--no-push`, a remote that is not configured or cannot be reached ends the call with exit 1 at the reconcile - before the gate, `git add` and the commit, and also on a clean tree. Nothing is committed, the index and the working tree are unchanged, and the message names `--no-push` as the way to a local commit. The next `publish` that reaches the remote pushes that commit along with whatever is new. A remote that answers but has no `<branch>` yet (a new, empty repository) is not this case: the first publish of an instance commits and pushes as before.
- Reconcile: fetches `<remote>/<branch>`, fast-forwards when only the remote moved, rebases the local commits on top when both sides moved but touched disjoint files, and exits 42 (rebase-review gate) when both sides touched the same file. A refused reconcile performs no rebase attempt. The `--confirm-rebase` token covers the exact upstream state and the set of files touched on both sides.
- Reconcile: fetches `<remote>/<branch>`, fast-forwards when only the remote moved, rebases the local commits on top when both sides moved but touched disjoint files, and exits 42 (Rebase-Review Gate) when both sides touched the same file. A refused reconcile performs no rebase attempt. The `--confirm-rebase` token covers the exact upstream state and the set of files touched on both sides.
- Generated files are never an overlap: where they are all that stops the reconcile, it merges them as `sync` does (both sides' log entries kept, the catalog and `kb/provenance.md` regenerated) and carries uncommitted changes no incoming commit touches through the rebase. The proactive reconcile runs before staging, so this publish commits the regenerated files - with `--path` too, see there; on the retry after a rejected push they get a commit of their own before the second push.
- The push target must be the checked-out branch; this is checked before anything is staged. The unborn branch of a fresh `git init -b main` counts as checked out, so the first publish of a new instance works; a real detached HEAD is refused.
- With nothing new to stage, a local commit the remote lacks is still pushed: one left behind by an earlier publish whose push failed, or every commit when the remote answers but does not have the branch yet (a new, empty remote repository).
+7 -7
View File
@@ -1343,7 +1343,7 @@ def apply_reconcile(outcome: ReconcileOutcome, remote: str, branch: str, command
notes=(
"Fetches `<remote>/<branch>`, then: fast-forwards when only the remote moved; rebases "
"the local commits on top when both sides moved but touched disjoint files; exits 42 "
"(rebase-review gate) when both sides touched the same file.",
"(Rebase-Review Gate) when both sides touched the same file.",
"Files `wikitool` generates (`kb/index.md`, `kb/log.md`, `kb/provenance.md`, every "
"`kb/**/INDEX.md`) never count as an overlap and never reach the gate. Where they are "
"what stops git - uncommitted ones in the way of a fast-forward or rebase, or a rebase "
@@ -1389,7 +1389,7 @@ def apply_reconcile(outcome: ReconcileOutcome, remote: str, branch: str, command
"out of the way, re-run once",
),
cli_contract.Failure(
cause="Rebase-review gate: `<remote>/<branch>` moved and both sides changed the "
cause="Rebase-Review Gate: `<remote>/<branch>` moved and both sides changed the "
"same file, generated files aside; the output lists the upstream commits, the "
"overlapping files and their diff",
reaction=cli_contract.token_gate_reaction("--confirm-rebase"),
@@ -1417,7 +1417,7 @@ def sync_command(
None,
"--confirm-rebase",
metavar="TOKEN",
help="Clear the rebase-review gate for the exact upstream state and file overlap this "
help="Clear the Rebase-Review Gate for the exact upstream state and file overlap this "
"token was issued for. The token comes from the gate's own refusal output.",
),
):
@@ -1506,7 +1506,7 @@ def commit_regenerated(remote: str, branch: str) -> None:
effect=cli_contract.Effect.WRITE,
idempotent=cli_contract.Idempotent.NO,
atomic="No - sequential git operations. Every gate runs before staging, except on the "
"one retry of a rejected push, where the rebase-review gate can exit 42 after the "
"one retry of a rejected push, where the Rebase-Review Gate can exit 42 after the "
"commit: nothing is pushed, and the re-run with `--confirm-rebase` pushes that commit",
budget=cli_contract.Budget.COUNTED,
network=cli_contract.Network.YES,
@@ -1525,7 +1525,7 @@ def commit_regenerated(remote: str, branch: str) -> None:
"case: the first publish of an instance commits and pushes as before.",
"Reconcile: fetches `<remote>/<branch>`, fast-forwards when only the remote moved, "
"rebases the local commits on top when both sides moved but touched disjoint files, "
"and exits 42 (rebase-review gate) when both sides touched the same file. A refused "
"and exits 42 (Rebase-Review Gate) when both sides touched the same file. A refused "
"reconcile performs no rebase attempt. The `--confirm-rebase` token covers the exact "
"upstream state and the set of files touched on both sides.",
"Generated files are never an overlap: where they are all that stops the reconcile, it "
@@ -1626,7 +1626,7 @@ def commit_regenerated(remote: str, branch: str) -> None:
code=42,
),
cli_contract.Failure(
cause="Rebase-review gate: `<remote>/<branch>` moved and both sides changed the "
cause="Rebase-Review Gate: `<remote>/<branch>` moved and both sides changed the "
"same file; the output lists the upstream commits, the overlapping files and their "
"diff",
reaction=cli_contract.token_gate_reaction("--confirm-rebase"),
@@ -1677,7 +1677,7 @@ def publish_command(
None,
"--confirm-rebase",
metavar="TOKEN",
help="Clear the rebase-review gate raised by the pre-push reconcile step. The token "
help="Clear the Rebase-Review Gate raised by the pre-push reconcile step. The token "
"comes from that gate's own refusal output - see `tools/wikitool sync`.",
),
yes: bool = typer.Option(