Lower cascade stages starve — 0 CEO/seo/maintenance runs in 2.5h #441
Labels
No labels
Agent
Compat/Breaking
Kind/Bug
Kind/Documentation
Kind/Enhancement
Kind/Feature
Kind/Security
Kind/Testing
Priority
Critical
Priority
High
Priority
Low
Priority
Medium
Reviewed
Confirmed
Reviewed
Duplicate
Reviewed
Invalid
Reviewed
Won't Fix
Status
Abandoned
Status
Blocked
Status
Need More Info
No milestone
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
joshtronic/igor#441
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
The cascade starves its own lower stages. Measured 2026-07-27: zero cascade-stage lines (
ceo:,seo:,sports:,maintenance:) in a 2.5-hour window — not one tick got deep enough to reach them, because automerge, deploy-watching, PR review and issue work consumed every tick higher up.That is not academic. igor#435 shipped a same-tick path for acting on board steering left on a CEO digest, and its responsiveness depends entirely on a tick reaching
do_ceo_tick. A fast path behind a stage that goes unreached for hours is not fast.Related measurement from the same window: 74 ticks, 58% utilization, median tick 79s, and only 9 of 74 claimed an issue. An idle tick still costs ~70s because every tick re-runs the whole fleet preamble before doing anything.
Decision: fairness, not reordering. Do not simply move the CEO stage earlier — that just starves whatever ends up last. A stage that has been skipped for N consecutive ticks should get priority on the next one. The cascade keeps its normal order when nothing is starving.
Explicitly NOT in scope: splitting the loop into separate services. That was designed and declined — both loops would write
discretionary-state.json(36 call sites) through a non-atomic jq+mv, and the hazard is not worth it.Also worth doing here since it is one line each and the measurement above is the justification:
AccuracySec=1sonagent.timer. It currently uses the systemd default of 1min, which batches wakeups and adds up to 60s of latency per fire on a machine that is not battery powered.OnUnitInactiveSecfrom1minto ~15s.Acceptance criteria
agent.timersetsAccuracySec=1sand a shorter inactive gap.