Repository navigation
push check: refuse, never throw, when git fails mid-read; read and push by commit id (#981) - #1088
Conversation
…sh the range by commit id (#981) Signed-off-by: Jayden Vasquez <jaydenvasquez1711@gmail.com>
|
Independent final check (R88a), posted by the coordinator. VERDICT: PASS @de6922dc7d9c20d2bb788377c3ce38dd5063dda1 (final check) PR #1088 (issue #981). Reviewed in a detached worktree at the head. The head was re-read with Findings
Follow-ups (not FAILs)
What I ran
|
|
Independent adversarial review (R88b), posted by the coordinator. VERDICT: PASS @de6922dc7d9c20d2bb788377c3ce38dd5063dda1 (adversarial) Findings
What I ran
Follow-ups (not FAILs)
|
|
Weakening scan decision for head The owner's instruction (verbatim): "Stp asking me quesgtions and just take recommended option each time". Applied only because both independent reviewers of this exact head (R88a, R88b) classified every flag as a strengthening or a limit, not a relaxation. The weakening scan of base
Decision: proceed (recommended option). This covers only this head; any new push needs a fresh scan and reviews. |
What changed
src/push-check.ts(the push limits,pushProblemsandcheckedPush):rev-parse --verify --end-of-options <r>^{commit}). Every later call reads those ids, never the names, so a branch moved or deleted between the check's git calls changes nothing it reads.checkedPushpushes the head commit id the limits judged, noto.head's name. On main, a head passed by name that moved after the check was pushed unchecked (measured, test 5 below). Every engine caller passes a commit id today (inferred from reading the callers: each passesrev-parse HEAD,commit-treeoutput or a recorded head). So this closes a route for future callers, not a live leak.Closes #981, for main as it is. See "Not done" for the snapshot half, which depends on #927.
Critical set: yes
This is the push check, under "locks and the tool guard" and the push limits. It also edits two locked tests,
test/push-check.test.tsandtest/push-names-plumbing.test.ts(engine-guards). It needs two independent reviews.One assertion changed in a locked test. In
test/push-names-plumbing.test.ts, the crafted empty-name tree case expectedpushProblemsto throw/empty filename in tree entry/. It now expects exactly one refusal that names that same git error and says nothing is pushed. This tightens the test rather than weakening it: the range is still never judged clean, and the caller now gets a refusal instead of an exception. Reviewers should confirm they agree.Evidence
The new tests live in
test/push-check.test.ts. A git stand-in placed first on PATH makes one change to the repo at a chosen git call, then runs the real git. That makes the race deterministic.diff -U0gives a named refusal ("bad config"), not a throw.checkedPushwith the config broken atrev-list --objectsgives a refusal, and the remote has notaskbranch.rev-list --objectschanges nothing: the refused path is still reported.git push: the checked commit is pushed.Fail-before (measured). I added the tests on unfixed
origin/main(d5650da) src, then rannpx tsc -p tsconfig.json && node --import ./dist/test/isolate.js --test --test-timeout=180000 dist/test/push-check.test.js. Result: tests 20, pass 15, fail 5. The 5 failures are exactly the new tests:fatal: bad config line 14 in file .git/config;execFileSync;fatal: ambiguous argument '<base>..topic': unknown revision;Pass-after (measured). Same commands at this head:
push-checkpush-names-plumbingpush-skill-linkspush-skill-nameschange-files-renamespush-guardOther checks (measured):
npm run typecheck: clean.npm run check:denylist: 1658 files clean.changelog.test.js: 27/27.flock /var/tmp/wl-coord/fulltest.lock nice -n 15 ionice -c3 npm test, run once at de6922d): 5845 tests, 5552 pass, 134 fail, 119 skipped, 40 todo./var/tmpparent the signer refuses,EINVALon chown, the sandbox's pip and proxy variables, and thenode_modulessymlink.merge-vacuity-r6, one of the failing files, passes 11/11 alone at this head, and 11/11 with main'ssrc/push-check.ts(measured).Not done
gitSnapshot. git: one runner for every engine git call, with replace refs and grafts off (#807) [PROTECTED: owner merges] #927 is still open, and it is not on main. This PR doesn't stack on it. When git: one runner for every engine git call, with replace refs and grafts off (#807) [PROTECTED: owner merges] #927 lands, its push-check hunks will conflict with this PR's. They compose like this (inferred):commitIdsand itsrangeNames/blobsByNamecalls run inside this boundary, so a throw there becomes a refusal too. git: one runner for every engine git call, with replace refs and grafts off (#807) [PROTECTED: owner merges] #927's owncommitIdscomment says it "Throws as git does on a bad name", which is one of the throw sites push check: refuse, never throw, when the repo changes between git calls #981 names.shallowCutbefore the push needs the same boundary. Without it, that call can still throw.sizeFileswith renames set to "configured") readsdiff.renamesfrom the repo's config on its own call. A config flipped (not broken) between calls changes the line count without any error. Pinning it means reading the config once, or reading it through the snapshot. That is git: one runner for every engine git call, with replace refs and grafts off (#807) [PROTECTED: owner merges] #927's design; this PR only makes a broken config refuse.Follow-ups noticed for #966 (not done here; not this PR's issue)
^{commit}makes a tree end of the range a refusal: "expected commit type, but the object dereferences to tree type" (measured: built dist at this head, thenpushProblems(repo, base, '<head>^{tree} id', DEFAULT_PUSH_LIMITS)in a scratch repo). This PR adds no test for it. push check: refuse a non-commit range end; glob ? and astral characters; NFC/NFD #966's builder should add its test with a tree head, then confirm and close that item. The refusal's last sentence ("if something changed the repository...") doesn't fit that case. push check: refuse a non-commit range end; glob ? and astral characters; NFC/NFD #966 may want its own wording.?with astral characters, and NFC/NFD) are untouched.