You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
A single failed PR-snapshot read at PR-open time permanently orphans that PR from the babysitter. There is no retry, no dead-letter, and no recovery path — and every subsequent event for that PR is silently discarded. Both log lines involved are debug level, so at normal log level the babysitter fails completely silently.
The mechanism
1. PR opens.#handlePrChange (src/orchestrator/factory.ts:10526) is the only path that spawns a babysitter. It reads the PR meta through the relayfile mount:
snapshot=parsePullSnapshot((awaitthis.#mount.readFile(path)).content,parts.number)}catch(error){this.#logger.debug?.('[factory] babysitter could not read PR snapshot',{ path,error: ... })return// ← gives up permanently. no retry, no dead-letter, no queue}
That read is failing in production — "error":"fetch failed" — 364 occurrences in the current log, still recurring:
[factory] babysitter could not read PR snapshot {"path":".../relaycast/pulls/329.../meta.json","error":"fetch failed"}
[factory] babysitter could not read PR snapshot {"path":".../relaycast-cloud/pulls/62.../meta.json","error":"fetch failed"}
2. No spawn means no owner.#babysitterOwnerFor (:10074) resolves an owner by scanning this.#babysitterPr for an entry whose ref.agentName matches the PR. No spawn → no entry → undefined.
3. Every later event is dropped.#routeBabysitterEvent (:10050):
constowner=awaitthis.#babysitterOwnerFor(`${event.owner}/${event.repo}`,target.prNumber)if(!owner){this.#increment('babysitterEventsIgnoredUnownedPr')this.#logger.debug?.('[factory] ignored unowned PR event for babysitter routing',{...})continue// ← reviews, comments, CI results, conflict state — all discarded}
111 occurrences in the current log. Note these are the downstream symptom of step 1, not an independent problem — "unowned" means no babysitter agent was ever registered for that PR, and has nothing to do with PR authorship.
Observed impact
AgentWorkforce/cloud#3024 was opened 2026-08-14T13:41:34Z by app/agent-relay-code (a Factory-created PR, from the cloud#3021 dispatch) and is CONFLICTING / mergeStateStatus: dirty. Factory's log contains zero events for PR 3024. It was never routed, never babysat, and its conflict has gone unattended.
Resolving conflicts is explicitly the babysitter's job — src/config/schema.ts:278 describes it as continuing to work a PR "addressing review comments, resolving conflicts, and fixing CI". The capability exists; the PR simply never reaches it.
Asked-for behaviour
Retry the PR-open snapshot read. A transient mount/fetch failure must not permanently decide that a PR is unshepherded. Retry with backoff, and on exhaustion dead-letter it visibly.
Raise the log level.could not read PR snapshot and ignored unowned PR event are both logger.debug?.. A PR silently losing its shepherd is not debug-level information; at minimum the first should be warn, and repeated occurrences should escalate.
Surface the counters.babysitterEventsIgnoredUnownedPr and babysitterFlatEventsUnreadable are already incremented — expose them where an operator will see them.
Definition of done
A PR whose open-event snapshot read fails is retried and still gets a babysitter.
An already-open Factory PR with no babysitter owner is adopted by a reconcile sweep. Verify against cloud#3024, which is currently in exactly this state.
These failures are visible at default log level.
Regression test: fail the snapshot read once, assert the babysitter is still spawned; leave a PR ownerless, assert the sweep adopts it.
Constraints
Branch from origin/main. The local checkout sits on codex/222-routed-pr-babysitter-v2 with an unrelated WIP commit (b2ad725) — do not build on it and do not disturb it.
mergePolicy: never. Open the PR and stop at review.
Summary
A single failed PR-snapshot read at PR-open time permanently orphans that PR from the babysitter. There is no retry, no dead-letter, and no recovery path — and every subsequent event for that PR is silently discarded. Both log lines involved are
debuglevel, so at normal log level the babysitter fails completely silently.The mechanism
1. PR opens.
#handlePrChange(src/orchestrator/factory.ts:10526) is the only path that spawns a babysitter. It reads the PR meta through the relayfile mount:That read is failing in production —
"error":"fetch failed"— 364 occurrences in the current log, still recurring:2. No spawn means no owner.
#babysitterOwnerFor(:10074) resolves an owner by scanningthis.#babysitterPrfor an entry whoseref.agentNamematches the PR. No spawn → no entry →undefined.3. Every later event is dropped.
#routeBabysitterEvent(:10050):111 occurrences in the current log. Note these are the downstream symptom of step 1, not an independent problem — "unowned" means no babysitter agent was ever registered for that PR, and has nothing to do with PR authorship.
Observed impact
AgentWorkforce/cloud#3024was opened2026-08-14T13:41:34Zbyapp/agent-relay-code(a Factory-created PR, from thecloud#3021dispatch) and isCONFLICTING/mergeStateStatus: dirty. Factory's log contains zero events for PR 3024. It was never routed, never babysat, and its conflict has gone unattended.Resolving conflicts is explicitly the babysitter's job —
src/config/schema.ts:278describes it as continuing to work a PR "addressing review comments, resolving conflicts, and fixing CI". The capability exists; the PR simply never reaches it.Asked-for behaviour
could not read PR snapshotandignored unowned PR eventare bothlogger.debug?.. A PR silently losing its shepherd is not debug-level information; at minimum the first should bewarn, and repeated occurrences should escalate.babysitterEventsIgnoredUnownedPrandbabysitterFlatEventsUnreadableare already incremented — expose them where an operator will see them.Definition of done
cloud#3024, which is currently in exactly this state.Constraints
origin/main. The local checkout sits oncodex/222-routed-pr-babysitter-v2with an unrelated WIP commit (b2ad725) — do not build on it and do not disturb it.mergePolicy: never. Open the PR and stop at review.