Delete marker from processedFallbackMessages on failure so message can be retried. Add MAX_PROCESSED_FALLBACK_MARKERS=500 with eviction to prevent unbounded Set growth.
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)
Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Improve not-configured error message with config file path. Wrap metadataFn in try/catch for best-effort metadata. Replace unsafe as-casts with getToolContextProperty helper. Show Name (model) format in errors. Return error directly for empty member selection.
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)
Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Return CouncilSessionWaitResult with timedOut/aborted flags instead of raw array, so callers know when results are partial. Add 5 tests covering normal flow, abort, partial results, and edge cases.
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)
Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Add .strict() to CouncilMemberSchema to reject unknown fields like temperature. Remove unused Zod-inferred type exports. Add test verifying unknown fields are rejected.
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)
Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Remove session-guard.ts (runtime gating uses hasPendingCouncilMembers instead), its test file, and dead snake_case type interfaces from types.ts that don't match the camelCase code.
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)
Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
The athena_council tool now waits for all council members to complete and
returns their collected results as markdown, eliminating the need for
Athena to repeatedly call background_output per member (which created
excessive UI noise).
- Add result-collector.ts that polls task status and fetches session content
- Update tool to accept BackgroundOutputClient and return formatted markdown
- Update Athena prompt to remove background_output polling steps
- Rewrite tests for new blocking behavior and markdown output format
Council member tasks were launched via BackgroundManager but lacked the
ctx.metadata() call that links background sessions to the tool call in
the OpenCode TUI. Users couldn't click to inspect individual member outputs.
- Add session-waiter.ts to poll for session creation on launched tasks
- Call ctx.metadata() for each council member with sessionId linkage
- Matches the pattern used by delegate-task/background-task.ts
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)
Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
The previous check used currentAgent?.toLowerCase() === 'athena' which failed
after display name remapping stored the agent as 'Athena (Council)' in session
state. Now uses getAgentConfigKey() to resolve display names back to config keys,
matching the established pattern used by other hooks (atlas, todo-continuation, etc.).
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)
Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Replace oracle as the agent for council background tasks with a purpose-built
council-member agent. This avoids coupling to oracle's config/prompt and provides
proper read-only tool restrictions (deny write, edit, task, athena_council).
- New council-member-agent.ts with analysis-oriented system prompt
- Registered in agentSources (hidden from Sisyphus delegation table)
- Added to type system, Zod schemas, display names, tool restrictions
- Minimal model fallback (always overridden per council member at launch)
- Council orchestrator now launches members as council-member agent
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)
Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Athena was the only agent setting name explicitly. The mismatch between
the name property ('Athena (Council Orchestrator)') and the config key
('Athena (Council)') caused TypeError during agent resolution.
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)
Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
LaunchInput.temperature and LaunchInput.permission were accepted and
passed through the council orchestrator but never forwarded to the
actual promptAsync API call (SDK doesn't support per-request temperature
or permission). Remove the dead fields, the unused AthenaConfig
interface, and update tests/docs/schema accordingly.
Already denied via agent-tool-restrictions.ts for all athena sessions,
but now also explicitly denied in the per-launch permission to make
the anti-recursion intent clear at the launch site.
Remove 9 files (913 lines) from the code-driven synthesis pipeline that
was superseded by the agent-driven approach in phases 6-8.
Phases 3/5 built: collectCouncilResults → formatForSynthesis →
buildSynthesisPrompt → formatFindingsForUser → buildDelegationPrompt.
Phases 6-8 replaced with: launch → background_output → Athena
synthesizes in conversation → switch_agent. The old pipeline was
never wired into runtime and all consumers were other dead code.
Also simplifies executeCouncil to return CouncilLaunchResult (task IDs
+ failures) instead of reading stale task status via collectCouncilResults.
Deleted: council-result-collector, synthesis-types, synthesis-prompt,
synthesis-formatter, findings-presenter, delegation-prompts (+ 4 tests).
Cleaned: CouncilMemberStatus, AgreementLevel, CouncilMemberResponse,
CouncilExecutionResult types from types.ts.
- Forward temperature and permission through council-launcher to background manager
- Add LaunchInput.temperature and LaunchInput.permission to background-agent types
- Extract session guard with 5-minute timeout to prevent stale council locks
- Make council optional in AthenaOverrideConfigSchema for partial user overrides
- Support member lookup by both name and model ID in filterCouncilMembers
- Add provider/model-id format validation to CouncilMemberSchema
- Fix findings-presenter group header to show finding count instead of first finding's reporter count
The installer now detects which providers the user has (Anthropic, OpenAI,
Google, Copilot, OpenCode Zen) and generates council member config for Athena.
Requires at least 2 distinct providers; skips council config otherwise.
This implements the documented claim in configurations.md.
After Athena synthesizes council findings, presents user with Question tool
TUI to choose: Atlas (fix now), Prometheus (create plan), or no action.
On selection, session_handoff tool stores intent + calls updateSessionAgent(),
then agent-handoff hook fires on session.idle to switch the main session's
active agent via promptAsync with synthesis context.
- update Athena workflow to launch council then call background_output per task
- require collecting all member responses before synthesis and delegation
- add optional members arg support to athena_council tool
- filter selected members case-insensitively with clear unknown-member errors
- add tests for default-all and member selection behavior
Prometheus needs to interview the user interactively, so it can't run as a
background task. Updated Athena's delegation prompt:
- Atlas: still delegates via task tool (autonomous execution)
- Prometheus: outputs structured findings summary and tells the user to
switch to Prometheus agent, which sees the conversation context and
can ask clarifying questions directly
Council members launched as agent='athena' got Athena's system prompt saying
'ALWAYS call athena_council first', plus the tool wasn't denied for bg athena
tasks. Each council member spawned 4 more → exponential explosion (47+ tasks).
Three fixes:
1. Deny athena_council in ATHENA_RESTRICTIONS (agent-tool-restrictions.ts)
- Only affects background athena tasks (task-starter.ts)
- Primary Athena (user-selected) still has access via permission field
2. Session-level dedup guard prevents re-calling while council is running
- If Athena retries during long wait, returns 'already running'
3. Increase wait timeout from 2min to 10min (council members need time
for real code analysis with Read/Grep/LSP)
The old prompt said 'when requiring multi-model analysis' which let Athena
decide to skip the council and do direct analysis herself. Combined with
keyword-detector injecting [search-mode] telling her to 'launch explore
agents and use Grep directly', Athena never called athena_council.
Two fixes:
1. System prompt now unconditionally requires athena_council as FIRST action
- Explicitly prohibits Read/Grep/Glob/LSP/call_omo_agent
- Identity is 'orchestrator, not analyst'
2. keyword-detector skips ALL injections for Athena agent
- search/analyze/ultrawork modes conflict with council orchestration
- Same pattern as isPlannerAgent() skip for Prometheus
- Build pure prompt constructors with confirmed finding context and agreement levels
- Add BDD tests for fix/planning intent, question context, and single-finding edge cases
- implement createAthenaAgent with primary-mode model behavior and prompt metadata
- export Athena factory and metadata through athena and root agent barrels
- Add synthesis result contracts with agreement, provenance, and Athena assessment fields\n- Add synthesis prompt builder and council-response formatter with failure-aware provenance output