Skip to content

instance_runtime_status.runtime publishes a raw status and blends two machines — #570's fix reached nodes[] only #587

Description

@serge-ivo

instance_runtime_status.runtime reports an offline machine as online, and is a composite of two machines

Measured live 2026-08-15 across 22 instances with capabilities.runtime != null (82 node rows).

Two instances state a falsehood inside a single response

12ebf1f0 (Coder Home) and 6d2d9401 (Facebook Friends):

field value
runtime.runnerNode RLs-MacBook-Air.local
runtime.status online
runtime.lastSeenAt 2026-08-15 10:11:58
runtime.runnerVersion 0.4.51, capabilities include coding.repo-write
nodes[] same node offline, lastSeenAt 2026-08-14 23:36:0410h36m stale
only live node Sergeys-Mac-mini.local, 0.4.45, no coding.repo-write

nodes[] is correct.

Mechanism, traced

  • workers/api/src/routes/instances.ts:433runtime: runtimeResponse(runtime), nodes: nodes.map(runtimeNodeResponse).
  • workers/api/src/lib/runtime-response.ts:26runtimeResponse publishes status: row.status raw. :63-71runtimeNodeResponse applies the 90s heartbeatFresh derivation. fcfbce0 (instance_runtime_nodes.status is a write-once "online" column — every machine an instance has ever seen reports online forever, including one last seen four days ago #570) fixed only the second.
  • updateRuntimeStatus (routes/instances-runtime.ts): the node UPDATE is filtered AND runner_node = ?4; the instance_runtimes UPDATE is WHERE instance_id = ?2 AND user_id = ?3no node filter. So the Mac mini's heartbeat (instances.ts:549) refreshes the shared row's status/last_seen_at while runner_node, runner_version and capabilities keep the last registrant's values.

The row is therefore not stale — it is two machines blended: one machine's liveness under another machine's identity and capability list.

Scope

runtime-response.ts:38-52 already documents this exact bug class. It was applied to one of the two functions it describes.

Why this misleads a user into a wrong action

This is the field an owner reads to decide whether to run pags up. It currently says the machine with coding.repo-write is online when that machine has been gone for ten hours and the live one cannot write to repos. A run dispatched on that basis fails for a reason the status screen denies.

Acceptance criteria

  1. runtimeResponse derives status from heartbeat freshness, as runtimeNodeResponse does. Neither may publish a stored status raw.
  2. runtime stops blending machines: either it is scoped to one node, or the field set it publishes comes from the same row its lastSeenAt does. State which, and why.
  3. probe:true is at least as truthful as the un-probed call. A path that skips a correctness derivation in the name of thoroughness is the defect, not a shortcut.
  4. A guard asserts every runtime-status publisher applies the derivation — denominator stated per ADR 0002 (the number of publishers found, not a hand-listed pair). instance_runtime_nodes.status is a write-once "online" column — every machine an instance has ever seen reports online forever, including one last seen four days ago #570's fix passing while this one survived is exactly what a per-function test cannot catch.
  5. Red demonstrated on today's code for the 2-of-22 case.

Verified vs inferred

  • Verified: all values above read live; every file:line; the two UPDATE statements and their differing WHERE clauses; the 22/22 and 7/22 counts.
  • Inferred: nothing load-bearing. The blend is read directly off the two SQL statements.

Activity

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

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions