Skip to content

Make agent terminal outcomes reflect final evidence #434

Description

@shiny-code-bot

Objective

Ensure agent status is derived from correlated semantic terminal evidence rather than the first error notification or child process exit alone. A retryable stream error is runtime degradation, not task failure when the same run/turn later produces TurnCompleted(status=Completed) and an authoritative final message.

Within the same track, expose an additive two-axis model: work outcome (Completed, Failed, Interrupted, Blocked, Abandoned) and runtime health (Healthy, Recovered, Degraded). Keep existing wire status fields compatible while consumers migrate. Treat legacy task_complete only as lifecycle quiescence; it is not proof of success.

Finish Line

Recovered retries complete successfully; true terminal failures remain failures; parent and child status agree.

Current Status

State: Active
Next action: Let the self-hosted chris-testing runner process PR #439's queued blob-size check, then review and merge the PR before continuing the broader additive outcome/health contract work.
Blocked by: PR #439's only GitHub check, Blob size policy, has remained queued on the self-hosted Linux/X64 runner since July 19, 2026 at 02:02 UTC. The equivalent local blob-size command passes for all seven changed files.
Waiting for: Self-hosted runner availability and PR review.
Last verified: July 19, 2026 against commit b8e01bf and current main. Focused tests, adjacent core suites, ./build-fast.sh, and the local blob-size policy all pass; final independent review found no blocker.

Scope

  • In: core session error semantics, app-server will_retry propagation, exec JSONL/human processors, agent completion watchers, parent aggregation, additive TUI/CLI status wording.
  • Out: provider-specific preflight policy, rollout persistence internals, automatic provider switching, unrelated multi-agent UX redesign.

Acceptance Criteria

  • A retryable error with will_retry=true never poisons a later successful terminal outcome.
  • Correlated TurnCompleted(status=Completed) plus the final message produces a successful exec exit and Completed child status.
  • Legacy task_complete alone never promotes a failed or incomplete run to success.
  • Exit 0 without a correlated semantic terminal event is treated as incomplete, not successful.
  • Retry exhaustion, TurnCompleted(status=Failed), or a non-retryable provider error produces Failed with the causal typed error.
  • A matching durable completion receipt can reconcile a transport/process-exit conflict once, while stale, malformed, or mismatched evidence is ignored.
  • Finalized outcomes are immutable; shutdown/cascade cleanup cannot overwrite Completed.
  • A completed run that needed retries is rendered as completed with recovered/degraded health, not failed.
  • Parent summaries distinguish completed, blocked, failed, interrupted, and abandoned children.
  • New structured fields/events are additive so existing JSONL/app-server consumers remain compatible.
  • A focused remediation/backport path for the released v0.6.116 behavior is explicitly assessed and is not blocked on the manager redesign.

Relationships

This will be attached as a sub-issue of the agent reliability parent. Provider preflight classification depends on the outcome/health contract defined here.

Validation

  • Release-line regression: v0.6.116 event sequence that previously emitted a generic error now emits/handles retryable stream semantics and exits 0 after a successful retry.
  • Core/app-server sequence: retryable stream error -> will_retry=true -> TurnCompleted(status=Completed) without poisoning turn summary.
  • Exec controls: retryable error then completed turn succeeds; retryable error without terminal turn fails incomplete; non-retryable error/failed turn remains fatal; unrelated thread error does not fail the primary turn.
  • Agent manager controls: completion watcher ignores retry warnings, shutdown does not overwrite completion, matching completion evidence can reconcile process exit, task_complete alone cannot, stale/mismatched evidence cannot.
  • End-to-end dogfood: child result, exec exit, rollout semantic terminal event, and parent summary all agree after a recoverable stream failure.

Decisions

  • Ship the minimal v0.6.116 retryable-event correction without waiting for manager reconciliation.
  • Terminal outcome comes from correlated typed semantic evidence, never from final-answer text, task_complete alone, or process exit alone.
  • Runtime/provider health is orthogonal to work outcome.
  • A semantic/transport conflict is reconciled only with matching run/thread/turn identity and one idempotent terminalization pass.
  • Keep CompletedWithWarnings out of the public enum; expose Completed plus optional diagnostic metadata.
  • No feature flag; ship one coherent status contract with additive compatibility fields.

Open Questions

  • Whether the released-line fix should be a minimal backport before the full additive status model lands on main.

Metadata

Metadata

Assignees

No one assigned

    Labels

    planDurable planning issueplan:activeCurrent active plan

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions