immune-brain 2.8.2

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 (101) hide show
  1. package/README.md +239 -0
  2. package/README.zh-CN.md +239 -0
  3. package/package.json +84 -0
  4. package/plugins/immune-brain/.pi-extension/imm-canary-enroll.ts +666 -0
  5. package/plugins/immune-brain/.pi-extension/imm-canary-work.ts +1622 -0
  6. package/plugins/immune-brain/.pi-extension/package.json +11 -0
  7. package/plugins/immune-brain/.pi-extension/pi-canary-assurance-progression.ts +711 -0
  8. package/plugins/immune-brain/.pi-extension/pi-canary-assurance.ts +154 -0
  9. package/plugins/immune-brain/.pi-extension/pi-canary-interaction.ts +349 -0
  10. package/plugins/immune-brain/.pi-extension/pi-canary-invocations.ts +90 -0
  11. package/plugins/immune-brain/.pi-extension/pi-canary-native-review.ts +214 -0
  12. package/plugins/immune-brain/.pi-extension/pi-canary-qa-findings.ts +50 -0
  13. package/plugins/immune-brain/.pi-extension/pi-canary-review-bundle.ts +262 -0
  14. package/plugins/immune-brain/.pi-extension/pi-canary-tool-failure.ts +28 -0
  15. package/plugins/immune-brain/.pi-extension/pi-canary-verification.ts +237 -0
  16. package/plugins/immune-brain/.pi-extension/runtime-stub.ts +414 -0
  17. package/plugins/immune-brain/.pi-extension/tsconfig.json +20 -0
  18. package/plugins/immune-brain/bin/imm-kernel +4 -0
  19. package/plugins/immune-brain/bin/imm-plan +4 -0
  20. package/plugins/immune-brain/bin/imm-pr-diag +230 -0
  21. package/plugins/immune-brain/bin/imm-retire-stale-wrapper +4 -0
  22. package/plugins/immune-brain/bin/imm-retired +4 -0
  23. package/plugins/immune-brain/bin/imm-tracker +4 -0
  24. package/plugins/immune-brain/dist/BASELINE.md +138 -0
  25. package/plugins/immune-brain/dist/docs/reference/HANDOFF-template.md +122 -0
  26. package/plugins/immune-brain/dist/docs/reference/design-contract-audit-rubric.md +149 -0
  27. package/plugins/immune-brain/dist/docs/reference/design-contract-review-checklist.md +55 -0
  28. package/plugins/immune-brain/dist/docs/reference/i18n-review-checklist.md +110 -0
  29. package/plugins/immune-brain/dist/docs/reference/immune-brain-config.md +52 -0
  30. package/plugins/immune-brain/dist/docs/reference/planning-artifact-retention.md +94 -0
  31. package/plugins/immune-brain/dist/docs/reference/planning-quality-gate.md +44 -0
  32. package/plugins/immune-brain/dist/docs/reference/subagent-dispatch-protocol.md +105 -0
  33. package/plugins/immune-brain/dist/docs/reference/ux-heuristic-checklist.md +131 -0
  34. package/plugins/immune-brain/dist/imm-brainstorm.md +140 -0
  35. package/plugins/immune-brain/dist/imm-doc-prune.md +137 -0
  36. package/plugins/immune-brain/dist/imm-loop.md +158 -0
  37. package/plugins/immune-brain/dist/imm-planner.md +387 -0
  38. package/plugins/immune-brain/dist/imm-pr-fix.md +71 -0
  39. package/plugins/immune-brain/dist/registry.yaml +49 -0
  40. package/plugins/immune-brain/dist/role-prompts/advisory-reviewer.md +16 -0
  41. package/plugins/immune-brain/dist/role-prompts/arch-explorer.md +14 -0
  42. package/plugins/immune-brain/dist/role-prompts/code-review.md +15 -0
  43. package/plugins/immune-brain/dist/role-prompts/compounder.md +20 -0
  44. package/plugins/immune-brain/dist/role-prompts/executor.md +13 -0
  45. package/plugins/immune-brain/dist/role-prompts/pr-fix.md +81 -0
  46. package/plugins/immune-brain/dist/role-prompts/qa.md +23 -0
  47. package/plugins/immune-brain/dist/role-prompts/test-fixer.md +3 -0
  48. package/plugins/immune-brain/dist/role-prompts/ui-review.md +14 -0
  49. package/plugins/immune-brain/runtime/authority_commit_receipts.ts +716 -0
  50. package/plugins/immune-brain/runtime/canonical_json.ts +19 -0
  51. package/plugins/immune-brain/runtime/commands/kernel.ts +1160 -0
  52. package/plugins/immune-brain/runtime/github_issue_tracker.ts +1009 -0
  53. package/plugins/immune-brain/runtime/kernel/application.ts +300 -0
  54. package/plugins/immune-brain/runtime/kernel/assurance_projection.ts +284 -0
  55. package/plugins/immune-brain/runtime/kernel/authority_port.ts +208 -0
  56. package/plugins/immune-brain/runtime/kernel/automatic_observations.ts +451 -0
  57. package/plugins/immune-brain/runtime/kernel/backend_claim.ts +197 -0
  58. package/plugins/immune-brain/runtime/kernel/canary_application.ts +507 -0
  59. package/plugins/immune-brain/runtime/kernel/canary_eligibility.ts +73 -0
  60. package/plugins/immune-brain/runtime/kernel/completion.ts +160 -0
  61. package/plugins/immune-brain/runtime/kernel/enrollment.ts +194 -0
  62. package/plugins/immune-brain/runtime/kernel/enrollment_authority.ts +123 -0
  63. package/plugins/immune-brain/runtime/kernel/index.ts +29 -0
  64. package/plugins/immune-brain/runtime/kernel/intent.ts +563 -0
  65. package/plugins/immune-brain/runtime/kernel/intent_token_registry.ts +80 -0
  66. package/plugins/immune-brain/runtime/kernel/legacy.ts +299 -0
  67. package/plugins/immune-brain/runtime/kernel/legacy_audit.ts +153 -0
  68. package/plugins/immune-brain/runtime/kernel/observation.ts +395 -0
  69. package/plugins/immune-brain/runtime/kernel/pi_canary_prepare.ts +169 -0
  70. package/plugins/immune-brain/runtime/kernel/readiness.ts +282 -0
  71. package/plugins/immune-brain/runtime/kernel/readiness_evidence.ts +132 -0
  72. package/plugins/immune-brain/runtime/kernel/reducer.ts +624 -0
  73. package/plugins/immune-brain/runtime/kernel/storage.ts +1780 -0
  74. package/plugins/immune-brain/runtime/kernel/storage_layout_migration.ts +791 -0
  75. package/plugins/immune-brain/runtime/kernel/storage_paths.ts +492 -0
  76. package/plugins/immune-brain/runtime/kernel/types.ts +295 -0
  77. package/plugins/immune-brain/runtime/kernel/validation.ts +963 -0
  78. package/plugins/immune-brain/runtime/loop_contract.ts +362 -0
  79. package/plugins/immune-brain/runtime/managed_task_routing_policy.ts +462 -0
  80. package/plugins/immune-brain/runtime/plan_core.ts +1053 -0
  81. package/plugins/immune-brain/runtime/prompts/advisory-reviewer.md +16 -0
  82. package/plugins/immune-brain/runtime/prompts/arch-explorer.md +14 -0
  83. package/plugins/immune-brain/runtime/prompts/code-review.md +15 -0
  84. package/plugins/immune-brain/runtime/prompts/compounder.md +20 -0
  85. package/plugins/immune-brain/runtime/prompts/executor.md +13 -0
  86. package/plugins/immune-brain/runtime/prompts/pr-fix.md +81 -0
  87. package/plugins/immune-brain/runtime/prompts/qa.md +23 -0
  88. package/plugins/immune-brain/runtime/prompts/test-fixer.md +3 -0
  89. package/plugins/immune-brain/runtime/prompts/ui-review.md +14 -0
  90. package/plugins/immune-brain/runtime/role_prompt_bridge.ts +160 -0
  91. package/plugins/immune-brain/runtime/v4_runtime.ts +295 -0
  92. package/plugins/immune-brain/runtime/verification_descriptor.ts +162 -0
  93. package/plugins/immune-brain/runtime/workspace_scope.ts +623 -0
  94. package/plugins/immune-brain/skills/.ignore +1 -0
  95. package/plugins/immune-brain/skills/BASELINE.md +138 -0
  96. package/plugins/immune-brain/skills/imm-brainstorm/SKILL.md +66 -0
  97. package/plugins/immune-brain/skills/imm-doc-prune/SKILL.md +11 -0
  98. package/plugins/immune-brain/skills/imm-loop/SKILL.md +52 -0
  99. package/plugins/immune-brain/skills/imm-planner/SKILL.md +221 -0
  100. package/plugins/immune-brain/skills/imm-pr-fix/SKILL.md +10 -0
  101. package/plugins/immune-brain/skills/registry.yaml +49 -0
@@ -0,0 +1,237 @@
1
+ // P2B2 verification descriptor v1 — Pi extension side.
2
+ //
3
+ // The strict canonical parser for `assurance_kernel/verification_descriptor/v1`
4
+ // is the shared pure module `runtime/verification_descriptor.ts`, consumed
5
+ // identically by Kernel intent author/validate and by Pi assurance. This file
6
+ // re-exports that single implementation and keeps Pi-only runner resolution
7
+ // and execution (frozen Bun runner binding, compatibility gate, fixed
8
+ // execution, findings digest) extension-owned.
9
+
10
+ import { createHash } from "node:crypto";
11
+ import { execFileSync, spawn } from "node:child_process";
12
+ import { realpathSync, statSync } from "node:fs";
13
+ import { isAbsolute, join, resolve, sep, relative } from "node:path";
14
+
15
+
16
+ export {
17
+ VERIFICATION_DESCRIPTOR_CONTRACT,
18
+ parseVerificationDescriptor,
19
+ canonicalDescriptorBytes,
20
+ VerificationDescriptorError,
21
+ VERIFICATION_DESCRIPTOR_BOUNDS,
22
+ type VerificationDescriptor,
23
+ } from "../runtime/verification_descriptor";
24
+ // Re-import for direct references in this module.
25
+ import {
26
+ VERIFICATION_DESCRIPTOR_BOUNDS,
27
+ VerificationDescriptorError,
28
+ type VerificationDescriptor,
29
+ } from "../runtime/verification_descriptor";
30
+
31
+ /** Host-owned frozen runner identity: absolute realpath, device/inode, content hash, version. */
32
+ export interface FrozenRunner {
33
+ runner_id: "bun";
34
+ path: string;
35
+ dev: number;
36
+ ino: number;
37
+ content_hash: string;
38
+ version: string;
39
+ }
40
+
41
+ export function resolveBunRunner(): FrozenRunner {
42
+ let executable: string;
43
+ try {
44
+ executable = execFileSync("which", ["bun"], { encoding: "utf8" }).trim();
45
+ } catch {
46
+ throw new VerificationDescriptorError("bun runner is unavailable on this host");
47
+ }
48
+ let real: string;
49
+ try {
50
+ real = realpathSync(executable);
51
+ } catch {
52
+ throw new VerificationDescriptorError("bun runner realpath is unresolvable");
53
+ }
54
+ let stat: ReturnType<typeof statSync>;
55
+ try {
56
+ stat = statSync(real);
57
+ } catch {
58
+ throw new VerificationDescriptorError("bun runner is unreadable");
59
+ }
60
+ if (!stat.isFile())
61
+ throw new VerificationDescriptorError("bun runner is not a regular file");
62
+ const { readFileSync } = require("node:fs") as typeof import("node:fs");
63
+ const contentHash = `sha256:${createHash("sha256").update(readFileSync(real)).digest("hex")}`;
64
+ let version = "";
65
+ try {
66
+ version = execFileSync(real, ["--version"], { encoding: "utf8" }).trim();
67
+ } catch {
68
+ throw new VerificationDescriptorError("bun runner version is unreadable");
69
+ }
70
+ return {
71
+ runner_id: "bun",
72
+ path: real,
73
+ dev: stat.dev,
74
+ ino: stat.ino,
75
+ content_hash: contentHash,
76
+ version,
77
+ };
78
+ }
79
+
80
+ /** The descriptor's claimed runner version must equal the frozen host runner version. */
81
+ export function assertRunnerCompatible(
82
+ descriptor: VerificationDescriptor,
83
+ runner: FrozenRunner,
84
+ ): void {
85
+ if (descriptor.runner_version !== runner.version)
86
+ throw new VerificationDescriptorError(
87
+ `frozen runner version mismatch: descriptor claims ${descriptor.runner_version}, host has ${runner.version}; assurance unavailable`,
88
+ );
89
+ }
90
+
91
+ /** Raised when the host cancels a running fixed verification. */
92
+ export class VerificationAbortedError extends Error {
93
+ constructor() {
94
+ super("fixed verification aborted");
95
+ this.name = "VerificationAbortedError";
96
+ }
97
+ }
98
+
99
+ /** Run the frozen runner with the descriptor argv/cwd under minimal environment. */
100
+ export async function runFixedVerification(
101
+ root: string,
102
+ descriptor: VerificationDescriptor,
103
+ runner: FrozenRunner,
104
+ options: { signal?: AbortSignal } = {},
105
+ ): Promise<{ exit_code: number; stdout: string; stderr: string; timed_out: boolean }> {
106
+ const canonicalRoot = resolve(root);
107
+ const cwd = resolve(canonicalRoot, descriptor.cwd);
108
+ if (cwd === canonicalRoot ? false : !relative(canonicalRoot, cwd).startsWith(".") === false)
109
+ throw new VerificationDescriptorError("verification cwd escapes the repository");
110
+ if (isAbsolute(descriptor.cwd) || relative(canonicalRoot, cwd).startsWith(`..${sep}`) || cwd === resolve(canonicalRoot, ".."))
111
+ throw new VerificationDescriptorError("verification cwd escapes the repository");
112
+ if (options.signal?.aborted) throw new VerificationAbortedError();
113
+ if (process.platform === "win32")
114
+ throw new VerificationDescriptorError("fixed verification process-group isolation requires a POSIX host");
115
+ const maxOutput = Math.min(descriptor.max_output_bytes, VERIFICATION_DESCRIPTOR_BOUNDS.max_output_bytes);
116
+ return new Promise((resolvePromise, rejectPromise) => {
117
+ let settled = false;
118
+ let stdout = Buffer.alloc(0);
119
+ let stderr = Buffer.alloc(0);
120
+ let capturedBytes = 0;
121
+ const child = spawn(runner.path, descriptor.argv, {
122
+ cwd,
123
+ env: { PATH: process.env.PATH ?? "", HOME: process.env.HOME ?? "" },
124
+ detached: process.platform !== "win32",
125
+ stdio: ["ignore", "pipe", "pipe"],
126
+ });
127
+
128
+ const killTree = () => {
129
+ if (child.pid === undefined) return;
130
+ try {
131
+ if (process.platform !== "win32") process.kill(-child.pid, "SIGKILL");
132
+ else child.kill("SIGKILL");
133
+ } catch {
134
+ // The process already exited.
135
+ }
136
+ };
137
+ const cleanup = () => {
138
+ clearTimeout(timeout);
139
+ options.signal?.removeEventListener("abort", onAbort);
140
+ };
141
+ const resolveOnce = (result: { exit_code: number; stdout: string; stderr: string; timed_out: boolean }) => {
142
+ if (settled) return;
143
+ settled = true;
144
+ cleanup();
145
+ resolvePromise(result);
146
+ };
147
+ const rejectOnce = (error: Error) => {
148
+ if (settled) return;
149
+ settled = true;
150
+ cleanup();
151
+ rejectPromise(error);
152
+ };
153
+ const appendBounded = (current: Buffer<ArrayBuffer>, chunk: Buffer<ArrayBuffer>): { content: Buffer<ArrayBuffer>; exceeded: boolean } => {
154
+ const available = Math.max(0, maxOutput - capturedBytes);
155
+ const accepted = chunk.subarray(0, available);
156
+ capturedBytes += accepted.length;
157
+ return {
158
+ content: accepted.length > 0 ? Buffer.concat([current, accepted]) : current,
159
+ exceeded: chunk.length > available,
160
+ };
161
+ };
162
+ const outputLimitExceeded = () => {
163
+ const marker = Buffer.from("verification output limit exceeded\n", "utf8");
164
+ stdout = stdout.subarray(0, Math.max(0, maxOutput - marker.length));
165
+ stderr = marker.subarray(0, maxOutput - stdout.length);
166
+ capturedBytes = stdout.length + stderr.length;
167
+ killTree();
168
+ child.stdout?.destroy();
169
+ child.stderr?.destroy();
170
+ resolveOnce({
171
+ exit_code: 1,
172
+ stdout: stdout.toString("utf8"),
173
+ stderr: stderr.toString("utf8"),
174
+ timed_out: false,
175
+ });
176
+ };
177
+ child.stdout?.on("data", (chunk: Buffer<ArrayBuffer>) => {
178
+ const appended = appendBounded(stdout, chunk);
179
+ stdout = appended.content;
180
+ if (appended.exceeded) outputLimitExceeded();
181
+ });
182
+ child.stderr?.on("data", (chunk: Buffer<ArrayBuffer>) => {
183
+ const appended = appendBounded(stderr, chunk);
184
+ stderr = appended.content;
185
+ if (appended.exceeded) outputLimitExceeded();
186
+ });
187
+ child.once("error", (error) => {
188
+ resolveOnce({
189
+ exit_code: 1,
190
+ stdout: stdout.toString("utf8"),
191
+ stderr: `${stderr.toString("utf8")}runner spawn failed: ${error.message}`.slice(0, maxOutput),
192
+ timed_out: false,
193
+ });
194
+ });
195
+ child.once("close", (code) => {
196
+ resolveOnce({
197
+ exit_code: code ?? 1,
198
+ stdout: stdout.toString("utf8"),
199
+ stderr: stderr.toString("utf8"),
200
+ timed_out: false,
201
+ });
202
+ });
203
+ const onAbort = () => {
204
+ killTree();
205
+ child.stdout?.destroy();
206
+ child.stderr?.destroy();
207
+ rejectOnce(new VerificationAbortedError());
208
+ };
209
+ options.signal?.addEventListener("abort", onAbort, { once: true });
210
+ const timeout = setTimeout(() => {
211
+ killTree();
212
+ child.stdout?.destroy();
213
+ child.stderr?.destroy();
214
+ resolveOnce({
215
+ exit_code: 1,
216
+ stdout: stdout.toString("utf8"),
217
+ stderr: stderr.toString("utf8"),
218
+ timed_out: true,
219
+ });
220
+ }, descriptor.timeout_ms);
221
+ });
222
+ }
223
+
224
+ /** Normalized findings digest: stable-sorted keys over id/kind/acceptance_id/summary. */
225
+ export function findingsDigest(
226
+ findings: Array<{ id: string; kind: string; acceptance_id: string | null; summary: string }>,
227
+ ): string {
228
+ const normalized = findings.map((f) =>
229
+ JSON.stringify({
230
+ acceptance_id: f.acceptance_id,
231
+ id: f.id,
232
+ kind: f.kind,
233
+ summary: f.summary,
234
+ }),
235
+ );
236
+ return `sha256:${createHash("sha256").update(`[${normalized.join(",")}]`).digest("hex")}`;
237
+ }
@@ -0,0 +1,414 @@
1
+ // Extension-local runtime adapter: type-isolated, executable stub.
2
+ // Extensions import this file directly (relative path, resolvable by the Pi
3
+ // extension loader); it forwards to the real Kernel modules via dynamic
4
+ // import. The runtime source graph (with its pre-existing type debt) is never
5
+ // type-checked from the extension.
6
+
7
+ // --- Types (structural contracts, no runtime import) ---
8
+ export interface EnrollmentCapabilityBinding {
9
+ task_id: string;
10
+ intent_path: string;
11
+ intent_revision: number;
12
+ intent_content_hash: string;
13
+ preparation_digest: string;
14
+ actor_id: string;
15
+ confirmation_ref: string;
16
+ expires_at: string;
17
+ nonce: string;
18
+ }
19
+ export interface EnrollmentAuthorityRegistry {
20
+ issue(binding: EnrollmentCapabilityBinding, issuedAt?: string): object;
21
+ inspect(capability: object, expected: EnrollmentCapabilityBinding, now?: number): unknown;
22
+ consume(capability: object, expected: EnrollmentCapabilityBinding, now?: number): unknown;
23
+ isConsumed(capability: object): boolean;
24
+ }
25
+ export interface CanaryWaiver {
26
+ gate: "observation_window_days";
27
+ task_id: string;
28
+ reason: string;
29
+ actor: string;
30
+ confirmation_ref: string;
31
+ expires_at: string;
32
+ nonce: string;
33
+ }
34
+ export interface PiCanaryPrepareInput {
35
+ task_id: string;
36
+ now: string;
37
+ }
38
+ export interface PiCanaryPreparation {
39
+ contract: "assurance_kernel/pi_canary_preparation/v1";
40
+ task_id: string;
41
+ generated_at: string;
42
+ root_state_path: string;
43
+ intent: { path: string; revision: number; content_hash: string } | null;
44
+ backend_claim: { present: boolean; task_id: string | null; lifecycle_status: string | null };
45
+ task_tombstone: { present: boolean; terminal_lifecycle: string | null };
46
+ task_record_v3: { present: boolean; lifecycle: string | null; artifact_state: string | null } | null;
47
+ workspace: { current_working: string | null };
48
+ digest: string;
49
+ }
50
+ export interface EnrollCanaryInput {
51
+ task_id: string;
52
+ intent_path: string;
53
+ intent_revision: number;
54
+ preparation_digest: string;
55
+ capability: object;
56
+ capability_binding: Record<string, unknown>;
57
+ now: string;
58
+ }
59
+
60
+ // --- P2B2 mutation authority / canary application types (structural) ---
61
+ export interface CapabilityBindingV2 {
62
+ authority_kind: "review" | "qa" | "user";
63
+ task_id: string;
64
+ action_digest: string;
65
+ expected_record_hash: string;
66
+ intent_revision: number;
67
+ intent_content_hash: string;
68
+ diff_hash: string;
69
+ actor_id: string;
70
+ confirmation_ref: string;
71
+ expires_at: string;
72
+ findings_digest: string | null;
73
+ }
74
+ export interface MutationAuthorityRegistry {
75
+ readonly brand: symbol;
76
+ issue(binding: CapabilityBindingV2, issuedAt?: string): object;
77
+ inspect(capability: object | undefined, expected: unknown, now?: number): unknown;
78
+ consume(capability: object, expected: unknown, now?: number): unknown;
79
+ isConsumed(capability: object): boolean;
80
+ }
81
+ export interface CanaryApplication {
82
+ readonly registry: MutationAuthorityRegistry;
83
+ execute(input: unknown): unknown;
84
+ beginDrain(input: {
85
+ root: string;
86
+ task_id: string;
87
+ capability: object;
88
+ now?: string;
89
+ }): unknown;
90
+ }
91
+ export interface StoredTaskMutation {
92
+ revision: string;
93
+ record: {
94
+ contract: "assurance_kernel/task_record/v3";
95
+ task_id: string;
96
+ intent_snapshot: { revision: number; [key: string]: unknown };
97
+ intent_ref: { path: string; content_hash: string };
98
+ lifecycle: "active" | "done" | "stopped";
99
+ artifact_state: "active" | "frozen";
100
+ attestations: unknown[];
101
+ findings: unknown[];
102
+ history: unknown[];
103
+ };
104
+ workspace: { revision: string; state: { contract: string; current_working: string | null } };
105
+ }
106
+ export interface BackendClaim {
107
+ contract: string;
108
+ backend: "kernel";
109
+ task_id: string;
110
+ intent_revision: number;
111
+ intent_content_hash: string;
112
+ enrollment_event_id: string;
113
+ lifecycle_status: "active" | "draining";
114
+ created_at: string;
115
+ updated_at: string;
116
+ }
117
+ export interface KernelAuthorityProjection {
118
+ contract: "assurance_kernel/authority_projection/v1";
119
+ requested_task_id: string;
120
+ state: "unowned" | "active_owner" | "terminal_owner" | "repairable_stale_claim" | "authority_conflict";
121
+ owner_task_id: string | null;
122
+ owner_lifecycle: string | null;
123
+ claim_lifecycle_status: "active" | "draining" | null;
124
+ diagnostic: string | null;
125
+ revision: string;
126
+ }
127
+ export interface TaskTombstone {
128
+ contract: string;
129
+ task_id: string;
130
+ lifecycle_status: "terminal";
131
+ terminal_lifecycle: string;
132
+ terminal_event_id: string;
133
+ final_record_hash: string;
134
+ terminalized_at: string;
135
+ }
136
+ export interface TaskRecordRead {
137
+ revision: string;
138
+ record: {
139
+ contract: "assurance_kernel/task_record/v3";
140
+ task_id: string;
141
+ intent_snapshot: {
142
+ task_id: string;
143
+ revision: number;
144
+ risk: "routine" | "material" | "critical";
145
+ acceptance: Array<{ id: string; assertion: string; verification: string }>;
146
+ scope_hint: string[];
147
+ };
148
+ intent_ref: { path: string; content_hash: string };
149
+ lifecycle: "active" | "done" | "stopped";
150
+ artifact_state: "active" | "frozen";
151
+ attestations: Array<{
152
+ id: string;
153
+ kind: "qa" | "review" | "user";
154
+ task_revision: number;
155
+ intent_content_hash: string;
156
+ diff_hash: string;
157
+ actor_id: string;
158
+ acceptance_results: Array<{ acceptance_id: string; status: "passed" | "failed" | "blocked"; summary: string }>;
159
+ }>;
160
+ findings: Array<{ id: string; kind: string; status: string; summary?: string }>;
161
+ } | null;
162
+ }
163
+
164
+ // --- Assurance projection (host-neutral Kernel facts, not exported from the
165
+ // public Kernel index) ---
166
+ export interface AssuranceAuthorizationReadiness {
167
+ state: "resolve_user_decision" | "record_user_approval" | "none";
168
+ blocked: string | null;
169
+ }
170
+ export interface AssuranceProjection {
171
+ record_revision: string;
172
+ workspace_revision: string;
173
+ intent_revision: number;
174
+ intent_content_hash: string;
175
+ diff_hash: string;
176
+ lifecycle: "active" | "done" | "stopped" | "";
177
+ artifact_state: "active" | "frozen" | "";
178
+ risk: "routine" | "material" | "critical" | "";
179
+ next_obligation: "resolve_findings" | "resolve_user_decision" | "revise_intent" | "submit_assurance" | "run_qa" | "run_review" | "authorize_user" | "complete" | "none";
180
+ fresh_acceptance_ids: string[];
181
+ missing_acceptance_ids: string[];
182
+ stale_attestation_ids: string[];
183
+ fresh_approval_kinds: string[];
184
+ missing_approval_kinds: string[];
185
+ blocking_finding_ids: string[];
186
+ unresolved_user_decision_ids: string[];
187
+ replan_required_ids: string[];
188
+ independence_violations: string[];
189
+ open_user_decision_count: number;
190
+ completion_ready: boolean;
191
+ authorization: AssuranceAuthorizationReadiness;
192
+ }
193
+ export interface AssuranceProjectionResult {
194
+ contract: "assurance_kernel/assurance_projection/v1";
195
+ task_id: string;
196
+ error: string | null;
197
+ claim: { task_id: string; lifecycle_status: string } | null;
198
+ projection: AssuranceProjection;
199
+ }
200
+
201
+ // --- Runtime forwarding (dynamic import keeps the graph out of tsc) ---
202
+ function kernelPath(module: string): string {
203
+ return `../runtime/kernel/${module}.ts`;
204
+ }
205
+ function runtimePath(module: string): string {
206
+ return `../runtime/${module}.ts`;
207
+ }
208
+
209
+ export interface GithubTrackerResult {
210
+ contract: "immune_brain/github_issue_tracker_result/v1";
211
+ operation: "create-initiative" | "upsert-task" | "mark-terminal";
212
+ status: "created" | "updated" | "already_current" | "retryable_failure" | "permanent_failure" | "ambiguous_remote_state";
213
+ association_found: boolean;
214
+ issue_number?: number;
215
+ issue_url?: string;
216
+ message: string;
217
+ }
218
+
219
+ export async function buildLoopAction(input: unknown): Promise<unknown> {
220
+ const mod = await import(/* @vite-ignore */ runtimePath("loop_contract"));
221
+ return mod.buildLoopAction(input);
222
+ }
223
+ export async function buildLoopRoleDispatch(input: unknown): Promise<unknown> {
224
+ const mod = await import(/* @vite-ignore */ runtimePath("loop_contract"));
225
+ return mod.buildLoopRoleDispatch(input);
226
+ }
227
+ export async function markGithubTaskTerminal(
228
+ root: string,
229
+ input: { task_id: string; phase: "done" | "stopped"; terminal_event_id: string },
230
+ ): Promise<GithubTrackerResult> {
231
+ const mod = await import(/* @vite-ignore */ runtimePath("github_issue_tracker"));
232
+ return mod.runGithubTrackerOperation(root, { op: "mark-terminal", ...input }) as Promise<GithubTrackerResult>;
233
+ }
234
+ export async function createEnrollmentAuthorityRegistry(): Promise<EnrollmentAuthorityRegistry> {
235
+ const mod = await import(/* @vite-ignore */ kernelPath("enrollment_authority"));
236
+ return mod.createEnrollmentAuthorityRegistry();
237
+ }
238
+ export async function preparePiCanary(
239
+ root: string,
240
+ input: PiCanaryPrepareInput,
241
+ ): Promise<PiCanaryPreparation> {
242
+ const mod = await import(/* @vite-ignore */ kernelPath("pi_canary_prepare"));
243
+ return mod.preparePiCanary(root, input) as unknown as PiCanaryPreparation;
244
+ }
245
+ export async function revalidatePiCanary(
246
+ root: string,
247
+ input: PiCanaryPrepareInput,
248
+ previous: PiCanaryPreparation,
249
+ ): Promise<{ unchanged: boolean; current: PiCanaryPreparation }> {
250
+ const mod = await import(/* @vite-ignore */ kernelPath("pi_canary_prepare"));
251
+ return mod.revalidatePiCanary(root, input, previous as never) as unknown as { unchanged: boolean; current: PiCanaryPreparation };
252
+ }
253
+ export async function evaluateCanaryEligibility(input: {
254
+ task: { id: string; intent_path: string; intent_revision: number; intent_content_hash: string };
255
+ waiver?: CanaryWaiver;
256
+ now: string;
257
+ }): Promise<{ eligible: boolean; waived_gates: string[]; unmet_non_waivable: string[]; rejections: string[] }> {
258
+ const mod = await import(/* @vite-ignore */ kernelPath("canary_eligibility"));
259
+ return mod.evaluateCanaryEligibility(input as never);
260
+ }
261
+ export async function runEnrollmentRehearsal(
262
+ root: string,
263
+ input: EnrollCanaryInput,
264
+ capability: object,
265
+ registry: EnrollmentAuthorityRegistry,
266
+ ): Promise<{ rehearsed: boolean; writes_performed: boolean; evidence: { outcome: "ready" | "not_ready"; blockers: string[] } }> {
267
+ const mod = await import(/* @vite-ignore */ kernelPath("enrollment"));
268
+ return mod.runEnrollmentRehearsal(root, input as never, capability, registry as never);
269
+ }
270
+ export async function enrollCanaryTask(
271
+ root: string,
272
+ input: EnrollCanaryInput,
273
+ registry: EnrollmentAuthorityRegistry,
274
+ ): Promise<{ record: { task_id: string; lifecycle: string; artifact_state: string }; backend_claim: { backend: string } }> {
275
+ const mod = await import(/* @vite-ignore */ kernelPath("enrollment"));
276
+ return mod.enrollCanaryTask(root, input as never, registry as never);
277
+ }
278
+
279
+ export async function createMutationAuthorityRegistry(): Promise<MutationAuthorityRegistry> {
280
+ const mod = await import(/* @vite-ignore */ kernelPath("authority_port"));
281
+ return mod.createMutationAuthorityRegistry();
282
+ }
283
+ export async function createCanaryApplication(
284
+ registry: MutationAuthorityRegistry,
285
+ ): Promise<CanaryApplication> {
286
+ const mod = await import(/* @vite-ignore */ kernelPath("canary_application"));
287
+ return mod.createCanaryApplication(registry as never);
288
+ }
289
+ export async function readTaskRecord(
290
+ root: string,
291
+ taskId: string,
292
+ ): Promise<TaskRecordRead> {
293
+ const mod = await import(/* @vite-ignore */ kernelPath("storage"));
294
+ return mod.readTaskRecord(root, taskId);
295
+ }
296
+ export async function withKernelStoreLock<T>(root: string, operation: () => T): Promise<T> {
297
+ const mod = await import(/* @vite-ignore */ kernelPath("storage"));
298
+ return mod.withKernelStoreLock(root, operation);
299
+ }
300
+ export async function readBackendClaim(root: string): Promise<BackendClaim | null> {
301
+ const mod = await import(/* @vite-ignore */ kernelPath("backend_claim"));
302
+ return mod.readBackendClaim(root);
303
+ }
304
+ export async function reconcileKernelAuthority(
305
+ root: string,
306
+ taskId: string,
307
+ ): Promise<KernelAuthorityProjection> {
308
+ const mod = await import(/* @vite-ignore */ kernelPath("storage"));
309
+ return mod.reconcileKernelAuthority(root, taskId);
310
+ }
311
+ export async function repairKernelAuthority(
312
+ root: string,
313
+ taskId: string,
314
+ expectedProjectionRevision: string,
315
+ ): Promise<KernelAuthorityProjection> {
316
+ const mod = await import(/* @vite-ignore */ kernelPath("storage"));
317
+ return mod.repairKernelAuthority(root, taskId, expectedProjectionRevision);
318
+ }
319
+ export async function readTaskTombstone(
320
+ root: string,
321
+ taskId: string,
322
+ ): Promise<TaskTombstone | null> {
323
+ const mod = await import(/* @vite-ignore */ kernelPath("backend_claim"));
324
+ return mod.readTaskTombstone(root, taskId);
325
+ }
326
+
327
+ export interface TaskIntentV1 {
328
+ contract: "assurance_kernel/task_intent/v1";
329
+ goal: string;
330
+ task_id: string;
331
+ revision: number;
332
+ risk: "routine" | "material" | "critical";
333
+ owner: "user";
334
+ acceptance: Array<{ id: string; assertion: string; verification: string }>;
335
+ scope_hint: string[];
336
+ }
337
+ export interface TaskIntentRead {
338
+ token: object;
339
+ content_hash: string;
340
+ intent: TaskIntentV1;
341
+ intent_ref: { path: string; revision: number; content_hash: string };
342
+ }
343
+ export interface WorkspaceRead {
344
+ revision: string;
345
+ state: { contract: string; current_working: string | null };
346
+ }
347
+ export async function readTaskIntent(root: string, taskId: string, path?: string): Promise<TaskIntentRead> {
348
+ const [intent, storage] = await Promise.all([
349
+ import(/* @vite-ignore */ kernelPath("intent")),
350
+ import(/* @vite-ignore */ kernelPath("storage")),
351
+ ]);
352
+ const currentPath = path ?? storage.readTaskRecordRaw(root, taskId).record?.intent_ref.path;
353
+ return intent.readTaskIntent(root, taskId, currentPath);
354
+ }
355
+ export async function parseTaskIntentV1(raw: unknown): Promise<TaskIntentV1> {
356
+ const mod = await import(/* @vite-ignore */ kernelPath("intent"));
357
+ return mod.parseTaskIntentV1(raw);
358
+ }
359
+ export async function canonicalIntentHash(intent: unknown): Promise<string> {
360
+ const mod = await import(/* @vite-ignore */ kernelPath("intent"));
361
+ return mod.canonicalIntentHash(intent);
362
+ }
363
+
364
+ export async function readWorkspaceState(root: string): Promise<WorkspaceRead> {
365
+ const mod = await import(/* @vite-ignore */ kernelPath("storage"));
366
+ return mod.readWorkspaceStateRaw(root);
367
+ }
368
+ export async function inspectStorageLayout(root: string): Promise<import("../runtime/kernel/storage_paths").StorageLayoutInspection> {
369
+ const mod = await import(/* @vite-ignore */ kernelPath("storage_paths"));
370
+ return mod.inspectStorageLayout(root);
371
+ }
372
+ export async function migrateLegacyLayout(root: string): Promise<import("../runtime/kernel/storage_layout_migration").MigrationOutcome> {
373
+ const mod = await import(/* @vite-ignore */ kernelPath("storage_layout_migration"));
374
+ return mod.migrateLegacyLayout(root);
375
+ }
376
+ export async function beginDrainCapabilityAction(
377
+ taskId: string,
378
+ at: string,
379
+ ): Promise<{ type: string; event_id: string; at: string; actor_id: string; reason: string }> {
380
+ const mod = await import(/* @vite-ignore */ kernelPath("canary_application"));
381
+ return mod.beginDrainCapabilityAction(taskId, at);
382
+ }
383
+
384
+ export async function capabilityActionFor(input: unknown): Promise<unknown> {
385
+ const mod = await import(/* @vite-ignore */ kernelPath("canary_application"));
386
+ return mod.capabilityActionFor(input);
387
+ }
388
+
389
+ export async function digestOfAction(action: unknown): Promise<string> {
390
+ const mod = await import(/* @vite-ignore */ kernelPath("authority_port"));
391
+ return mod.digestOfAction(action);
392
+ }
393
+
394
+ export async function findingsDigestV2(findings: unknown[]): Promise<string> {
395
+ const mod = await import(/* @vite-ignore */ kernelPath("reducer"));
396
+ return mod.findingsDigestV2(findings);
397
+ }
398
+
399
+ export async function projectAssurance(
400
+ root: string,
401
+ taskId: string,
402
+ diffProvider: (root: string, intent: { scope_hint?: unknown }) => string,
403
+ ): Promise<AssuranceProjectionResult> {
404
+ const mod = await import(/* @vite-ignore */ kernelPath("assurance_projection"));
405
+ return mod.projectAssurance(root, taskId, diffProvider) as unknown as AssuranceProjectionResult;
406
+ }
407
+
408
+ export async function deriveAssuranceAuthorization(input: {
409
+ next_obligation: AssuranceProjectionResult["projection"]["next_obligation"];
410
+ open_user_decision_count: number;
411
+ }): Promise<AssuranceAuthorizationReadiness> {
412
+ const mod = await import(/* @vite-ignore */ kernelPath("assurance_projection"));
413
+ return mod.deriveAssuranceAuthorization(input) as unknown as AssuranceAuthorizationReadiness;
414
+ }
@@ -0,0 +1,20 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2022",
4
+ "module": "ESNext",
5
+ "moduleResolution": "Bundler",
6
+ "strict": true,
7
+ "noEmit": true,
8
+ "skipLibCheck": true,
9
+ "allowImportingTsExtensions": false,
10
+ "types": [
11
+ "node"
12
+ ]
13
+ },
14
+ "include": [
15
+ "imm-canary-enroll.ts",
16
+ "imm-canary-work.ts",
17
+ "pi-canary-assurance-progression.ts",
18
+ "runtime-stub.ts"
19
+ ]
20
+ }
@@ -0,0 +1,4 @@
1
+ #!/bin/sh
2
+ set -eu
3
+ PLUGIN_ROOT=$(cd "$(dirname "$0")/.." && pwd -P)
4
+ exec bun "$PLUGIN_ROOT/runtime/v4_runtime.ts" cli imm-kernel "$@"
@@ -0,0 +1,4 @@
1
+ #!/bin/sh
2
+ set -eu
3
+ PLUGIN_ROOT=$(cd "$(dirname "$0")/.." && pwd -P)
4
+ exec bun "$PLUGIN_ROOT/runtime/v4_runtime.ts" cli imm-plan "$@"