immune-brain 3.6.8 → 4.0.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.
- package/README.md +11 -4
- package/README.zh-CN.md +10 -3
- package/package.json +3 -2
- package/plugins/immune-brain/.claude-plugin/plugin.json +1 -1
- package/plugins/immune-brain/.pi-extension/imm-canary-enroll.ts +18 -2
- package/plugins/immune-brain/.pi-extension/imm-canary-work.ts +76 -121
- package/plugins/immune-brain/.pi-extension/imm-unattended-batch.ts +106 -600
- package/plugins/immune-brain/.pi-extension/pi-canary-assurance-progression.ts +1 -0
- package/plugins/immune-brain/.pi-extension/pi-canary-verification.ts +3 -3
- package/plugins/immune-brain/.pi-extension/runtime-stub.ts +17 -43
- package/plugins/immune-brain/dist/claude/mcp-server.mjs +7581 -5042
- package/plugins/immune-brain/dist/docs/reference/planning-artifact-retention.md +11 -12
- package/plugins/immune-brain/dist/docs/reference/subagent-dispatch-protocol.md +1 -1
- package/plugins/immune-brain/dist/imm-loop.md +27 -25
- package/plugins/immune-brain/dist/imm-planner.md +53 -32
- package/plugins/immune-brain/dist/imm-review-retro.md +123 -0
- package/plugins/immune-brain/dist/registry.yaml +9 -0
- package/plugins/immune-brain/dist/role-prompts/code-review.md +3 -1
- package/plugins/immune-brain/dist/role-prompts/executor.md +4 -4
- package/plugins/immune-brain/runtime/assurance/coordinator.ts +183 -40
- package/plugins/immune-brain/runtime/assurance/delivery_workspace.ts +240 -0
- package/plugins/immune-brain/runtime/assurance/qa.ts +132 -58
- package/plugins/immune-brain/runtime/assurance/review_evidence.ts +15 -7
- package/plugins/immune-brain/runtime/assurance/verification.ts +246 -206
- package/plugins/immune-brain/runtime/authorization_operation.ts +20 -0
- package/plugins/immune-brain/runtime/claude/kernel_ports.ts +288 -721
- package/plugins/immune-brain/runtime/commands/kernel.ts +158 -67
- package/plugins/immune-brain/runtime/github_issue_tracker.ts +254 -29
- package/plugins/immune-brain/runtime/kernel/actor_identity.ts +33 -0
- package/plugins/immune-brain/runtime/kernel/application.ts +22 -6
- package/plugins/immune-brain/runtime/kernel/assurance_projection.ts +94 -5
- package/plugins/immune-brain/runtime/kernel/authority_port.ts +27 -6
- package/plugins/immune-brain/runtime/kernel/backend_claim.ts +43 -16
- package/plugins/immune-brain/runtime/kernel/batch_authority.ts +10 -6
- package/plugins/immune-brain/runtime/kernel/canary_application.ts +50 -63
- package/plugins/immune-brain/runtime/kernel/canary_eligibility.ts +13 -4
- package/plugins/immune-brain/runtime/kernel/completion.ts +5 -14
- package/plugins/immune-brain/runtime/kernel/enrollment.ts +124 -34
- package/plugins/immune-brain/runtime/kernel/enrollment_authority.ts +13 -5
- package/plugins/immune-brain/runtime/kernel/index.ts +3 -1
- package/plugins/immune-brain/runtime/kernel/intent.ts +7 -11
- package/plugins/immune-brain/runtime/kernel/legacy_audit.ts +4 -1
- package/plugins/immune-brain/runtime/kernel/legacy_task_record.ts +323 -0
- package/plugins/immune-brain/runtime/kernel/pi_canary_prepare.ts +10 -1
- package/plugins/immune-brain/runtime/kernel/reducer.ts +32 -31
- package/plugins/immune-brain/runtime/kernel/run_identity.ts +121 -0
- package/plugins/immune-brain/runtime/kernel/spec_binding.ts +100 -0
- package/plugins/immune-brain/runtime/kernel/sqlite_migration.ts +950 -0
- package/plugins/immune-brain/runtime/kernel/sqlite_store.ts +1193 -0
- package/plugins/immune-brain/runtime/kernel/storage.ts +1254 -1206
- package/plugins/immune-brain/runtime/kernel/storage_layout_migration.ts +129 -755
- package/plugins/immune-brain/runtime/kernel/storage_paths.ts +419 -46
- package/plugins/immune-brain/runtime/kernel/types.ts +12 -43
- package/plugins/immune-brain/runtime/kernel/validation.ts +60 -274
- package/plugins/immune-brain/runtime/managed_task_routing_policy.ts +0 -1
- package/plugins/immune-brain/runtime/plan_core.ts +27 -65
- package/plugins/immune-brain/runtime/plugin_version.ts +1 -1
- package/plugins/immune-brain/runtime/prompts/code-review.md +3 -1
- package/plugins/immune-brain/runtime/prompts/executor.md +4 -4
- package/plugins/immune-brain/runtime/staged_intent.ts +58 -0
- package/plugins/immune-brain/runtime/unattended/batch_git.ts +37 -7
- package/plugins/immune-brain/runtime/unattended/batch_plan.ts +42 -2
- package/plugins/immune-brain/runtime/unattended/batch_preflight.ts +771 -0
- package/plugins/immune-brain/runtime/unattended/batch_reasons.ts +189 -0
- package/plugins/immune-brain/runtime/unattended/batch_runner.ts +35 -0
- package/plugins/immune-brain/runtime/unattended/confirmation_deadline.ts +33 -0
- package/plugins/immune-brain/runtime/unattended/types.ts +14 -1
- package/plugins/immune-brain/runtime/v4_runtime.ts +19 -23
- package/plugins/immune-brain/runtime/verification_descriptor.ts +92 -136
- package/plugins/immune-brain/runtime/workspace_scope.ts +98 -13
- package/plugins/immune-brain/skills/imm-planner/SKILL.md +3 -3
- package/plugins/immune-brain/skills/imm-review-retro/SKILL.md +23 -0
- package/plugins/immune-brain/skills/imm-review-retro/scripts/review_retro.ts +355 -0
- package/plugins/immune-brain/skills/registry.yaml +9 -0
- package/plugins/immune-brain/bin/imm-retire-stale-wrapper +0 -4
- package/plugins/immune-brain/bin/imm-retired +0 -4
- package/plugins/immune-brain/runtime/authority_commit_receipts.ts +0 -716
- package/plugins/immune-brain/runtime/kernel/automatic_observations.ts +0 -451
- package/plugins/immune-brain/runtime/kernel/legacy.ts +0 -299
- package/plugins/immune-brain/runtime/kernel/observation.ts +0 -397
- package/plugins/immune-brain/runtime/kernel/readiness.ts +0 -282
- package/plugins/immune-brain/runtime/kernel/readiness_evidence.ts +0 -132
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { createHash } from "node:crypto";
|
|
2
1
|
import {
|
|
3
2
|
closeSync,
|
|
4
3
|
constants as fsConstants,
|
|
@@ -8,7 +7,7 @@ import {
|
|
|
8
7
|
writeFileSync,
|
|
9
8
|
} from "node:fs";
|
|
10
9
|
import { execFileSync } from "node:child_process";
|
|
11
|
-
import {
|
|
10
|
+
import { resolve } from "node:path";
|
|
12
11
|
import process from "node:process";
|
|
13
12
|
import { fileURLToPath } from "node:url";
|
|
14
13
|
import {
|
|
@@ -27,6 +26,7 @@ import {
|
|
|
27
26
|
parseTaskIntentV1,
|
|
28
27
|
RISK_FLOOR_SCOPE_PREFIXES,
|
|
29
28
|
} from "../kernel/intent";
|
|
29
|
+
import { inspectSpecBinding } from "../kernel/spec_binding";
|
|
30
30
|
import { projectTask, resolveProjectedRisk } from "../kernel/completion";
|
|
31
31
|
import { deriveAssuranceAuthorization } from "../kernel/assurance_projection";
|
|
32
32
|
import { taskDiffIdentity, taskRevisionIdentity } from "../workspace_scope";
|
|
@@ -40,7 +40,7 @@ import { projectLegacyAudit } from "../kernel/legacy_audit";
|
|
|
40
40
|
import { inspectStorageLayout } from "../kernel/storage_paths";
|
|
41
41
|
import { migrateLegacyLayout } from "../kernel/storage_layout_migration";
|
|
42
42
|
import { readBackendClaim } from "../kernel/backend_claim";
|
|
43
|
-
import {
|
|
43
|
+
import { probeKernelStore } from "../kernel";
|
|
44
44
|
|
|
45
45
|
export interface KernelCommandResult {
|
|
46
46
|
stdout: string;
|
|
@@ -65,12 +65,6 @@ function errorResult(code: string, message: string, returncode: number): KernelC
|
|
|
65
65
|
return jsonResult({ error: { code, message } }, returncode);
|
|
66
66
|
}
|
|
67
67
|
|
|
68
|
-
function asRecord(value: unknown): Record<string, unknown> {
|
|
69
|
-
return value && typeof value === "object" && !Array.isArray(value)
|
|
70
|
-
? (value as Record<string, unknown>)
|
|
71
|
-
: {};
|
|
72
|
-
}
|
|
73
|
-
|
|
74
68
|
function journalFor(
|
|
75
69
|
command: string,
|
|
76
70
|
phase: TaskPhase | null,
|
|
@@ -121,16 +115,7 @@ function runStatus(root: string): KernelExecution {
|
|
|
121
115
|
try {
|
|
122
116
|
const layout = inspectStorageLayout(root);
|
|
123
117
|
const claim = readBackendClaim(root);
|
|
124
|
-
const workspace = (
|
|
125
|
-
try {
|
|
126
|
-
const raw = JSON.parse(readSecureProjectFile(root, ".imm/state/workspace.json")) as {
|
|
127
|
-
current_working?: unknown;
|
|
128
|
-
};
|
|
129
|
-
return typeof raw.current_working === "string" ? raw.current_working : null;
|
|
130
|
-
} catch {
|
|
131
|
-
return null;
|
|
132
|
-
}
|
|
133
|
-
})();
|
|
118
|
+
const workspace = readWorkspaceOwner(root);
|
|
134
119
|
return {
|
|
135
120
|
result: jsonResult({
|
|
136
121
|
contract: "assurance_kernel/status/v1",
|
|
@@ -193,10 +178,7 @@ function matchingFloorEntries(intent: TaskIntentV1): string[] {
|
|
|
193
178
|
|
|
194
179
|
function readWorkspaceOwner(root: string): string | null {
|
|
195
180
|
try {
|
|
196
|
-
|
|
197
|
-
current_working?: unknown;
|
|
198
|
-
};
|
|
199
|
-
return typeof raw.current_working === "string" ? raw.current_working : null;
|
|
181
|
+
return readWorkspaceStateRaw(root).state.current_working;
|
|
200
182
|
} catch {
|
|
201
183
|
return null;
|
|
202
184
|
}
|
|
@@ -292,8 +274,8 @@ function runInspect(root: string): KernelExecution {
|
|
|
292
274
|
try {
|
|
293
275
|
identity =
|
|
294
276
|
record.contract === "assurance_kernel/task_record/v4"
|
|
295
|
-
? taskRevisionIdentity(root, intent.scope_hint, record.git_base_head)
|
|
296
|
-
: taskDiffIdentity(root, intent.scope_hint);
|
|
277
|
+
? taskRevisionIdentity(root, intent.scope_hint, record.git_base_head, intent.task_id)
|
|
278
|
+
: taskDiffIdentity(root, intent.scope_hint, intent.task_id);
|
|
297
279
|
} catch (error) {
|
|
298
280
|
return sourceFailure("inspect", error);
|
|
299
281
|
}
|
|
@@ -499,7 +481,7 @@ function runIntentAuthor(args: string[], root: string): KernelExecution {
|
|
|
499
481
|
// its frozen manifest under both locks. The original authoring is retried
|
|
500
482
|
// only after the affected migration diff is committed.
|
|
501
483
|
try {
|
|
502
|
-
|
|
484
|
+
probeKernelStore(root);
|
|
503
485
|
} catch (error) {
|
|
504
486
|
return {
|
|
505
487
|
result: errorResult(
|
|
@@ -536,46 +518,13 @@ function runIntentAuthor(args: string[], root: string): KernelExecution {
|
|
|
536
518
|
};
|
|
537
519
|
}
|
|
538
520
|
if (layout.layout === "recovery_required" || layout.layout === "migration_required") {
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
result: jsonResult({
|
|
543
|
-
contract: "assurance_kernel/migration_completed/v1",
|
|
544
|
-
operation: "intent author",
|
|
545
|
-
affected_paths: migration.affected_paths,
|
|
546
|
-
next_action: "commit the affected migration paths, then retry intent author",
|
|
547
|
-
}),
|
|
548
|
-
journal: journalFor(
|
|
549
|
-
"intent",
|
|
550
|
-
null,
|
|
551
|
-
"escalated",
|
|
552
|
-
"migration_ambiguous",
|
|
553
|
-
null,
|
|
554
|
-
"Legacy evidence was relocated without Git index writes; commit and retry.",
|
|
555
|
-
),
|
|
556
|
-
};
|
|
557
|
-
}
|
|
558
|
-
if (migration.outcome === "migration_uncommitted") {
|
|
559
|
-
return {
|
|
560
|
-
result: errorResult(
|
|
561
|
-
"migration_uncommitted",
|
|
562
|
-
`affected storage paths differ from HEAD: ${migration.affected_paths.join(", ") || "(none)"}`,
|
|
563
|
-
1,
|
|
564
|
-
),
|
|
565
|
-
journal: journalFor(
|
|
566
|
-
"intent",
|
|
567
|
-
null,
|
|
568
|
-
"rejected",
|
|
569
|
-
"migration_ambiguous",
|
|
570
|
-
null,
|
|
571
|
-
"Commit or restore the affected paths before retrying.",
|
|
572
|
-
),
|
|
573
|
-
};
|
|
574
|
-
}
|
|
521
|
+
// Authoring never migrates implicitly: the retired layout is converted by
|
|
522
|
+
// the explicit claimless command only, so creating a draft cannot publish a
|
|
523
|
+
// database or retire historical files behind the operator's back.
|
|
575
524
|
return {
|
|
576
525
|
result: errorResult(
|
|
577
|
-
layout.layout === "recovery_required" ? "layout_recovery_required" : "
|
|
578
|
-
|
|
526
|
+
layout.layout === "recovery_required" ? "layout_recovery_required" : "layout_migration_required",
|
|
527
|
+
`${layout.reason ?? "storage layout is not ready"}; run imm-kernel migrate --storage-layout first`,
|
|
579
528
|
1,
|
|
580
529
|
),
|
|
581
530
|
journal: journalFor(
|
|
@@ -584,7 +533,7 @@ function runIntentAuthor(args: string[], root: string): KernelExecution {
|
|
|
584
533
|
"rejected",
|
|
585
534
|
"source_invalid",
|
|
586
535
|
null,
|
|
587
|
-
"
|
|
536
|
+
"Run imm-kernel migrate --storage-layout, commit the affected paths, then retry intent author.",
|
|
588
537
|
),
|
|
589
538
|
};
|
|
590
539
|
}
|
|
@@ -760,7 +709,7 @@ function runIntentAuthor(args: string[], root: string): KernelExecution {
|
|
|
760
709
|
return {
|
|
761
710
|
result: errorResult(
|
|
762
711
|
"intent_invalid",
|
|
763
|
-
`candidate acceptance verification failed strict verification_descriptor/
|
|
712
|
+
`candidate acceptance verification failed strict verification_descriptor/v2 parsing: ${error instanceof Error ? error.message : error}`,
|
|
764
713
|
1,
|
|
765
714
|
),
|
|
766
715
|
journal: journalFor(
|
|
@@ -769,7 +718,7 @@ function runIntentAuthor(args: string[], root: string): KernelExecution {
|
|
|
769
718
|
"rejected",
|
|
770
719
|
"intent_invalid",
|
|
771
720
|
null,
|
|
772
|
-
"Fix the reported verification_descriptor/
|
|
721
|
+
"Fix the reported verification_descriptor/v2 violations and retry.",
|
|
773
722
|
),
|
|
774
723
|
};
|
|
775
724
|
}
|
|
@@ -1132,6 +1081,29 @@ function runIntentValidate(args: string[], root: string): KernelExecution {
|
|
|
1132
1081
|
),
|
|
1133
1082
|
};
|
|
1134
1083
|
}
|
|
1084
|
+
const specBinding = inspectSpecBinding(intent);
|
|
1085
|
+
if (!specBinding.ok) {
|
|
1086
|
+
return {
|
|
1087
|
+
result: jsonResult(
|
|
1088
|
+
{
|
|
1089
|
+
contract: "assurance_kernel/intent_validation/v1",
|
|
1090
|
+
valid: false,
|
|
1091
|
+
path: relative,
|
|
1092
|
+
task_id: intent.task_id,
|
|
1093
|
+
reason: specBinding.message,
|
|
1094
|
+
},
|
|
1095
|
+
0,
|
|
1096
|
+
),
|
|
1097
|
+
journal: journalFor(
|
|
1098
|
+
"intent",
|
|
1099
|
+
null,
|
|
1100
|
+
"ok",
|
|
1101
|
+
"command_ok",
|
|
1102
|
+
null,
|
|
1103
|
+
null,
|
|
1104
|
+
),
|
|
1105
|
+
};
|
|
1106
|
+
}
|
|
1135
1107
|
|
|
1136
1108
|
const verification: Array<{ id: string; eligible: boolean; reason: string | null }> = [];
|
|
1137
1109
|
let allEligible = true;
|
|
@@ -1244,6 +1216,25 @@ function executeKernelCommand(args: string[], root: string): KernelExecution {
|
|
|
1244
1216
|
};
|
|
1245
1217
|
return runInspect(root);
|
|
1246
1218
|
}
|
|
1219
|
+
if (command === "migrate") {
|
|
1220
|
+
if (flags.length !== 1 || flags[0] !== "--storage-layout")
|
|
1221
|
+
return {
|
|
1222
|
+
result: errorResult(
|
|
1223
|
+
"invalid_command",
|
|
1224
|
+
"migrate accepts only --storage-layout",
|
|
1225
|
+
2,
|
|
1226
|
+
),
|
|
1227
|
+
journal: journalFor(
|
|
1228
|
+
command,
|
|
1229
|
+
null,
|
|
1230
|
+
"rejected",
|
|
1231
|
+
"invalid_command",
|
|
1232
|
+
null,
|
|
1233
|
+
"Run imm-kernel migrate --storage-layout.",
|
|
1234
|
+
),
|
|
1235
|
+
};
|
|
1236
|
+
return runStorageLayoutMigration(root);
|
|
1237
|
+
}
|
|
1247
1238
|
if (command === "audit") {
|
|
1248
1239
|
if (args.length !== 2 || args[1] !== "--legacy")
|
|
1249
1240
|
return {
|
|
@@ -1341,6 +1332,106 @@ function executeKernelCommand(args: string[], root: string): KernelExecution {
|
|
|
1341
1332
|
};
|
|
1342
1333
|
}
|
|
1343
1334
|
|
|
1335
|
+
/**
|
|
1336
|
+
* Explicit claimless storage-layout migration.
|
|
1337
|
+
*
|
|
1338
|
+
* The retired file store is converted here and nowhere else: this command never
|
|
1339
|
+
* authors an intent, never opens a task, and never needs an active claim, so a
|
|
1340
|
+
* worktree that is still on the retired layout has one reachable entry point.
|
|
1341
|
+
* Mutating commands keep their fail-closed gate; this is the command that
|
|
1342
|
+
* resolves it.
|
|
1343
|
+
*/
|
|
1344
|
+
function runStorageLayoutMigration(root: string): KernelExecution {
|
|
1345
|
+
const inspection = inspectStorageLayout(root);
|
|
1346
|
+
// Only a live owner blocks the command. Every other diagnosis is handed to
|
|
1347
|
+
// the migrator, which owns the recovery decisions: an interrupted
|
|
1348
|
+
// publication shows both stores and must stay reachable through this CLI.
|
|
1349
|
+
if (inspection.layout === "migration_blocked_active")
|
|
1350
|
+
return {
|
|
1351
|
+
result: errorResult(
|
|
1352
|
+
"layout_migration_blocked",
|
|
1353
|
+
inspection.reason ?? "a live legacy task still owns work; settle or stop it on the prior runtime first",
|
|
1354
|
+
1,
|
|
1355
|
+
),
|
|
1356
|
+
journal: journalFor(
|
|
1357
|
+
"migrate",
|
|
1358
|
+
null,
|
|
1359
|
+
"rejected",
|
|
1360
|
+
"source_invalid",
|
|
1361
|
+
null,
|
|
1362
|
+
"Resolve the reported layout condition, then rerun imm-kernel migrate --storage-layout.",
|
|
1363
|
+
),
|
|
1364
|
+
};
|
|
1365
|
+
const migration = migrateLegacyLayout(root);
|
|
1366
|
+
if (migration.outcome === "migrated")
|
|
1367
|
+
return {
|
|
1368
|
+
result: jsonResult({
|
|
1369
|
+
contract: "assurance_kernel/migration_completed/v1",
|
|
1370
|
+
operation: "storage layout migration",
|
|
1371
|
+
affected_paths: migration.affected_paths,
|
|
1372
|
+
next_action: "commit the affected migration paths, then retry the original command",
|
|
1373
|
+
}),
|
|
1374
|
+
journal: journalFor(
|
|
1375
|
+
"migrate",
|
|
1376
|
+
null,
|
|
1377
|
+
"escalated",
|
|
1378
|
+
"migration_ambiguous",
|
|
1379
|
+
null,
|
|
1380
|
+
"Commit the affected migration paths, then retry the original command.",
|
|
1381
|
+
),
|
|
1382
|
+
};
|
|
1383
|
+
if (migration.outcome === "migration_uncommitted")
|
|
1384
|
+
return {
|
|
1385
|
+
result: jsonResult({
|
|
1386
|
+
contract: "assurance_kernel/migration_pending_commit/v1",
|
|
1387
|
+
operation: "storage layout migration",
|
|
1388
|
+
affected_paths: migration.affected_paths,
|
|
1389
|
+
reason: migration.reason,
|
|
1390
|
+
next_action: "commit the preserved audit evidence, then rerun imm-kernel migrate --storage-layout",
|
|
1391
|
+
}),
|
|
1392
|
+
journal: journalFor(
|
|
1393
|
+
"migrate",
|
|
1394
|
+
null,
|
|
1395
|
+
"escalated",
|
|
1396
|
+
"migration_ambiguous",
|
|
1397
|
+
null,
|
|
1398
|
+
"Commit the preserved audit evidence, then rerun imm-kernel migrate --storage-layout.",
|
|
1399
|
+
),
|
|
1400
|
+
};
|
|
1401
|
+
if (migration.outcome === "already_migrated")
|
|
1402
|
+
return {
|
|
1403
|
+
result: jsonResult({
|
|
1404
|
+
contract: "assurance_kernel/migration_completed/v1",
|
|
1405
|
+
operation: "storage layout migration",
|
|
1406
|
+
affected_paths: [],
|
|
1407
|
+
next_action: "retry the original command",
|
|
1408
|
+
}),
|
|
1409
|
+
journal: journalFor(
|
|
1410
|
+
"migrate",
|
|
1411
|
+
null,
|
|
1412
|
+
"ok",
|
|
1413
|
+
"command_ok",
|
|
1414
|
+
null,
|
|
1415
|
+
"Retry the original command.",
|
|
1416
|
+
),
|
|
1417
|
+
};
|
|
1418
|
+
return {
|
|
1419
|
+
result: errorResult(
|
|
1420
|
+
"layout_migration_blocked",
|
|
1421
|
+
migration.reason ?? "the storage layout migration did not complete",
|
|
1422
|
+
1,
|
|
1423
|
+
),
|
|
1424
|
+
journal: journalFor(
|
|
1425
|
+
"migrate",
|
|
1426
|
+
null,
|
|
1427
|
+
"rejected",
|
|
1428
|
+
"source_invalid",
|
|
1429
|
+
null,
|
|
1430
|
+
"Resolve the reported layout condition, then rerun imm-kernel migrate --storage-layout.",
|
|
1431
|
+
),
|
|
1432
|
+
};
|
|
1433
|
+
}
|
|
1434
|
+
|
|
1344
1435
|
export function runKernelCommand(
|
|
1345
1436
|
args: string[],
|
|
1346
1437
|
root = process.cwd(),
|