Skip to content

Let the run-liveness watchdog see Witnessed Runs, not just Conducted ones - #704

Merged
xmap merged 1 commit into
mainfrom
fix/liveness-sees-witnessed-runs
Aug 21, 2026
Merged

Let the run-liveness watchdog see Witnessed Runs, not just Conducted ones#704
xmap merged 1 commit into
mainfrom
fix/liveness-sees-witnessed-runs

Conversation

@xmap

@xmap xmap commented Aug 21, 2026

Copy link
Copy Markdown
Owner

Closes the gap a 2026-08-20 incident at APS 2-BM exposed: a TomoScan scan wedged for two and a half hours and the RunSupervisor never saw it.

Mechanism. _supervise_tick dropped every conduct_mode != "Conducted" Run in one filter, before any rule ran. 2-BM Runs are Witnessed, so the run-liveness rule, and Rules Q and R, were structurally dead there. The liveness rule is the right detector for a wedge (it is beam-free and keys on running_since, which every Witnessed Run has); it simply never got a Run to look at.

That one filter is now two scopes. liveness_candidates carries every Running Run and feeds only the liveness pass's SHADOW and ADVISE rungs. running / held stay Conducted-only and feed every command rung: the hold FSM, the gated resume, Rule Q's abort act, Rule R's stop act. inflight_ids widens to match so the liveness edge-trigger entries are still garbage-collected.

Why the truncate act stays Conducted-only. RunWitnessRecorder already truncates a stale Witnessed Run on the next BEGUN for the same capture code. Re-deciding a terminal another authority owns is what project_conjunct_symmetry_design rules out. Worth recording the limit of that argument, which the gate review surfaced: that terminal only fires if a next BEGUN ever arrives. If TomoScan never restarts the code, a wedged Witnessed Run gets no automatic terminal from either authority and the advise Decision is the only signal a human receives. That is the condition under which to revisit the act rung.

Scope. One source file and its tests. No new Decision choice (SupervisionQuieted already exists), no port, adapter, schema, or setting change. Rules Q and R are deliberately not extended to Witnessed Runs: a Witnessed Run has no expected_observation_interval_seconds, so Rule R is disabled for one anyway.

Also adds a deployment note to the Rule R section recording that 2-BM's station shutter doubles as its fast shutter and is cycled many times per scan, so beam_open reads False through long stretches of every healthy scan and Rule R defers. Documented limitation, not a behaviour change.

Gate review. Baseline panel (architecture, test coverage, cross-BC consistency). Cross-BC found nothing: no projection joins a Decision back to a Run's conduct_mode, and the record export drops context and inputs for DecisionRegistered unconditionally. Architecture found no P0/P1. Test coverage found one P0, a decorative Witnessed-resume test that passed because the unpatched envelope assembly failed on the fixture's missing Plan rather than because the gate held; it is fixed and now mirrors its Conducted sibling with only conduct_mode differing. Every guard in this PR is mutation-verified: deleting it turns a named test red.

Testing. 114 supervisor unit tests and 31,288 architecture fitness tests pass.

…ones

A TomoScan-driven scan wedged for 2.5 hours on 2026-08-20 unseen by
RunSupervisor, because the conduct_mode filter excluded every Witnessed
Run before the liveness rule ever ran. The command-issuing rungs (hold,
resume, Rule Q/R acts) rightly stay Conducted-only: CORA has no
authority to hold, resume, abort, or stop a Run an external tool
drives. But shadow-flagging and advising a human are just observation,
and observation is exactly what a Witnessed Run needs when it hangs.
Widen the liveness pass to a second list, liveness_candidates, that
carries every Running Run regardless of conduct_mode, and rebuild
inflight_ids from it so the liveness edge-trigger set still garbage
collects correctly. The truncate act stays Conducted-only: a stale
Witnessed Run's terminal already belongs to RunWitnessRecorder, which
truncates it on the next BEGUN observation, so the supervisor
re-deciding that terminal would just be overriding another authority's
verdict on a Run it does not drive.

Also documents a 2-BM deployment fact next to Rule R: TomoScan cycles
the station shutter for dark/flat fields many times per scan, and that
same PV feeds beam_open, so Rule R defers through long stretches of
every healthy scan. Not a behavior change, just naming the limitation
where the next reader will look for it.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

Gate review (2026-08-21, baseline panel) fixes folded in: the Witnessed
resume test was decorative, passing because the unpatched envelope
assembly failed on the fixture's missing Plan rather than because the
conduct_mode gate held. It now mirrors its Conducted sibling exactly
(envelope patched good, settle window passed) so only conduct_mode
differs. Added a mixed-tick test proving both the wide scope and the
act gate are per-item, not all-or-nothing, and an advise-off assertion
on the shadow path. Every guard in this commit is mutation-verified:
deleting it turns a named test red.
@github-actions

Copy link
Copy Markdown

Coverage report

Click to see where and how coverage changed

FileStatementsMissingCoverageCoverage
(new stmts)
Lines missing
  apps/api/src/cora/api
  _run_supervisor.py
Project Total  

This report was generated by python-coverage-comment-action

@xmap
xmap merged commit 2d9f024 into main Aug 21, 2026
19 checks passed
@xmap
xmap deleted the fix/liveness-sees-witnessed-runs branch August 21, 2026 13:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant