Files
chemenu/docs/reference/commands/git.md
T
torbenandClaude Code db8f90c229
CI / verify (push) Failing after 7m41s
CI / pwsh (push) Successful in 2m32s
Release / release (push) Successful in 37s
Release / wiki-mirror (push) Skipped
settings: the four per-feature files .wikitool-remotes/-telemetry/-upload/-tasks.json move into the three tiers and disappear; new command config migrate; 10.0.0-beta.1 (#208)
Files changed:
- .gitignore
- AGENTS.md
- CHANGES.md
- INSTALL.md
- VERSION
- docs/explanation/knowledge-and-commitment.md
- docs/explanation/telemetry-and-evaluation.md
- docs/explanation/why-gates-are-code.md
- docs/how-to/run-the-weekly-review.md
- docs/how-to/set-up-the-mcp-server.md
- docs/how-to/trace-and-score-sessions.md
- docs/how-to/troubleshoot.md
- docs/reference/commands/README.md
- docs/reference/commands/configuration.md
- docs/reference/commands/finding-and-checking.md
- docs/reference/commands/git.md
- docs/reference/commands/instance-health.md
- docs/reference/commands/pages.md
- docs/reference/commands/raw-material-and-uploads.md
- docs/reference/configuration.md
- docs/reference/exit-codes.md
- instructions/dev/doc-pull-through.md
- instructions/dev/tracker-testing.md
- instructions/gates.md
- instructions/ingest-queue.md
- instructions/mcp-read-server.md
- instructions/migrate-corpus.md
- instructions/migrations/10.0.0-settings-tiers.md
- instructions/setup-instance.md
- raw/CONTRACT.md
- reports/CONTRACT.md
- tools/CONTRACT.md
- tools/README.md
- tools/bugreport.py
- tools/chemenu/cli_contract.py
- tools/chemenu/commands/_util.py
- tools/chemenu/commands/config_cmd.py
- tools/chemenu/commands/docs_verify.py
- tools/chemenu/commands/doctor.py
- tools/chemenu/commands/export_cmd.py
- tools/chemenu/commands/git_publish.py
- tools/chemenu/commands/new_page.py
- tools/chemenu/commands/review_cmd.py
- tools/chemenu/commands/task_cmd.py
- tools/chemenu/commands/upload_cmd.py
- tools/chemenu/config.py
- tools/chemenu/config_shapes.py
- tools/chemenu/legacy_settings.py
- tools/chemenu/mcp/__main__.py
- tools/chemenu/mcp/server.py
- tools/chemenu/reference_doc.py
- tools/chemenu/review.py
- tools/chemenu/settings.py
- tools/chemenu/tasks/__init__.py
- tools/chemenu/tasks/caldav.py
- tools/chemenu/tasks/config.py
- tools/chemenu/tasks/superproductivity.py
- tools/chemenu/telemetry/policy.py
- tools/chemenu/tests/conftest.py
- tools/chemenu/tests/record_sp_fixtures.py
- tools/chemenu/tests/test_bugreport.py
- tools/chemenu/tests/test_caldav.py
- tools/chemenu/tests/test_config_shapes.py
- tools/chemenu/tests/test_doctor.py
- tools/chemenu/tests/test_git_publish.py
- tools/chemenu/tests/test_legacy_settings.py
- tools/chemenu/tests/test_mcp_server.py
- tools/chemenu/tests/test_new_page.py
- tools/chemenu/tests/test_review.py
- tools/chemenu/tests/test_settings.py
- tools/chemenu/tests/test_sp_recorded.py
- tools/chemenu/tests/test_superproductivity.py
- tools/chemenu/tests/test_task_cmd.py
- tools/chemenu/tests/test_tasks_config.py
- tools/chemenu/tests/test_telemetry_policy.py
- tools/chemenu/tests/test_tracker_live.py
- tools/chemenu/tests/test_upload.py
- tools/chemenu/tests/tracker_live.py
- tools/chemenu/upload.py

Co-Authored-By: Claude Code <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SnAJ7Z3CpVD3PRbN73QtU2
2026-10-11 06:54:35 +02:00

13 KiB

Git

Pulling in the remote and publishing a change - the only way a change leaves this checkout.

Contents

sync

Fetch <remote>/<branch> and bring the local branch up to date with it.

Synopsis

  • wikitool sync [--remote origin] [--branch main] [--confirm-rebase TOKEN]

Options

  --remote <str>          Git remote to reconcile against  [default: origin]
  --branch <str>          Branch to reconcile  [default: main]
  --confirm-rebase TOKEN  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.
  -h, --help              Show this message and exit.

Examples

tools/wikitool sync
tools/wikitool sync --confirm-rebase <token>    # re-run after exit 42, once the user approved

Behaviour

  • 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.
  • A refused call performs no rebase attempt and leaves the branch where it was.
  • The --confirm-rebase token covers the exact upstream state and the set of files touched on both sides, generated files excluded; either one moving makes it stale.
  • Makes no commit, no push, and no forced operation of any kind.
  • Three messages for a fetch that fails: no remote of that name, a remote that answers but has no such branch yet (a new, empty repository), and a remote that cannot be reached. All three exit 0 here; publish stops on the first and the last.
  • Run it once at the start of a writing session.

Properties

  • Changes files: yes
  • Idempotent: yes
  • Atomic: No - fetch, then at most one merge/rebase attempt, aborted cleanly on failure with the working tree restored; a success that merged generated files then rewrites the catalog
  • Counts toward the session call budget: yes
  • Can reach the network: yes
  • Gates: rebase-review - see exit codes and gates

Exit codes

  • 0 - success
  • 0 - No remote configured - reported and skipped, not a failure
  • 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

See also

  • wikitool publish - runs the same reconcile before it commits and pushes
  • instructions/session-setup.md - where a session runs sync
  • instructions/gates.md - the gate procedure

publish

Reconcile with <remote>/<branch>, then stage all changes, commit, and push.

Synopsis

  • wikitool publish --message "<op>: <desc>" [--no-push] [--confirm TOKEN] [--confirm-rebase TOKEN] [--threshold N] [--remote origin] [--branch main] [--path P ...]

Options

  --message <str>         Commit message summary, e.g. 'ingest: docker-
                          cheatsheet'  [required]
  --push / --no-push      [default: push]
  --confirm TOKEN         Clear the Mass-Update Gate for the exact changeset
                          this token was issued for. The token comes from the
                          gate's own refusal output - run without it first to
                          see the file list, show that output to the user, and
                          only pass this once they have approved it.
  --confirm-rebase TOKEN  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`.
  --threshold <int>       Mass-Update Gate threshold: number of counted files
                          at/above which clearance is required.  [default: 10]
  --remote <str>          Git remote to push to  [default: origin]
  --branch <str>          Branch to push  [default: main]
  --path <str>            Limit this publish to a path (repeatable). Lets a
                          large change be committed in reviewable batches
                          instead of one opaque commit - the Mass-Update Gate
                          then counts only the files in scope.
  -h, --help              Show this message and exit.

Examples

tools/wikitool publish --message "ingest: docker-cheatsheet"
tools/wikitool publish --confirm <token> --message "ingest: docker-cheatsheet"    # re-run after a Mass-Update exit 42, once the user approved
tools/wikitool publish --confirm-rebase <token> --message "ingest: docker-cheatsheet"    # re-run after a rebase-review exit 42, once the user approved

Behaviour

  • 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.
  • 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).
  • A rejected push that finds the remote unreachable on its one retry reports the original push error.
  • A rejected push gets exactly one more reconcile-and-push; never more than one.
  • Mass-Update Gate: counts the files that would be committed, refuses with exit 42 at --threshold (default 10) or more, and prints a review report - a scale line (file count, total lines added/removed, status breakdown), attention notes where they apply (deletions by name, control-plane and harness-config touches, published pages, the largest single change, binaries), and every counted path grouped by area with its status and churn. The list is what the commit will hold: it is computed from a scratch copy of the index after git add -A, so a path that is staged as deleted and back in the working tree is not counted twice, and a rename counts as its old path deleted plus its new path added. The real index and the working tree are not touched, so a refused publish leaves both byte-identical.
  • Never counted and never shown for approval, but committed like everything else: anything under work/, and the files wikitool generates itself (kb/index.md, kb/log.md, kb/provenance.md, every INDEX.md under kb/). The refusal line accounts for both, by reason.
  • The --confirm token covers each counted path, the blob id of its contents and the publish target: a different file list or edited contents need a new clearance.
  • Publish-Remote Gate: when .wikitool-local.json carries remotes.allowed_push_urls and the push URL of --remote is not listed in it, exits 42 before the reconcile fetches anything. The URL is read with git remote get-url --push, so a repointed remote does not pass on its name. An absent section means unrestricted; a malformed one is an error, not permission.
  • The remotes settings file of an earlier version is not read: while it exists this exits 42 and names tools/wikitool config migrate, so a restriction is never lost silently.
  • --path (repeatable) scopes the whole operation - gate count, staging and commit - to that subtree, with one exception: uncommitted generated files outside --path (kb/index.md, kb/log.md, kb/provenance.md, every INDEX.md under kb/) are staged and committed too, and a line names them - whether a reconcile or the change itself wrote them. They stay out of the gate count, and the --confirm token and the re-run line cover the --path given. Every other file outside --path is left as it is.
  • Commit message: --message, then a Files changed: paragraph listing every committed path. When --message ends in a paragraph git reads as a trailer block (Co-Authored-By: and the like), that block stays the last paragraph and the list goes in front of it, since git reads trailers from the last paragraph only. git interpret-trailers decides whether there is such a block, and the list moves only when git reads the same trailers from the result; otherwise it is appended at the end. --message is not part of any gate token.
  • After a successful commit or push whose changed files include tools/, types/, instructions/, AGENTS.md or a path ending in CONTRACT.md, prints one reminder line: the phase past this point (an issue-body rewrite, docs/ staleness, a changelog entry's accuracy) is not covered by docs verify, instructions verify or pytest. It is not a gate: no exit code change, nothing to clear, and silent for an ordinary content publish.

Properties

  • Changes files: yes
  • 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
  • Counts toward the session call budget: yes
  • Can reach the network: yes
  • Gates: mass-update, publish-remote, rebase-review - see exit codes and gates

Exit codes

  • 0 - success
  • 1 - git failed - git add, git commit, git push, or the reconcile's automatic rebase (a conflict outside the generated files, an edited kb/log.md, or an uncommitted change on a path the incoming commits change)
  • 1 - The push target (--branch) is not the checked-out branch, or HEAD is detached; the unborn branch of a fresh git init is not this case
  • 1 - No --no-push, and the remote is not configured or cannot be reached; nothing was committed
  • 1 - --yes/-y was passed - the flag does not exist and fails with an explicit error
  • 1 - The settings files do not pass their check, or remotes.allowed_push_urls is not a list of strings
  • 42 - The remotes settings file of an earlier version is still there
  • 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 - Publish-Remote Gate: remotes.allowed_push_urls is set and the push URL of --remote is not listed in it, or --remote resolves to no push URL

See also

  • wikitool sync - the same reconcile on its own, without committing or pushing
  • instructions/gates.md - the gate procedure
  • instructions/setup-instance.md - the first publish of a new instance