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
@@ -0,0 +1,242 @@
1
+ "use strict";
2
+ /**
3
+ * Phase 5: Semantic Execution Kernel
4
+ *
5
+ * Single entry point: intent → validated code → file written → audit verified.
6
+ * Wires together: IR extraction → Planner → EmitCode → Fingerprint.
7
+ *
8
+ * This is what progmune_execute MCP tool calls internally.
9
+ */
10
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
11
+ if (k2 === undefined) k2 = k;
12
+ var desc = Object.getOwnPropertyDescriptor(m, k);
13
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
14
+ desc = { enumerable: true, get: function() { return m[k]; } };
15
+ }
16
+ Object.defineProperty(o, k2, desc);
17
+ }) : (function(o, m, k, k2) {
18
+ if (k2 === undefined) k2 = k;
19
+ o[k2] = m[k];
20
+ }));
21
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
22
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
23
+ }) : function(o, v) {
24
+ o["default"] = v;
25
+ });
26
+ var __importStar = (this && this.__importStar) || (function () {
27
+ var ownKeys = function(o) {
28
+ ownKeys = Object.getOwnPropertyNames || function (o) {
29
+ var ar = [];
30
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
31
+ return ar;
32
+ };
33
+ return ownKeys(o);
34
+ };
35
+ return function (mod) {
36
+ if (mod && mod.__esModule) return mod;
37
+ var result = {};
38
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
39
+ __setModuleDefault(result, mod);
40
+ return result;
41
+ };
42
+ })();
43
+ Object.defineProperty(exports, "__esModule", { value: true });
44
+ exports.recordGeneration = recordGeneration;
45
+ exports.getExecutionMetrics = getExecutionMetrics;
46
+ exports.execute = execute;
47
+ exports.verifyCompiles = verifyCompiles;
48
+ exports.verifyFileMarker = verifyFileMarker;
49
+ const fs = __importStar(require("fs"));
50
+ const path = __importStar(require("path"));
51
+ const planner_1 = require("./planner");
52
+ const extract_ir_1 = require("./extract-ir");
53
+ const failure_collector_1 = require("./failure-collector");
54
+ const emitter_1 = require("./emitter");
55
+ const METRICS_FILE = ".progmune_corpus/metrics.json";
56
+ function loadMetrics() {
57
+ try {
58
+ if (fs.existsSync(METRICS_FILE)) {
59
+ return JSON.parse(fs.readFileSync(METRICS_FILE, "utf-8"));
60
+ }
61
+ }
62
+ catch { }
63
+ return { generated: 0, repaired: 0, lastGeneration: null, history: [] };
64
+ }
65
+ function saveMetrics(m) {
66
+ const dir = ".progmune_corpus";
67
+ if (!fs.existsSync(dir))
68
+ fs.mkdirSync(dir, { recursive: true });
69
+ fs.writeFileSync(METRICS_FILE, JSON.stringify(m, null, 2), "utf-8");
70
+ }
71
+ /** Record a generation event. Called automatically by execute(). */
72
+ function recordGeneration(record) {
73
+ const m = loadMetrics();
74
+ m.generated++;
75
+ if (record.repaired)
76
+ m.repaired++;
77
+ m.lastGeneration = record.filePath;
78
+ m.history.push(record);
79
+ // Keep last 100 entries
80
+ if (m.history.length > 100)
81
+ m.history = m.history.slice(-100);
82
+ saveMetrics(m);
83
+ }
84
+ /** Get current execution metrics. */
85
+ function getExecutionMetrics() {
86
+ return loadMetrics();
87
+ }
88
+ /**
89
+ * Execute the full Progmune pipeline: intent → validated code → file.
90
+ *
91
+ * @param intent - Natural language programming intent
92
+ * @param projectPath - Absolute path to project root
93
+ * @param filePath - Optional: write generated code to this file
94
+ */
95
+ async function execute(intent, projectPath, filePath) {
96
+ // 1. IR extraction
97
+ let ir;
98
+ try {
99
+ ir = (0, extract_ir_1.extractIR)(projectPath);
100
+ }
101
+ catch (e) {
102
+ return { success: false, code: "", sessionId: "", hash: "", ruleHash: "", irFunctionCount: 0, protocolRuleCount: 0, violations: 0, repairApplied: false, repairCount: 0, repairBranchIds: [], branchWinner: undefined, error: `IR extraction failed: ${e.message}` };
103
+ }
104
+ // 2. Protocol rule count
105
+ let protocolRuleCount = 0;
106
+ try {
107
+ const protoPath = path.resolve(projectPath, "protocols.json");
108
+ if (fs.existsSync(protoPath)) {
109
+ protocolRuleCount = Object.keys(JSON.parse(fs.readFileSync(protoPath, "utf-8")).rules || {}).length;
110
+ }
111
+ }
112
+ catch { }
113
+ // 3. Plan (LLM + immune constraints)
114
+ let planResult;
115
+ try {
116
+ planResult = await (0, planner_1.plan)(intent);
117
+ }
118
+ catch (e) {
119
+ (0, failure_collector_1.recordFailure)({
120
+ intent,
121
+ stage: "plan",
122
+ plan: [],
123
+ compileErrors: [e.message],
124
+ rootCause: (0, failure_collector_1.classifyPlanError)(e.message),
125
+ sessionId: undefined,
126
+ });
127
+ return { success: false, code: "", sessionId: "", hash: "", ruleHash: "", irFunctionCount: ir.length, protocolRuleCount, violations: 0, repairApplied: false, repairCount: 0, repairBranchIds: [], branchWinner: undefined, error: `Planning failed: ${e.message}` };
128
+ }
129
+ const actions = planResult.actions || [];
130
+ if (actions.length === 0) {
131
+ return { success: false, code: "", sessionId: planResult.sessionId, hash: "", ruleHash: planResult.ruleHash || "", irFunctionCount: ir.length, protocolRuleCount, violations: 0, repairApplied: false, repairCount: 0, repairBranchIds: [], branchWinner: undefined, error: "Planner returned empty action sequence" };
132
+ }
133
+ // 4. Emit code with generation marker
134
+ const code = (0, emitter_1.emitCode)(actions, {
135
+ sessionId: planResult.sessionId,
136
+ ruleHash: planResult.ruleHash,
137
+ irFunctionCount: ir.length,
138
+ protocolRuleCount,
139
+ });
140
+ // 5. Write to file if requested
141
+ if (filePath) {
142
+ const resolvedPath = path.isAbsolute(filePath) ? filePath : path.resolve(projectPath, filePath);
143
+ const dir = path.dirname(resolvedPath);
144
+ if (!fs.existsSync(dir)) {
145
+ fs.mkdirSync(dir, { recursive: true });
146
+ }
147
+ fs.writeFileSync(resolvedPath, code, "utf-8");
148
+ }
149
+ // 6. Compute hash (from code content)
150
+ const crypto = require("crypto");
151
+ const hash = crypto.createHash("sha256").update(code).digest("hex").slice(0, 16);
152
+ const ruleHash = planResult.ruleHash || "";
153
+ // Phase 7: Record execution metrics
154
+ if (filePath) {
155
+ recordGeneration({
156
+ sessionId: planResult.sessionId,
157
+ timestamp: Date.now(),
158
+ filePath: filePath,
159
+ repaired: planResult.repairApplied,
160
+ repairCount: planResult.repairCount,
161
+ irFunctionCount: ir.length,
162
+ });
163
+ }
164
+ // Fingerprint registration is NOT done here.
165
+ // plan() internally calls recordSession() which writes real transitions to
166
+ // .progmune_corpus/sessions/. The fingerprint is registered later by
167
+ // `npm run check` → registerAllMissingFingerprints() which reads the
168
+ // actual session file with real StateTransition[].
169
+ return {
170
+ success: true,
171
+ code,
172
+ sessionId: planResult.sessionId,
173
+ filePath: filePath || undefined,
174
+ hash,
175
+ ruleHash,
176
+ irFunctionCount: ir.length,
177
+ protocolRuleCount,
178
+ violations: 0,
179
+ repairApplied: planResult.repairApplied,
180
+ repairCount: planResult.repairCount,
181
+ repairBranchIds: planResult.repairBranchIds,
182
+ branchWinner: planResult.repairApplied && planResult.repairBranchIds.length >= 2
183
+ ? (() => {
184
+ try {
185
+ // Load branches from the session file to evaluate
186
+ const sessionFile = `.progmune_corpus/sessions/${planResult.sessionId}.json`;
187
+ if (fs.existsSync(sessionFile)) {
188
+ const session = JSON.parse(fs.readFileSync(sessionFile, "utf-8"));
189
+ if (session.branchTree && session.branchTree.length > 0) {
190
+ const { evaluateBranches } = require("./branch-ledger");
191
+ const { getNsInit } = require("./protocol-registry");
192
+ const evalResult = evaluateBranches(session.branchTree, getNsInit());
193
+ if (evalResult.winner) {
194
+ return {
195
+ id: evalResult.winner.branchId.slice(0, 12),
196
+ score: evalResult.winner.score,
197
+ recommendation: evalResult.winner.recommendation,
198
+ };
199
+ }
200
+ }
201
+ }
202
+ }
203
+ catch { }
204
+ return undefined;
205
+ })()
206
+ : undefined,
207
+ };
208
+ }
209
+ /** Verify a file compiles without errors. Returns {pass, errors[]}.
210
+ * Uses tsc directly — no grep tricks, no pipefail ambiguity. */
211
+ function verifyCompiles(filePath) {
212
+ try {
213
+ const { execSync } = require("child_process");
214
+ const result = execSync(`npx tsc --noEmit --project tsconfig.json --pretty false 2>&1`, {
215
+ timeout: 30000,
216
+ encoding: "utf-8",
217
+ stdio: "pipe",
218
+ });
219
+ // tsc exits 0, check if our file is mentioned in output anyway (unlikely but safe)
220
+ const lines = result.split("\n").filter((l) => l.includes(filePath));
221
+ return { pass: lines.length === 0, errors: lines };
222
+ }
223
+ catch (e) {
224
+ // tsc exits non-zero — parse stderr/stdout for our file's errors
225
+ const output = (e.stdout || "") + (e.stderr || "");
226
+ const lines = output.split("\n").filter((l) => l.includes(filePath));
227
+ return { pass: lines.length === 0, errors: lines };
228
+ }
229
+ }
230
+ /** Quick audit: check whether a file has the @progmune-generated marker. */
231
+ function verifyFileMarker(filePath) {
232
+ try {
233
+ const content = fs.readFileSync(filePath, "utf-8");
234
+ const head = content.split("\n").slice(0, 5).join("\n");
235
+ const match = head.match(/@progmune-generated\s+session=(\S+)(?:\s+timestamp=(\S+))?/);
236
+ if (match) {
237
+ return { marked: true, sessionId: match[1], timestamp: match[2] };
238
+ }
239
+ }
240
+ catch { }
241
+ return { marked: false };
242
+ }