fix(athena): address 11 audit findings (H2,H3,H5,M1-M4,M8-M11)
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
@@ -0,0 +1,7 @@
|
||||
export const COUNCIL_DEFAULTS = {
|
||||
CLEANUP_DELAY_MS: 30 * 60 * 1000,
|
||||
BACKGROUND_WAIT_TIMEOUT_MS: 30000,
|
||||
STUCK_THRESHOLD_SECONDS: 120,
|
||||
MEMBER_MAX_RUNNING_SECONDS: 1800,
|
||||
ARCHIVE_ID_BYTES: 2,
|
||||
} as const
|
||||
@@ -1,5 +1,5 @@
|
||||
import { describe, expect, it } from "bun:test"
|
||||
import { COUNCIL_MEMBER_PROMPT } from "./council-member-agent"
|
||||
import { COUNCIL_MEMBER_PROMPT, createCouncilMemberAgent } from "./council-member-agent"
|
||||
|
||||
describe("COUNCIL_MEMBER_PROMPT", () => {
|
||||
describe("#given the prompt constant", () => {
|
||||
@@ -44,3 +44,79 @@ describe("COUNCIL_MEMBER_PROMPT", () => {
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe("createCouncilMemberAgent", () => {
|
||||
describe("#given a model string", () => {
|
||||
describe("#when creating a council member agent", () => {
|
||||
const agent = createCouncilMemberAgent("openai/gpt-5-nano")
|
||||
|
||||
it("#then returns an object with the given model", () => {
|
||||
expect(agent.model).toBe("openai/gpt-5-nano")
|
||||
})
|
||||
|
||||
it("#then has temperature 0.1", () => {
|
||||
expect(agent.temperature).toBe(0.1)
|
||||
})
|
||||
|
||||
it("#then has the COUNCIL_MEMBER_PROMPT as prompt", () => {
|
||||
expect(agent.prompt).toBe(COUNCIL_MEMBER_PROMPT)
|
||||
})
|
||||
|
||||
it("#then has mode subagent", () => {
|
||||
expect(agent.mode).toBe("subagent")
|
||||
})
|
||||
|
||||
it("#then has tool restrictions with permission object", () => {
|
||||
expect(agent.permission).toBeDefined()
|
||||
})
|
||||
|
||||
it("#then allows read tool", () => {
|
||||
const perm = agent.permission as Record<string, string>
|
||||
expect(perm.read).toBe("allow")
|
||||
})
|
||||
|
||||
it("#then allows grep tool", () => {
|
||||
const perm = agent.permission as Record<string, string>
|
||||
expect(perm.grep).toBe("allow")
|
||||
})
|
||||
|
||||
it("#then allows glob tool", () => {
|
||||
const perm = agent.permission as Record<string, string>
|
||||
expect(perm.glob).toBe("allow")
|
||||
})
|
||||
|
||||
it("#then allows lsp_goto_definition tool", () => {
|
||||
const perm = agent.permission as Record<string, string>
|
||||
expect(perm.lsp_goto_definition).toBe("allow")
|
||||
})
|
||||
|
||||
it("#then allows ast_grep_search tool", () => {
|
||||
const perm = agent.permission as Record<string, string>
|
||||
expect(perm.ast_grep_search).toBe("allow")
|
||||
})
|
||||
|
||||
it("#then denies all other tools via wildcard", () => {
|
||||
const perm = agent.permission as Record<string, string>
|
||||
expect(perm["*"]).toBe("deny")
|
||||
})
|
||||
|
||||
it("#then explicitly denies todowrite", () => {
|
||||
const perm = agent.permission as Record<string, string>
|
||||
expect(perm.todowrite).toBe("deny")
|
||||
})
|
||||
|
||||
it("#then explicitly denies todoread", () => {
|
||||
const perm = agent.permission as Record<string, string>
|
||||
expect(perm.todoread).toBe("deny")
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe("#given the factory function", () => {
|
||||
describe("#when checking the static mode property", () => {
|
||||
it("#then has mode 'subagent'", () => {
|
||||
expect(createCouncilMemberAgent.mode).toBe("subagent")
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@@ -36,7 +36,8 @@ Example:
|
||||
Your analysis here...
|
||||
</COUNCIL_MEMBER_RESPONSE>
|
||||
|
||||
If you do not wrap your response in <COUNCIL_MEMBER_RESPONSE> tags, your analysis will not be included in the synthesis.`
|
||||
If you do not wrap your response in <COUNCIL_MEMBER_RESPONSE> tags, your analysis will not be included in the synthesis.
|
||||
Your response inside the tags must be at least 100 characters of substantive content. Empty or trivially short responses will be treated as missing and will not count toward quorum.`
|
||||
|
||||
export const COUNCIL_SOLO_ADDENDUM = `
|
||||
## Solo Analysis Mode
|
||||
|
||||
@@ -0,0 +1,170 @@
|
||||
import { describe, expect, it } from "bun:test"
|
||||
import { resolveCouncilIntent, buildAthenaRuntimeGuidance, getValidCouncilIntents } from "./council-runtime-guidance"
|
||||
|
||||
describe("council-runtime-guidance", () => {
|
||||
describe("resolveCouncilIntent", () => {
|
||||
describe("#given valid uppercase intents", () => {
|
||||
describe("#when called with each valid intent", () => {
|
||||
const validIntents = ["DIAGNOSE", "AUDIT", "PLAN", "EVALUATE", "EXPLAIN", "CREATE", "PERSPECTIVES", "FREEFORM"] as const
|
||||
|
||||
for (const intent of validIntents) {
|
||||
it(`#then returns "${intent}" for "${intent}"`, () => {
|
||||
expect(resolveCouncilIntent(intent)).toBe(intent)
|
||||
})
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
describe("#given lowercase intents", () => {
|
||||
describe("#when called with lowercase versions", () => {
|
||||
it("#then normalizes 'diagnose' to 'DIAGNOSE'", () => {
|
||||
expect(resolveCouncilIntent("diagnose")).toBe("DIAGNOSE")
|
||||
})
|
||||
|
||||
it("#then normalizes 'audit' to 'AUDIT'", () => {
|
||||
expect(resolveCouncilIntent("audit")).toBe("AUDIT")
|
||||
})
|
||||
|
||||
it("#then normalizes 'freeform' to 'FREEFORM'", () => {
|
||||
expect(resolveCouncilIntent("freeform")).toBe("FREEFORM")
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe("#given mixed case intents", () => {
|
||||
describe("#when called with mixed case", () => {
|
||||
it("#then normalizes 'Audit' to 'AUDIT'", () => {
|
||||
expect(resolveCouncilIntent("Audit")).toBe("AUDIT")
|
||||
})
|
||||
|
||||
it("#then normalizes 'DiAgNoSe' to 'DIAGNOSE'", () => {
|
||||
expect(resolveCouncilIntent("DiAgNoSe")).toBe("DIAGNOSE")
|
||||
})
|
||||
|
||||
it("#then normalizes 'Perspectives' to 'PERSPECTIVES'", () => {
|
||||
expect(resolveCouncilIntent("Perspectives")).toBe("PERSPECTIVES")
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe("#given invalid inputs", () => {
|
||||
describe("#when called with an unrecognized intent", () => {
|
||||
it("#then returns null for 'INVALID'", () => {
|
||||
expect(resolveCouncilIntent("INVALID")).toBeNull()
|
||||
})
|
||||
|
||||
it("#then returns null for 'COMPARISON'", () => {
|
||||
expect(resolveCouncilIntent("COMPARISON")).toBeNull()
|
||||
})
|
||||
})
|
||||
|
||||
describe("#when called with undefined", () => {
|
||||
it("#then returns null", () => {
|
||||
expect(resolveCouncilIntent(undefined)).toBeNull()
|
||||
})
|
||||
})
|
||||
|
||||
describe("#when called with empty string", () => {
|
||||
it("#then returns null", () => {
|
||||
expect(resolveCouncilIntent("")).toBeNull()
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe("buildAthenaRuntimeGuidance", () => {
|
||||
describe("#given a valid intent", () => {
|
||||
describe("#when building guidance for DIAGNOSE", () => {
|
||||
it("#then wraps content in athena_runtime_guidance tags", () => {
|
||||
const result = buildAthenaRuntimeGuidance("DIAGNOSE")
|
||||
expect(result).toContain("<athena_runtime_guidance>")
|
||||
expect(result).toContain("</athena_runtime_guidance>")
|
||||
})
|
||||
|
||||
it("#then contains the intent name", () => {
|
||||
const result = buildAthenaRuntimeGuidance("DIAGNOSE")
|
||||
expect(result).toContain("intent: DIAGNOSE")
|
||||
})
|
||||
|
||||
it("#then contains DIAGNOSE-specific content about root cause", () => {
|
||||
const result = buildAthenaRuntimeGuidance("DIAGNOSE")
|
||||
expect(result).toContain("root cause")
|
||||
})
|
||||
})
|
||||
|
||||
describe("#when building guidance for AUDIT", () => {
|
||||
it("#then contains the AUDIT intent name", () => {
|
||||
const result = buildAthenaRuntimeGuidance("AUDIT")
|
||||
expect(result).toContain("intent: AUDIT")
|
||||
})
|
||||
|
||||
it("#then contains AUDIT-specific synthesis rules", () => {
|
||||
const result = buildAthenaRuntimeGuidance("AUDIT")
|
||||
expect(result).toContain("AUDIT synthesis")
|
||||
})
|
||||
})
|
||||
|
||||
describe("#when building guidance for FREEFORM", () => {
|
||||
it("#then contains FREEFORM intent name", () => {
|
||||
const result = buildAthenaRuntimeGuidance("FREEFORM")
|
||||
expect(result).toContain("intent: FREEFORM")
|
||||
})
|
||||
|
||||
it("#then contains FREEFORM-specific content", () => {
|
||||
const result = buildAthenaRuntimeGuidance("FREEFORM")
|
||||
expect(result).toContain("FREEFORM synthesis")
|
||||
})
|
||||
})
|
||||
|
||||
describe("#when building guidance for each intent", () => {
|
||||
const allIntents = ["DIAGNOSE", "AUDIT", "PLAN", "EVALUATE", "EXPLAIN", "CREATE", "PERSPECTIVES", "FREEFORM"] as const
|
||||
|
||||
for (const intent of allIntents) {
|
||||
it(`#then ${intent} guidance contains runtime_synthesis_rules`, () => {
|
||||
const result = buildAthenaRuntimeGuidance(intent)
|
||||
expect(result).toContain("runtime_synthesis_rules")
|
||||
})
|
||||
|
||||
it(`#then ${intent} guidance contains runtime_action_paths`, () => {
|
||||
const result = buildAthenaRuntimeGuidance(intent)
|
||||
expect(result).toContain("runtime_action_paths")
|
||||
})
|
||||
|
||||
it(`#then ${intent} guidance contains source: council_finalize`, () => {
|
||||
const result = buildAthenaRuntimeGuidance(intent)
|
||||
expect(result).toContain("source: council_finalize")
|
||||
})
|
||||
}
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe("getValidCouncilIntents", () => {
|
||||
describe("#given the function is called", () => {
|
||||
describe("#when retrieving valid intents", () => {
|
||||
it("#then returns an array of 8 intents", () => {
|
||||
const intents = getValidCouncilIntents()
|
||||
expect(intents).toHaveLength(8)
|
||||
})
|
||||
|
||||
it("#then contains all expected intent values", () => {
|
||||
const intents = getValidCouncilIntents()
|
||||
expect(intents).toContain("DIAGNOSE")
|
||||
expect(intents).toContain("AUDIT")
|
||||
expect(intents).toContain("PLAN")
|
||||
expect(intents).toContain("EVALUATE")
|
||||
expect(intents).toContain("EXPLAIN")
|
||||
expect(intents).toContain("CREATE")
|
||||
expect(intents).toContain("PERSPECTIVES")
|
||||
expect(intents).toContain("FREEFORM")
|
||||
})
|
||||
|
||||
it("#then returns a readonly array", () => {
|
||||
const intents1 = getValidCouncilIntents()
|
||||
const intents2 = getValidCouncilIntents()
|
||||
expect(intents1).toBe(intents2)
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
@@ -7,3 +7,4 @@ export {
|
||||
resolveCouncilIntent,
|
||||
} from "./council-runtime-guidance"
|
||||
export type { CouncilIntent } from "./council-runtime-guidance"
|
||||
export { COUNCIL_DEFAULTS } from "./constants"
|
||||
|
||||
@@ -83,4 +83,75 @@ describe("council-member-agents", () => {
|
||||
expect(result.registeredKeys).toHaveLength(0)
|
||||
expect(result.agents).toEqual({})
|
||||
})
|
||||
|
||||
test("returns skippedMembers with reason for invalid model format", () => {
|
||||
//#given
|
||||
const config = {
|
||||
members: [
|
||||
{ model: "openai/gpt-5.3-codex", name: "GPT" },
|
||||
{ model: "no-slash", name: "Bad" },
|
||||
{ model: "anthropic/claude-opus-4-6", name: "Claude" },
|
||||
],
|
||||
retry_on_fail: 0,
|
||||
retry_failed_if_others_finished: false,
|
||||
cancel_retrying_on_quorum: true,
|
||||
stuck_threshold_seconds: 120,
|
||||
member_max_running_seconds: 1800,
|
||||
}
|
||||
//#when
|
||||
const result = registerCouncilMemberAgents(config)
|
||||
//#then
|
||||
expect(result.skippedMembers).toHaveLength(1)
|
||||
expect(result.skippedMembers[0].name).toBe("Bad")
|
||||
expect(result.skippedMembers[0].reason).toContain("Invalid model format")
|
||||
expect(result.skippedMembers[0].reason).toContain("no-slash")
|
||||
})
|
||||
|
||||
test("returns skippedMembers with reason for duplicate names", () => {
|
||||
//#given
|
||||
const config = {
|
||||
members: [
|
||||
{ model: "openai/gpt-5.3-codex", name: "Alpha" },
|
||||
{ model: "anthropic/claude-opus-4-6", name: "Beta" },
|
||||
{ model: "google/gemini-3-pro", name: "alpha" },
|
||||
],
|
||||
retry_on_fail: 0,
|
||||
retry_failed_if_others_finished: false,
|
||||
cancel_retrying_on_quorum: true,
|
||||
stuck_threshold_seconds: 120,
|
||||
member_max_running_seconds: 1800,
|
||||
}
|
||||
//#when
|
||||
const result = registerCouncilMemberAgents(config)
|
||||
//#then
|
||||
expect(result.registeredKeys).toHaveLength(2)
|
||||
expect(result.skippedMembers).toHaveLength(1)
|
||||
expect(result.skippedMembers[0].name).toBe("alpha")
|
||||
expect(result.skippedMembers[0].reason).toContain("Duplicate name")
|
||||
})
|
||||
|
||||
test("returns skippedMembers combining both invalid model and duplicate reasons", () => {
|
||||
//#given
|
||||
const config = {
|
||||
members: [
|
||||
{ model: "openai/gpt-5.3-codex", name: "GPT" },
|
||||
{ model: "bad-model", name: "Invalid" },
|
||||
{ model: "anthropic/claude-opus-4-6", name: "Claude" },
|
||||
{ model: "google/gemini-3-pro", name: "gpt" },
|
||||
],
|
||||
retry_on_fail: 0,
|
||||
retry_failed_if_others_finished: false,
|
||||
cancel_retrying_on_quorum: true,
|
||||
stuck_threshold_seconds: 120,
|
||||
member_max_running_seconds: 1800,
|
||||
}
|
||||
//#when
|
||||
const result = registerCouncilMemberAgents(config)
|
||||
//#then
|
||||
expect(result.skippedMembers).toHaveLength(2)
|
||||
expect(result.skippedMembers[0].name).toBe("Invalid")
|
||||
expect(result.skippedMembers[0].reason).toContain("Invalid model format")
|
||||
expect(result.skippedMembers[1].name).toBe("gpt")
|
||||
expect(result.skippedMembers[1].reason).toContain("Duplicate name")
|
||||
})
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user