fix(babysitter): ignore executable bits the sandbox's filesystem dropped

Merged
KH
1mo ago
+362-199

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-6 fixed exactly the reviewed defect (a RangeError on a bad attempts, 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)

  • checkoutHead records core.fileMode=false in the fresh checkout's config, so the agent's git status and the merge step (git -C <checkout>) are clean.
  • proposeChanges sets core.fileMode=false in 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, give files: ['src/retry.ts'].
  • fixer.test.ts: "a checkout whose filesystem dropped executable bits reads as clean". After checkoutHead, a chmodded executable gives an empty git status --porcelain.

Evidence (examples/babysitter/evidence/p2-task-modes/)

  • 09-filemode-mutation.txt, from the committed scripts/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 false in the checkout) fails the clean-status test.
    • After each mutation, fix.ts is restored with git restore --source=HEAD, and its sha256 matches the original, 47b09cd1….
  • 02-all-babysitter-green.txt: 176 tests, 169 pass / 0 fail / 7 todo.
  • 03-artifact-check.txt: fixer fe9f2512….

🤖 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.


View with [code]smith Autofix with [code]smith
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.

  • checkoutHead records core.fileMode=false in the fresh checkout, so the agent's git status and the merge step are clean.
  • proposeChanges sets core.fileMode=false in 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

  • claude session 497569fc · opened via gh pr create · last active 2026-10-10
  • claude session 5863fddb · contributor · ran gh pr commands · last active 2026-10-10