-
-
Notifications
You must be signed in to change notification settings - Fork 80.7k
RFC: opt-in cron.jobs[].notifyOnCompletion for parent wake after isolated cron run #96190
Copy link
Copy link
Open
Labels
P2Normal backlog priority with limited blast radius.Normal backlog priority with limited blast radius.clawsweeper:needs-maintainer-reviewClawSweeper marked this issue as needing maintainer review before automation.ClawSweeper marked this issue as needing maintainer review before automation.clawsweeper:needs-product-decisionClawSweeper marked this issue as needing a product or behavior decision.ClawSweeper marked this issue as needing a product or behavior decision.clawsweeper:no-new-fix-prClawSweeper does not recommend queueing a new automated fix PR for this issue.ClawSweeper does not recommend queueing a new automated fix PR for this issue.clawsweeper:source-reproClawSweeper found a high-confidence source-level issue reproduction.ClawSweeper found a high-confidence source-level issue reproduction.impact:message-lossChannel message delivery can be lost, duplicated, or misrouted.Channel message delivery can be lost, duplicated, or misrouted.impact:session-stateSession, memory, transcript, context, or agent state can drift or corrupt.Session, memory, transcript, context, or agent state can drift or corrupt.issue-rating: 🦞 diamond lobsterVery strong issue quality with high-confidence source-level or clear reproduction.Very strong issue quality with high-confidence source-level or clear reproduction.
Description
Metadata
Metadata
Assignees
Labels
P2Normal backlog priority with limited blast radius.Normal backlog priority with limited blast radius.clawsweeper:needs-maintainer-reviewClawSweeper marked this issue as needing maintainer review before automation.ClawSweeper marked this issue as needing maintainer review before automation.clawsweeper:needs-product-decisionClawSweeper marked this issue as needing a product or behavior decision.ClawSweeper marked this issue as needing a product or behavior decision.clawsweeper:no-new-fix-prClawSweeper does not recommend queueing a new automated fix PR for this issue.ClawSweeper does not recommend queueing a new automated fix PR for this issue.clawsweeper:source-reproClawSweeper found a high-confidence source-level issue reproduction.ClawSweeper found a high-confidence source-level issue reproduction.impact:message-lossChannel message delivery can be lost, duplicated, or misrouted.Channel message delivery can be lost, duplicated, or misrouted.impact:session-stateSession, memory, transcript, context, or agent state can drift or corrupt.Session, memory, transcript, context, or agent state can drift or corrupt.issue-rating: 🦞 diamond lobsterVery strong issue quality with high-confidence source-level or clear reproduction.Very strong issue quality with high-confidence source-level or clear reproduction.
Type
Fields
Priority
None yet
Summary
This is an RFC (no PR attached) to surface a fourth silent-drop path from the #89095 cluster as a product decision, not a bug fix. ClawSweeper has held back the same scope on #90178 ("adding retry/expiry config knobs ... is a separate maintainer/product decision"), so this issue exists to give that decision a structured place to land independently of the wait-layer + no-output-payload fixes in #96189, #91370, and #95080.
The path
Parent session calls a yielding tool that ultimately spawns an isolated cron run (`executeDetachedCronJob` in `src/gateway/server-methods/server-cron-*.ts`). The cron runs to completion successfully — the cron registry records a clean terminal outcome — but the parent waiting via `sessions_yield` is never resumed, because isolated cron runs are intentionally decoupled from any parent session's completion delivery path.
This is not a bug in the way RC1–RC3 are bugs: the decoupling is intentional. Isolated crons are not supposed to push completion events to arbitrary parent sessions; that would create a many-to-many wakeup graph the cron runtime has explicitly avoided.
But for the narrow case where a parent explicitly opted in to wait for a specific cron run's completion (because the surface that spawned the cron was thread-bound), the current behavior is indistinguishable from RC1/RC2 from the user's perspective: the parent hangs forever.
Proposed surface (Path B)
Opt-in per cron job:
```yaml
cron:
jobs:
- id: nightly-distillation
schedule: "30 23 * * *"
task: ...
notifyOnCompletion: true # opt-in; default false
```
Or per-spawn for ad-hoc detached cron runs:
```ts
spawnCron({
jobId: "...",
notifyOnCompletion: true,
notifyTarget: { sessionKey: "..." }, // explicit; no implicit "parent" fan-out
});
```
When set, `executeDetachedCronJob` queues a bounded completion event into the named target session at terminal time, with the same shape as the synth notice landing in #96189:
Default is false — no behavior change for any existing cron job.
Why opt-in, not always-on
Alternatives considered
Path A: implicit wake based on "the spawning session was thread-bound at spawn time." Rejected because (a) it conflates two different contracts (cron lifetime vs. parent-session lifetime), (b) thread-bound spawn sites are not always parent-session-bound, and (c) it would require persisting the parent-session reference inside the cron registry, which the cron runtime has otherwise avoided.
Path C: leave it alone and document that yielded waits on cron must time out. Rejected because the empirical behavior is identical to RC1/RC2 — "yield then nothing forever" — and users will keep filing the same bug report against the cron surface.
Scope of this RFC
This issue is for the product decision and the API surface, not the implementation. If the decision is "ship Path B," a follow-up PR can implement it; if the decision is "don't ship," please document the explicit non-goal so future similar reports can be triaged faster.
Linked context
cc @clawsweeper for triage routing.