Authored by Claude Opus 4.7 (Claude Code). Session 5572d9a5-558d-4bea-b416-e31496c289c4.
FAIR-band: in-band [verify @ merge-gate]
Resolves #11861 (Sub 19 of Epic #11831)
Evidence: L1 (22/22 new MaintenanceBackpressureService spec + 206/206 orchestrator suite + 2059/2059 full unit suite, 0 failures) → L1 required for additive pure-function-first extraction (no behavioral mutation at orchestrator surface; Sub 18 #11862 wires the new service). No residuals.
Summary
B-prime extraction: moves the orchestrator's execution-phase policy surface (heavy/dependency classification predicates + deferral recording + lease/dependency executor wrappers) into a single new service so the Sub 18 closer can wire poll() as a generic registry-driven dispatch.
Additive only. Does NOT delete the inline §E-H methods from Orchestrator.mjs — Sub 18 #11862 owns the cutover (wire poll() to call the new service + delete the old inline methods). This keeps the per-sub risk surface atomic and matches the Sub 17/20 batched precedent on PR #11866.
New files
ai/daemons/orchestrator/services/MaintenanceBackpressureService.mjs — 3 internally-visible surface groups (pure predicates/finders → consolidated recordDeferral → executor wrappers wrapping HeavyMaintenanceLeaseService primitives). 549 LOC.
test/playwright/unit/ai/daemons/orchestrator/services/MaintenanceBackpressureService.spec.mjs — 22 tests covering predicate/finder edge cases, all 3 reasonCode branches of recordDeferral, and integration coverage for both executor wrappers (deferral paths + acquire/throw/release/promise-settle paths). 513 LOC.
Touched files (re-routes only — no behavioral change)
ai/daemons/orchestrator/Orchestrator.mjs — Drops the local DEFAULT_HEAVY_MAINTENANCE_TASK_NAMES + DEFAULT_GOLDEN_PATH_DEPENDENCY_TASK_NAMES definitions; imports them from the new canonical home. Single source of truth, zero drift risk between Sub-19 and Sub-18 merge windows. (No re-export — v13 work is unreleased, no backward-compat substrate needed.)
test/playwright/unit/ai/daemons/orchestrator/Orchestrator.spec.mjs — Import path swap for DEFAULT_HEAVY_MAINTENANCE_TASK_NAMES (Orchestrator.mjs → MaintenanceBackpressureService.mjs). Spec assertions unchanged.
Filename / describe cleanup (operator-flagged)
- Renamed
laneCManualScriptLeaseAdoption.spec.mjs → manualHeavyMaintenanceScriptLeaseAdoption.spec.mjs. "Lane C" is opaque epic-lineage drift baked into a filename — same Sub-15 decay-prone-reference lesson applied to file names + describe strings.
- Updated
appName const + test.describe accordingly.
- Applied the same lesson proactively to my new files: dropped
§E §F §G §H discussion-specific section labels from JSDoc, dropped (#11861 / Epic #11831) describe-string anchors, dropped (#11513 AC2) test-name anchors — kept descriptive prose.
Design choices
Pure-function-first shape matches the HeavyMaintenanceLeaseService.mjs precedent: module-level exports are the primary API (testable in isolation, no Neo bootstrap required); the Neo class is a thin wrapper holding instance state (deferralLogKeys Set) + injecting collaborators via reactive configs.
Consolidated recordDeferral replaces the 3 prior methods (recordMaintenanceDeferral / recordCrossDaemonLeaseDeferral / recordGoldenPathDependencyDeferral) with a single entry point polymorphic on reasonCode. Dedup-key construction varies per class (lease-held uses owner; others use blockingTaskName), but log message format + outcome payload shape collapse to one code path.
Executor wrappers preserve the lease-release timing contract exactly: synchronous false → release immediately; thenable → release on settle (both fulfill + reject); synchronous throw → release before re-throwing; other → release immediately.
No post-construction assignment bags (Sub-1 anti-pattern guard per #11857 Cycle-3.5 GPT signal): swappable dependencies (taskStateService, healthService, taskDefinitions, acquireLeaseFn, releaseLeaseFn) all flow through reactive class configs.
Test Evidence
npm run test-unit -- --grep="MaintenanceBackpressureService" → 22/22 pass (2.8s)
npm run test-unit -- --grep="Orchestrator|Manual heavy-maintenance script" → 206/206 pass (10.2s)
npm run test-unit (full suite) → 2059 passed, 2 skipped, 13 did not run, 0 failed (2.1m)
L1 evidence for pure-function extraction + additive-only change: no behavioral mutation at orchestrator surface in this PR (Sub 18 wires the new service).
Post-Merge Validation
AC mapping
| AC |
Status |
| 1. Service ships with 3 surface groups, visibly separate |
✓ Section-divider comments separate predicates/finders, deferral recording, and executor wrappers |
2. Wraps / delegates to existing HeavyMaintenanceLeaseService (does NOT replace) |
✓ Imports acquireHeavyMaintenanceLeaseSync + releaseHeavyMaintenanceLeaseSync as swappable config defaults |
| 3. Pure-function unit tests for predicates + finders |
✓ 5 dedicated tests (isHeavyMaintenanceTask, isGoldenPathDependencyTask, getActiveHeavyMaintenanceTask with exclude, getActiveGoldenPathDependencyTask priority, resolveHeavyMaintenanceLeasePath fallback chain) |
| 4. Integration tests for executor wrappers using lease seams |
✓ 8 tests covering deferral classes + all 4 release timings + throw path |
5. Orchestrator's poll() calls service methods |
Sub 18 #11862 territory (this PR is additive) |
| 6. Sub 19 extracts ≥70% of §E-H ~303 LOC |
✓ All ~303 LOC of substantive logic reflected in the new service (predicates 57 + deferral 109 + heavy executor 114 + golden-path executor 23 = 303) |
Deltas from ticket
DEFAULT_HEAVY_MAINTENANCE_TASK_NAMES + DEFAULT_GOLDEN_PATH_DEPENDENCY_TASK_NAMES constants live in MaintenanceBackpressureService.mjs as the canonical home; Orchestrator.mjs imports (no re-export). Per operator: "v13 work, never released, no backwards-compat bloat."
- Filename rename + describe-string cleanup of pre-existing
laneCManualScriptLeaseAdoption.spec.mjs folded in — operator-flagged friction caught during this lane.
Depends on
Epic #11831. Independent of Subs 14-17 + 20 (already merged or independent).
Unblocks
Sub 18 #11862 (Round-2 closer) — Orchestrator generic registry wire-up + CadenceEngine pure-trigger-builder correction. Sub 18 wires poll() to call MaintenanceBackpressureService.acquireLeaseAndExecute({...}) + .executeWithGoldenPathDependencyGate({...}) and deletes the now-dead inline §E-H methods.
Authority
Discussion #11857 Cycle-3.5 GPT [GRADUATION_APPROVED] + operator architectural ratify.
Per @tobiu's "you and me" instruction for Epic #11831 lane: no peer-review broadcast.
Authored by Claude Opus 4.7 (Claude Code). Session 5572d9a5-558d-4bea-b416-e31496c289c4.
FAIR-band: in-band [verify @ merge-gate]
Resolves #11861 (Sub 19 of Epic #11831)
Evidence: L1 (22/22 new MaintenanceBackpressureService spec + 206/206 orchestrator suite + 2059/2059 full unit suite, 0 failures) → L1 required for additive pure-function-first extraction (no behavioral mutation at orchestrator surface; Sub 18 #11862 wires the new service). No residuals.
Summary
B-prime extraction: moves the orchestrator's execution-phase policy surface (heavy/dependency classification predicates + deferral recording + lease/dependency executor wrappers) into a single new service so the Sub 18 closer can wire
poll()as a generic registry-driven dispatch.Additive only. Does NOT delete the inline
§E-Hmethods fromOrchestrator.mjs— Sub 18 #11862 owns the cutover (wirepoll()to call the new service + delete the old inline methods). This keeps the per-sub risk surface atomic and matches the Sub 17/20 batched precedent on PR #11866.New files
ai/daemons/orchestrator/services/MaintenanceBackpressureService.mjs— 3 internally-visible surface groups (pure predicates/finders → consolidatedrecordDeferral→ executor wrappers wrappingHeavyMaintenanceLeaseServiceprimitives). 549 LOC.test/playwright/unit/ai/daemons/orchestrator/services/MaintenanceBackpressureService.spec.mjs— 22 tests covering predicate/finder edge cases, all 3reasonCodebranches ofrecordDeferral, and integration coverage for both executor wrappers (deferral paths + acquire/throw/release/promise-settle paths). 513 LOC.Touched files (re-routes only — no behavioral change)
ai/daemons/orchestrator/Orchestrator.mjs— Drops the localDEFAULT_HEAVY_MAINTENANCE_TASK_NAMES+DEFAULT_GOLDEN_PATH_DEPENDENCY_TASK_NAMESdefinitions; imports them from the new canonical home. Single source of truth, zero drift risk between Sub-19 and Sub-18 merge windows. (No re-export — v13 work is unreleased, no backward-compat substrate needed.)test/playwright/unit/ai/daemons/orchestrator/Orchestrator.spec.mjs— Import path swap forDEFAULT_HEAVY_MAINTENANCE_TASK_NAMES(Orchestrator.mjs → MaintenanceBackpressureService.mjs). Spec assertions unchanged.Filename / describe cleanup (operator-flagged)
laneCManualScriptLeaseAdoption.spec.mjs→manualHeavyMaintenanceScriptLeaseAdoption.spec.mjs. "Lane C" is opaque epic-lineage drift baked into a filename — same Sub-15 decay-prone-reference lesson applied to file names + describe strings.appNameconst +test.describeaccordingly.§E §F §G §Hdiscussion-specific section labels from JSDoc, dropped(#11861 / Epic #11831)describe-string anchors, dropped(#11513 AC2)test-name anchors — kept descriptive prose.Design choices
Pure-function-first shape matches the
HeavyMaintenanceLeaseService.mjsprecedent: module-level exports are the primary API (testable in isolation, no Neo bootstrap required); the Neo class is a thin wrapper holding instance state (deferralLogKeysSet) + injecting collaborators via reactive configs.Consolidated
recordDeferralreplaces the 3 prior methods (recordMaintenanceDeferral/recordCrossDaemonLeaseDeferral/recordGoldenPathDependencyDeferral) with a single entry point polymorphic onreasonCode. Dedup-key construction varies per class (lease-held uses owner; others use blockingTaskName), but log message format + outcome payload shape collapse to one code path.Executor wrappers preserve the lease-release timing contract exactly: synchronous
false→ release immediately; thenable → release on settle (both fulfill + reject); synchronous throw → release before re-throwing; other → release immediately.No post-construction assignment bags (Sub-1 anti-pattern guard per #11857 Cycle-3.5 GPT signal): swappable dependencies (
taskStateService,healthService,taskDefinitions,acquireLeaseFn,releaseLeaseFn) all flow through reactive class configs.Test Evidence
npm run test-unit -- --grep="MaintenanceBackpressureService"→ 22/22 pass (2.8s)npm run test-unit -- --grep="Orchestrator|Manual heavy-maintenance script"→ 206/206 pass (10.2s)npm run test-unit(full suite) → 2059 passed, 2 skipped, 13 did not run, 0 failed (2.1m)L1 evidence for pure-function extraction + additive-only change: no behavioral mutation at orchestrator surface in this PR (Sub 18 wires the new service).
Post-Merge Validation
MaintenanceBackpressureServiceforpoll()wire-upAC mapping
HeavyMaintenanceLeaseService(does NOT replace)acquireHeavyMaintenanceLeaseSync+releaseHeavyMaintenanceLeaseSyncas swappable config defaultsisHeavyMaintenanceTask,isGoldenPathDependencyTask,getActiveHeavyMaintenanceTaskwith exclude,getActiveGoldenPathDependencyTaskpriority,resolveHeavyMaintenanceLeasePathfallback chain)poll()calls service methodsDeltas from ticket
DEFAULT_HEAVY_MAINTENANCE_TASK_NAMES+DEFAULT_GOLDEN_PATH_DEPENDENCY_TASK_NAMESconstants live inMaintenanceBackpressureService.mjsas the canonical home; Orchestrator.mjs imports (no re-export). Per operator: "v13 work, never released, no backwards-compat bloat."laneCManualScriptLeaseAdoption.spec.mjsfolded in — operator-flagged friction caught during this lane.Depends on
Epic #11831. Independent of Subs 14-17 + 20 (already merged or independent).
Unblocks
Sub 18 #11862 (Round-2 closer) — Orchestrator generic registry wire-up + CadenceEngine pure-trigger-builder correction. Sub 18 wires
poll()to callMaintenanceBackpressureService.acquireLeaseAndExecute({...})+.executeWithGoldenPathDependencyGate({...})and deletes the now-dead inline§E-Hmethods.Authority
Discussion #11857 Cycle-3.5 GPT
[GRADUATION_APPROVED]+ operator architectural ratify.Per @tobiu's "you and me" instruction for Epic #11831 lane: no peer-review broadcast.