Skip to content

Orion Tasking — feat/flag-044-recovery-cooldown

To: Orion (he/him) From: Vesper (she/her) CC: Katja (Captain), Atlas (he/him) Date: 2026-04-21 Branch: feat/flag-044-recovery-cooldown Atlas ruling: 07 Agent Coordination/[C] Atlas Ruling — Cool-Down Session Model (FLAG-044).md


Context

FLAG-042 introduced a per-episode cap (recovery_exhausted_halt) to prevent oscillation after a failed recovery attempt. S43–S45 revealed that this cap also prevents the engine from waiting out a persistently hostile regime — in S45 the engine halted at 163 seconds even though it was behaving correctly. Atlas has ruled to replace the hard cap with a cool-down model.

This is a focused follow-on to FLAG-042. Not a redesign — DEGRADED semantics, recovery thresholds, and hysteresis are unchanged.


What Changes

Remove

  • degraded_recovery.<source>.attempts counter logic from engine_state
  • recovery_exhausted_halt halt taxonomy token
  • All code that checks attempt count and triggers halt on second entry

Add — per-source cool-down tracking

Add to engine_state (per guard source: anchor, drift, corridor): - degraded_recovery.<source>.cooldown_until_tick — tick number after which recovery re-enables. 0 = not in cool-down. - degraded_recovery.<source>.episode_count — number of times this source has entered DEGRADED this session (incremented on each DEGRADED entry, not on each recovery attempt)

Add — config params

In the appropriate guard config(s) or a shared recovery config:

recovery_cooldown_ticks: 120                          # ticks to suppress recovery after a failed attempt (~8 min)
max_degraded_episodes_per_source_per_session: 3       # episode cap before HALT
Both must be config-driven and tunable. Use 120 and 3 as defaults.

Cool-down trigger logic

The cool-down timer is set when: 1. Recovery was attempted (engine exited DEGRADED) 2. The same source guard re-fires (engine re-enters DEGRADED from same source)

On that re-entry: cooldown_until_tick = current_tick + recovery_cooldown_ticks

The cool-down timer is NOT extended continuously just because the hostile condition persists. It is a fixed-length waiting window, not a sliding lockout.

Episode cap logic

episode_count increments each time the source enters DEGRADED (initial entry + all re-entries). When episode_count >= max_degraded_episodes_per_source_per_session: halt with new taxonomy token.

New halt token: degraded_episode_limit_halt (replaces recovery_exhausted_halt).

Recovery evaluator behavior during cool-down

During active cool-down (current_tick < cooldown_until_tick): - Recovery evaluator does NOT run for that source - Log recovery_suppressed_by_cooldown with ticks remaining - Engine stays in DEGRADED (no quoting, no orders) - Truth checks continue as normal

After cool-down expires: recovery evaluator re-enables, normal recovery cycle resumes.

Logged state additions

These must be visible in logs and engine state for operator observability: - degraded_episode_count (per source) - cooldown_until_tick (per source) - recovery_suppressed_by_cooldown (boolean or ticks remaining, per source)


What Must NOT Change

  • DEGRADED behavior: cancel all orders, stop quoting, continue observation, continue truth checks
  • Recovery criteria: exit thresholds, hysteresis, stability window requirements
  • Drift condition C exclusion from recovery (established in FLAG-042)
  • Wallet-truth recovery path (uncapped, different causal layer — leave entirely alone)
  • Session duration limit

Startup Reset Extension

Extend the startup reset (added in FLAG-042) to also clear: - degraded_recovery.<source>.cooldown_until_tick → 0 - degraded_recovery.<source>.episode_count → 0

These must reset on each fresh session start alongside mode, degraded_since, degraded_reason.


Required Tests (minimum 8)

  1. Cool-down activation — guard re-fires after recovery; verify cooldown_until_tick is set correctly and recovery evaluator is suppressed
  2. Cool-down suppression — while cool-down is active, recovery evaluator does not run; engine stays DEGRADED
  3. Cool-down expiry — after recovery_cooldown_ticks ticks, recovery evaluator re-enables
  4. Successful recovery after cool-down — conditions clear after cool-down; engine exits DEGRADED and resumes ACTIVE
  5. Episode cap triggers HALT — same source enters DEGRADED 3 times; verify degraded_episode_limit_halt fires on 3rd entry
  6. Episode cap is per-source — anchor hitting cap does not affect drift or corridor episode count
  7. Startup resetcooldown_until_tick and episode_count reset to 0 at fresh session start
  8. Cool-down timer not sliding — hostile condition persisting does not extend cooldown_until_tick beyond initial set value

Add any additional tests you judge necessary. Full regression must pass (currently 162 tests on Katja's machine).


Commit Plan

  1. Drop attempt-counter logic + recovery_exhausted_halt token
  2. Add per-source cool-down tracking + config params
  3. Add per-source episode counting + degraded_episode_limit_halt token
  4. Wire cool-down suppression into recovery evaluator (Step 8.4)
  5. Extend startup reset

Separate commits per logical unit. Self-contained commit messages.


Delivery Format

Deliver via NEO Desk: NEO Desk/handoffs/TO_VESPER_patch_delivery_FLAG-044.md

Delivery memo must include: - Commit list with hashes and one-line descriptions - Test count (new tests + full regression total) - Any deviations from this spec, documented with engineering justification - Apply instructions in correct PowerShell form

Standing apply instruction rules (enforced by Vesper in every review): 1. No pre-creating branches during investigation 2. No *.patch glob in PowerShell — use Get-ChildItem ... -Filter "*.patch" | Sort-Object Name | ForEach-Object { git am $_.FullName } 3. Always include defensive branch delete: git branch -D feat/flag-044-recovery-cooldown 2>$null before git checkout -b

Patch bundle path: 08 Patches/patches-flag-044-recovery-cooldown/


Pre-Code Investigation Required

Before writing code, confirm: 1. All sites where attempts counter is read/written — identify every location to remove 2. All sites where recovery_exhausted_halt is emitted — confirm clean removal 3. Where to store cooldown_until_tick and episode_count in engine_state — confirm schema impact 4. Whether max_degraded_episodes_per_source_per_session belongs in shared recovery config or per-guard config

If any finding changes the implementation plan materially, deliver pre-code findings via NEO Desk/handoffs/TO_VESPER_pre_code_findings_FLAG-044.md before writing code.

— Vesper