Skip to content

A failed critical task injection leaves the agent running un-briefed — it guesses (observed: fabricated on-call policy) instead of aborting #96

Description

@khaliqgant

Summary

When #sendImplementerTask fails to deliver, factory logs an error and lets the agent proceed anyway on the bare triage task. That task carries the issue body but none of the operational instructions — including the ability to ask a human. The agent then guesses. Observed producing a fabricated on-call policy on an issue that explicitly forbade guessing.

Observed

factory dispatch on AgentWorkforce/relayed#49:

[factory] error {"name":"Error","message":"Critical delivery failed to ar-49-impl-relayed: max delivery retries exceeded","issue":"49"}

Dispatch continued. The implementer ran to completion on spec.task (from triage) and wrote:

# Support Rotation
## Rotation length
One on-call shift lasts **1 week**.
## Escalation contact
When the on-call cannot resolve an incident, page **Khaliq — khaliq@agent-relay.com**.

Both facts invented. The issue said: "neither fact exists anywhere in this repo... Do not guess, do not infer, and do not write a placeholder — a fabricated rotation is worse than no file, because someone will follow it during an incident. If you do not know both facts, ask the maintainer."

The agent had the prohibition (it's in the issue body, which is in the triage task) but not the mechanism ([factory-needs-input], which is only in the injected task). Given a rule it couldn't follow and no way to ask, it invented a policy someone would follow at 3am.

Why the delivery failed (secondary)

Both agents were registered at the time — lastSeen current — but with status: "unknown" and no pid/cli, i.e. registered as names but not yet live as deliverable PTY agents, while ps showed the codex process running. That points at the #50-class cold-start race: codex became deliverable later than INJECTION_MAX_ATTEMPTS = 6 / INJECTION_CONFIRMATION_TIMEOUT_MS = 90_000 allow (factory.ts:172-175).

Worth tuning, but the tuning isn't the bug. The bug is that a failed critical delivery is non-fatal to the dispatch.

The actual defect

#handleDeliveryFailed records the failure and surfaces an error, but nothing stops the agent. So the failure mode is:

  • the agent is alive, working, and confident
  • it is missing every instruction factory meant to give it — PR flow, merge policy, reviewer handoff, and the ask mechanism
  • it produces plausible output that looks like a normal run
  • the only trace is one [factory] error line in the dispatch log

A critical message that cannot be delivered should not leave the agent running as if it had been. Options, roughly in order of preference:

  1. Abort the dispatch for that agent — release it, mark the issue for human attention. A dispatch that couldn't brief its agent hasn't started.
  2. Retry against liveness rather than a fixed budget — wait for the agent to become deliverable (registered and live) instead of 6 attempts / 90s from spawn. The current budget races cold-start on a slow CLI.
  3. At minimum, surface it on the issue/PR rather than only in the log, so a human sees "this agent was never briefed."

Related

Also seen: dirty label state blocks a clean retry

Re-dispatching #49 after the failed run: Error: Live state changed before writeback for 49 — the first run left factory:in-progress on the issue, so a retry aborts until the label is manually stripped. A dispatch that failed to brief its agent should arguably not leave the issue marked in-progress.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    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