fix(babysitter): ignore executable bits the sandbox's filesystem dropped
Live run #2 of the Babysitter fixer (Cloud run ba91b3b1-aaff-5242-b390-d4782587fc98, AgentWorkforce/cloud-e2e-sandbox#49, fixer f107bcf9) got past the EACCES that stopped run #1 (#646):
- it woke 30 s after the push;
- all 11 steps succeeded;
agent-6fixed exactly the reviewed defect (aRangeErroron a badattempts, plus a test).
But publication failed closed:
Relayflow v2 run parked and needs human recovery: Flow "Babysitter fixer" needs_human; … Babysitter proposal refused: changes 63 files; at most 50
Cause: the sandbox checkout loses executable bits. cloud-e2e-sandbox has exactly 61 files at mode 100755 at the PR head (git/trees/b232680e?recursive=1), and 61 plus the 2 files the agent edited = 63. Every executable read as a mode change. The agent's own initial git status showed the same: "All other listed modifications were already present in the working tree before I started".
Change (examples/babysitter/fix.ts)
checkoutHeadrecordscore.fileMode=falsein the fresh checkout's config, so the agent'sgit statusand the merge step (git -C <checkout>) are clean.proposeChangessetscore.fileMode=falsein its private git dir's environment. It never reads the checkout's config (#646), so a lost mode never reaches a proposal.
A mode the agent itself sets is now ignored too. The publisher (buildCommitOperations) never applied mode changes anyway.
New fixer digest: fe9f2512421fdbeac327e360db078c2a33c2d3542590382807b75b65a666e4eb. Diagnose is unchanged at 580bab1d…. Cloud's pin needs a one-line follow-up.
Tests
task.test.ts: "a checkout whose filesystem dropped executable bits proposes only the real edits". Two executables committed at 755 and chmodded to 644 in the checkout, plus one real edit, givefiles: ['src/retry.ts'].fixer.test.ts: "a checkout whose filesystem dropped executable bits reads as clean". AftercheckoutHead, a chmodded executable gives an emptygit status --porcelain.
Evidence (examples/babysitter/evidence/p2-task-modes/)
09-filemode-mutation.txt, from the committedscripts/filemode-mutation.sh, run verbatim:- M1 (no fileMode in the private git dir) fails exactly like the live run:
actual: [ 'scripts/a.sh', 'scripts/b.sh', 'src/retry.ts' ]. - M2 (no
git config core.fileMode falsein the checkout) fails the clean-status test. - After each mutation,
fix.tsis restored withgit restore --source=HEAD, and its sha256 matches the original,47b09cd1….
- M1 (no fileMode in the private git dir) fails exactly like the live run:
02-all-babysitter-green.txt: 176 tests, 169 pass / 0 fail / 7 todo.03-artifact-check.txt: fixerfe9f2512….
🤖 Generated with Claude Code
[!NOTE]
Low Risk
Narrows proposal diffs by ignoring file-mode noise in checkout and proposal git; content changes are unchanged and modes were not published anyway.
Overview
Fixes Babysitter fixer runs that were refused for “changes 63 files” when the sandbox checkout lost executable bits on tracked scripts—only a couple of real edits were intended.
Checkout (checkoutHead) now sets core.fileMode=false on the fresh repo after init, so git status stays clean for the agent when the filesystem no longer matches index modes.
Proposal (proposeChanges) adds the same setting to the isolated private git environment (alongside existing hooks/quotePath overrides), so mode-only diffs are not counted toward the patch file list or caps.
The shipped babysitter-fixer artifact and manifest digest are updated (fe9f2512…). New tests simulate chmod 755→644 on executables; mutation evidence (filemode-mutation.sh) shows each half of the fix is required.
Reviewed by Cursor Bugbot for commit 9a46d05c8164a19195a7d6d1cf2ba3b4d2da2a53. Bugbot is set up for automated code reviews on this repo. Configure here.
Need help on this PR? Tag @codesmith-bot with what you need. Autofix is disabled.
Summary by cubic
Fixes Babysitter proposals tripping the 50-file cap when the sandbox checkout loses executable bits, because every executable read as changed.
checkoutHeadrecordscore.fileMode=falsein the fresh checkout, so the agent'sgit statusand the merge step are clean.proposeChangessetscore.fileMode=falsein its private git dir, so a lost mode never reaches a proposal; a mode the agent sets is ignored too, and the publisher never applied modes anyway.- Adds tests covering both paths and mutation evidence showing each failure mode before the fix.
Agent Relay sessions