immune-brain 3.6.5 → 3.6.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +69 -3
- package/README.zh-CN.md +23 -3
- package/package.json +2 -1
- package/plugins/immune-brain/.claude-plugin/plugin.json +1 -1
- package/plugins/immune-brain/.pi-extension/imm-canary-work.ts +60 -21
- package/plugins/immune-brain/.pi-extension/imm-unattended-batch.ts +932 -0
- package/plugins/immune-brain/.pi-extension/pi-canary-interaction.ts +38 -10
- package/plugins/immune-brain/.pi-extension/runtime-stub.ts +200 -2
- package/plugins/immune-brain/dist/BASELINE.md +48 -15
- package/plugins/immune-brain/dist/claude/mcp-server.mjs +3415 -228
- package/plugins/immune-brain/dist/docs/reference/planning-quality-gate.md +1 -1
- package/plugins/immune-brain/dist/docs/reference/subagent-dispatch-protocol.md +1 -1
- package/plugins/immune-brain/dist/imm-agent-doc-maintain.md +9 -1
- package/plugins/immune-brain/dist/imm-brainstorm.md +49 -35
- package/plugins/immune-brain/dist/imm-doc-prune.md +7 -1
- package/plugins/immune-brain/dist/imm-loop.md +45 -11
- package/plugins/immune-brain/dist/imm-planner.md +65 -28
- package/plugins/immune-brain/dist/imm-pr-fix.md +6 -2
- package/plugins/immune-brain/dist/role-prompts/code-review.md +9 -1
- package/plugins/immune-brain/dist/role-prompts/executor.md +18 -10
- package/plugins/immune-brain/dist/role-prompts/pr-fix.md +5 -2
- package/plugins/immune-brain/runtime/assurance/coordinator.ts +101 -3
- package/plugins/immune-brain/runtime/assurance/verification.ts +13 -2
- package/plugins/immune-brain/runtime/claude/interaction.ts +16 -3
- package/plugins/immune-brain/runtime/claude/kernel_ports.ts +840 -17
- package/plugins/immune-brain/runtime/claude/mcp_server.ts +72 -10
- package/plugins/immune-brain/runtime/github_issue_tracker.ts +1018 -17
- package/plugins/immune-brain/runtime/kernel/canary_application.ts +16 -1
- package/plugins/immune-brain/runtime/kernel/completion.ts +19 -1
- package/plugins/immune-brain/runtime/kernel/reducer.ts +165 -12
- package/plugins/immune-brain/runtime/kernel/refutation.ts +82 -0
- package/plugins/immune-brain/runtime/kernel/types.ts +34 -1
- package/plugins/immune-brain/runtime/kernel/validation.ts +202 -9
- package/plugins/immune-brain/runtime/plugin_version.ts +1 -1
- package/plugins/immune-brain/runtime/prompts/code-review.md +9 -1
- package/plugins/immune-brain/runtime/prompts/executor.md +18 -10
- package/plugins/immune-brain/runtime/prompts/pr-fix.md +5 -2
- package/plugins/immune-brain/runtime/unattended/batch_git.ts +775 -0
- package/plugins/immune-brain/runtime/unattended/batch_plan.ts +203 -0
- package/plugins/immune-brain/runtime/unattended/batch_runner.ts +1224 -0
- package/plugins/immune-brain/runtime/unattended/batch_state.ts +360 -0
- package/plugins/immune-brain/runtime/unattended/types.ts +60 -0
- package/plugins/immune-brain/skills/BASELINE.md +48 -15
- package/plugins/immune-brain/skills/imm-agent-doc-maintain/SKILL.md +20 -4
- package/plugins/immune-brain/skills/imm-brainstorm/SKILL.md +24 -64
- package/plugins/immune-brain/skills/imm-doc-prune/SKILL.md +18 -3
- package/plugins/immune-brain/skills/imm-loop/SKILL.md +21 -6
- package/plugins/immune-brain/skills/imm-planner/SKILL.md +35 -8
- package/plugins/immune-brain/skills/imm-pr-fix/SKILL.md +17 -3
|
@@ -25,8 +25,10 @@ export const TOOLS = [
|
|
|
25
25
|
{ name: "request_authorization", description: "Apply exact literal-user authorization.", privileged: true },
|
|
26
26
|
{ name: "approve_breaking_intent_revision", description: "Approve a breaking TaskIntent revision.", privileged: true },
|
|
27
27
|
{ name: "stop", description: "Stop the active task with literal-user authority.", privileged: true },
|
|
28
|
+
{ name: "start_unattended_batch", description: "Start an unattended serial batch run for an Initiative after native confirmation.", privileged: true },
|
|
28
29
|
{ name: "repair_authority_state", description: "Repair a proven recoverable stale backend claim.", privileged: false },
|
|
29
30
|
{ name: "resolve_finding", description: "Resolve one open blocking or advisory finding whose cause is fixed and verified.", privileged: false },
|
|
31
|
+
{ name: "refute_finding", description: "Refute one open finding by binding the fresh passing QA attestation that contradicts it.", privileged: false },
|
|
30
32
|
] as const;
|
|
31
33
|
|
|
32
34
|
export function listMcpTools() {
|
|
@@ -36,17 +38,26 @@ export function listMcpTools() {
|
|
|
36
38
|
inputSchema: {
|
|
37
39
|
type: "object",
|
|
38
40
|
properties: {
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
41
|
+
...(tool.name === "start_unattended_batch"
|
|
42
|
+
? { initiative_slug: { type: "string" } }
|
|
43
|
+
: {
|
|
44
|
+
task_id: { type: "string" },
|
|
45
|
+
...(tool.name === "approve_breaking_intent_revision" ? { next_intent: { type: "object" } } : {}),
|
|
46
|
+
...(tool.name === "stop" ? { reason: { type: "string" } } : {}),
|
|
47
|
+
...(tool.name === "submit_review" ? { verdict: { type: "object" } } : {}),
|
|
48
|
+
...(tool.name === "resolve_finding" ? { finding_id: { type: "string" } } : {}),
|
|
49
|
+
...(tool.name === "refute_finding" ? { finding_id: { type: "string" }, attestation_id: { type: "string" } } : {}),
|
|
50
|
+
}),
|
|
44
51
|
},
|
|
45
|
-
required: tool.name === "
|
|
46
|
-
? ["
|
|
47
|
-
: tool.name === "
|
|
48
|
-
? ["task_id", "
|
|
49
|
-
:
|
|
52
|
+
required: tool.name === "start_unattended_batch"
|
|
53
|
+
? ["initiative_slug"]
|
|
54
|
+
: tool.name === "submit_review"
|
|
55
|
+
? ["task_id", "verdict"]
|
|
56
|
+
: tool.name === "resolve_finding"
|
|
57
|
+
? ["task_id", "finding_id"]
|
|
58
|
+
: tool.name === "refute_finding"
|
|
59
|
+
? ["task_id", "finding_id", "attestation_id"]
|
|
60
|
+
: ["task_id"],
|
|
50
61
|
},
|
|
51
62
|
annotations: tool.privileged ? privilegedAnnotations() : { readOnlyHint: tool.name === "status" },
|
|
52
63
|
}));
|
|
@@ -63,6 +74,9 @@ export interface McpRuntimeOptions {
|
|
|
63
74
|
host?: ClaudeReviewHost;
|
|
64
75
|
interactive?: boolean;
|
|
65
76
|
requestConfirmation?: NativeConfirmationPort;
|
|
77
|
+
batchKernel?: Partial<import("../unattended/batch_runner").BatchRunnerKernelPort>;
|
|
78
|
+
batchGit?: import("../unattended/batch_git").BatchRunnerGitPort;
|
|
79
|
+
readInitiative?: import("../unattended/types").InitiativeObservationReader;
|
|
66
80
|
}
|
|
67
81
|
|
|
68
82
|
export function createMcpRuntime(options: McpRuntimeOptions = {}) {
|
|
@@ -74,6 +88,9 @@ export function createMcpRuntime(options: McpRuntimeOptions = {}) {
|
|
|
74
88
|
ports: options.ports,
|
|
75
89
|
interactive: options.interactive,
|
|
76
90
|
requestConfirmation: options.requestConfirmation,
|
|
91
|
+
batchKernel: options.batchKernel,
|
|
92
|
+
batchGit: options.batchGit,
|
|
93
|
+
readInitiative: options.readInitiative,
|
|
77
94
|
});
|
|
78
95
|
// Trusted Host evidence negotiated on this JSON-RPC connection. Absent
|
|
79
96
|
// handshake evidence means unversioned and non-interactive: fail closed.
|
|
@@ -95,6 +112,26 @@ export function createMcpRuntime(options: McpRuntimeOptions = {}) {
|
|
|
95
112
|
},
|
|
96
113
|
sessionInteractive: () => negotiatedInteractive,
|
|
97
114
|
async callTool(name: string, args: Record<string, unknown>, meta: Partial<ToolMeta> = {}) {
|
|
115
|
+
if (name === "start_unattended_batch") {
|
|
116
|
+
const initiativeSlug = String(args.initiative_slug ?? "");
|
|
117
|
+
if (!initiativeSlug) throw new Error("initiative_slug is required");
|
|
118
|
+
if ("native_decision" in args) throw new Error("native_decision cannot be supplied in tool arguments");
|
|
119
|
+
if (!negotiatedVersion) throw new NativeAuthorityError("unsupported_host", "Claude Code version is unavailable");
|
|
120
|
+
if (!negotiatedInteractive) {
|
|
121
|
+
throw new NativeAuthorityError("unsupported_host", "interactive MCP elicitation is unavailable");
|
|
122
|
+
}
|
|
123
|
+
const probe = probeHost(options.env ?? process.env, process.platform, negotiatedVersion);
|
|
124
|
+
if (!probe.ok) throw new NativeAuthorityError("unsupported_host", probe.reason);
|
|
125
|
+
const toolMeta: ToolMeta = {
|
|
126
|
+
sessionId: meta.sessionId ?? connectionId,
|
|
127
|
+
toolCallId: meta.toolCallId ?? `call-${name}`,
|
|
128
|
+
taskId: initiativeSlug,
|
|
129
|
+
initiativeSlug,
|
|
130
|
+
interactive: meta.interactive ?? options.interactive ?? negotiatedInteractive,
|
|
131
|
+
signal: meta.signal,
|
|
132
|
+
};
|
|
133
|
+
return runtime.startUnattendedBatch(initiativeSlug, toolMeta);
|
|
134
|
+
}
|
|
98
135
|
const taskId = String(args.task_id ?? "");
|
|
99
136
|
if (!taskId) throw new Error("task_id is required");
|
|
100
137
|
if ("native_decision" in args) throw new Error("native_decision cannot be supplied in tool arguments");
|
|
@@ -132,6 +169,13 @@ export function createMcpRuntime(options: McpRuntimeOptions = {}) {
|
|
|
132
169
|
if (typeof args.finding_id !== "string" || !args.finding_id) throw new Error("finding_id is required");
|
|
133
170
|
return runtime.resolveFinding(taskId, args.finding_id);
|
|
134
171
|
}
|
|
172
|
+
if (name === "refute_finding") {
|
|
173
|
+
// Structural only, exactly like resolve_finding: the reducer owns
|
|
174
|
+
// which findings may be refuted and with which evidence.
|
|
175
|
+
if (typeof args.finding_id !== "string" || !args.finding_id) throw new Error("finding_id is required");
|
|
176
|
+
if (typeof args.attestation_id !== "string" || !args.attestation_id) throw new Error("attestation_id is required");
|
|
177
|
+
return runtime.refuteFinding(taskId, args.finding_id, args.attestation_id);
|
|
178
|
+
}
|
|
135
179
|
if (name === "request_authorization" || name === "approve_breaking_intent_revision" || name === "stop" || name === "repair_authority_state") {
|
|
136
180
|
return runtime.authorize(taskId, name, toolMeta, args);
|
|
137
181
|
}
|
|
@@ -309,6 +353,24 @@ async function writeReply(output: Writable, reply: JsonRpc): Promise<void> {
|
|
|
309
353
|
}
|
|
310
354
|
|
|
311
355
|
export function elicitationParams(input: NativeConfirmationInput) {
|
|
356
|
+
if (input.operation === "start_unattended_batch") {
|
|
357
|
+
const b = input.batchDetails;
|
|
358
|
+
const details = [
|
|
359
|
+
`Operation: start_unattended_batch`,
|
|
360
|
+
`Initiative: ${input.initiativeSlug ?? b?.initiative_slug}`,
|
|
361
|
+
b?.batch_branch ? `Batch branch: ${b.batch_branch}` : null,
|
|
362
|
+
input.planDigest ? `Plan digest: ${input.planDigest}` : null,
|
|
363
|
+
b?.children ? `Ordered children (${b.children.length}):\n${b.children.map((c) => ` - ${c.task_id} (${c.slice_id}) [risk: ${c.risk ?? "unknown"}]`).join("\n")}` : null,
|
|
364
|
+
b?.excluded && b.excluded.length > 0 ? `Excluded children (${b.excluded.length}):\n${b.excluded.map((e) => ` - ${e.task_id} (${e.slice_id}): ${e.reason}`).join("\n")}` : null,
|
|
365
|
+
b?.budget ? `Budget: max_children=${b.budget.max_children}, deadline_at=${b.budget.deadline_at}, qa_failure_limit=${b.budget.qa_failure_limit}` : null,
|
|
366
|
+
b?.expires_at ? `Expires at: ${b.expires_at}` : null,
|
|
367
|
+
].filter(Boolean);
|
|
368
|
+
return {
|
|
369
|
+
mode: "form",
|
|
370
|
+
message: `Authorize this unattended batch run for ${input.initiativeSlug}?\n\n${details.join("\n")}`,
|
|
371
|
+
requestedSchema: { type: "object", properties: {} },
|
|
372
|
+
};
|
|
373
|
+
}
|
|
312
374
|
const details = [
|
|
313
375
|
`Operation: ${input.operation}`,
|
|
314
376
|
`Task: ${input.taskId}`,
|