Disciplines · Audits

Eve SOTA operator fleet read model — eve.fleet-read.v1

One restrained, scannable answer to "what is the fleet doing, and what needs me?": a fixed ten-section view that leads with a capped, severity-ordered attention list, answers every facet task 2.5 names from rows and events read in

6sections5 minread

On this page
  • Task: 2.5
  • Evaluated: 2026-09-05
  • Decision: operator-read-model-exposed
  • ADR gate: operator-read-model (docs/adr/ADR-0076-eve-governed-delivery-lifecycle.md)
  • Tool: admin_agent_fleet, registered by buildWorkbenchReadOnlyToolBindings
  • Record digest: c886a4f5fb1d57398d5df731f96a3f6cf7fec7cd233db0a3d37d2dda82285a14

The rule#

One restrained, scannable answer to "what is the fleet doing, and what needs me?": a fixed ten-section view that leads with a capped, severity-ordered attention list, answers every facet task 2.5 names from rows and events read in a single snapshot, reports a measurement this plane does not carry as an explicit absence rather than a zero, and grants no authority over anything it describes.

The sections are read from the module and must equal the view type’s own keys; every facet names a field path resolved by parsing the FleetView interface and a spec title found in the spec sources; the tool’s read-only registration is located by slicing the two builders out of the tools module.

What the task asks for, and where it is answered#

Facet Answered at Proved by
queue/dependency depth queue.ready, queue.blockedByDependency, queue.dependencyDepth "counts the chain of declared dependencies, not the number of them"; "counts only the ready items still waiting on an unverified dependency"; "reports the fleet this spec actually built, not a fixture"
leases/ages/owners leases.live, leases.expired, leases.oldestLiveAgeSeconds, leases.owners "separates live holds from lapsed ones and names the owners"
triage triage.total, triage.byClass, triage.byDisposition, triage.needingHumanDecision "counts triage by class and by disposition, and finds the latest"; "counts real triage records and finds the drain that wrote them"
last drain lastDrain.runRef, lastDrain.at, lastDrain.itemsTriaged "derives the last drain from the run reference the drain stamps, taking the newest"; "reports no drain seen rather than inventing one"
throughput outcomes.windowSeconds, outcomes.shipped, outcomes.verified "counts only what happened inside the window"; "defaults the window to a week"
cost cost.configured, cost.reason "reports cost as unconfigured rather than zero"; "never reports cost as zero, because this plane records no spend"
intervention intervention.humanActs, intervention.machineActs, intervention.humanShare "measures how much of the window a human had to act in"
verification rate outcomes.verifiedPerShipped, outcomes.gapsPerShipped, outcomes.shipVerifyGaps "computes verified and gap rates against what actually shipped"; "reports a rate over zero shipped items as null, not as zero"
rollback rate outcomes.rollback.observedBackwardMoves, outcomes.rollback.reopenPerShipped, outcomes.rollback.postShipRate.configured, outcomes.rollback.irreversibleAfterShip.transitionId "refuses to report a post-ship rollback rate, and says why in the machine's own words"; "counts the backward edges that were actually taken, and zeroes the ones that were not"; "counts a real backward move, and still refuses a post-ship rollback rate"
kill-switch state killSwitch.engaged, killSwitch.source, killSwitch.reason "passes the engaged state and the operator's reason straight through"; "shows the kill switch engaged, and the admission door then refuses everything"; "reads the switch fail-safe: a value it does not understand halts the fleet"
trace links trace.ledgerEvents, trace.ledgerEventsInWindow, trace.links.locator "names where every number came from, and counts the ledger it read"; "separates the whole ledger from the part inside the window"

All 11 facets resolve to a field the FleetView type actually declares — the paths are checked against the parsed interface, not against a hopeful string — and each is asserted by a named spec case.

What it refuses to make up#

Absence Field Proved by
cost cost.configured "reports cost as unconfigured rather than zero"
post-ship-rollback-rate outcomes.rollback.postShipRate.configured "refuses to report a post-ship rollback rate, and says why in the machine's own words"
rate-over-zero-shipped outcomes.verifiedPerShipped "reports a rate over zero shipped items as null, not as zero"
empty-queue-and-lease-age queue.oldestWaitSeconds "reports an empty queue age and lease age as null, not as zero seconds"
no-drain-seen lastDrain.runRef "reports no drain seen rather than inventing one"

Restraint#

  • Sections (10, fixed): attention, queue, leases, triage, lastDrain, outcomes, intervention, cost, killSwitch, trace
  • Attention leads the view: true
  • Attention is capped at 8: true
  • Attention is severity-ordered (halted > blocked > stalled > watch): true
  • The section list equals the view type's own keys: true

Authority#

  • Registered by buildWorkbenchReadOnlyToolBindings: true
  • Absent from buildWorkbenchAgentToolBindings: true
  • Registration sites in the tools module: 2, of which 0 are outside the read-only builder
  • The kill switch arrives as an input, so the view reports it and cannot press it: true
  • The model imports only its own siblings: true
  • It takes the store as a type and never as a value: true
  • The binding reads one MVCC snapshot: true
  • The switch falls through ENGAGED; only 0, false, off, no release it, so a typo halts rather than opens: true

Honest limits#

  • This record closes task 2.5 only. It adds no execution isolation (2.6), no provider-free orchestrator model or parity proof (2.7), and no live drain or soak result (2.8).
  • The surface is a tool binding returning a value. There is no operator UI: "restrained and scannable" is enforced as a fixed section set, a capped severity-ordered attention list, and a section order that leads with attention — not as a rendered layout anyone has looked at.
  • Cost is reported as an explicit absence because no lease, report, ship, or verify event on this plane carries a token, provider, or price. Making it a number is task 2.8 and the model-cost registry, not this surface.
  • A post-ship rollback rate does not exist because the work-item machine declares ship and verify irreversible. If a rollback transition is ever added, the section reports it without an edit here — but until then the honest answer is an absence, not a zero.
  • The last drain is derived from the run reference the drain stamps on triage records. A drain whose every item advanced writes no triage and therefore leaves no trace on this plane, which reads as "no drain seen" rather than "no drain ran".
  • Throughput, intervention and verification counts are computed over a caller-chosen window bounded to between an hour and thirty days. Nothing here retains history: the numbers are recomputed from the ledger on every call, so a ledger compaction would change them.
  • The kill switch is read from the process environment of whoever calls the tool. It halts acquisition through the queue admission door; it does not reach into a drain already running in another process, which is that drain’s own bounded supervision from task 2.3.