Wake the CEO when the team stalls, not only when tasks are zero
The bootstrap gate fired on goalCount > 0 && taskCount === 0, which missed the common failure mode: every task stuck in_review or blocked so the counter stays positive while no progress happens. The CEO then waited for the normal timer interval to spot the stall. Add countAdvancingTasksForCompany (todo + in_progress only) and gate bootstrap on that. Also pull messages to the top of the timer wake step list so an agent waking on the normal cadence doesn't skip over unanswered peer DMs in favour of its own task work.
This commit is contained in:
1 parent
2e60ecc0e0
commit
2b2a6446cb
4 files changed
+32
-5
No files matched your search
@@ -95,15 +95,23 @@ export function createHeartbeatScheduler(
|
||||
}
|
||||
|
||||
const goalCount = db.countActiveGoalsForCompany(company.id);
|
||||
const taskCount = db.countActiveTasksForCompany(company.id);
|
||||
if (goalCount > 0 && taskCount === 0) {
|
||||
// Bootstrap when the company has active goals but no work is
|
||||
// actually advancing. The previous gate ("taskCount === 0")
|
||||
// missed the case where every task is in_review or blocked —
|
||||
// the company looks busy to the counter but produces zero
|
||||
// progress, and the CEO would not be woken until the next
|
||||
// regular timer interval. countAdvancingTasksForCompany
|
||||
// counts only todo + in_progress so bootstrapping still
|
||||
// fires once the team stalls.
|
||||
const advancingCount = db.countAdvancingTasksForCompany(company.id);
|
||||
if (goalCount > 0 && advancingCount === 0) {
|
||||
const ceo = db.getCeoForCompany(company.id);
|
||||
const ceoLastWake = ceo?.lastHeartbeatAt ? new Date(ceo.lastHeartbeatAt).getTime() : 0;
|
||||
const ceoLastAttempt = ceo ? attemptedAtByAgent.get(ceo.id) ?? 0 : 0;
|
||||
const ceoLastTouch = Math.max(ceoLastWake, ceoLastAttempt);
|
||||
const bootstrapCooldown = 120_000;
|
||||
if (ceo && !hasActiveRun({ agentId: ceo.id, companyId: company.id }) && (now - ceoLastTouch > bootstrapCooldown)) {
|
||||
logger.info(`[heartbeat] Company ${company.name} has ${goalCount} goals but no tasks — bootstrapping CEO ${ceo.name}`);
|
||||
logger.info(`[heartbeat] Company ${company.name} has ${goalCount} goal(s) and no advancing tasks — bootstrapping CEO ${ceo.name}`);
|
||||
tryWake(ceo.id, company.id, ceo.name, "bootstrap");
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user