Commit Graph

5257 Commits

Author SHA1 Message Date
ismeth 44b3efe7a3 feat(athena): structured synthesis header + audit cross-check flow
Add universal YAML front-matter header to all synthesis.md outputs (council,
question, date, members, session_ids, mode, intent, responded count).

AUDIT: structured finding format with required fields (severity, confidence,
members reported, evidence, impact, fix direction). New cross-check flow asks
user to verify minority/solo findings via a second council round before
proceeding to findings processing.

Also fix prompt-file cleanup: skip cleanupPromptFile when movePromptFile
already succeeded.
2026-04-15 16:48:50 +09:00
ismeth 974eb8e176 feat(athena): replace hard quorum gate with interactive failure handling
Interactive prompt: Athena now asks the user whether to retry failed members
or skip and synthesize with available results. Recommends based on success ratio.
Non-interactive prompt: always proceeds to synthesis with available results,
sets status to partial/failed accordingly.
2026-04-15 16:48:50 +09:00
ismeth 37f03b4238 fix(switch-agent): use native tui.selectSession, use cross-platform symlink test target 2026-04-15 16:48:50 +09:00
ismeth 68cd8814d8 refactor(switch-agent): replace as-any with type guard, use const tuple for agent names 2026-04-15 16:48:49 +09:00
ismeth 9c226948d3 fix(athena): per-task TTL for council members instead of blanket exemption
Add optional ttl field to BackgroundTask/LaunchInput. Council launcher
passes COUNCIL_MEMBER_TTL_MS (2 hours) per member. Task poller uses
task.ttl ?? TASK_TTL_MS, replacing the blanket TTL_EXEMPT_AGENTS bypass
for council members with a bounded timeout.

Co-authored-by: Vacbo <2445>
2026-04-15 16:48:49 +09:00
ismeth 77d929a3ab fix(athena): tie prompt-file lifecycle to council_finalize
Remove blind 30-min setTimeout cleanup from prepare_council_prompt. Prompt
files now stay until council_finalize archives them in a try/finally block.
Extract shared resolvePromptTempFilePath helper used by both movePromptFile
and the new cleanupPromptFile safety net.

Co-authored-by: Vacbo <2445>
2026-04-15 16:48:49 +09:00
ismeth 69bb6eda8a fix(athena): canonical realpath path validation with symlink rejection
Resolve symlinks via realpathSync before checking path policy, preventing
symlink-based escapes from .sisyphus/ sandbox. Walks up to nearest existing
ancestor for new-file writes. Adds 7 tests including real-filesystem symlink
scenarios.

Co-authored-by: Vacbo <2445>
2026-04-15 16:48:49 +09:00
ismeth 9d6dc3a8a8 chore(athena): update audit guidance prompt
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-15 16:48:49 +09:00
ismeth 96c9cf98ed fix(athena): harden interactive prompt to prevent implementation behavior
Add 7 guardrails to stop Athena from acting as an implementation
orchestrator when receiving feature requests:

- Role + Tool Firewall: task() exclusively for council, todowrite banned
- Implementation-first pre-check: highest precedence in routing
- Expanded Category B: broader signals (build, make a feature, etc.)
- Strengthened Category F: vague features = ambiguous by default
- Handoff context integrity: no fabricated specs in switch_agent
- Routing read budget: 3-file cap for routing context
- New constraints: task() scope, todowrite ban, drift detection

Fixes bug where Athena created 9 todos and orchestrated implementation
via task() instead of routing to Prometheus/Sisyphus.
2026-04-15 16:48:49 +09:00
ismeth a2712c57c9 fix: deny switch_agent for all sub-agents 2026-04-15 16:48:49 +09:00
ismeth 276cb9352f fix(athena): gate non-interactive synthesis on finalized task ids 2026-04-15 16:48:49 +09:00
ismeth fb1be5923f test(config): cover athena-junior in overridable agent names 2026-04-15 16:48:49 +09:00
ismeth 11f6712dde fix(athena): add termination guards to non-interactive retry loop 2026-04-15 16:48:49 +09:00
ismeth 9d284accce fix(schema): recurse additional and pattern properties in required cleanup 2026-04-15 16:48:49 +09:00
ismeth 1ae6089bb3 fix(athena): restore opportunistic retry flow and include athena-junior builtin name 2026-04-15 16:48:49 +09:00
ismeth 169118c9e1 fix: preserve tuple items in schema build and harden athena prompt path guard 2026-04-15 16:48:49 +09:00
ismeth 62cf707502 fix: resolve 11 council-audited violations across athena subsystem
- Add switch_agent to athena-junior deny list (P1 defense-in-depth)
- Add terminal status check to waitForSessionIds polling loop
- Add athena-junior to OverridableAgentNameSchema and AgentOverridesSchema
- Add explicit retry workflow instructions to non-interactive prompt Step 9
- Fix JSON schema generation to exclude defaulted fields from required arrays
- Fix docs example for non_interactive_member_list (remove Council: prefix)
- Use segment-aware regex in path-policy.ts to block fake.sisyphus/ paths
- Add defensive path resolution and contract validation for prompt_file
- Add explicit .optional() to AthenaOverrideConfigSchema fields for clarity
- Fix traversal check precision for .. prefixed directory names
2026-04-15 16:48:49 +09:00
ismeth 6db83b937f fix: resolve 7 council-validated PR violations
- Fix misleading background_wait instructions to show loop pattern with
  remaining_task_ids (race semantics, not block-all)
- Fix wrong Gemini model string: gemini-3-pro-preview → gemini-3-pro
- Add getMainSessionID() fallback when input.sessionID is undefined
- Narrow .gitignore packages/ to only ignore built binaries
- Fix contradictory config doc: non_interactive_members 'all' → 'custom'
- Add athena-junior to keyword-detector exclusion check
- Add .trim() before .toUpperCase() in resolveCouncilIntent
- Update snapshots for model string change
2026-04-15 16:48:48 +09:00
ismeth c796187ee5 fix(test): replace /etc/passwd with innocuous paths to avoid GitGuardian false positive 2026-04-15 16:48:48 +09:00
ismeth a8eb22d3f1 docs(athena): comprehensive council documentation covering all configs and behaviors
Added missing documentation for:
- Council resilience settings (retry_on_fail, stuck_threshold, member_max_running)
- bulk_launch config for launch strategy
- Council tools (prepare_council_prompt, athena_council, council_finalize)
- Council archives (.sisyphus/athena/)
- Force-background and TTL exemption for athena-junior
- Council-member agent overrides and tool allowlist
- How to invoke athena-junior (task() and CLI)
- Updated agent list to include athena and council-member
- Added Athena subsections to table of contents
- Auto-generated schema.json update for bulk_launch field
2026-04-15 16:48:48 +09:00
ismeth 67de601807 fix(athena): always show background_wait guidance for athena-junior, not just when forced
The background_wait instruction was only shown when the caller passed
run_in_background=false (forced case). But callers passing true also need
the guidance since they were polling background_output instead. Now
athena-junior always gets background_wait instructions regardless of how
it was launched.
2026-04-15 16:48:48 +09:00
ismeth 4d3cbda8ce fix(athena): guide callers to background_wait when athena-junior is force-backgrounded
When athena-junior is force-backgrounded (caller passed run_in_background=false),
the response now instructs the caller to use background_wait instead of
background_output, preventing repeated polling loops.
2026-04-15 16:48:47 +09:00
ismeth 513a5c90b1 fix(athena): force athena-junior to background and exempt from hard TTL
Council sessions are long-running: athena-junior launches members then
waits for them via background_wait. Two changes prevent premature kills:

- Force run_in_background=true when subagent_type resolves to athena-junior,
  avoiding the 10-minute sync poll timeout (MAX_POLL_TIME_MS)
- Exempt athena-junior from the 30-minute TASK_TTL_MS hard cutoff since
  council members have their own independent TTLs
- Fix missing bulk_launch field in AthenaOverrideConfigSchema (type error)
2026-04-15 16:48:47 +09:00
ismeth 5e71d84a69 feat(athena): add bulk_launch config for council launch strategy
New config: agents.athena.bulk_launch (boolean, default false)
- false: launch members one-by-one via task() for TUI inspectability
- true: launch all members at once via athena_council tool

Prompt uses {BULK_LAUNCH_STEP_5_2} placeholder injected at runtime
based on config value. Schema, caller, and tests updated.
2026-04-15 16:48:47 +09:00
ismeth febffeebb1 fix(tools): deny council tools globally via permission system
The config.tools boolean false wasn't blocking plugin-registered tools.
Add prepare_council_prompt, council_finalize, athena_council to global
permission deny — same pattern as task: deny. Per-agent allow on
athena/athena-junior overrides the global deny.
2026-04-15 16:48:47 +09:00
ismeth c384fd0a02 fix(athena): grant athena_council tool to athena primary agent
Council tools (prepare_council_prompt, council_finalize, athena_council) are
globally disabled and only re-enabled for athena and athena-junior. Athena
was missing athena_council — now both agents have symmetric access.

Also fix parity test to include council_finalize and athena_council in
ATHENA_HANDLER_GRANTS for complete coverage.
2026-04-15 16:48:47 +09:00
ismeth 30cf71a845 fix(athena-junior): remove synthesis and question from council result JSON
Keep the council result JSON lean as a metadata envelope. Full synthesis
is already persisted at {archive_dir}/synthesis.md — duplicating it in
the JSON created noise that obscured structural fields like archive_dir.

Also instructs athena-junior to remind the caller to read the full
synthesis and member responses from the archive directory.
2026-04-15 16:48:47 +09:00
ismeth 102b754f1e fix(athena): remove athena primary from delegation list and switch_agent targets
Athena primary should not be routable via switch_agent or appear in the
delegation table. Only athena-junior (subagent) remains delegatable via task().

- Remove athena from ALLOWED_AGENTS and DESCRIPTION in switch-agent tool
- Remove ATHENA_PROMPT_METADATA from agentMetadata, agent.ts, barrel export
- Update switch-agent test to assert athena rejection
- Remove ATHENA_PROMPT_METADATA test block
2026-04-15 16:48:47 +09:00
ismeth efc53de531 feat(athena): complete delegation routing fix with mode-aware delegation table
- Re-add ATHENA_PROMPT_METADATA with tight triggers and avoidWhen guardrails
- Update switch_agent tool description with permanent handoff guardrail
- Make buildDelegationTable mode-aware: switch_agent for primary, task() for subagent
- Pass agent mode through general-agents to AvailableAgent interface
- Improve primary agent error messages in subagent-resolver with alternatives
- Add council-first bias to Athena interactive prompt
- Update athena-junior trigger text for clearer task() invocation guidance
- Add tests for ATHENA_PROMPT_METADATA shape, triggers, useWhen, avoidWhen
2026-04-15 16:48:46 +09:00
ismeth 7ffdd15b52 feat(athena-junior): add athena_council bulk launch tool
- Create src/tools/athena-council/ with council-launcher, tool factory, types
- Launch all council members in parallel via BackgroundManager with writeOutputToFile: true
- Wire tool into registry with backgroundManager + councilConfig dependencies
- Grant athena-junior athena_council permission, remove task permission
- Update non-interactive prompt to use athena_council instead of task tool
- Add explicit stop-after-result instruction to prevent post-output text
- 23 tests (14 tool + 9 launcher) using real temp files, no mock.module
2026-04-15 16:48:46 +09:00
ismeth ffde7a6853 fix(test): update model-requirements test for 13 builtin agents
Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-15 16:48:46 +09:00
ismeth 149d065d68 feat(athena): split into athena (interactive) and athena-junior (subagent)
Split the Athena council orchestrator into two distinct agents:
- athena: primary mode, interactive prompt with Question tool and switch_agent
- athena-junior: subagent mode, non-interactive prompt with structured JSON output

Key changes:
- Create athena-junior-agent.ts factory (mode=subagent, denies question+call_omo_agent)
- Revert athena agent.ts to primary mode (no env var switching)
- Make buildAthenaRuntimeGuidance mode-aware (strips action_paths for non-interactive)
- Add mode parameter to council_finalize tool
- Register athena-junior in builtin-agents, tool-config, model-requirements
- Replace "athena" with "athena-junior" in call_omo_agent ALLOWED_AGENTS
- Update all tests for new architecture

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-15 16:48:46 +09:00
ismeth deb2a2754e feat(athena): add non-interactive fields to override schema
Extend AthenaOverrideConfigSchema with non_interactive_mode,
non_interactive_members, non_interactive_member_list. Replace
Record<string, unknown> casts with proper typed access.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-15 16:48:45 +09:00
ismeth 05d4ecf2ff feat(athena): inject non-interactive config placeholders into prompt
Add 4 new .replace() calls for NON_INTERACTIVE_MODE, NON_INTERACTIVE_MEMBERS,
NON_INTERACTIVE_MEMBER_LIST, and BACKGROUND_WAIT_TIMEOUT_MS. Pass athena
non-interactive config from agent-config-handler to createBuiltinAgents.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-15 16:48:45 +09:00
ismeth 61ccd7f9a7 fix(athena): include MODE=all agents in uiSelectedModel passthrough
The general-agents.ts isPrimaryAgent check only considered mode=primary,
causing Athena (now mode=all) to lose uiSelectedModel resolution.
Also adds metadata tests for non-interactive triggers.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-15 16:48:45 +09:00
ismeth 6fb6d1256c feat(athena): dual prompt selection with MODE=all
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-15 16:48:45 +09:00
ismeth e01742c8b2 feat(athena): add athena to switch-agent and call-omo-agent allowed lists 2026-04-15 16:48:45 +09:00
ismeth cee2baf421 feat(athena): add non-interactive prompt
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-15 16:48:45 +09:00
ismeth 6a889d472d feat(athena): extend config schema with non-interactive fields
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-15 16:48:45 +09:00
ismeth 1c27867fc9 feat(athena): extract interactive prompt to dedicated file
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-15 16:48:45 +09:00
ismeth 3468c72dfa test(council): add comprehensive meta-yaml-formatter tests 2026-04-15 16:48:45 +09:00
ismeth 9e196a21d7 fix(council): fix nudge retry cap bypass and add memory cleanup 2026-04-15 16:48:45 +09:00
ismeth e15ce7b279 fix(council): increase archive ID entropy and remove unused toolContext param
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-15 16:48:45 +09:00
ismeth 3d36f6c5d8 fix(council): handle whitespace around COUNCIL_MEMBER_RESPONSE tags
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-15 16:48:45 +09:00
ismeth 93b77046cf refactor(athena): extract shared guidance boilerplate into shared module 2026-04-15 16:48:45 +09:00
ismeth 5837ec1b6b fix(athena): rewrite council member prompt to be intent-agnostic (Option B)
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-15 16:48:44 +09:00
ismeth 4a7ddae53f refactor(council): move hasCouncilResponseTag to council-response-extractor
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-15 16:48:44 +09:00
ismeth 45d3eb65df fix(council): add error logging to empty catch in council-finalize-helpers
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-15 16:48:44 +09:00
ismeth 9eb91ab631 fix(athena): use constants.ts as single source of truth for council defaults
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-15 16:48:44 +09:00
ismeth 7bfd5f13d0 fix(athena): replace generic Option A/B labels with synthesis-derived fix approaches in audit one-by-one review
Athena misinterpreted generic per-finding option labels as execution agent names. Rewrite Step 3 "Mode: One by one" to use descriptive remediation approach labels derived from synthesis, add instruction block clarifying options vs execution methods, and show all three cases (multiple/single/no fix suggestions) in the example.
2026-04-15 16:48:44 +09:00