Resolves #13971
Related: #13755
Adds a backlog-aware REM catch-up path for saturated but non-overflowing Dream cycles. When a REM extraction run fills the configured batch limit, the scheduler can fire a bounded follow-up after the typed catch-up cooldown instead of waiting the full steady-state Dream cadence; non-saturated, overflowed, skipped, failed, or disabled-cooldown cycles keep the existing cadence.
Evidence: L2 (scheduler/service unit coverage for saturated REM cycles, cooldown gating, and completion-state metadata) -> L2 required (orchestrator scheduling contract). No residuals.
Deltas from ticket
- Uses
AiConfig.orchestrator.intervals.remBacklogCatchupCooldownMs as a typed leaf and fails loud when registry wiring omits it.
- Persists Dream completion metadata in
TaskStateService so the scheduler can distinguish saturated REM work from ordinary successful Dream runs.
- Keeps the existing hourly Dream cadence for non-saturated cycles and for cycles that exceeded the runtime threshold.
Test Evidence
git diff --check
git diff --cached --check
npm run test-unit -- test/playwright/unit/ai/daemons/orchestrator/scheduling/dream.spec.mjs test/playwright/unit/ai/daemons/orchestrator/scheduling/registry.spec.mjs test/playwright/unit/ai/daemons/orchestrator/scheduling/pipeline.spec.mjs test/playwright/unit/ai/daemons/orchestrator/services/TaskStateService.spec.mjs test/playwright/unit/ai/daemons/orchestrator/services/DreamService.executeRemCycle.spec.mjs -> 62 passed.
Post-Merge Validation
Commits
2dd5e7c7e5 — fix(ai): add REM backlog catch-up scheduling (#13971)
Authored by Euclid (GPT-5, Codex Desktop). Session 019ef378-527d-7393-bc74-ec3a1d3f2ddf.
Resolves #13971
Related: #13755
Adds a backlog-aware REM catch-up path for saturated but non-overflowing Dream cycles. When a REM extraction run fills the configured batch limit, the scheduler can fire a bounded follow-up after the typed catch-up cooldown instead of waiting the full steady-state Dream cadence; non-saturated, overflowed, skipped, failed, or disabled-cooldown cycles keep the existing cadence.
Evidence: L2 (scheduler/service unit coverage for saturated REM cycles, cooldown gating, and completion-state metadata) -> L2 required (orchestrator scheduling contract). No residuals.
Deltas from ticket
AiConfig.orchestrator.intervals.remBacklogCatchupCooldownMsas a typed leaf and fails loud when registry wiring omits it.TaskStateServiceso the scheduler can distinguish saturated REM work from ordinary successful Dream runs.Test Evidence
git diff --checkgit diff --cached --checknpm run test-unit -- test/playwright/unit/ai/daemons/orchestrator/scheduling/dream.spec.mjs test/playwright/unit/ai/daemons/orchestrator/scheduling/registry.spec.mjs test/playwright/unit/ai/daemons/orchestrator/scheduling/pipeline.spec.mjs test/playwright/unit/ai/daemons/orchestrator/services/TaskStateService.spec.mjs test/playwright/unit/ai/daemons/orchestrator/services/DreamService.executeRemCycle.spec.mjs-> 62 passed.Post-Merge Validation
rem-backlog-catchupafterNEO_ORCHESTRATOR_REM_BACKLOG_CATCHUP_COOLDOWN_MSinstead of waitingdreamMs.Commits
2dd5e7c7e5—fix(ai): add REM backlog catch-up scheduling (#13971)Authored by Euclid (GPT-5, Codex Desktop). Session 019ef378-527d-7393-bc74-ec3a1d3f2ddf.