Skip to content

Prevent isolated cron announce jobs from repeatedly running when implicit last delivery has no route #78608

@mochiexists

Description

@mochiexists

Summary

Isolated cron agentTurn jobs currently default to delivery.mode="announce", but some jobs can still be created/updated when their implicit delivery target is already known to be unroutable (delivery.channel=last with no previous route).

At runtime, those jobs still execute the agent turn and spend tokens before delivery fails with a delivery-target error. Repeated runs can create a noisy/wasteful failure loop and, in the worst case, destabilize the gateway.

Repro shape

The problematic shape is:

  • sessionTarget: "isolated"
  • payload.kind: "agentTurn"
  • delivery.mode: "announce"
  • no explicit delivery.channel / delivery.to
  • no usable previous route for implicit last

What current code appears to do

Default delivery still creates the footgun

resolveInitialCronDelivery(...) defaults isolated agentTurn jobs to:

{ mode: "announce" }

So isolated jobs opt into announce-by-default even without an explicit target.

Relevant file:

  • src/cron/service/initial-delivery.ts

Preview already knows it will fail closed

resolveCronDeliveryPreview(...) already surfaces this condition with messages like:

  • last -> no route, will fail-closed
  • last -> no route, will fail-closed: ${params.error}

Relevant file:

  • src/cron/delivery-preview.ts

Runtime still spends tokens before failing delivery

In the isolated cron run path, the agent turn can still run before delivery target failure is surfaced.

Current failure looks like:

  • Channel is required when delivery.channel=last has no previous channel.

Relevant files:

  • src/cron/isolated-agent/delivery-target.ts
  • src/cron/isolated-agent/run.ts
  • src/cron/isolated-agent/delivery-dispatch.ts

And delivery-target failure can elevate to:

  • status: "error"
  • errorKind: "delivery-target"

Why this hurts

  • wastes model tokens on runs that were never deliverable
  • repeats on every cron fire
  • creates confusing operator experience because preview already hints that the route is invalid
  • can contribute to failure loops / gateway instability when left running

Suggested direction

Any of these would help; ideally more than one:

  1. Reject unroutable implicit announce jobs at add/update time

    • If preview resolves to last -> no route, will fail-closed, require explicit delivery.channel or an existing route.
  2. Preflight delivery target before model execution

    • For isolated cron runs, if delivery is requested and target resolution is permanently impossible, skip the agent turn and fail early.
  3. Auto-disable after repeated permanent delivery-target failures

    • Treat this as a safety rail so a bad cron job cannot burn tokens forever.

Expected outcome

Cron jobs that are known to have no valid delivery route should fail earlier and more safely, instead of repeatedly running the model and only failing after the expensive part is already done.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions