progmune-runtime 2.0.2 → 2.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 (107) hide show
  1. package/.mcp.json +11 -0
  2. package/.progmune_allowlist +50 -0
  3. package/.test_report/test_report.md +87 -0
  4. package/Dockerfile +2 -10
  5. package/FAQ.md +167 -0
  6. package/demo-project/auth.ts +55 -0
  7. package/demo-project/tsconfig.json +8 -0
  8. package/dist/ab-stats.js +11 -0
  9. package/dist/acl-breakdown.js +13 -0
  10. package/dist/all-sessions.js +11 -0
  11. package/dist/antibody-stats.js +11 -0
  12. package/dist/audit.js +218 -0
  13. package/dist/benchmark-count.js +7 -0
  14. package/dist/benchmark-full.js +17 -0
  15. package/dist/benchmark-pass-rate.js +54 -0
  16. package/dist/benchmark-report.js +67 -0
  17. package/dist/benchmark-save.js +62 -0
  18. package/dist/benchmark-status.js +15 -0
  19. package/dist/branch-ledger.js +365 -0
  20. package/dist/branch-tree-count.js +14 -0
  21. package/dist/check.js +506 -0
  22. package/dist/common-fixpath.js +12 -0
  23. package/dist/constraint-types.js +12 -0
  24. package/dist/deterministic-replay.js +277 -0
  25. package/dist/emitter.js +112 -12
  26. package/dist/exec-metrics.js +11 -0
  27. package/dist/execute.js +242 -0
  28. package/dist/extract-ir.js +550 -5
  29. package/dist/failure-collector.js +143 -0
  30. package/dist/failure-corpus.js +481 -35
  31. package/dist/failure-report.js +11 -0
  32. package/dist/failures.js +11 -0
  33. package/dist/fast-path-hits.js +13 -0
  34. package/dist/feedback.js +6 -3
  35. package/dist/file-lock.js +82 -0
  36. package/dist/find-session.js +10 -0
  37. package/dist/fingerprint-list.js +15 -0
  38. package/dist/gen-history-log.js +13 -0
  39. package/dist/generate.js +2 -1
  40. package/dist/generate_500.js +4 -2
  41. package/dist/genome.js +11 -0
  42. package/dist/heatmap-data.js +11 -0
  43. package/dist/heatmap.js +11 -0
  44. package/dist/immune-reporter.js +137 -0
  45. package/dist/learned.js +11 -0
  46. package/dist/ledger-registry.js +241 -0
  47. package/dist/llm.js +43 -2
  48. package/dist/load-benchmarks.js +47 -0
  49. package/dist/main.js +2 -1
  50. package/dist/mcp-server.mjs +446 -34
  51. package/dist/memory-layer.js +51 -13
  52. package/dist/metrics.js +11 -0
  53. package/dist/obs-web.js +561 -0
  54. package/dist/p0_ssg_demo.js +255 -40
  55. package/dist/planner.js +933 -65
  56. package/dist/protocol-registry.js +105 -0
  57. package/dist/recent-session.js +12 -0
  58. package/dist/repair-proposal.js +353 -0
  59. package/dist/report.js +32 -0
  60. package/dist/runtime-invariants.js +161 -0
  61. package/dist/runtime-types.js +117 -0
  62. package/dist/search-planner.js +38 -9
  63. package/dist/semantic-snapshot.js +155 -0
  64. package/dist/semantic-trace.js +1497 -0
  65. package/dist/semantic-validator.js +3 -2
  66. package/dist/semantic_guard_test.js +2 -1
  67. package/dist/sessions.js +11 -0
  68. package/dist/ssg-validator.js +658 -20
  69. package/dist/svl-distribution.js +11 -0
  70. package/dist/terminal-status.js +11 -0
  71. package/dist/test_failure_corpus.js +3 -1
  72. package/dist/token-savings.js +11 -0
  73. package/dist/total-repairs.js +12 -0
  74. package/dist/unresolved-count.js +12 -0
  75. package/dist/valid-fingerprints.js +13 -0
  76. package/dist/validator.js +116 -60
  77. package/dist/verify-fps.js +11 -0
  78. package/dist/verify-ledgers.js +11 -0
  79. package/docs/whitepaper-style.css +77 -0
  80. package/docs/whitepaper-v2.1.md +609 -0
  81. package/docs/whitepaper-v2.2.md +1064 -0
  82. package/docs/whitepaper-v2.2.pdf +0 -0
  83. package/fly.toml +1 -1
  84. package/package.json +13 -4
  85. package/protocols.json +136 -0
  86. package/public/dashboard.html +119 -0
  87. package/readme.md +829 -0
  88. package/server/hub.js +84 -12
  89. package/test/replay-golden/sess_1780063202050_mgeld.json +9 -0
  90. package/test/replay-golden/sess_1780064032560_gocld.json +354 -0
  91. package/test/replay-golden/sess_1780064413331_s2709.json +606 -0
  92. package/test/replay-golden/sess_1780064792710_y3avo.json +614 -0
  93. package/test/replay-golden.ts +84 -0
  94. package/test_benchmark.js +165 -0
  95. package/test_comprehensive.mjs +638 -0
  96. package/test_concurrency.js +129 -0
  97. package/test_ir_robustness.js +85 -0
  98. package/test_semantic_contracts.js +269 -0
  99. package/test_ssg_stress.js +156 -0
  100. package/test_svl3.js +58 -0
  101. package/tsconfig.json +1 -1
  102. package/.env.example +0 -3
  103. package/.progmune_memory/fingerprints.json +0 -7
  104. package/.progmune_memory/opt_in.json +0 -4
  105. package/README.md +0 -118
  106. package/dist/mcp-server.js +0 -55
  107. package/immune_hub_data/2026-05-14.json +0 -50
package/dist/check.js ADDED
@@ -0,0 +1,506 @@
1
+ "use strict";
2
+ /**
3
+ * Progmune Check — 一键代码库免疫状态巡检
4
+ *
5
+ * Usage: npm run check
6
+ *
7
+ * 检查项目:
8
+ * 1. IR 重新提取(确保与当前代码同步)
9
+ * 2. TypeScript 编译(零类型错误)
10
+ * 3. SSG dev_pipeline 协议验证
11
+ * 4. Ledger 不变量 + 回放验证 (Invariant-0, Invariant-1, Replay)
12
+ * 5. 各命名空间状态快照
13
+ * 6. 失败基因组概要
14
+ * 7. 抗体效能统计
15
+ */
16
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
17
+ if (k2 === undefined) k2 = k;
18
+ var desc = Object.getOwnPropertyDescriptor(m, k);
19
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
20
+ desc = { enumerable: true, get: function() { return m[k]; } };
21
+ }
22
+ Object.defineProperty(o, k2, desc);
23
+ }) : (function(o, m, k, k2) {
24
+ if (k2 === undefined) k2 = k;
25
+ o[k2] = m[k];
26
+ }));
27
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
28
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
29
+ }) : function(o, v) {
30
+ o["default"] = v;
31
+ });
32
+ var __importStar = (this && this.__importStar) || (function () {
33
+ var ownKeys = function(o) {
34
+ ownKeys = Object.getOwnPropertyNames || function (o) {
35
+ var ar = [];
36
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
37
+ return ar;
38
+ };
39
+ return ownKeys(o);
40
+ };
41
+ return function (mod) {
42
+ if (mod && mod.__esModule) return mod;
43
+ var result = {};
44
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
45
+ __setModuleDefault(result, mod);
46
+ return result;
47
+ };
48
+ })();
49
+ Object.defineProperty(exports, "__esModule", { value: true });
50
+ const fs = __importStar(require("fs"));
51
+ const path = __importStar(require("path"));
52
+ const child_process_1 = require("child_process");
53
+ const ssg_validator_1 = require("./ssg-validator");
54
+ const failure_corpus_1 = require("./failure-corpus");
55
+ const runtime_invariants_1 = require("./runtime-invariants");
56
+ const ledger_registry_1 = require("./ledger-registry");
57
+ const deterministic_replay_1 = require("./deterministic-replay");
58
+ const protocol_registry_1 = require("./protocol-registry");
59
+ const C = {
60
+ reset: "\x1b[0m",
61
+ green: "\x1b[32m",
62
+ red: "\x1b[31m",
63
+ yellow: "\x1b[33m",
64
+ cyan: "\x1b[36m",
65
+ gray: "\x1b[90m",
66
+ bold: "\x1b[1m",
67
+ };
68
+ const G = (s) => `${C.green}${s}${C.reset}`;
69
+ const R = (s) => `${C.red}${s}${C.reset}`;
70
+ const Y = (s) => `${C.yellow}${s}${C.reset}`;
71
+ const C_ = (s) => `${C.cyan}${s}${C.reset}`;
72
+ const D = (s) => `${C.gray}${s}${C.reset}`;
73
+ const B = (s) => `${C.bold}${s}${C.reset}`;
74
+ let failures = 0;
75
+ let warnings = 0;
76
+ // ── CLI: single-session ledger validation ──
77
+ const cliArg = process.argv[2];
78
+ if (cliArg === "--ledger") {
79
+ const sessionId = process.argv[3];
80
+ if (!sessionId) {
81
+ console.error(`${R("Usage:")} npx ts-node src/check.ts --ledger <sessionId>`);
82
+ process.exit(1);
83
+ }
84
+ const sessions = (0, failure_corpus_1.getAllSessions)();
85
+ const session = sessions.find(s => s.sessionId === sessionId || s.sessionId.startsWith(sessionId));
86
+ if (!session) {
87
+ console.error(`${R("Session not found:")} ${sessionId}`);
88
+ process.exit(1);
89
+ }
90
+ const nsInit = new Map();
91
+ nsInit.set("_global", "UNAUTHENTICATED");
92
+ try {
93
+ const protoPath = path.resolve(__dirname, "../protocols.json");
94
+ if (fs.existsSync(protoPath)) {
95
+ const protoDef = JSON.parse(fs.readFileSync(protoPath, "utf-8"));
96
+ if (protoDef.namespaceInitialStates) {
97
+ for (const [ns, s] of Object.entries(protoDef.namespaceInitialStates)) {
98
+ nsInit.set(ns, s);
99
+ }
100
+ }
101
+ }
102
+ }
103
+ catch { }
104
+ const allTransitions = session.attempts.flatMap(a => a.transitions || []);
105
+ if (allTransitions.length === 0) {
106
+ console.log(`${D("No ledger data in this session.")}`);
107
+ process.exit(0);
108
+ }
109
+ console.log(`${C_("Ledger Validation")} — ${session.sessionId}`);
110
+ console.log(`${D("═".repeat(50))}`);
111
+ console.log(` Intent: ${session.intent}`);
112
+ console.log(` Ledger: ${allTransitions.length} transitions across ${session.attempts.filter(a => (a.transitions || []).length > 0).length} attempt(s)`);
113
+ // Invariants
114
+ const consistency = (0, ssg_validator_1.checkLedgerConsistency)(allTransitions, nsInit);
115
+ console.log(` Invariants: ${consistency.consistent ? G("clean") : R(`${consistency.violations.length} violations`)}`);
116
+ // Replay
117
+ const rebuilt = (0, ssg_validator_1.rebuildState)(allTransitions, nsInit);
118
+ const lastTransition = allTransitions[allTransitions.length - 1];
119
+ const recorded = lastTransition.statesAfter;
120
+ const allNs = new Set([...Object.keys(rebuilt), ...Object.keys(recorded)]);
121
+ const norm = (snap) => {
122
+ const out = {};
123
+ for (const ns of [...allNs].sort())
124
+ out[ns] = [...(snap[ns] || [])].sort();
125
+ return out;
126
+ };
127
+ const replayOk = JSON.stringify(norm(rebuilt)) === JSON.stringify(norm(recorded));
128
+ console.log(` Replay: ${replayOk ? G("state matches") : R("state mismatch")}`);
129
+ // Integrity
130
+ const ledgerHash = (0, ssg_validator_1.hashLedger)(allTransitions);
131
+ console.log(` Fingerprint: ${D(ledgerHash)}`);
132
+ // Per-attempt detail
133
+ for (const attempt of session.attempts) {
134
+ const ts = attempt.transitions || [];
135
+ if (ts.length === 0)
136
+ continue;
137
+ const validCount = ts.filter(t => t.valid).length;
138
+ const consAtt = (0, ssg_validator_1.checkLedgerConsistency)(ts, nsInit);
139
+ console.log(` ${D("─".repeat(40))}`);
140
+ console.log(` Attempt #${attempt.attemptNumber} (${attempt.outcome}): ${validCount}/${ts.length} valid, invariants ${consAtt.consistent ? G("ok") : R("fail")}`);
141
+ for (const t of ts) {
142
+ const icon = t.valid ? G("✓") : R("✗");
143
+ const delta = [t.acquired.length ? G("+" + t.acquired.join(",")) : "", t.invalidated.length ? R("-" + t.invalidated.join(",")) : ""].filter(Boolean).join(" ");
144
+ console.log(` ${icon} ${t.function.padEnd(22)} ${D(t.namespace.padEnd(14))} ${delta || D("(no delta)")}`);
145
+ }
146
+ }
147
+ if (consistency.consistent && replayOk) {
148
+ console.log(`\n ${G("✔")} ${B("Ledger is valid and replayable.")}`);
149
+ process.exit(0);
150
+ }
151
+ else {
152
+ console.log(`\n ${R("✖")} ${B("Ledger has issues.")}`);
153
+ process.exit(1);
154
+ }
155
+ }
156
+ function step(label) {
157
+ console.log(`\n${B("━━━")} ${B(label)} ${"━".repeat(Math.max(2, 60 - label.length))}`);
158
+ }
159
+ function pass(msg) {
160
+ console.log(` ${G("✔")} ${msg}`);
161
+ }
162
+ function fail(msg) {
163
+ console.log(` ${R("✖")} ${msg}`);
164
+ failures++;
165
+ }
166
+ function warn(msg) {
167
+ console.log(` ${Y("!")} ${msg}`);
168
+ warnings++;
169
+ }
170
+ // CLI: --verify — fingerprint integrity check
171
+ if (cliArg === "--verify") {
172
+ console.log(`${B("━━━")} ${B("Fingerprint Verification")} ${"━".repeat(40)}`);
173
+ const summary = (0, ledger_registry_1.verifyAllFingerprints)();
174
+ console.log(` Total fingerprints: ${summary.total}`);
175
+ console.log(` ${G("✔")} Valid: ${summary.valid}`);
176
+ if (summary.tampered > 0) {
177
+ console.log(` ${R("✖")} Tampered: ${summary.tampered}`);
178
+ for (const r of summary.verified.filter(r => r.tampered)) {
179
+ console.log(` ${R(r.sessionId)}: stored=${r.stored.ledgerHash.slice(0, 16)} current=${(r.currentHash || "?").slice(0, 16)}`);
180
+ }
181
+ }
182
+ if (summary.notFound > 0) {
183
+ console.log(` ${Y("!")} Sessions missing: ${summary.notFound} (fingerprint exists but session file gone)`);
184
+ }
185
+ console.log();
186
+ if (summary.tampered > 0) {
187
+ console.log(`${R("✖")} Integrity check failed.`);
188
+ process.exit(1);
189
+ }
190
+ else {
191
+ console.log(`${G("✔")} All execution certificates intact.`);
192
+ process.exit(0);
193
+ }
194
+ }
195
+ // ── 1. IR 提取 ──
196
+ step("1/6 IR 提取");
197
+ try {
198
+ (0, child_process_1.execSync)("npx ts-node src/extract-ir.ts .", { stdio: "pipe", cwd: path.resolve(__dirname, "..") });
199
+ const irRaw = JSON.parse(fs.readFileSync(path.resolve(__dirname, "../ir.json"), "utf-8"));
200
+ const ir = Array.isArray(irRaw) ? irRaw : (irRaw.functions || []);
201
+ const externalCount = ir.filter((f) => f.external).length;
202
+ pass(`IR 提取完成: ${ir.length} 个函数 (${externalCount} 外部)`);
203
+ }
204
+ catch (e) {
205
+ fail(`IR 提取失败: ${e.message}`);
206
+ }
207
+ // ── 2. TypeScript 编译 ──
208
+ step("2/6 TypeScript 类型检查");
209
+ try {
210
+ (0, child_process_1.execSync)("npx tsc --noEmit", { stdio: "pipe", cwd: path.resolve(__dirname, "..") });
211
+ pass("零类型错误");
212
+ }
213
+ catch (e) {
214
+ const stderr = e.stderr?.toString() || e.stdout?.toString() || "";
215
+ const lines = stderr.split("\n").filter((l) => l.includes("error TS"));
216
+ if (lines.length > 0) {
217
+ fail(`${lines.length} 个类型错误`);
218
+ lines.slice(0, 5).forEach((l) => console.log(` ${D(l.trim())}`));
219
+ if (lines.length > 5)
220
+ console.log(` ${D(`... 及其他 ${lines.length - 5} 个错误`)}`);
221
+ }
222
+ else {
223
+ fail(`编译失败`);
224
+ }
225
+ }
226
+ // ── 3. SSG 协议验证 ──
227
+ step("3/6 SSG 协议验证");
228
+ const protoPath = path.resolve(__dirname, "../protocols.json");
229
+ if (!fs.existsSync(protoPath)) {
230
+ fail("protocols.json 不存在");
231
+ }
232
+ else {
233
+ const protoDef = JSON.parse(fs.readFileSync(protoPath, "utf-8"));
234
+ const protocols = (0, ssg_validator_1.parseProtocolsFromJSON)(protoDef);
235
+ pass(`已加载 ${protocols.length} 条协议规则`);
236
+ // 检查命名空间
237
+ const namespaces = new Set(protocols.map((p) => p.protocol.namespace || "_global"));
238
+ console.log(` ${D("命名空间:")} ${[...namespaces].map(n => C_(n)).join(", ")}`);
239
+ // dev_pipeline 验证
240
+ const nsStates = new Map();
241
+ nsStates.set("_global", "UNAUTHENTICATED");
242
+ if (protoDef.namespaceInitialStates) {
243
+ for (const [ns, s] of Object.entries(protoDef.namespaceInitialStates)) {
244
+ nsStates.set(ns, s);
245
+ }
246
+ }
247
+ // dev_pipeline 验证 (pure functions, no StateMachineValidator instance)
248
+ const rules = new Map();
249
+ for (const p of protocols)
250
+ rules.set(p.function, p.protocol);
251
+ const ruleHash = (0, ssg_validator_1.hashRules)(rules);
252
+ const ctx = {
253
+ ledger: [],
254
+ currentState: (0, ssg_validator_1.rebuildState)([], nsStates),
255
+ };
256
+ const transitions = [];
257
+ const devSeq = [
258
+ { fn: "extractIR", name: "IR 提取" },
259
+ { fn: "validateAction", name: "动作校验" },
260
+ { fn: "validateActionSequence", name: "序列校验" },
261
+ { fn: "emitCode", name: "代码生成" },
262
+ { fn: "recordSession", name: "会话记录" },
263
+ ];
264
+ let pipelineOk = true;
265
+ for (let i = 0; i < devSeq.length; i++) {
266
+ const { fn, name } = devSeq[i];
267
+ const { valid, transition, rejection } = (0, ssg_validator_1.validateTransition)(ctx, fn, i, rules, nsStates, ruleHash);
268
+ transitions.push(transition);
269
+ ctx.ledger = transitions;
270
+ if (valid) {
271
+ ctx.currentState = transition.statesAfter;
272
+ const gained = transition.acquired.length ? G("+" + transition.acquired.join(",+")) : "";
273
+ const lost = transition.invalidated.length ? R("-" + transition.invalidated.join(",-")) : "";
274
+ console.log(` ${G("✅")} ${fn.padEnd(25)} ${[gained, lost].filter(Boolean).join(" ") || D("(no delta)")}`);
275
+ }
276
+ else {
277
+ const missing = rejection?.missingFunctions.join(" → ") || "?";
278
+ console.log(` ${R("🚫")} ${fn.padEnd(25)} ${R("需 " + missing)}`);
279
+ pipelineOk = false;
280
+ }
281
+ }
282
+ if (pipelineOk) {
283
+ pass("dev_pipeline 协议全部通过");
284
+ }
285
+ else {
286
+ fail("dev_pipeline 协议存在违规");
287
+ }
288
+ // Per-namespace 状态 (from ledger via rebuildState)
289
+ const snap = (0, ssg_validator_1.rebuildState)(transitions, nsStates);
290
+ console.log(`\n ${B("命名空间状态快照:")}`);
291
+ for (const [ns, states] of Object.entries(snap).sort()) {
292
+ const statesStr = states.length > 0 ? states.map(s => C_(s)).join(", ") : D("(empty)");
293
+ console.log(` ${C_(ns.padEnd(20))} ${statesStr}`);
294
+ }
295
+ }
296
+ // ── 4. Ledger 不变量检查 (Phase 3) ──
297
+ step("4/6 Ledger 不变量");
298
+ {
299
+ // Load namespace initial states from protocols.json for correct replay
300
+ const nsInit = (0, protocol_registry_1.getNsInit)();
301
+ let checked = 0;
302
+ let consistent = 0;
303
+ let stateMatch = 0;
304
+ const allLedgers = [];
305
+ const violationsDetail = [];
306
+ const replayMismatchDetail = [];
307
+ const sessionsDir = path.resolve(process.env.PROGMUNE_PROJECT_DIR || process.cwd(), ".progmune_corpus/sessions");
308
+ const norm = (snap, allNs) => {
309
+ const out = {};
310
+ for (const ns of [...allNs].sort()) {
311
+ out[ns] = [...(snap[ns] || [])].sort();
312
+ }
313
+ return out;
314
+ };
315
+ if (fs.existsSync(sessionsDir)) {
316
+ for (const file of fs.readdirSync(sessionsDir)) {
317
+ if (!file.endsWith(".json"))
318
+ continue;
319
+ try {
320
+ const session = JSON.parse(fs.readFileSync(path.join(sessionsDir, file), "utf-8"));
321
+ for (const attempt of (session.attempts || [])) {
322
+ const transitions = attempt.transitions || [];
323
+ if (transitions.length === 0)
324
+ continue;
325
+ allLedgers.push(...transitions);
326
+ // Invariant check
327
+ const result = (0, ssg_validator_1.checkLedgerConsistency)(transitions, nsInit);
328
+ checked++;
329
+ if (result.consistent) {
330
+ consistent++;
331
+ }
332
+ else {
333
+ for (const v of result.violations.slice(0, 2)) {
334
+ violationsDetail.push(`[${v.invariant}] session=${session.sessionId} idx=${v.index}`);
335
+ }
336
+ }
337
+ // Replay check: rebuildState === recorded statesAfter
338
+ const rebuilt = (0, ssg_validator_1.rebuildState)(transitions, nsInit);
339
+ const recorded = transitions[transitions.length - 1].statesAfter;
340
+ const allNs = new Set([...Object.keys(rebuilt), ...Object.keys(recorded)]);
341
+ if (JSON.stringify(norm(rebuilt, allNs)) === JSON.stringify(norm(recorded, allNs))) {
342
+ stateMatch++;
343
+ }
344
+ else {
345
+ replayMismatchDetail.push(`session=${session.sessionId} attempt=${attempt.attemptNumber}`);
346
+ }
347
+ }
348
+ }
349
+ catch { }
350
+ }
351
+ }
352
+ if (checked === 0) {
353
+ pass("无可检查的 Ledger(需要更多规划会话)");
354
+ }
355
+ else if (consistent === checked && stateMatch === checked) {
356
+ const combinedHash = (0, ssg_validator_1.hashLedger)(allLedgers);
357
+ pass(`全部 ${checked} 个 Ledger 通过 (Invariant-0 + Invariant-1 + Replay) | 完整性指纹: ${combinedHash}`);
358
+ }
359
+ else {
360
+ if (consistent < checked) {
361
+ fail(`${checked - consistent}/${checked} 个 Ledger 存在一致性问题`);
362
+ for (const d of violationsDetail.slice(0, 3)) {
363
+ console.log(` ${D(d)}`);
364
+ }
365
+ // P0: Strict mode — invariant violations are now hard failures
366
+ if (process.env.PROGMUNE_STRICT !== "false") {
367
+ console.log(` ${R("PROGMUNE_STRICT=true — 不变量违规视为硬错误")}`);
368
+ }
369
+ }
370
+ if (stateMatch < checked) {
371
+ fail(`${checked - stateMatch}/${checked} 个 Ledger 回放状态不匹配`);
372
+ for (const d of replayMismatchDetail.slice(0, 3)) {
373
+ console.log(` ${D(d)}`);
374
+ }
375
+ }
376
+ if (consistent === checked && stateMatch === checked) {
377
+ // This shouldn't happen due to outer condition, but keep it safe
378
+ }
379
+ }
380
+ // P0: Strict invariant assertion — catch any violation that escaped per-session checks
381
+ // Per-ledger check (not combined, since different sessions have independent index sequences)
382
+ if (process.env.PROGMUNE_STRICT !== "false" && checked > 0) {
383
+ let invariantFailed = false;
384
+ for (const file of fs.readdirSync(sessionsDir)) {
385
+ if (!file.endsWith(".json"))
386
+ continue;
387
+ try {
388
+ const session = JSON.parse(fs.readFileSync(path.join(sessionsDir, file), "utf-8"));
389
+ for (const attempt of (session.attempts || [])) {
390
+ const transitions = attempt.transitions || [];
391
+ if (transitions.length === 0)
392
+ continue;
393
+ try {
394
+ (0, runtime_invariants_1.assertLedgerInvariants)(transitions, nsInit);
395
+ }
396
+ catch (e) {
397
+ if (e instanceof runtime_invariants_1.InvariantViolationError) {
398
+ invariantFailed = true;
399
+ console.log(` ${R(`[${e.detail.invariant}] session=${session.sessionId} attempt=${attempt.attemptNumber}: ${e.message.slice(0, 80)}`)}`);
400
+ }
401
+ }
402
+ }
403
+ }
404
+ catch { }
405
+ }
406
+ if (invariantFailed) {
407
+ fail("PROGMUNE_STRICT=true — 严格不变量断言发现违规");
408
+ }
409
+ }
410
+ // P0: Fingerprint registration — ensure every session has an execution certificate
411
+ {
412
+ const registered = (0, ledger_registry_1.registerAllMissingFingerprints)();
413
+ if (registered > 0) {
414
+ console.log(` ${C_(`新注册 ${registered} 个指纹`)}`);
415
+ }
416
+ }
417
+ // Phase 6: Auto Replay — replay is health check, not special command
418
+ if (checked > 0) {
419
+ const sessionFiles = fs.readdirSync(sessionsDir).filter(f => f.endsWith(".json"));
420
+ const toReplay = sessionFiles.length <= 20
421
+ ? sessionFiles
422
+ : sessionFiles.slice(-10); // sample recent 10 if > 20
423
+ let replayed = 0;
424
+ let replayPassed = 0;
425
+ for (const file of toReplay) {
426
+ try {
427
+ const sid = file.replace(".json", "");
428
+ const result = (0, deterministic_replay_1.replaySession)(sid);
429
+ replayed++;
430
+ if (result.success)
431
+ replayPassed++;
432
+ else if (result.divergencePoint !== undefined) {
433
+ console.log(` ${Y(`Replay divergence: ${sid.slice(0, 13)}... at index ${result.divergencePoint}`)}`);
434
+ }
435
+ }
436
+ catch { }
437
+ }
438
+ if (replayed > 0) {
439
+ const status = replayPassed === replayed
440
+ ? `${G("✔")} ${replayed}/${replayed} Replay 通过`
441
+ : `${Y("!")} ${replayPassed}/${replayed} Replay 通过`;
442
+ console.log(` ${status}`);
443
+ }
444
+ }
445
+ }
446
+ // ── 5. 失败基因组 ──
447
+ step("5/6 失败基因组");
448
+ const genome = (0, failure_corpus_1.getFailureGenome)();
449
+ if (genome.totalFailures === 0) {
450
+ pass("零失败记录");
451
+ }
452
+ else {
453
+ warn(`${genome.totalFailures} 次违规记录`);
454
+ console.log(` SVL-1: ${genome.bySVL["SVL-1"]} | SVL-2: ${genome.bySVL["SVL-2"]} | SVL-3: ${genome.bySVL["SVL-3"]} | SVL-4: ${genome.bySVL["SVL-4"]}`);
455
+ console.log(` ${D("平均重试:")} ${genome.averageRetriesToSuccess}`);
456
+ if (genome.commonFixPaths.length > 0) {
457
+ const top = genome.commonFixPaths[0];
458
+ console.log(` ${D("最常用修复:")} ${Y(top.fixPath.join(" → "))} (${top.count}x)`);
459
+ }
460
+ }
461
+ // ── 6. 抗体效能 ──
462
+ step("6/6 抗体效能");
463
+ const abStats = (0, failure_corpus_1.getAntibodyStats)();
464
+ if (abStats.totalHits === 0) {
465
+ pass("暂无抗体命中(需要更多会话积累)");
466
+ }
467
+ else {
468
+ const pct = Math.round((abStats.fastPathHits / abStats.totalHits) * 100);
469
+ pass(`${abStats.totalHits} 次命中 | ${abStats.fastPathHits} 快速通道 | ${abStats.totalLLMCallsSaved} 次 LLM 节省 | ${abStats.totalTokensSaved} tokens 节省`);
470
+ console.log(` ${D("免疫效率:")} ${G(pct + "%")} ${D("绕过 LLM")}`);
471
+ }
472
+ // ── 7. Progmune Coverage ──
473
+ step("7/7 覆盖率");
474
+ {
475
+ const { auditDirectory } = require("./audit");
476
+ const srcDir = path.resolve(process.env.PROGMUNE_PROJECT_DIR || process.cwd(), "src");
477
+ const auditResult = auditDirectory(srcDir);
478
+ const pct = Math.round(auditResult.coverage * 100);
479
+ if (pct >= 50) {
480
+ pass(`@progmune-generated 覆盖率 ${pct}% (${auditResult.progmuneFiles}/${auditResult.totalFiles})`);
481
+ }
482
+ else if (pct >= 20) {
483
+ warn(`覆盖率 ${pct}% — 低于 50% 目标 (${auditResult.progmuneFiles}/${auditResult.totalFiles})`);
484
+ }
485
+ else {
486
+ fail(`覆盖率 ${pct}% — 严重低于 20% (${auditResult.progmuneFiles}/${auditResult.totalFiles})`);
487
+ }
488
+ const { getExecutionMetrics } = require("./execute");
489
+ const m = getExecutionMetrics();
490
+ if (m.generated > 0) {
491
+ console.log(` ${D(`执行次数: ${m.generated} | 修复: ${m.repaired} | 最近: ${m.lastGeneration || '无'}`)}`);
492
+ }
493
+ }
494
+ // ── 总结 ──
495
+ console.log(`\n${"═".repeat(66)}`);
496
+ if (failures === 0 && warnings === 0) {
497
+ console.log(` ${G("✦")} ${B("免疫状态: 健康")} — 所有检查通过,SSG 协议正常,零类型错误。`);
498
+ }
499
+ else if (failures === 0) {
500
+ console.log(` ${Y("◇")} ${B("免疫状态: 正常")} — ${warnings} 个提示,无阻塞性问题。`);
501
+ }
502
+ else {
503
+ console.log(` ${R("✖")} ${B("免疫状态: 需要关注")} — ${failures} 个失败, ${warnings} 个警告。`);
504
+ }
505
+ console.log(`${"═".repeat(66)}\n`);
506
+ process.exit(failures > 0 ? 1 : 0);
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.main = main;
4
+ // @progmune-generated session=sess_1780343958169_8r1tt timestamp=2026-06-01T19:59:20.198Z ruleHash=9dec68bc2995e92a
5
+ // Generated with IR constraint: 399 functions, 17 protocol rules
6
+ const failure_corpus_1 = require("./failure-corpus");
7
+ function main() {
8
+ const genome = (0, failure_corpus_1.getFailureGenome)();
9
+ const patterns = (0, failure_corpus_1.getTopFailurePatterns)(0);
10
+ return genome;
11
+ }
12
+ main();
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.main = main;
4
+ // @progmune-generated session=sess_1780343606682_645o6 timestamp=2026-06-01T19:53:28.291Z ruleHash=9dec68bc2995e92a
5
+ // Generated with IR constraint: 388 functions, 17 protocol rules
6
+ const failure_corpus_1 = require("./failure-corpus");
7
+ const planner_1 = require("./planner");
8
+ function main() {
9
+ const genome = (0, failure_corpus_1.getFailureGenome)();
10
+ const type = (0, planner_1.determineConstraintType)({});
11
+ }
12
+ main();