Sub of #14144 (heavy-maintenance lease fairness). The lease-service side of the time-driven cooperative yield.
Context
The yield primitive already exists but is unconsumed: shouldYieldHeavyMaintenanceLease(lease, {maxActiveHoldMs}) (HeavyMaintenanceLeaseService.mjs:121, pure/read-only, held > maxActiveHoldMs) + acquireHeavyMaintenanceLeaseSync / releaseHeavyMaintenanceLeaseSync. What's missing: the policy value (maxActiveHoldMs has no config leaf) and a holder-facing wrapper so the kbSync yield-point (sub #B, @neo-opus-grace) consults it without threading config at the call-site.
Scope
- Add
orchestrator.heavyMaintenance.maxActiveHoldMs reactive config leaf (config.template.mjs, read at the use-site per ADR-0019) — the fairness bound. Sized to interleave a multi-minute githubWorkflowSync without thrashing the heavy mutex (e.g. ~30–60 min default; falsy ⇒ never-yields back-compat, which shouldYieldHeavyMaintenanceLease already honors).
- A thin service method (e.g.
Orchestrator#shouldYieldHeavyLease(lease) or a lease-service instance method) that reads the leaf + delegates to the pure shouldYieldHeavyMaintenanceLease.
- Unit test (pure: lease + bound → boolean; the primitive's degrade-on-falsy path).
Contract Ledger
| Surface |
Signature |
Consumer |
Notes |
| service yield-check |
shouldYieldHeavyLease(lease) → Boolean |
sub #B kbSync yield-point |
reads maxActiveHoldMs leaf; delegates to pure shouldYieldHeavyMaintenanceLease(lease,{maxActiveHoldMs}) |
| config leaf |
orchestrator.heavyMaintenance.maxActiveHoldMs (number, env-overridable, falsy⇒never-yield) |
the service method |
the fairness policy value |
Acceptance Criteria
Refs #14144 (epic), #14146 (resumable kbSync that makes the yield safe), #14161.
🤖 Authored by Ada (@neo-opus-ada · Claude Opus 4.8, Claude Code).
Sub of #14144 (heavy-maintenance lease fairness). The lease-service side of the time-driven cooperative yield.
Context
The yield primitive already exists but is unconsumed:
shouldYieldHeavyMaintenanceLease(lease, {maxActiveHoldMs})(HeavyMaintenanceLeaseService.mjs:121, pure/read-only,held > maxActiveHoldMs) +acquireHeavyMaintenanceLeaseSync/releaseHeavyMaintenanceLeaseSync. What's missing: the policy value (maxActiveHoldMshas no config leaf) and a holder-facing wrapper so the kbSync yield-point (sub #B, @neo-opus-grace) consults it without threading config at the call-site.Scope
orchestrator.heavyMaintenance.maxActiveHoldMsreactive config leaf (config.template.mjs, read at the use-site per ADR-0019) — the fairness bound. Sized to interleave a multi-minutegithubWorkflowSyncwithout thrashing the heavy mutex (e.g. ~30–60 min default; falsy ⇒ never-yields back-compat, whichshouldYieldHeavyMaintenanceLeasealready honors).Orchestrator#shouldYieldHeavyLease(lease)or a lease-service instance method) that reads the leaf + delegates to the pureshouldYieldHeavyMaintenanceLease.Contract Ledger
shouldYieldHeavyLease(lease) → BooleanmaxActiveHoldMsleaf; delegates to pureshouldYieldHeavyMaintenanceLease(lease,{maxActiveHoldMs})orchestrator.heavyMaintenance.maxActiveHoldMs(number, env-overridable, falsy⇒never-yield)Acceptance Criteria
maxActiveHoldMsreactive config leaf exists + read at the use-site (not pass-through).Refs #14144 (epic), #14146 (resumable kbSync that makes the yield safe), #14161.
🤖 Authored by Ada (@neo-opus-ada · Claude Opus 4.8, Claude Code).