immune-brain 4.6.0 → 5.1.0

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.
Files changed (75) hide show
  1. package/README.md +374 -46
  2. package/README.zh-CN.md +384 -47
  3. package/package.json +2 -1
  4. package/plugins/immune-brain/.claude-plugin/plugin.json +1 -1
  5. package/plugins/immune-brain/.pi-extension/imm-canary-enroll.ts +42 -44
  6. package/plugins/immune-brain/.pi-extension/imm-canary-work.ts +143 -474
  7. package/plugins/immune-brain/.pi-extension/imm-unattended-batch.ts +78 -87
  8. package/plugins/immune-brain/.pi-extension/pi-canary-assurance-progression.ts +7 -2
  9. package/plugins/immune-brain/.pi-extension/tsconfig.json +2 -2
  10. package/plugins/immune-brain/agents/immune-brain-advisory-reviewer.md +23 -0
  11. package/plugins/immune-brain/agents/immune-brain-qa.md +42 -0
  12. package/plugins/immune-brain/agents/immune-brain-reviewer.md +90 -1
  13. package/plugins/immune-brain/agents/immune-brain-ui-review.md +21 -0
  14. package/plugins/immune-brain/dist/BASELINE.md +4 -4
  15. package/plugins/immune-brain/dist/claude/mcp-server.mjs +8601 -6975
  16. package/plugins/immune-brain/dist/docs/reference/immune-brain-config.md +27 -0
  17. package/plugins/immune-brain/dist/docs/reference/planning-quality-gate.md +3 -3
  18. package/plugins/immune-brain/dist/docs/reference/subagent-dispatch-protocol.md +30 -1
  19. package/plugins/immune-brain/dist/imm-brainstorm.md +1 -1
  20. package/plugins/immune-brain/dist/imm-doc-prune.md +2 -2
  21. package/plugins/immune-brain/dist/{imm-agent-doc-maintain.md → imm-doc-slim.md} +9 -9
  22. package/plugins/immune-brain/dist/imm-planner.md +23 -8
  23. package/plugins/immune-brain/dist/imm-pr-fix.md +1 -1
  24. package/plugins/immune-brain/dist/{imm-review-retro.md → imm-retro.md} +26 -13
  25. package/plugins/immune-brain/dist/{imm-loop.md → imm-run.md} +231 -10
  26. package/plugins/immune-brain/dist/registry.yaml +9 -9
  27. package/plugins/immune-brain/dist/role-prompts/code-review.md +7 -0
  28. package/plugins/immune-brain/dist/role-prompts/executor.md +35 -2
  29. package/plugins/immune-brain/dist/role-prompts/lane-steward.md +44 -0
  30. package/plugins/immune-brain/runtime/assurance/coordinator.ts +83 -67
  31. package/plugins/immune-brain/runtime/assurance/host_port.ts +20 -0
  32. package/plugins/immune-brain/runtime/assurance/qa.ts +2 -2
  33. package/plugins/immune-brain/runtime/assurance/verdict_authority.ts +347 -0
  34. package/plugins/immune-brain/runtime/claude/interaction.ts +6 -0
  35. package/plugins/immune-brain/runtime/claude/kernel_ports.ts +78 -373
  36. package/plugins/immune-brain/runtime/claude/mcp_server.ts +26 -2
  37. package/plugins/immune-brain/runtime/claude/review_host.ts +48 -16
  38. package/plugins/immune-brain/runtime/claude/role_agents.ts +84 -0
  39. package/plugins/immune-brain/runtime/commands/kernel.ts +3 -6
  40. package/plugins/immune-brain/runtime/kernel/application.ts +6 -3
  41. package/plugins/immune-brain/runtime/kernel/assurance_projection.ts +15 -8
  42. package/plugins/immune-brain/runtime/kernel/canary_application.ts +5 -3
  43. package/plugins/immune-brain/runtime/kernel/enrollment.ts +149 -5
  44. package/plugins/immune-brain/runtime/kernel/index.ts +3 -1
  45. package/plugins/immune-brain/runtime/kernel/storage.ts +170 -11
  46. package/plugins/immune-brain/runtime/kernel/storage_paths.ts +13 -0
  47. package/plugins/immune-brain/runtime/local_initiative.ts +94 -0
  48. package/plugins/immune-brain/runtime/loop_contract.ts +77 -24
  49. package/plugins/immune-brain/runtime/plugin_version.ts +1 -1
  50. package/plugins/immune-brain/runtime/prompts/code-review.md +7 -0
  51. package/plugins/immune-brain/runtime/prompts/executor.md +35 -2
  52. package/plugins/immune-brain/runtime/prompts/lane-steward.md +44 -0
  53. package/plugins/immune-brain/runtime/role_prompt_bridge.ts +42 -2
  54. package/plugins/immune-brain/runtime/unattended/batch_git.ts +57 -27
  55. package/plugins/immune-brain/runtime/unattended/batch_integration.ts +387 -0
  56. package/plugins/immune-brain/runtime/unattended/batch_kernel_port.ts +106 -0
  57. package/plugins/immune-brain/runtime/unattended/batch_lanes.ts +909 -0
  58. package/plugins/immune-brain/runtime/unattended/batch_plan.ts +36 -11
  59. package/plugins/immune-brain/runtime/unattended/batch_preflight.ts +53 -36
  60. package/plugins/immune-brain/runtime/unattended/batch_reconfirmation.ts +34 -29
  61. package/plugins/immune-brain/runtime/unattended/batch_runner.ts +46 -91
  62. package/plugins/immune-brain/runtime/unattended/batch_schedule.ts +162 -0
  63. package/plugins/immune-brain/runtime/unattended/batch_state.ts +356 -8
  64. package/plugins/immune-brain/runtime/unattended/types.ts +21 -2
  65. package/plugins/immune-brain/runtime/workspace_scope.ts +34 -0
  66. package/plugins/immune-brain/skills/BASELINE.md +4 -4
  67. package/plugins/immune-brain/skills/imm-doc-prune/SKILL.md +1 -1
  68. package/plugins/immune-brain/skills/{imm-agent-doc-maintain → imm-doc-slim}/SKILL.md +9 -9
  69. package/plugins/immune-brain/skills/imm-planner/SKILL.md +4 -2
  70. package/plugins/immune-brain/skills/imm-pr-fix/SKILL.md +1 -1
  71. package/plugins/immune-brain/skills/{imm-review-retro → imm-retro}/SKILL.md +7 -7
  72. package/plugins/immune-brain/skills/{imm-review-retro → imm-retro}/scripts/review_retro.ts +46 -21
  73. package/plugins/immune-brain/skills/{imm-loop → imm-run}/SKILL.md +11 -7
  74. package/plugins/immune-brain/skills/registry.yaml +9 -9
  75. package/plugins/immune-brain/.pi-extension/runtime-stub.ts +0 -581
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "immune-brain",
3
- "version": "4.6.0",
3
+ "version": "5.1.0",
4
4
  "description": "Immune-Brain agent skill system",
5
5
  "publishConfig": {
6
6
  "access": "public",
@@ -78,6 +78,7 @@
78
78
  "plugins/immune-brain/runtime/workspace_scope.ts",
79
79
  "plugins/immune-brain/runtime/managed_task_routing_policy.ts",
80
80
  "plugins/immune-brain/runtime/github_issue_tracker.ts",
81
+ "plugins/immune-brain/runtime/local_initiative.ts",
81
82
  "plugins/immune-brain/runtime/verification_descriptor.ts",
82
83
  "plugins/immune-brain/runtime/role_prompt_bridge.ts",
83
84
  "plugins/immune-brain/runtime/loop_contract.ts",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "immune-brain",
3
- "version": "4.6.0",
3
+ "version": "5.1.0",
4
4
  "description": "Immune-Brain Claude Code Host: native Enrollment, QA, Review, and Kernel settlement.",
5
5
  "author": {
6
6
  "name": "Immune-Brain Team"
@@ -9,27 +9,24 @@ import type { ExtensionAPI, ExtensionContext } from "@earendil-works/pi-coding-a
9
9
  import { Type } from "typebox";
10
10
  import { createHash, randomUUID } from "node:crypto";
11
11
  import { resolve } from "node:path";
12
- // The Kernel runtime graph is never type-checked from this extension: static
13
- // imports resolve to ./runtime-stub.ts (relative so the Pi extension loader
14
- // can resolve them at runtime), and the stub forwards to the real Kernel
15
- // modules via dynamic import.
12
+ // The Pi adapter imports the host-neutral runtime modules statically, exactly
13
+ // as the Claude adapter does. Kernel prepare is reached only through the
14
+ // shared Enrollment boundary (runtime/assurance/enrollment), never directly
15
+ // from the Kernel's own prepare module.
16
+ import { LITERAL_USER_ACTOR_ID } from "../runtime/kernel/actor_identity";
17
+ import { createEnrollmentAuthorityRegistry } from "../runtime/kernel/enrollment_authority";
18
+ import { preparePiCanary, revalidatePiCanary } from "../runtime/assurance/enrollment";
19
+ import { evaluateCanaryEligibility } from "../runtime/kernel/canary_eligibility";
20
+ import { enrollTask, EnrollmentRehearsalError } from "../runtime/kernel/enrollment";
21
+ import { reconcileKernelAuthority, withKernelStoreLock } from "../runtime/kernel/storage";
22
+ import { inspectStorageLayout } from "../runtime/kernel/storage_paths";
23
+ import { migrateLegacyLayout } from "../runtime/kernel/storage_layout_migration";
16
24
  import {
17
- LITERAL_USER_ACTOR_ID,
18
- createEnrollmentAuthorityRegistry,
19
- preparePiCanary,
20
- revalidatePiCanary,
21
- evaluateCanaryEligibility,
22
- reconcileKernelAuthority,
23
- readTaskIntent,
24
- runEnrollmentRehearsal,
25
- enrollCanaryTask,
26
- withKernelStoreLock,
27
- inspectStorageLayout,
28
- migrateLegacyLayout,
29
25
  inspectEnrollmentGitBase,
30
26
  enrollmentGitBaseNotice,
31
27
  initializeEnrollmentGitBase,
32
- } from "./runtime-stub";
28
+ } from "../runtime/assurance/enrollment_git_base";
29
+ import { readTaskIntentForRecord } from "./imm-canary-work";
33
30
  import {
34
31
  presentTaskRail,
35
32
  presentTaskRailResult,
@@ -253,7 +250,7 @@ async function classifyCommitFailure(
253
250
  "completed",
254
251
  "committing",
255
252
  `Kernel enrollment committed for ${taskId}; terminal receipt was recovered from authoritative owners`,
256
- "continue with imm-loop",
253
+ "continue with imm-run",
257
254
  );
258
255
  }
259
256
  if (
@@ -315,7 +312,7 @@ async function executeForegroundEnrollment(
315
312
  signal.throwIfAborted();
316
313
  progress("preparing", uxText(UX_LANG, `Preparing immutable Kernel owners for ${taskId}`, `正在为 ${taskId} 准备不可变 Kernel 所有者`));
317
314
  const now = new Date().toISOString();
318
- let taskIntent: Awaited<ReturnType<typeof readTaskIntent>>;
315
+ let taskIntent: Awaited<ReturnType<typeof readTaskIntentForRecord>>;
319
316
 
320
317
  // Storage-layout gate (BR-REQ-005/006): enrollment is the stateful
321
318
  // mutation boundary. Kernel transaction markers recover under the
@@ -387,10 +384,10 @@ async function executeForegroundEnrollment(
387
384
  }
388
385
 
389
386
  try {
390
- taskIntent = await readTaskIntent(root, taskId);
387
+ taskIntent = await readTaskIntentForRecord(root, taskId);
391
388
  } catch (error) {
392
389
  const message = errorMessage(error);
393
- // `readTaskIntent` reports an absent sidecar semantically now, so the
390
+ // `readTaskIntentForRecord` reports an absent sidecar semantically now, so the
394
391
  // "missing" classification must recognise that wording as well as the raw
395
392
  // filesystem errors; otherwise a missing file is misreported as a schema
396
393
  // defect and the operator is told to repair fields that do not exist.
@@ -406,7 +403,7 @@ async function executeForegroundEnrollment(
406
403
  "route_incumbent",
407
404
  stage,
408
405
  `Kernel task ${authority.owner_task_id} already owns this workspace`,
409
- `continue ${authority.owner_task_id} through imm-loop without re-enrollment`,
406
+ `continue ${authority.owner_task_id} through imm-run without re-enrollment`,
410
407
  );
411
408
  if (authority.state === "repairable_stale_claim")
412
409
  return terminal(
@@ -518,7 +515,7 @@ async function executeForegroundEnrollment(
518
515
  {
519
516
  let liveEarly: string | null = null;
520
517
  try {
521
- liveEarly = (await readTaskIntent(resolve(root), taskId)).content_hash;
518
+ liveEarly = (await readTaskIntentForRecord(resolve(root), taskId)).content_hash;
522
519
  } catch {
523
520
  liveEarly = null;
524
521
  }
@@ -529,7 +526,7 @@ async function executeForegroundEnrollment(
529
526
  {
530
527
  let liveContentHash: string | null = null;
531
528
  try {
532
- liveContentHash = (await readTaskIntent(resolve(root), taskId)).content_hash;
529
+ liveContentHash = (await readTaskIntentForRecord(resolve(root), taskId)).content_hash;
533
530
  } catch {
534
531
  liveContentHash = null;
535
532
  }
@@ -559,37 +556,38 @@ async function executeForegroundEnrollment(
559
556
  confirmation_ref: `pi-confirm-${createHash("sha256").update(`${taskId}\0${now}\0${nonce}`).digest("hex").slice(0, 16)}`,
560
557
  nonce,
561
558
  };
562
- const capability = registry.issue(binding);
563
- const input = {
564
- task_id: taskId,
565
- intent_path: binding.intent_path,
566
- intent_revision: binding.intent_revision,
567
- preparation_digest: binding.preparation_digest,
568
- capability,
569
- capability_binding: binding,
570
- now,
571
- };
572
559
 
573
560
  progress("rehearsing", uxText(UX_LANG, "Running the zero-write Kernel owner rehearsal", "正在执行 Kernel 所有者零写入预演"));
574
- const rehearsal = await runEnrollmentRehearsal(root, input, capability, registry);
575
- if (!rehearsal.rehearsed || rehearsal.evidence.outcome !== "ready")
576
- return terminal(action, taskId, "failed", stage, `Kernel enrollment rehearsal failed: ${rehearsal.evidence.blockers.join("; ")}${gitBaseNote}`, "resolve the final-lock preconditions and retry");
577
- if (signal.aborted) return cancelled();
578
- if (!beginCommit()) return cancelled();
579
-
580
- stage = "committing";
581
- onUpdate?.(updateResult(action, taskId, stage, "Kernel enrollment commit owns settlement and is no longer cancellable"));
582
561
  try {
583
- const result = await enrollCanaryTask(root, input, registry);
562
+ // The single Enrollment entry owns issue -> rehearse -> checkpoint ->
563
+ // commit. The checkpoint keeps the Tool's abort/begin-commit gate
564
+ // between rehearsal and commit: a declined checkpoint cancels with
565
+ // zero writes, and once it accepts, commit is no longer cancellable.
566
+ const outcome = await enrollTask(root, registry, {
567
+ binding,
568
+ now,
569
+ checkpoint: () => {
570
+ if (signal.aborted) return false;
571
+ if (!beginCommit()) return false;
572
+ stage = "committing";
573
+ onUpdate?.(updateResult(action, taskId, stage, "Kernel enrollment commit owns settlement and is no longer cancellable"));
574
+ return true;
575
+ },
576
+ });
577
+ if (outcome.outcome === "cancelled") return cancelled();
578
+ const result = outcome.result;
584
579
  return terminal(
585
580
  action,
586
581
  taskId,
587
582
  "completed",
588
583
  stage,
589
584
  `Kernel enrollment completed: task ${result.record.task_id} state=${result.record.lifecycle}:${result.record.artifact_state} backend=${result.backend_claim.backend}`,
590
- "continue with imm-loop",
585
+ "continue with imm-run",
591
586
  );
592
587
  } catch (error) {
588
+ if (error instanceof EnrollmentRehearsalError)
589
+ return terminal(action, taskId, "failed", stage, `${error.message}${gitBaseNote}`, "resolve the final-lock preconditions and retry");
590
+ if (stage !== "committing") throw error;
593
591
  const failure = await classifyCommitFailure(root, action, taskId, now, error);
594
592
  failure.summary += gitBaseNote;
595
593
  return failure;