Two ship children asked to "send me screenshots" (nominal#3537, run 55c2a001; polylanedotcom#382, run 93a175a0; 2026-09-20) posted the PNGs to the Slack thread and the run page only. Their handoff deviations cite the push guard.
Root cause: the coding prompt mandates a destination the tool rules forbid. src/agents/registry.ts:221 (SHOW_FILES, in both coding prompts; agent-coding.md item 10 "destination rule") says: commit the images to an assets branch (never the PR's own diff) and reference them from the description or a PR comment. src/core/harness/pi/toolRules.ts:263–266 judgePush refuses, for a run with a bound branch (every ship child, on branch <unit branch> via spawn.ts:211), any refspec other than ctx.branch: repo:use — push to X, not the run's branch. Evidence: 55c2a001 seq 317–320 tool_refused … assets/badge-version-8; 93a175a0 finding at eventIndex 268 assets/pricing-estimate-buttons refused.
The alternatives are closed too: the run-page artifact proxy (/runs/:id/artifacts/<key>, live-view.md item 26) needs the live ?t= token or an Access actor, so GitHub's camo cannot fetch it; GitHub has no API for user-attachment uploads; github_issue_comment can only reference a URL. So no working path exists, and agent-coding.md's e2e criterion at line 69 is [agent]-class and has never been proven. The vendored skills/pr-description/SKILL.md carries no visual-change screenshot criterion; that rule lives only in the operator's validation rules.
Design flaws. (4) Prompt vs grant contradiction — invariant: no prompt demands a write the tool rules refuse; one spec owns both (agent-coding.md item 10 vs toolRules.ts; authorization.md:128 lists the push target as an open row). (5) No PR-renderable file address — invariant: a produced file has one durable address a PR body can embed (a public artifact URL, or a GitHub-native upload) — live-view item 26, record 0033.
Fix direction (a design decision, not a patch): pick the one destination (a public, token-free artifact URL per produced file is the smallest change that also serves #2102's inbound catalogue), make the prompt say only that, delete the assets-branch sentence, and prove the e2e criterion with one live PR. Related: #2102 (inbound half of the same boundary), #1950, #908.
Two ship children asked to "send me screenshots" (nominal#3537, run 55c2a001; polylanedotcom#382, run 93a175a0; 2026-09-20) posted the PNGs to the Slack thread and the run page only. Their handoff deviations cite the push guard.
Root cause: the coding prompt mandates a destination the tool rules forbid.
src/agents/registry.ts:221(SHOW_FILES, in both coding prompts; agent-coding.md item 10 "destination rule") says: commit the images to an assets branch (never the PR's own diff) and reference them from the description or a PR comment.src/core/harness/pi/toolRules.ts:263–266judgePushrefuses, for a run with a bound branch (every ship child,on branch <unit branch>via spawn.ts:211), any refspec other thanctx.branch:repo:use — push to X, not the run's branch. Evidence: 55c2a001 seq 317–320tool_refused … assets/badge-version-8; 93a175a0 finding at eventIndex 268assets/pricing-estimate-buttonsrefused.The alternatives are closed too: the run-page artifact proxy (
/runs/:id/artifacts/<key>, live-view.md item 26) needs the live?t=token or an Access actor, so GitHub's camo cannot fetch it; GitHub has no API for user-attachment uploads;github_issue_commentcan only reference a URL. So no working path exists, and agent-coding.md's e2e criterion at line 69 is[agent]-class and has never been proven. The vendoredskills/pr-description/SKILL.mdcarries no visual-change screenshot criterion; that rule lives only in the operator's validation rules.Design flaws. (4) Prompt vs grant contradiction — invariant: no prompt demands a write the tool rules refuse; one spec owns both (agent-coding.md item 10 vs toolRules.ts; authorization.md:128 lists the push target as an open row). (5) No PR-renderable file address — invariant: a produced file has one durable address a PR body can embed (a public artifact URL, or a GitHub-native upload) — live-view item 26, record 0033.
Fix direction (a design decision, not a patch): pick the one destination (a public, token-free artifact URL per produced file is the smallest change that also serves #2102's inbound catalogue), make the prompt say only that, delete the assets-branch sentence, and prove the e2e criterion with one live PR. Related: #2102 (inbound half of the same boundary), #1950, #908.