Skip to content

Make run status authoritative, bounded, and read-only #1145

Closed

Description

@aviggiano

Suggested labels: bug, priority:P0, cli, state-machine

Problem

A dead controller can leave a run marked running. Different persisted sources can describe the same workflow as finished, succeeded, and failed. The status command can hang and may update state or accounting timestamps while inspecting the run.

Generic reproduction

  1. Kill a detached controller without a clean shutdown.
  2. Wait for its lease to expire.
  3. Run ultrafuzz status <run-id> repeatedly.
  4. Compare output and file hashes before and after inspection.

Expected behavior

Status returns quickly without mutation. Reconciliation is explicit and results in one coherent state.

Proposed fix

  • Separate status from reconcile.
  • Add bounded gateway and lock timeouts.
  • Define one authoritative transition table.
  • Reconcile an expired controller lease to interrupted or another explicit state.
  • Atomically clear controller leases at terminal transition.

Acceptance criteria

  • Status completes within a documented bound.
  • Repeated status calls do not alter run-file hashes.
  • A dead controller cannot leave an indefinitely running state.
  • Workflow, event, lease, and CLI state agree after explicit reconciliation.

This issue intentionally omits the audited repository and all audit results.

Activity

  1. added
    bugSomething isn't working
    In ProgressClaimed and actively worked on; has an assignee. Remove if work stops.
    on Sep 25, 2026
  2. aviggiano commented on Sep 29, 2026

    @aviggiano
    CollaboratorAuthor

    Resolved by #1180.

    • Bounded: read-only runner queries time out after 120 s by default (ULTRAFUZZ_RUNNER_QUERY_TIMEOUT_MS, capped at 600 s), and a timeout becomes a diagnostic instead of a hang.
    • No mutation on observation: a projection whose only changes are the controller-lease and concurrency clocks no longer rewrites state.json for status or for a finished run.
    • One writer: synchronizations take a non-blocking per-run lock; a pass that finds another in progress reports WORKFLOW_SYNC_IN_PROGRESS and writes nothing, so observers never race.
    • Non-fatal: status reports the runner's health even when synchronization fails.
    • Dead controller: the orphan hint now says ultrafuzz resume <run-id>. Verified on a real campaign: after SIGKILLing the engine and supervisor, status reported orphaned with that hint within ~50 s, and ultrafuzz resume recovered the run.

    Kept by design: status still pumps synchronization. It is the only process that advances state.json and enforces workflow_deadline_seconds (#1110), so a read-only status would make both worse.

  3. aviggiano commented on Oct 15, 2026

    @aviggiano
    CollaboratorAuthor

    Post-closure repository-neutral observation from UltraFuzz v0.1.4:

    • A single-run status request over a detached exhaustive run with keep_workspaces = true and roughly 8.1 GB of retained workspaces took about 80 minutes.
    • The workflow itself remained healthy during that time; direct read-only workflow-database queries returned current counts and heartbeat information immediately.
    • This made the supported product-level monitoring path impractical during recovery, even though the underlying health data was small.

    The current unstable code has bounded observe-only synchronization, so this may already be fixed after the release. Please retain a regression fixture with large retained workspaces and assert that status latency is independent of workspace byte size/file count, or that the documented observation deadline returns runner health with a stale-local-state warning.

    This was a P2 monitoring roadblock rather than a run-ending failure because a lower-level read-only workaround existed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    In ProgressClaimed and actively worked on; has an assignee. Remove if work stops.P2Real but moderatebugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions