Category: behavioral · Lane: babysit (dynamic /loop /source-control:babysit-prs, no fixed interval)
Triggering example
Across 2 consecutive cycles in one session, the snapshot's queue-state.json computed
recommended_cadence: "active" both times (per reference/cadence.md: 5-minute polling —
correct, since both cycles had genuinely pending CI / new blocking bot feedback on watched
PRs). Both times I (the orchestrator) called ScheduleWakeup with delaySeconds in the
1200-1500 range (20-25 min) instead — I never actually read the recommended_cadence field
out of the snapshot/state JSON at all. I picked the delay from the generic /loop skill's own
"idle tick" heuristic (1200-1800s) instead of this skill's domain-specific, already-computed
recommendation.
Net effect: PRs with pending CI (e.g. #490, #492 mid-cycle) or unresolved blocking feedback sat
unchecked for up to 4-5x longer than the skill's own adaptive-cadence contract calls for. User
noticed the lag empirically ("could wait 20 minutes and not realize PRs have been ready for
5-10+ minutes").
Observed vs expected
- Observed:
SKILL.md step 9 says "Schedule the next wake from the snapshot's
recommended_cadence" and reference/cadence.md fully specifies the states
(active=5m/normal=15m/quiet=1h/idle=1d), but nothing in the operational runbook tells the
orchestrator how to translate that string into a concrete ScheduleWakeup call in dynamic
/loop mode — so it's easy (and is exactly what happened) to fall back to the generic /loop
skill's own delay-picking guidance instead, silently overriding the domain skill's tighter
contract.
- Expected: the runbook should explicitly say, e.g.: "map
recommended_cadence to
ScheduleWakeup.delaySeconds via {active: 300, normal: 900, quiet: 3600, idle: 3600} (idle's
documented 1-day cadence must clamp to ScheduleWakeup's hard 3600s ceiling — call this out
explicitly rather than leaving it to be silently truncated or ignored)."
- Separately:
ScheduleWakeup's [60, 3600] clamp cannot express cadence.md's "Idle: daily"
state at all in a single-session /loop. Worth documenting as a known ceiling (durable
/schedule cron is the correct tool for a real daily cadence) rather than a silent gap.
Related (already filed, referenced not duplicated)
#472 (fixed-interval /loop Nm overlaps long fan-out cycles — a different failure mode: this
issue is about dynamic /loop ignoring the engine's own cadence signal entirely, not about a
fixed cron interval being too short) · #477 (absorb v4 loop-prompt rules into the skill —
lists "loop-pacing guidance keyed to worker concurrency cap" but not this specific
recommended_cadence-consumption gap)
Suggested fix location
reference/loop.md §5.3 (the static cadence ladder / dynamic-mode wake guidance) — add the
explicit string-to-seconds mapping and the idle-ceiling caveat.
Category: behavioral · Lane: babysit (dynamic
/loop /source-control:babysit-prs, no fixed interval)Triggering example
Across 2 consecutive cycles in one session, the snapshot's
queue-state.jsoncomputedrecommended_cadence: "active"both times (perreference/cadence.md: 5-minute polling —correct, since both cycles had genuinely pending CI / new blocking bot feedback on watched
PRs). Both times I (the orchestrator) called
ScheduleWakeupwithdelaySecondsin the1200-1500 range (20-25 min) instead — I never actually read the
recommended_cadencefieldout of the snapshot/state JSON at all. I picked the delay from the generic
/loopskill's own"idle tick" heuristic (1200-1800s) instead of this skill's domain-specific, already-computed
recommendation.
Net effect: PRs with pending CI (e.g. #490, #492 mid-cycle) or unresolved blocking feedback sat
unchecked for up to 4-5x longer than the skill's own adaptive-cadence contract calls for. User
noticed the lag empirically ("could wait 20 minutes and not realize PRs have been ready for
5-10+ minutes").
Observed vs expected
SKILL.mdstep 9 says "Schedule the next wake from the snapshot'srecommended_cadence" andreference/cadence.mdfully specifies the states(active=5m/normal=15m/quiet=1h/idle=1d), but nothing in the operational runbook tells the
orchestrator how to translate that string into a concrete
ScheduleWakeupcall in dynamic/loopmode — so it's easy (and is exactly what happened) to fall back to the generic/loopskill's own delay-picking guidance instead, silently overriding the domain skill's tighter
contract.
recommended_cadencetoScheduleWakeup.delaySecondsvia{active: 300, normal: 900, quiet: 3600, idle: 3600}(idle'sdocumented 1-day cadence must clamp to
ScheduleWakeup's hard 3600s ceiling — call this outexplicitly rather than leaving it to be silently truncated or ignored)."
ScheduleWakeup's[60, 3600]clamp cannot express cadence.md's "Idle: daily"state at all in a single-session
/loop. Worth documenting as a known ceiling (durable/schedulecron is the correct tool for a real daily cadence) rather than a silent gap.Related (already filed, referenced not duplicated)
#472 (fixed-interval
/loop Nmoverlaps long fan-out cycles — a different failure mode: thisissue is about dynamic
/loopignoring the engine's own cadence signal entirely, not about afixed cron interval being too short) · #477 (absorb v4 loop-prompt rules into the skill —
lists "loop-pacing guidance keyed to worker concurrency cap" but not this specific
recommended_cadence-consumption gap)
Suggested fix location
reference/loop.md§5.3 (the static cadence ladder / dynamic-mode wake guidance) — add theexplicit string-to-seconds mapping and the idle-ceiling caveat.