⚠️ Definition of Done: this issue must be completed in full, in a single PR. Do not split this
work across multiple PRs, and do not defer any Deliverable below to a follow-up issue. A PR that
satisfies only some of the Deliverables, stubs a required test, or leaves a checkbox
partially-done does NOT resolve this issue and will be closed.
Context
This issue is scoped to a pure ledger-persistence bug — it does NOT touch
evaluateRunLoopHalt's own halt/no-halt determination logic, which stays exactly as-is.
evaluateRunLoopBoundaryGate in packages/loopover-miner/lib/governor-run-halt.ts (~lines 59-76)
computes:
const newlyHalted = !wasHalted && verdict.shouldHalt;
...
const recorded =
newlyHalted || (!wasHalted && !verdict.shouldHalt)
? append(...)
: null;
Tracing all four (wasHalted, shouldHalt) combinations against this condition:
| wasHalted |
shouldHalt |
newlyHalted |
(!wasHalted && !shouldHalt) |
recorded? |
| false |
false |
false |
true |
yes — every steady iteration |
| false |
true |
true |
false |
yes (correct — halt trip) |
| true |
false |
false |
false |
no — resume/un-halt never recorded |
| true |
true |
false |
false |
no (correct — still halted, no transition) |
The steady "never halted, still not halted" case appends a governor-ledger row on every single
iteration of a healthy run — flooding the append-only ledger with no transition to record. The
(wasHalted=true, shouldHalt=false) resume/un-halt transition — the case symmetric with the
halt-trip case this function does correctly capture — is never recorded at all, so a run's
recovery from a halted state leaves no ledger trace.
The correct condition is a genuine transition detector: wasHalted !== verdict.shouldHalt (true
exactly on the halt-trip and the resume cases, false on both steady states).
Requirements
- Replace the
recorded condition with wasHalted !== verdict.shouldHalt.
- Do not change
verdict, evaluateRunLoopHalt, newlyHalted, or the releasedItem/markFailed
logic above it — only the recorded condition.
- Do not change
buildRunLoopHaltGovernorLedgerEvent's own signature or contents.
Deliverables
All four deliverables are required in this single PR.
Test Coverage Requirements
This repo enforces 99%+ Codecov patch coverage, branch-counted, on all changed lines/branches
(applies to packages/loopover-miner/lib/** per this repo's Codecov config). The corrected
condition and its two new test cases above must be covered.
Expected Outcome
The governor ledger only gains a new row on an actual halt or resume transition — a healthy,
never-halted run no longer appends one ledger event per iteration, and a run's recovery from a
halted state now leaves a real ledger trace it previously didn't.
Links & Resources
packages/loopover-miner/lib/governor-run-halt.ts (evaluateRunLoopBoundaryGate, ~lines 59-76)
- Existing test file covering this function under
packages/loopover-miner/test/ or
test/unit/ (search for evaluateRunLoopBoundaryGate or governor-run-halt to find it)
Context
This issue is scoped to a pure ledger-persistence bug — it does NOT touch
evaluateRunLoopHalt's own halt/no-halt determination logic, which stays exactly as-is.evaluateRunLoopBoundaryGateinpackages/loopover-miner/lib/governor-run-halt.ts(~lines 59-76)computes:
Tracing all four
(wasHalted, shouldHalt)combinations against this condition:newlyHalted(!wasHalted && !shouldHalt)The steady "never halted, still not halted" case appends a governor-ledger row on every single
iteration of a healthy run — flooding the append-only ledger with no transition to record. The
(wasHalted=true, shouldHalt=false)resume/un-halt transition — the case symmetric with thehalt-trip case this function does correctly capture — is never recorded at all, so a run's
recovery from a halted state leaves no ledger trace.
The correct condition is a genuine transition detector:
wasHalted !== verdict.shouldHalt(trueexactly on the halt-trip and the resume cases, false on both steady states).
Requirements
recordedcondition withwasHalted !== verdict.shouldHalt.verdict,evaluateRunLoopHalt,newlyHalted, or thereleasedItem/markFailedlogic above it — only the
recordedcondition.buildRunLoopHaltGovernorLedgerEvent's own signature or contents.Deliverables
evaluateRunLoopBoundaryGate'srecordedcondition changed towasHalted !== verdict.shouldHalt.(wasHalted=false, shouldHalt=false)case does NOT append aledger event (
recordedisnull).(wasHalted=true, shouldHalt=false)resume transition DOES appenda ledger event (
recordedis non-null), mirroring the existing coverage for the halt-trip(wasHalted=false, shouldHalt=true)case.unmodified (regression guard that this change doesn't alter those two outcomes).
All four deliverables are required in this single PR.
Test Coverage Requirements
This repo enforces 99%+ Codecov patch coverage, branch-counted, on all changed lines/branches
(applies to
packages/loopover-miner/lib/**per this repo's Codecov config). The correctedcondition and its two new test cases above must be covered.
Expected Outcome
The governor ledger only gains a new row on an actual halt or resume transition — a healthy,
never-halted run no longer appends one ledger event per iteration, and a run's recovery from a
halted state now leaves a real ledger trace it previously didn't.
Links & Resources
packages/loopover-miner/lib/governor-run-halt.ts(evaluateRunLoopBoundaryGate, ~lines 59-76)packages/loopover-miner/test/ortest/unit/(search forevaluateRunLoopBoundaryGateorgovernor-run-haltto find it)