progmune-runtime 2.0.4 → 2.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.mcp.json +11 -0
- package/.progmune_allowlist +50 -0
- package/.test_report/test_report.md +87 -0
- package/Dockerfile +2 -10
- package/FAQ.md +167 -0
- package/README.md +108 -54
- package/demo-project/auth.ts +55 -0
- package/demo-project/tsconfig.json +8 -0
- package/dist/ab-stats.js +11 -0
- package/dist/acl-breakdown.js +13 -0
- package/dist/action-runtime.js +1 -0
- package/dist/all-sessions.js +11 -0
- package/dist/antibody-stats.js +11 -0
- package/dist/audit.js +222 -0
- package/dist/benchmark-count.js +7 -0
- package/dist/benchmark-full.js +17 -0
- package/dist/benchmark-pass-rate.js +54 -0
- package/dist/benchmark-report.js +67 -0
- package/dist/benchmark-save.js +62 -0
- package/dist/benchmark-status.js +15 -0
- package/dist/branch-ledger.js +393 -0
- package/dist/branch-tree-count.js +14 -0
- package/dist/check.js +506 -0
- package/dist/common-fixpath.js +12 -0
- package/dist/constraint-types.js +12 -0
- package/dist/deterministic-replay.js +283 -0
- package/dist/emitter.js +143 -12
- package/dist/exec-metrics.js +11 -0
- package/dist/execute.js +251 -0
- package/dist/extract-ir.js +592 -5
- package/dist/failure-collector.js +163 -0
- package/dist/failure-corpus.js +507 -35
- package/dist/failure-report.js +11 -0
- package/dist/failures.js +11 -0
- package/dist/fast-path-hits.js +13 -0
- package/dist/feedback.js +10 -3
- package/dist/file-lock.js +82 -0
- package/dist/find-session.js +10 -0
- package/dist/fingerprint-list.js +15 -0
- package/dist/gen-history-log.js +13 -0
- package/dist/generate.js +2 -1
- package/dist/generate_500.js +4 -2
- package/dist/genome.js +11 -0
- package/dist/heatmap-data.js +11 -0
- package/dist/heatmap.js +11 -0
- package/dist/immune-reporter.js +34 -22
- package/dist/ir-utils.js +18 -0
- package/dist/learned.js +11 -0
- package/dist/ledger-registry.js +252 -0
- package/dist/llm.js +46 -2
- package/dist/load-benchmarks.js +47 -0
- package/dist/main.js +2 -1
- package/dist/mcp-server.mjs +445 -43
- package/dist/memory-layer.js +54 -13
- package/dist/metrics.js +11 -0
- package/dist/obs-web.js +561 -0
- package/dist/p0_ssg_demo.js +255 -40
- package/dist/planner.js +996 -80
- package/dist/protocol-registry.js +112 -0
- package/dist/recent-session.js +12 -0
- package/dist/repair-proposal.js +363 -0
- package/dist/runtime-invariants.js +170 -0
- package/dist/runtime-types.js +117 -0
- package/dist/runtime.js +1 -0
- package/dist/search-planner.js +39 -9
- package/dist/semantic-snapshot.js +157 -0
- package/dist/semantic-trace.js +1497 -0
- package/dist/semantic-validator.js +3 -2
- package/dist/semantic_guard_test.js +2 -1
- package/dist/session-utils.js +19 -0
- package/dist/sessions.js +11 -0
- package/dist/ssg-validator.js +666 -20
- package/dist/svl-distribution.js +11 -0
- package/dist/terminal-status.js +11 -0
- package/dist/test_failure_corpus.js +3 -1
- package/dist/token-savings.js +11 -0
- package/dist/total-repairs.js +12 -0
- package/dist/unresolved-count.js +12 -0
- package/dist/utils.js +2 -0
- package/dist/valid-fingerprints.js +13 -0
- package/dist/validator.js +118 -60
- package/dist/verify-fps.js +11 -0
- package/dist/verify-ledgers.js +11 -0
- package/docs/whitepaper-style.css +77 -0
- package/docs/whitepaper-v2.1.md +609 -0
- package/docs/whitepaper-v2.2.md +1064 -0
- package/docs/whitepaper-v2.2.pdf +0 -0
- package/fly.toml +1 -1
- package/package.json +13 -4
- package/protocols.json +131 -11
- package/public/dashboard.html +119 -0
- package/server/hub.js +84 -12
- package/test/replay-golden/sess_1780063202050_mgeld.json +9 -0
- package/test/replay-golden/sess_1780064032560_gocld.json +354 -0
- package/test/replay-golden/sess_1780064413331_s2709.json +606 -0
- package/test/replay-golden/sess_1780064792710_y3avo.json +614 -0
- package/test/replay-golden.ts +84 -0
- package/test_benchmark.js +165 -0
- package/test_comprehensive.mjs +638 -0
- package/test_concurrency.js +129 -0
- package/test_ir_robustness.js +85 -0
- package/test_semantic_contracts.js +269 -0
- package/test_ssg_stress.js +156 -0
- package/test_svl3.js +58 -0
- package/tsconfig.json +1 -1
- package/.env.example +0 -3
- package/.progmune_memory/episodic.json +0 -186
- package/.progmune_memory/fingerprints.json +0 -7
- package/.progmune_memory/opt_in.json +0 -4
- package/immune_hub_data/2026-05-14.json +0 -50
package/dist/execute.js
ADDED
|
@@ -0,0 +1,251 @@
|
|
|
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
|
+
/** @requires GENERATION_EVENT @produces METRICS_DATA */
|
|
73
|
+
function recordGeneration(record) {
|
|
74
|
+
const m = loadMetrics();
|
|
75
|
+
m.generated++;
|
|
76
|
+
if (record.repaired)
|
|
77
|
+
m.repaired++;
|
|
78
|
+
m.lastGeneration = record.filePath;
|
|
79
|
+
m.history.push(record);
|
|
80
|
+
// Keep last 100 entries
|
|
81
|
+
if (m.history.length > 100)
|
|
82
|
+
m.history = m.history.slice(-100);
|
|
83
|
+
saveMetrics(m);
|
|
84
|
+
}
|
|
85
|
+
/** Get current execution metrics. */
|
|
86
|
+
/** @requires METRICS_DATA @produces EXECUTION_METRICS */
|
|
87
|
+
/** @requires METRICS_DATA @produces EXECUTION_METRICS */
|
|
88
|
+
function getExecutionMetrics() {
|
|
89
|
+
return loadMetrics();
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Execute the full Progmune pipeline: intent → validated code → file.
|
|
93
|
+
*
|
|
94
|
+
* @param intent - Natural language programming intent
|
|
95
|
+
* @param projectPath - Absolute path to project root
|
|
96
|
+
* @param filePath - Optional: write generated code to this file
|
|
97
|
+
*/
|
|
98
|
+
/** @requires INTENT @produces CODE */
|
|
99
|
+
/** @requires INTENT @produces CODE */
|
|
100
|
+
async function execute(intent, projectPath, filePath) {
|
|
101
|
+
// 1. IR extraction
|
|
102
|
+
let ir;
|
|
103
|
+
try {
|
|
104
|
+
ir = (0, extract_ir_1.extractIR)(projectPath);
|
|
105
|
+
}
|
|
106
|
+
catch (e) {
|
|
107
|
+
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}` };
|
|
108
|
+
}
|
|
109
|
+
// 2. Protocol rule count
|
|
110
|
+
let protocolRuleCount = 0;
|
|
111
|
+
try {
|
|
112
|
+
const protoPath = path.resolve(projectPath, "protocols.json");
|
|
113
|
+
if (fs.existsSync(protoPath)) {
|
|
114
|
+
protocolRuleCount = Object.keys(JSON.parse(fs.readFileSync(protoPath, "utf-8")).rules || {}).length;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
catch { }
|
|
118
|
+
// 3. Plan (LLM + immune constraints)
|
|
119
|
+
let planResult;
|
|
120
|
+
try {
|
|
121
|
+
planResult = await (0, planner_1.plan)(intent);
|
|
122
|
+
}
|
|
123
|
+
catch (e) {
|
|
124
|
+
(0, failure_collector_1.recordFailure)({
|
|
125
|
+
intent,
|
|
126
|
+
stage: "plan",
|
|
127
|
+
plan: [],
|
|
128
|
+
compileErrors: [e.message],
|
|
129
|
+
rootCause: (0, failure_collector_1.classifyPlanError)(e.message),
|
|
130
|
+
sessionId: undefined,
|
|
131
|
+
});
|
|
132
|
+
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}` };
|
|
133
|
+
}
|
|
134
|
+
const actions = planResult.actions || [];
|
|
135
|
+
if (actions.length === 0) {
|
|
136
|
+
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" };
|
|
137
|
+
}
|
|
138
|
+
// 4. Emit code with generation marker
|
|
139
|
+
const code = (0, emitter_1.emitCode)(actions, {
|
|
140
|
+
sessionId: planResult.sessionId,
|
|
141
|
+
ruleHash: planResult.ruleHash,
|
|
142
|
+
irFunctionCount: ir.length,
|
|
143
|
+
protocolRuleCount,
|
|
144
|
+
});
|
|
145
|
+
// 5. Write to file if requested
|
|
146
|
+
if (filePath) {
|
|
147
|
+
const resolvedPath = path.isAbsolute(filePath) ? filePath : path.resolve(projectPath, filePath);
|
|
148
|
+
const dir = path.dirname(resolvedPath);
|
|
149
|
+
if (!fs.existsSync(dir)) {
|
|
150
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
151
|
+
}
|
|
152
|
+
fs.writeFileSync(resolvedPath, code, "utf-8");
|
|
153
|
+
}
|
|
154
|
+
// 6. Compute hash (from code content)
|
|
155
|
+
const crypto = require("crypto");
|
|
156
|
+
const hash = crypto.createHash("sha256").update(code).digest("hex").slice(0, 16);
|
|
157
|
+
const ruleHash = planResult.ruleHash || "";
|
|
158
|
+
// Phase 7: Record execution metrics
|
|
159
|
+
if (filePath) {
|
|
160
|
+
recordGeneration({
|
|
161
|
+
sessionId: planResult.sessionId,
|
|
162
|
+
timestamp: Date.now(),
|
|
163
|
+
filePath: filePath,
|
|
164
|
+
repaired: planResult.repairApplied,
|
|
165
|
+
repairCount: planResult.repairCount,
|
|
166
|
+
irFunctionCount: ir.length,
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
// Fingerprint registration is NOT done here.
|
|
170
|
+
// plan() internally calls recordSession() which writes real transitions to
|
|
171
|
+
// .progmune_corpus/sessions/. The fingerprint is registered later by
|
|
172
|
+
// `npm run check` → registerAllMissingFingerprints() which reads the
|
|
173
|
+
// actual session file with real StateTransition[].
|
|
174
|
+
return {
|
|
175
|
+
success: true,
|
|
176
|
+
code,
|
|
177
|
+
sessionId: planResult.sessionId,
|
|
178
|
+
filePath: filePath || undefined,
|
|
179
|
+
hash,
|
|
180
|
+
ruleHash,
|
|
181
|
+
irFunctionCount: ir.length,
|
|
182
|
+
protocolRuleCount,
|
|
183
|
+
violations: 0,
|
|
184
|
+
repairApplied: planResult.repairApplied,
|
|
185
|
+
repairCount: planResult.repairCount,
|
|
186
|
+
repairBranchIds: planResult.repairBranchIds,
|
|
187
|
+
branchWinner: planResult.repairApplied && planResult.repairBranchIds.length >= 2
|
|
188
|
+
? (() => {
|
|
189
|
+
try {
|
|
190
|
+
// Load branches from the session file to evaluate
|
|
191
|
+
const sessionFile = `.progmune_corpus/sessions/${planResult.sessionId}.json`;
|
|
192
|
+
if (fs.existsSync(sessionFile)) {
|
|
193
|
+
const session = JSON.parse(fs.readFileSync(sessionFile, "utf-8"));
|
|
194
|
+
if (session.branchTree && session.branchTree.length > 0) {
|
|
195
|
+
const { evaluateBranches } = require("./branch-ledger");
|
|
196
|
+
const { getNsInit } = require("./protocol-registry");
|
|
197
|
+
const evalResult = evaluateBranches(session.branchTree, getNsInit());
|
|
198
|
+
if (evalResult.winner) {
|
|
199
|
+
return {
|
|
200
|
+
id: evalResult.winner.branchId.slice(0, 12),
|
|
201
|
+
score: evalResult.winner.score,
|
|
202
|
+
recommendation: evalResult.winner.recommendation,
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
catch { }
|
|
209
|
+
return undefined;
|
|
210
|
+
})()
|
|
211
|
+
: undefined,
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
/** Verify a file compiles without errors. Returns {pass, errors[]}.
|
|
215
|
+
* Uses tsc directly — no grep tricks, no pipefail ambiguity. */
|
|
216
|
+
/** @requires FILE_PATH @produces COMPILE_RESULT */
|
|
217
|
+
/** @requires FILE_PATH @produces COMPILE_RESULT */
|
|
218
|
+
/** @requires FILE_PATH @produces COMPILE_RESULT */
|
|
219
|
+
function verifyCompiles(filePath) {
|
|
220
|
+
try {
|
|
221
|
+
const { execSync } = require("child_process");
|
|
222
|
+
const result = execSync(`npx tsc --noEmit --project tsconfig.json --pretty false 2>&1`, {
|
|
223
|
+
timeout: 30000,
|
|
224
|
+
encoding: "utf-8",
|
|
225
|
+
stdio: "pipe",
|
|
226
|
+
});
|
|
227
|
+
// tsc exits 0, check if our file is mentioned in output anyway (unlikely but safe)
|
|
228
|
+
const lines = result.split("\n").filter((l) => l.includes(filePath));
|
|
229
|
+
return { pass: lines.length === 0, errors: lines };
|
|
230
|
+
}
|
|
231
|
+
catch (e) {
|
|
232
|
+
// tsc exits non-zero — parse stderr/stdout for our file's errors
|
|
233
|
+
const output = (e.stdout || "") + (e.stderr || "");
|
|
234
|
+
const lines = output.split("\n").filter((l) => l.includes(filePath));
|
|
235
|
+
return { pass: lines.length === 0, errors: lines };
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
/** Quick audit: check whether a file has the @progmune-generated marker. */
|
|
239
|
+
/** @requires FILE_PATH @produces MARKER_STATUS */
|
|
240
|
+
function verifyFileMarker(filePath) {
|
|
241
|
+
try {
|
|
242
|
+
const content = fs.readFileSync(filePath, "utf-8");
|
|
243
|
+
const head = content.split("\n").slice(0, 5).join("\n");
|
|
244
|
+
const match = head.match(/@progmune-generated\s+session=(\S+)(?:\s+timestamp=(\S+))?/);
|
|
245
|
+
if (match) {
|
|
246
|
+
return { marked: true, sessionId: match[1], timestamp: match[2] };
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
catch { }
|
|
250
|
+
return { marked: false };
|
|
251
|
+
}
|