diff --git a/src/agents/athena/guidance/audit.ts b/src/agents/athena/guidance/audit.ts
index 489311bca..099457ae4 100644
--- a/src/agents/athena/guidance/audit.ts
+++ b/src/agents/athena/guidance/audit.ts
@@ -3,16 +3,50 @@ import { FOLLOWUP_OR_DONE_QUESTION_BODY } from "./shared-action-paths"
export const AUDIT_GUIDANCE = `
Use AUDIT synthesis.
-- Output numbered findings grouped by confidence: unanimous, majority, minority, solo.
-- For each finding: issue, impact, evidence, fix direction.
+- Output numbered findings grouped by confidence: UNANIMOUS (all or nearly all members agree), MAJORITY (more than half agree), MINORITY (2-3 members), SOLO (single member).
+- Each finding MUST use this exact format:
+
+ #### #{number}: {title}
+ - **Severity**: {Critical|High|Medium|Low}
+ - **Confidence**: {Unanimous|Majority|Minority|Solo} ({N} members)
+ - **Members Reported**: [{member1}, {member2}, ...]
+ - **Issue**: {description}
+ - **Evidence**: {file:line references, code snippets}
+ - **Impact**: {what breaks or degrades}
+ - **Fix Direction**: {concrete remediation approach}
+
+- After all findings, include a summary table with columns: #, Finding, Severity, Agreement, Members Reported.
+- End with a Priority Recommendations section grouping findings by action urgency.
+- If any findings are dismissed as false positives, list them in a Dismissed section with reasoning.
Path type: ACTIONABLE.
-1) Build actionable findings list from audit synthesis.
+1) After synthesis, check for minority and solo findings (findings reported by fewer than half the council members).
-2) Ask how the user wants to process findings:
+2) If minority or solo findings exist, ask the user about cross-checking BEFORE processing:
+Question({
+ questions: [{
+ question: "The audit found {N} findings with low agreement (minority/solo). Cross-checking sends these to ALL council members for independent verification. This costs one additional council round.",
+ header: "Cross-check?",
+ options: [
+ { label: "Cross-check low-confidence findings", description: "Launch a new council round where all members evaluate the {N} minority/solo findings" },
+ { label: "Skip cross-check", description: "Proceed to findings processing with current confidence levels" }
+ ],
+ multiple: false
+ }]
+})
+
+3) If user chose cross-check:
+- Build a cross-check prompt listing each minority/solo finding with its full details (ID, title, severity, evidence, fix direction).
+- Use the standard council flow: prepare_council_prompt(prompt=cross_check_prompt, mode=same_mode, intent="AUDIT") -> athena_council -> background_wait -> council_finalize.
+- The cross-check prompt should instruct each member: "For each finding below, independently evaluate against the codebase. For each: (1) AGREE or DISAGREE, (2) your severity rating, (3) evidence supporting your assessment. Wrap your evaluation in tags."
+- After collecting cross-check results, re-synthesize: update each cross-checked finding with the new agreement level, note changed assessments, promote/demote findings based on cross-check votes.
+- Write the updated synthesis.md (overwrite the previous one in the same archive_dir).
+- Include a Cross-Check Results section showing how each finding's confidence changed.
+
+4) If no minority/solo findings exist, OR user chose to skip cross-check, proceed to processing mode:
Question({
questions: [{
question: "How would you like to process the findings?",
@@ -26,12 +60,12 @@ Question({
}]
})
-3) Branch by processing mode.
+5) Branch by processing mode.
Mode: One by one
- Per-finding fix options MUST be derived from the synthesis's fix directions / suggested fixes.
- Each option represents a remediation APPROACH (e.g., "Add input validation", "Refactor to use parameterized queries"), NOT an execution agent.
-- NEVER use agent names (Atlas, Prometheus, Hephaestus, Sisyphus) as per-finding option labels — those belong ONLY to Step 5 (execution method).
+- NEVER use agent names (Atlas, Prometheus, Hephaestus, Sisyphus) as per-finding option labels — those belong ONLY in Step 7 (execution method).
- Handle variable fix counts per finding:
- If a finding has NO fix suggestion from synthesis -> show only Skip / Defer / Stop review.
- If a finding has exactly ONE fix suggestion -> show that fix + Skip / Defer / Stop review.
@@ -124,13 +158,13 @@ Question({
})
- Resolve selected buckets into concrete finding IDs.
-4) If actionable findings count is 0 OR user selected no findings, do NOT ask execution action. Ask:
+6) If actionable findings count is 0 OR user selected no findings, do NOT ask execution action. Ask:
Question({
questions: [{
question: "No findings were selected for action. What should we do next?",
${FOLLOWUP_OR_DONE_QUESTION_BODY}
-5) If selected findings exist, ask what action to take on the selected findings:
+7) If selected findings exist, ask what action to take on the selected findings:
Question({
questions: [{
question: "How should we handle the selected findings?",
@@ -140,18 +174,16 @@ Question({
{ label: "Fix now with (Hephaestus)", description: "Hand off to Hephaestus for direct implementation" },
{ label: "Fix now with (Sisyphus)", description: "Hand off to Sisyphus for collaborative implementation" },
{ label: "Create plan (Prometheus)", description: "Hand off to Prometheus for planning and phased execution" },
- { label: "Cross-check with council", description: "Launch a new council session with this synthesis as context" },
{ label: "No action", description: "Review only - no delegation" }
],
multiple: false
}]
})
-6) Execute selected action:
+8) Execute selected action:
- Fix now with (Atlas) -> switch_agent(agent="atlas") with ONLY selected findings
- Fix now with (Hephaestus) -> switch_agent(agent="hephaestus") with ONLY selected findings
- Fix now with (Sisyphus) -> switch_agent(agent="sisyphus") with ONLY selected findings
- Create plan (Prometheus) -> switch_agent(agent="prometheus") with ONLY selected findings
-- Cross-check with council -> launch a new council session with the current synthesis as context. Restart from Step 2 (council setup) with the synthesis included in the prompt.
- No action -> acknowledge and end
`
diff --git a/src/agents/athena/interactive-prompt.ts b/src/agents/athena/interactive-prompt.ts
index aa63e2cfd..db63e6498 100644
--- a/src/agents/athena/interactive-prompt.ts
+++ b/src/agents/athena/interactive-prompt.ts
@@ -270,6 +270,21 @@ After Step 7, you will receive a separate runtime guidance message injected by c
Treat the injected runtime guidance as authoritative over generic defaults.
Universal requirements (all intents):
+- ALWAYS start synthesis.md with this YAML front-matter header:
+
+ ---
+ council: {archive_dir basename, e.g. council-auth-review-a1b2c3d4}
+ question: {original user question, verbatim}
+ date: {ISO 8601 date of synthesis}
+ members: [{member1}, {member2}, ...]
+ session_ids: [{bg_xxx}, {bg_xxx}, ...]
+ mode: {Solo|Delegation}
+ intent: {AUDIT|PLAN|EVALUATE|DIAGNOSE|EXPLAIN|CREATE|PERSPECTIVES|FREEFORM}
+ responded: {N}/{total}
+ ---
+
+- The header values come from your council session: question and intent from council_finalize args, members and session_ids from Step 6 launch, mode from Step 2, responded count from council_finalize result.
+- After the front-matter, write the intent-specific synthesis content following the runtime guidance.
- Track agreement/disagreement across members and use agreement level as a confidence signal.
- Flag single-member points as lower confidence.
- Be concrete and evidence-based.
diff --git a/src/tools/council-archive/create-council-finalize.ts b/src/tools/council-archive/create-council-finalize.ts
index 6f5063563..d21cf1c74 100644
--- a/src/tools/council-archive/create-council-finalize.ts
+++ b/src/tools/council-archive/create-council-finalize.ts
@@ -144,8 +144,12 @@ export function createCouncilFinalize(
})
}
+ let promptFileMoved = false
const relPromptFile = args.prompt_file
- ? await movePromptFile(args.prompt_file, base, absArchiveDir, relArchiveDir)
+ ? await movePromptFile(args.prompt_file, base, absArchiveDir, relArchiveDir).then((result) => {
+ promptFileMoved = true
+ return result
+ })
: undefined
const relMetaFile = join(relArchiveDir, "meta.yaml")
@@ -164,7 +168,7 @@ export function createCouncilFinalize(
const guidance = buildAthenaRuntimeGuidance(resolvedIntent, resolvedMode)
return JSON.stringify(result, null, 2) + "\n\n" + guidance
} finally {
- if (args.prompt_file) {
+ if (args.prompt_file && !promptFileMoved) {
await cleanupPromptFile(args.prompt_file, base)
}
}