Skip to content

Orion Tasking — fix/halt-reason-taxonomy-leak

To: Orion (he/him) From: Vesper (she/her) CC: Katja (Captain), Atlas (he/him) Date: 2026-04-21 Branch: fix/halt-reason-taxonomy-leak Priority: HIGH — FLAG-041, required before S43 Flag: FLAG-041


Context

S42 investigation confirmed that _shutdown in run() hardcodes halt_reason=HALT_REASON_ENGINE_REQUESTED, which overwrites the specific halt token already written by whatever triggered the halt. Every non-duration halt surfaces as engine_requested_halt in the DB. The authentic token survives only in halt.detail — which means the halt.reason field is unreliable for post-session diagnostics.

In S42, the authentic token was inventory_truth_halt (written by _escalate_degraded_to_halt at line 2284). _shutdown at line 1020 overwrote it because halt_reason or existing_reason gives the passed argument priority over the existing value. The comment at line 4294 in run() explicitly says the specific halt path will have already written halt.reason — the implementation just doesn't honor that.

Atlas has approved this fix and classified it as FLAG-041.


Fix

File: neo_engine/main_loop.py

Location: NEOEngine.run() at lines 4296–4299 (approximately):

if not should_continue:
    self._shutdown(
        "halt condition triggered",
        halt_reason=HALT_REASON_ENGINE_REQUESTED,
    )
    break

Change: Drop the halt_reason= argument (or pass halt_reason=None) so _shutdown falls through to the existing_reason path:

if not should_continue:
    self._shutdown(
        "halt condition triggered",
    )
    break

This honors the intent of the comment at line 4294 — the specific triggering path writes the authentic token, and _shutdown preserves it via the existing_reason fallback.

No other changes. Do not touch _shutdown's internal logic.


Pre-Code Investigation Required

Before writing the patch, confirm:

Q1 — _shutdown fallback behavior. With halt_reason=None (or no argument), what does _shutdown write to halt.reason if no existing value is set (fresh engine, unexpected crash before any halt path runs)? Confirm the HALT_REASON_UNEXPECTED fallback is in place — we must not silently write empty string or None to halt.reason.

Q2 — All non-duration return-False paths. Confirm Orion's table from the investigation is complete — that every _tick() return-False path already writes a specific halt.reason before returning. The fix is only safe if every path has coverage. If any path returns False without first writing halt.reason, list it — it needs a token added.

Q3 — Duration-elapsed path. Confirm the duration-elapsed halt path is unaffected. That path should not be going through the _tick() → run() → _shutdown route with halt_reason= — confirm it writes halt.reason directly and the change to run() does not alter its behavior.

Report findings before writing any code.


Test Requirements

Minimum 2 tests (may extend existing tests rather than add new ones):

  1. Token preservation test: Exercise the DEGRADED-timeout escalation path (or mock _tick() returning False after _escalate_degraded_to_halt runs). Assert that halt.reason in engine_state equals inventory_truth_halt at shutdown — not engine_requested_halt. This is the regression that S42 exposed.
  2. Fallback safety test: Call _shutdown with no halt_reason and no prior halt.reason set. Assert that halt.reason is written as HALT_REASON_UNEXPECTED (not empty string, not None).

If extending existing tests is cleaner than adding new ones, do that — just make sure the token-preservation assertion is explicit and named.


Commit Plan

  1. fix(main_loop): preserve authentic halt.reason token — drop halt_reason override in run()
  2. test(halt): assert authentic halt token survives shutdown — FLAG-041

Two commits. Standard delivery format.


Regression Suite

Current baseline: 219 tests (218 passed + 1 skipped on Windows). Run full suite after patch. Provide updated command.


Constraints

  • No pre-creating the branch during investigation
  • PowerShell apply instructions: Get-ChildItem form
  • Always include defensive git branch -D before git checkout -b
  • No other changes — this is a focused one-line fix with tests

Deliverable

Standard format: branch, commits with hashes, test count and pass rate, investigation findings, deviations if any. Vesper reviews before merge.

— Vesper