Skip to content

Epic: Make headless NDJSON lifecycle and usage telemetry reliable #89

Description

@byapparov

Goal

Make headless NDJSON output durable, complete, and semantically explicit across successful runs, provider failures, validation failures, cancellation, and shutdown.

This tracker replaces the original combined diagnosis. The original report identified several valid reliability gaps, but local testing did not reproduce the claim that small fast-failure output is commonly lost by immediate process.exit(): Bun 1.3.10 preserved piped writes through 64 KiB in repeated tests and truncated a 1 MiB immediate-exit write at 64 KiB. Output flushing is still required, but its share of production null telemetry remains unproven.

The live z.ai test also established that thinking mode returns standard OpenAI-shaped usage and is not a source of missing usage.

Workstreams

Explicitly Rejected Assumptions

  • Forced exit is not currently proven to explain the majority of empty production streams.
  • SIGTERM must not automatically be labeled as a timeout.
  • session_start must not be emitted before a real session exists.
  • Tokens must not be blindly accumulated across finish-step events without a reproduction proving that multiple events belong to one assistant message.
  • Missing usage must not be represented as a known zero.

Completion Criteria

  • Every supported headless lifecycle has an explicit event contract.
  • Output accepted by the NDJSON writer is flushed during controlled shutdown.
  • Message terminal events are unique and scoped to the intended session.
  • Reported zero usage is distinguishable from missing or estimated usage.
  • Signals, executor timeouts, and provider idle timeouts have distinct semantics.
  • Contract and real subprocess tests cover the failure paths.

Roadmap Alignment

  • Pillar: EXEC
  • Quarter: Q3 2026
  • Priority: P0
  • Theme fit: Pilot-ready executor reliability and trustworthy execution telemetry.

Upstream OpenCode Prior Art

The aictrl CLI retains behavior inherited from OpenCode, and its backlog contains closely related reports:

In particular, OpenCode #31435 documents an event-ordering race that produces empty JSON independently of stdout flushing. The workstreams in this tracker must keep output transport, event delivery, lifecycle semantics, and usage semantics independently testable.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    Fields

    No fields configured for Task.

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions