feat(devkit): add resumable workspace automation and UI review tooling
Verified with the coordinated workspace changes by devkit full run 2026-09-08T225814-186389-0000-3e3ed7cd (all seven phases passed). This shared UI pass does not mark the individual module reviews complete.
This commit is contained in:
Executable
+97
@@ -0,0 +1,97 @@
|
||||
# Selected-path Git maintenance
|
||||
|
||||
The optional `git` namespace of `tools/devkit/devkit.py` is a deliberately
|
||||
narrow maintenance workflow. It is not a replacement for normal Git, the
|
||||
release executor, required human review, or Gitea's canonical issue state.
|
||||
|
||||
From the Meta repository, preview and then save a plan for explicit files:
|
||||
|
||||
```sh
|
||||
python3 tools/devkit/devkit.py git plan --repo core --path webui/src/example.ts --message "Fix the reviewed example"
|
||||
python3 tools/devkit/devkit.py git plan --repo core --path webui/src/example.ts --message "Fix the reviewed example" --apply
|
||||
```
|
||||
|
||||
Use the saved `git-…` plan ID for the remaining commands. Each mutation needs
|
||||
its own `--apply`; an unqualified command only previews the operation:
|
||||
|
||||
```sh
|
||||
python3 tools/devkit/devkit.py git commit git-PLAN_ID
|
||||
python3 tools/devkit/devkit.py git commit git-PLAN_ID --apply
|
||||
python3 tools/devkit/devkit.py git push git-PLAN_ID
|
||||
python3 tools/devkit/devkit.py git push git-PLAN_ID --apply
|
||||
python3 tools/devkit/devkit.py git status git-PLAN_ID
|
||||
```
|
||||
|
||||
The immutable local plan binds the registered repository, HEAD, branch, origin
|
||||
fetch/push URL hashes, Git configuration, complete index identity, explicit
|
||||
selected file paths, working-tree hashes, expected Git blobs, and commit message.
|
||||
Raw remote URLs and file contents are not stored. A changed input blocks the
|
||||
operation; inspect it and create another plan instead of weakening the check.
|
||||
Receipts are private local records with integrity checks, not signed approval
|
||||
or a security attestation.
|
||||
|
||||
Commit captures each selected file once, verifies the captured bytes and Git
|
||||
blob against the plan, and builds an isolated index/tree from the frozen HEAD
|
||||
plus only those blobs. Git's normal identity rules create the commit object;
|
||||
an atomic branch compare-and-swap publishes it only if the planned parent is
|
||||
still current. Active hooks/signing remain refused rather than bypassed.
|
||||
An editor racing with this operation cannot substitute newer working-tree
|
||||
bytes: those edits remain uncommitted, and the helper never overwrites files.
|
||||
|
||||
The real index is protected by Git's standard index lock. Only selected entries
|
||||
are updated from a prepared private copy; unrelated staging and index flags are
|
||||
preserved. If the index changes independently, its new data is not overwritten
|
||||
and the receipt requires reconciliation. The resulting parent, message,
|
||||
changed paths, blobs/modes and unrelated index entries are verified.
|
||||
Git refs and index files are separately atomic, not one filesystem transaction.
|
||||
Independent writers that ignore the standard index lock can still change refs
|
||||
during publication. The helper rechecks the exact recorded candidate before
|
||||
index recovery and before recording success; it refuses an uncertain result
|
||||
instead of adopting a newer HEAD or claiming that competing work was its own.
|
||||
Directories, noncanonical paths, implicit globs, staging-all, amend,
|
||||
force-push and extra-tag publication are not supported. A selected file with
|
||||
different staged and working-tree changes is refused; decide explicitly which
|
||||
version to commit using normal Git first.
|
||||
|
||||
Push requires the recorded commit to remain current, an unchanged origin and
|
||||
one standard-transport push destination. It requests a normal, non-forced push
|
||||
of that commit to the recorded branch and checks the remote branch afterward.
|
||||
The push preview does not contact a remote. A normal push may run the remote's
|
||||
usual CI or server-side hooks; this is an external effect of the separately
|
||||
authorized push, not of planning or committing.
|
||||
|
||||
Local active hooks (including index-change hooks), filter/encoding attributes,
|
||||
signing, external fsmonitor/SSH configuration, Git environment overrides,
|
||||
in-progress merge/rebase/cherry-pick operations, submodules, symlinks and
|
||||
assume-unchanged/skip-worktree entries, split indexes and replacement/graft
|
||||
history are deliberately
|
||||
unsupported. The helper
|
||||
refuses these cases instead of disabling hooks, signatures or filters. An
|
||||
unused globally installed filter definition alone does not block maintenance;
|
||||
active attributes are checked across tracked files as well as selected files.
|
||||
Custom remote receive-pack/upload-pack/helper commands, recursive submodule
|
||||
pushes and partial-clone lazy fetch are also refused. Of inherited `GIT_*`
|
||||
variables, only `GIT_OPTIONAL_LOCKS`, `GIT_TERMINAL_PROMPT` and `GIT_PAGER` are
|
||||
allowed (every command explicitly passes `--no-pager`, so the pager is inert);
|
||||
namespace, identity, alternate-index/object-directory and unknown overrides
|
||||
are not silently removed. Git subprocesses have bounded input/output and
|
||||
deadlines; cancellation terminates their owned process group, including
|
||||
transport helpers. Network failures can still leave a remote effect uncertain,
|
||||
which is why receipts require explicit reconciliation rather than blind retry.
|
||||
|
||||
An interruption or uncertain failure is recorded before any retry. Use
|
||||
`git reconcile git-PLAN_ID` to preview, then add `--apply` to verify an
|
||||
already-existing result. Reconciliation never makes a commit or push. It may
|
||||
finish the selected real-index update after an interrupted commit publication,
|
||||
but only when the original index fingerprint still matches; independent staged
|
||||
work is preserved and requires normal Git resolution. For an
|
||||
uncertain push it may read the frozen remote, but only with `--apply`. If no
|
||||
planned commit is current, the helper reports that state and requires a fresh
|
||||
plan after inspection. A forcibly killed process may leave its private scratch
|
||||
index or an owned Git index lock; the helper never guesses that an existing
|
||||
lock is safe to delete. Blob/commit preparation can leave unreferenced Git
|
||||
objects for ordinary Git garbage collection. It never automatically resets,
|
||||
restores, deletes, or rolls back user work.
|
||||
|
||||
The maintenance tests use disposable local repositories and local bare remotes.
|
||||
They never commit or push the user's workspace repositories.
|
||||
Reference in New Issue
Block a user