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
@@ -1,64 +1,279 @@
1
1
  "use strict";
2
+ /**
3
+ * P0: SSG 端到端演示
4
+ *
5
+ * 展示完整的协议级语义验证链路:
6
+ * 1. 从 demo-project 提取 IR(含 @protocol 注解)
7
+ * 2. 从 protocols.json 加载协议规则
8
+ * 3. 合法序列 → 全部通过
9
+ * 4. 非法序列 → 被 SSG 拦截(含结构化 rejection + fixPath)
10
+ * 5. 输出可读的拦截解释
11
+ */
12
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
13
+ if (k2 === undefined) k2 = k;
14
+ var desc = Object.getOwnPropertyDescriptor(m, k);
15
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
16
+ desc = { enumerable: true, get: function() { return m[k]; } };
17
+ }
18
+ Object.defineProperty(o, k2, desc);
19
+ }) : (function(o, m, k, k2) {
20
+ if (k2 === undefined) k2 = k;
21
+ o[k2] = m[k];
22
+ }));
23
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
24
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
25
+ }) : function(o, v) {
26
+ o["default"] = v;
27
+ });
28
+ var __importStar = (this && this.__importStar) || (function () {
29
+ var ownKeys = function(o) {
30
+ ownKeys = Object.getOwnPropertyNames || function (o) {
31
+ var ar = [];
32
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
33
+ return ar;
34
+ };
35
+ return ownKeys(o);
36
+ };
37
+ return function (mod) {
38
+ if (mod && mod.__esModule) return mod;
39
+ var result = {};
40
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
41
+ __setModuleDefault(result, mod);
42
+ return result;
43
+ };
44
+ })();
2
45
  Object.defineProperty(exports, "__esModule", { value: true });
3
46
  const ssg_validator_1 = require("./ssg-validator");
4
- const authProtocol = [
5
- {
6
- function: 'verify_password',
7
- protocol: {
8
- pre_states: ['UNAUTHENTICATED'],
9
- post_states: ['AUTHENTICATED'],
10
- }
11
- },
12
- {
13
- function: 'generate_jwt',
14
- protocol: {
15
- pre_states: ['AUTHENTICATED'],
16
- post_states: ['TOKEN_ISSUED'],
17
- invalidate: ['AUTHENTICATED']
18
- }
19
- },
20
- {
21
- function: 'create_session',
22
- protocol: {
23
- pre_states: ['TOKEN_ISSUED'],
24
- post_states: ['SESSION_ACTIVE'],
25
- invalidate: ['TOKEN_ISSUED']
26
- }
47
+ const extract_ir_1 = require("./extract-ir");
48
+ const fs = __importStar(require("fs"));
49
+ const path = __importStar(require("path"));
50
+ function loadProtocolsFromFile(filePath) {
51
+ const raw = JSON.parse(fs.readFileSync(filePath, 'utf-8'));
52
+ const protocols = [];
53
+ for (const [funcName, rule] of Object.entries(raw.rules || {})) {
54
+ const r = rule;
55
+ protocols.push({
56
+ function: funcName,
57
+ protocol: {
58
+ pre_states: r.pre_states || [],
59
+ post_states: r.post_states || [],
60
+ invalidate: r.invalidate,
61
+ namespace: r.namespace,
62
+ },
63
+ });
27
64
  }
28
- ];
65
+ return {
66
+ protocols,
67
+ initialState: raw.initialState || 'INIT',
68
+ namespaceInitialStates: raw.namespaceInitialStates || { _global: raw.initialState || 'INIT' },
69
+ };
70
+ }
71
+ function loadProtocolsFromIR(ir) {
72
+ return ir
73
+ .filter((f) => f.protocol)
74
+ .map((f) => ({ function: f.name, protocol: f.protocol }));
75
+ }
29
76
  function runDemo() {
30
- console.log('═══ Semantic State Graph (SSG) 原型演示 ═══\n');
31
- console.log('场景1:合法序列 (verify_password → generate_jwt → create_session)');
77
+ console.log('═══ Progmune SSG 端到端演示 ═══\n');
78
+ // 1) 加载协议
79
+ const protocolsJson = path.join(__dirname, '..', 'protocols.json');
80
+ const fromFile = fs.existsSync(protocolsJson)
81
+ ? loadProtocolsFromFile(protocolsJson)
82
+ : { protocols: [], initialState: 'INIT', namespaceInitialStates: {} };
83
+ // 2) 从 IR 加载协议(@protocol JSDoc 注解)
84
+ const ir = (0, extract_ir_1.extractIR)(path.join(__dirname, '..', 'demo-project'));
85
+ const fromIR = loadProtocolsFromIR(ir);
86
+ // 合并协议,JSON 定义 namespace,IR @protocol 定义规则细节
87
+ const uniqueProtocols = new Map();
88
+ fromFile.protocols.forEach(p => uniqueProtocols.set(p.function, p));
89
+ fromIR.forEach(p => {
90
+ const existing = uniqueProtocols.get(p.function);
91
+ if (existing && existing.protocol.namespace && !p.protocol.namespace) {
92
+ p.protocol.namespace = existing.protocol.namespace;
93
+ }
94
+ uniqueProtocols.set(p.function, p);
95
+ });
96
+ const protocols = [...uniqueProtocols.values()];
97
+ console.log(`📋 已加载 ${protocols.length} 条协议规则:`);
98
+ protocols.forEach(p => {
99
+ const ns = p.protocol.namespace ? ` [${p.protocol.namespace}]` : '';
100
+ console.log(` ${p.function}${ns}: [${p.protocol.pre_states.join(', ')}] → [${p.protocol.post_states.join(', ')}]`);
101
+ });
102
+ console.log();
103
+ // Pure function factory — replaces StateMachineValidator instances
104
+ const rules = new Map();
105
+ for (const p of protocols)
106
+ rules.set(p.function, p.protocol);
107
+ const nsInit = new Map(Object.entries(fromFile.namespaceInitialStates || {}));
108
+ if (!nsInit.has('_global'))
109
+ nsInit.set('_global', fromFile.initialState || 'INIT');
110
+ const ruleHash = (0, ssg_validator_1.hashRules)(rules);
111
+ function createPureContext() {
112
+ let ctx = { ledger: [], currentState: (0, ssg_validator_1.rebuildState)([], nsInit) };
113
+ let transitions = [];
114
+ return {
115
+ apply(fn) {
116
+ const { valid, transition, rejection } = (0, ssg_validator_1.validateTransition)(ctx, fn, transitions.length, rules, nsInit, ruleHash);
117
+ transitions.push(transition);
118
+ ctx = { ledger: transitions, currentState: valid ? transition.statesAfter : ctx.currentState };
119
+ return { valid, rejection, acquired: transition.acquired, invalidated: transition.invalidated, statesAfter: transition.statesAfter };
120
+ },
121
+ getTrace() {
122
+ return transitions.map(t => ({
123
+ function: t.function,
124
+ valid: t.valid,
125
+ statesBefore: t.statesBefore,
126
+ statesAfter: t.statesAfter,
127
+ rejection: t.valid ? undefined : { fixPath: (0, ssg_validator_1.findFixPathStatic)(rules, t.namespace, t.statesBefore[t.namespace] || [], rules.get(t.function)?.pre_states || []) },
128
+ }));
129
+ },
130
+ };
131
+ }
132
+ // 3) 合法序列
133
+ console.log('── 场景 1: 合法序列 (Pure Functions) ──');
32
134
  const legalSequence = ['verify_password', 'generate_jwt', 'create_session'];
33
- const validator1 = new ssg_validator_1.StateMachineValidator(authProtocol, 'UNAUTHENTICATED');
135
+ const ctx1 = createPureContext();
34
136
  let allPassed = true;
35
137
  for (const fn of legalSequence) {
36
- const result = validator1.apply(fn);
138
+ const result = ctx1.apply(fn);
37
139
  if (!result.valid) {
38
- console.log(` ❌ ${fn} 被拦截:${result.error}`);
140
+ console.log((0, ssg_validator_1.explainRejection)(result.rejection));
39
141
  allPassed = false;
40
142
  break;
41
143
  }
42
144
  else {
43
- console.log(` ✅ ${fn} 通过,当前状态:[${result.statesAfter}]`);
145
+ console.log(` ✅ ${fn} [${Object.values(result.statesAfter).flat().join(', ')}]`);
44
146
  }
45
147
  }
46
148
  if (allPassed)
47
- console.log(' ✔ 合法序列全部通过\n');
48
- console.log('场景2:非法序列 (generate_jwt verify_password)');
49
- const illegalSequence = ['generate_jwt', 'verify_password'];
50
- const validator2 = new ssg_validator_1.StateMachineValidator(authProtocol, 'UNAUTHENTICATED');
51
- for (const fn of illegalSequence) {
52
- const result = validator2.apply(fn);
149
+ console.log(' ✔ 合法序列全部通过 (纯函数验证)\n');
150
+ // 4) 非法序列 — 跳过前置步骤
151
+ console.log('── 场景 2: 跳过前置步骤 ──');
152
+ const ctx2 = createPureContext();
153
+ const badSequence1 = ['generate_jwt', 'create_session'];
154
+ for (const fn of badSequence1) {
155
+ const result = ctx2.apply(fn);
53
156
  if (!result.valid) {
54
- console.log(` 🚫 ${fn} 被拦截:${result.error}`);
55
- console.log(' 🛡️ SSG 成功阻止了非法状态跃迁!');
157
+ console.log((0, ssg_validator_1.explainRejection)(result.rejection));
158
+ console.log();
159
+ console.log(' 📊 结构化报告:');
160
+ console.log(' ' + JSON.stringify((0, ssg_validator_1.rejectionToJSON)(result.rejection), null, 2).replace(/\n/g, '\n '));
56
161
  break;
57
162
  }
163
+ console.log(` ✅ ${fn} → [${Object.values(result.statesAfter).flat().join(', ')}]`);
164
+ }
165
+ // 5) 非法序列 — 调用后被撤销
166
+ console.log('\n── 场景 3: 令牌签发后,令牌状态已被消费 (Pure Functions) ──');
167
+ const ctx3 = createPureContext();
168
+ ctx3.apply('verify_password');
169
+ ctx3.apply('generate_jwt');
170
+ ctx3.apply('create_session');
171
+ const result3 = ctx3.apply('generate_jwt');
172
+ if (!result3.valid) {
173
+ console.log((0, ssg_validator_1.explainRejection)(result3.rejection));
174
+ }
175
+ // 6) 完整跟踪 (from pure function ledger)
176
+ console.log('\n── 场景 1 完整跟踪 (Pure Ledger) ──');
177
+ console.log(' Intent → Planner → Candidate Path → SSG Validation');
178
+ console.log(' ' + '─'.repeat(50));
179
+ const trace = ctx1.getTrace();
180
+ trace.forEach((node, i) => {
181
+ const icon = node.valid ? '✅' : '🚫';
182
+ console.log(` ${icon} 步骤 ${i + 1}: ${node.function}`);
183
+ console.log(` 状态: [${Object.values(node.statesBefore).flat().join(', ')}] → [${Object.values(node.statesAfter).flat().join(', ')}]`);
184
+ if (node.rejection) {
185
+ console.log(` 修复: ${node.rejection.fixPath.join(' → ')}`);
186
+ }
187
+ });
188
+ console.log('\n═══ SSG 演示完成 ═══');
189
+ // 7) 资源命名空间演示
190
+ console.log('\n── 场景 5: 资源生命周期(file/db 命名空间隔离)──');
191
+ const fileCtx = createPureContext();
192
+ const preRead = fileCtx.apply('read_file');
193
+ if (!preRead.valid) {
194
+ console.log((0, ssg_validator_1.explainRejection)(preRead.rejection));
195
+ console.log();
196
+ }
197
+ fileCtx.apply('open_file');
198
+ console.log(' ✅ open_file → FILE_OPEN');
199
+ fileCtx.apply('read_file');
200
+ console.log(' ✅ read_file (文件操作与 DB 操作命名空间隔离,互不影响)');
201
+ fileCtx.apply('write_file');
202
+ console.log(' ✅ write_file');
203
+ fileCtx.apply('close_file');
204
+ console.log(' ✅ close_file → FILE_OPEN 失效');
205
+ console.log('');
206
+ const dbAttempt = fileCtx.apply('query_db');
207
+ if (!dbAttempt.valid) {
208
+ console.log(` 🚫 query_db 被拦截: ${dbAttempt.rejection?.namespace} 命名空间需要 DB_CONNECTED`);
209
+ console.log(' → 修复路径: connect_db');
210
+ console.log(' → 这证明 file 和 db 命名空间的状态机完全隔离');
211
+ }
212
+ // ── Phase 3: Semantic Ledger Pure Functions ──
213
+ let demoLedger = [];
214
+ console.log('\n── 场景 6: Semantic Ledger 纯函数 API ──');
215
+ console.log(` ruleHash: ${ruleHash}`);
216
+ // Validate transitions using pure functions
217
+ const ctx = { ledger: [], currentState: (0, ssg_validator_1.rebuildState)([], nsInit) };
218
+ demoLedger = [];
219
+ console.log(' 初始状态:', JSON.stringify(ctx.currentState));
220
+ for (const fn of legalSequence) {
221
+ const { valid, transition, rejection } = (0, ssg_validator_1.validateTransition)(ctx, fn, demoLedger.length, rules, nsInit, ruleHash);
222
+ demoLedger.push(transition);
223
+ ctx.ledger = demoLedger;
224
+ if (valid) {
225
+ ctx.currentState = transition.statesAfter;
226
+ console.log(` ✅ ${fn}: acquired=[${transition.acquired}] invalidated=[${transition.invalidated}]`);
227
+ }
58
228
  else {
59
- console.log(` ${fn} 通过,当前状态:[${result.statesAfter}]`);
229
+ console.log(` 🚫 ${fn}: ${rejection?.missingFunctions.join(' → ')}`);
60
230
  }
61
231
  }
62
- console.log('\n═══ 演示完成 ═══');
232
+ // rebuildState should match final context state
233
+ const rebuilt = (0, ssg_validator_1.rebuildState)(demoLedger, nsInit);
234
+ console.log(` rebuildState(demoLedger) = ${JSON.stringify(rebuilt)}`);
235
+ const ctxJson = JSON.stringify(ctx.currentState);
236
+ const rebuiltJson = JSON.stringify(rebuilt);
237
+ console.log(` rebuildState === ctx.currentState: ${rebuiltJson === ctxJson ? '✅' : '🚫 MISMATCH'}`);
238
+ // Invariant check
239
+ const consistency = (0, ssg_validator_1.checkLedgerConsistency)(demoLedger, nsInit);
240
+ console.log(` Invariant-0+1: ${consistency.consistent ? '✅ consistent' : `🚫 ${consistency.violations.length} violations`}`);
241
+ for (const v of consistency.violations) {
242
+ console.log(` [${v.invariant}] index=${v.index}: ${v.detail}`);
243
+ }
244
+ // Invariant-1 negative test: craft an inconsistent transition
245
+ console.log('\n Invariant-1 负向测试:');
246
+ const badTransition = {
247
+ actionIndex: 0, function: "verify_password", namespace: "auth",
248
+ acquired: ["TOKEN_ISSUED"], invalidated: [],
249
+ statesBefore: { "_global": ["INIT"], "auth": ["UNAUTHENTICATED"] },
250
+ statesAfter: { "_global": ["INIT"], "auth": ["UNAUTHENTICATED"] }, // TOKEN_ISSUED missing!
251
+ valid: true, ruleHash,
252
+ };
253
+ const badConsistency = (0, ssg_validator_1.checkLedgerConsistency)([badTransition], nsInit);
254
+ const deltaViolations = badConsistency.violations.filter(v => v.invariant === "delta-consistency");
255
+ console.log(` Delta violations detected: ${deltaViolations.length} ${deltaViolations.length > 0 ? '✅ (correctly caught)' : '🚫 MISSED'}`);
256
+ // ── Phase 3 P1-C: Ledger Query API ──
257
+ console.log('\n── 场景 7: Ledger Query API ──');
258
+ const queryLedger = demoLedger; // from scenario 6
259
+ // findProducer
260
+ const tokenProducers = (0, ssg_validator_1.findProducer)("TOKEN_ISSUED", queryLedger);
261
+ console.log(` findProducer("TOKEN_ISSUED") → ${tokenProducers.map(p => `${p.transition.function}@${p.index}`).join(", ")}`);
262
+ // findConsumer
263
+ const passwordConsumers = (0, ssg_validator_1.findConsumer)("PASSWORD_VERIFIED", queryLedger);
264
+ console.log(` findConsumer("PASSWORD_VERIFIED") → ${passwordConsumers.map(c => `${c.transition.function}@${c.index}`).join(", ")}`);
265
+ // findViolations
266
+ const violations = (0, ssg_validator_1.findViolations)(queryLedger);
267
+ console.log(` findViolations() → ${violations.length} violation(s)`);
268
+ // findTransition
269
+ const t1 = (0, ssg_validator_1.findTransition)(1, queryLedger);
270
+ console.log(` findTransition(1) → ${t1?.transition.function} (${t1?.namespace})`);
271
+ // listAllStates
272
+ const allStates = (0, ssg_validator_1.listAllStates)(queryLedger);
273
+ console.log(` listAllStates() → ${allStates.map(s => `${s.namespace}:${s.state}`).join(", ")}`);
274
+ // Ledger integrity
275
+ const lh = (0, ssg_validator_1.hashLedger)(demoLedger);
276
+ console.log(` hashLedger() → ${lh} (tamper-evident fingerprint)`);
277
+ console.log('\n═══ 全部演示完成 ═══');
63
278
  }
64
279
  runDemo();