fix(athena): harden council members — compaction recovery, block TodoWrite, analysis mode

- Add session.compacted handler in BackgroundManager to prevent premature
  task completion after compaction (defer first post-compaction idle)
- Explicitly block TodoWrite/TodoRead for council members in all sync
  points (AgentConfig permission + session tools + prompt instructions)
- Add council member prefix check to todo-continuation-enforcer skip list
  to prevent infinite continuation loops on completed council members
- Add optional analysis mode (solo/delegation) question to Athena setup:
  solo = thorough but heavier, delegation = fast via explore/librarian
- Allow call_omo_agent in council member allow-list for delegation mode
- Update COUNCIL_MEMBER_PROMPT with TodoWrite prohibition and delegation
  addendum for when delegation mode is selected
- Update prepare_council_prompt tool with mode parameter
This commit is contained in:
ismeth
2026-02-23 19:42:56 +01:00
committed by YeonGyu-Kim
parent c75ae6bffd
commit fb543f88d5
7 changed files with 109 additions and 24 deletions
@@ -5,6 +5,7 @@ import { normalizeSDKResponse } from "../../shared"
import { log } from "../../shared/logger"
import { getAgentConfigKey } from "../../shared/agent-display-names"
import { COUNCIL_MEMBER_KEY_PREFIX } from "../../agents/builtin-agents/council-member-agents"
import { ABORT_WINDOW_MS, CONTINUATION_COOLDOWN_MS, DEFAULT_SKIP_AGENTS, FAILURE_RESET_WINDOW_MS, HOOK_NAME, MAX_CONSECUTIVE_FAILURES } from "./constants"
import { isLastAssistantMessageAborted } from "./abort-detection"
import { hasUnansweredQuestion } from "./pending-question-detection"
@@ -184,6 +185,10 @@ export async function handleSessionIdle(args: {
})
const resolvedAgentName = resolvedInfo?.agent
if (resolvedAgentName && resolvedAgentName.startsWith(COUNCIL_MEMBER_KEY_PREFIX)) {
log(`[${HOOK_NAME}] Skipped: council member agent`, { sessionID, agent: resolvedAgentName })
return
}
if (resolvedAgentName && skipAgents.some(s => getAgentConfigKey(s) === getAgentConfigKey(resolvedAgentName))) {
log(`[${HOOK_NAME}] Skipped: agent in skipAgents list`, { sessionID, agent: resolvedAgentName })
return