progmune-runtime 2.1.6 → 3.2.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.
- package/README.md +108 -468
- package/dist/ablation-study.js +144 -0
- package/dist/ablation-study.test.js +18 -0
- package/dist/action-runtime.js +3 -1
- package/dist/active-learning.js +211 -0
- package/dist/analytics.js +139 -0
- package/dist/asset-factory.js +309 -0
- package/dist/asset-growth.js +244 -0
- package/dist/asset-promotion.js +382 -0
- package/dist/asset-quality.js +550 -0
- package/dist/audit/business-translator.js +285 -0
- package/dist/audit/cli.js +66 -0
- package/dist/audit/formatters/html.js +379 -0
- package/dist/audit/formatters/json.js +11 -0
- package/dist/audit/formatters/markdown.js +192 -0
- package/dist/audit/formatters/terminal.js +189 -0
- package/dist/audit/index.js +25 -0
- package/dist/audit/report-builder.js +318 -0
- package/dist/audit/types.js +8 -0
- package/dist/audit.js +3 -3
- package/dist/auto-benchmark-generator.js +137 -0
- package/dist/auto-benchmark-generator.test.js +45 -0
- package/dist/auto-protocol-synthesizer.js +362 -0
- package/dist/auto-protocol-synthesizer.test.js +82 -0
- package/dist/autonomous-patch.js +175 -0
- package/dist/autonomous-patch.test.js +128 -0
- package/dist/badge/badge-server.js +98 -0
- package/dist/behavior-miner.js +442 -0
- package/dist/belief-layer.js +475 -0
- package/dist/benchmark-count.js +5 -0
- package/dist/benchmark-generator.js +211 -0
- package/dist/benchmark-harness.js +201 -0
- package/dist/benchmark-pass-rate.js +7 -0
- package/dist/benchmark-report.js +8 -3
- package/dist/benchmark-save.js +14 -1
- package/dist/bootstrap-validation.js +197 -0
- package/dist/bootstrap-validation.test.js +51 -0
- package/dist/branch-ledger.js +1 -1
- package/dist/capability-gap.js +130 -0
- package/dist/certify-html.js +351 -0
- package/dist/certify.js +326 -0
- package/dist/check.js +4 -4
- package/dist/compliance-miner.js +447 -0
- package/dist/continuous-benchmark.js +194 -0
- package/dist/continuous-benchmark.test.js +116 -0
- package/dist/corpus-stats.js +173 -0
- package/dist/counterfactual-engine.js +288 -0
- package/dist/coverage-dashboard.js +109 -0
- package/dist/coverage-system.test.js +205 -0
- package/dist/cross-repo-precision.js +352 -0
- package/dist/cve-benchmark.js +180 -0
- package/dist/cve-benchmark.test.js +28 -0
- package/dist/cve-collector.js +73 -0
- package/dist/data-quality.js +141 -0
- package/dist/decision-engine.js +388 -0
- package/dist/derive-metadata.js +250 -0
- package/dist/difficulty-active.test.js +198 -0
- package/dist/difficulty-map.js +244 -0
- package/dist/discovery-analytics.js +125 -0
- package/dist/discovery-model.js +149 -0
- package/dist/discovery-optimize.test.js +199 -0
- package/dist/discovery-trace.js +276 -0
- package/dist/discovery-trace.test.js +97 -0
- package/dist/emitter.js +83 -1
- package/dist/enterprise-dashboard.js +405 -0
- package/dist/eval-hardening.js +297 -0
- package/dist/eval-hardening.test.js +85 -0
- package/dist/evaluation-campaign.js +359 -0
- package/dist/evaluation-campaign.test.js +181 -0
- package/dist/evidence-growth.js +143 -0
- package/dist/evidence-repository.js +209 -0
- package/dist/evidence-system.js +441 -0
- package/dist/execute.js +15 -7
- package/dist/experimental/software-physics.js +291 -0
- package/dist/experimental/state-inference.js +516 -0
- package/dist/experimental/unsupervised-physics.js +230 -0
- package/dist/extract-ir-python.js +54 -7
- package/dist/extract-ir.js +376 -12
- package/dist/failure-collector.js +2 -2
- package/dist/failure-corpus.js +322 -9
- package/dist/feedback.js +16 -5
- package/dist/feedback.test.js +49 -0
- package/dist/file-lock.js +1 -1
- package/dist/flywheel-batch.js +292 -0
- package/dist/frameworks/express-cli.js +237 -0
- package/dist/frameworks/express-detector.js +445 -0
- package/dist/frameworks/express-detector.test.js +206 -0
- package/dist/frameworks/index.js +30 -0
- package/dist/frameworks/nestjs-detector.js +302 -0
- package/dist/frameworks/trpc-detector.js +161 -0
- package/dist/frameworks/version-awareness.js +179 -0
- package/dist/function-synonyms.js +164 -0
- package/dist/function-synonyms.test.js +68 -0
- package/dist/generalization.test.js +352 -0
- package/dist/goal-annotator.js +113 -0
- package/dist/goal-planner.js +563 -0
- package/dist/gold-cve.js +164 -0
- package/dist/gold-cve.test.js +104 -0
- package/dist/gold-quality.js +206 -0
- package/dist/gold-tiers.js +241 -0
- package/dist/governance-dashboard.js +327 -0
- package/dist/graph-viz.js +240 -0
- package/dist/guided-frontier.js +195 -0
- package/dist/hierarchical-planner.js +148 -0
- package/dist/identifier-parser.js +260 -0
- package/dist/immune-metrics.js +93 -0
- package/dist/immune-receiver.js +158 -0
- package/dist/immune-reporter.js +1 -1
- package/dist/improvement-orchestrator.js +206 -0
- package/dist/inject-p0-vocabulary.js +300 -0
- package/dist/intent-parser.js +218 -0
- package/dist/invariant-algebra.js +476 -0
- package/dist/invariant-calculus.js +533 -0
- package/dist/ir-utils.js +70 -0
- package/dist/ir-utils.test.js +50 -0
- package/dist/knowledge-api.js +312 -0
- package/dist/knowledge-evolution.js +452 -0
- package/dist/knowledge-explorer.js +506 -0
- package/dist/knowledge-flywheel.js +274 -0
- package/dist/knowledge-governance.js +338 -0
- package/dist/knowledge-governance.test.js +150 -0
- package/dist/knowledge-graph.js +181 -0
- package/dist/knowledge-guided-synth.js +246 -0
- package/dist/knowledge-loop.test.js +77 -0
- package/dist/knowledge-object.js +316 -0
- package/dist/knowledge-package.js +98 -0
- package/dist/kpi-dashboard.js +561 -0
- package/dist/l3-cross-function.js +280 -0
- package/dist/learning-ranker.js +148 -0
- package/dist/learning-ranker.test.js +291 -0
- package/dist/ledger/accountability.js +322 -0
- package/dist/ledger/chain-builder.js +185 -0
- package/dist/ledger/cli.js +222 -0
- package/dist/ledger/index.js +13 -0
- package/dist/ledger/signatures.js +193 -0
- package/dist/ledger/types.js +9 -0
- package/dist/llm.js +74 -3
- package/dist/load-benchmarks.js +8 -3
- package/dist/logger.js +66 -0
- package/dist/logger.test.js +37 -0
- package/dist/logistic-reward.js +339 -0
- package/dist/logistic-reward.test.js +180 -0
- package/dist/macro-graph.js +193 -0
- package/dist/macro-repair.js +183 -0
- package/dist/mcp-server.mjs +1202 -483
- package/dist/memory-layer.js +42 -5
- package/dist/multi-repo-precision.js +422 -0
- package/dist/name-free-protocol.js +425 -0
- package/dist/name-free-protocol.test.js +170 -0
- package/dist/name-scrambling.js +138 -0
- package/dist/name-scrambling.test.js +16 -0
- package/dist/p3-observability.test.js +281 -0
- package/dist/p5-orchestrator.test.js +225 -0
- package/dist/pairwise-preference.js +294 -0
- package/dist/pairwise-preference.test.js +140 -0
- package/dist/planner-constraints.js +104 -0
- package/dist/planner-prompts.js +155 -0
- package/dist/planner-telemetry.js +415 -0
- package/dist/planner-trace.js +214 -0
- package/dist/planner.js +162 -167
- package/dist/plsb/artifact.js +116 -0
- package/dist/plsb/cli.js +71 -0
- package/dist/plsb/index.js +19 -0
- package/dist/plsb/leaderboard.js +249 -0
- package/dist/plsb/report-md.js +156 -0
- package/dist/plsb/schema.js +179 -0
- package/dist/plsb-benchmark.js +284 -0
- package/dist/plsb-benchmark.test.js +119 -0
- package/dist/policy/cli.js +134 -0
- package/dist/policy/engine.js +333 -0
- package/dist/policy/index.js +12 -0
- package/dist/policy/types.js +59 -0
- package/dist/policy-miner.js +505 -0
- package/dist/precision-analyze.js +229 -0
- package/dist/precision-benchmark.js +147 -0
- package/dist/precision-label-c.js +134 -0
- package/dist/precision-label.js +193 -0
- package/dist/precision-report-c.js +149 -0
- package/dist/precision-report.js +246 -0
- package/dist/progmune-status.js +108 -0
- package/dist/proof-engine.js +479 -0
- package/dist/proof-provenance.js +315 -0
- package/dist/protocol-coverage.js +294 -0
- package/dist/protocol-detector.js +1189 -0
- package/dist/protocol-embedding-expanded.js +297 -0
- package/dist/protocol-embedding-expanded.test.js +97 -0
- package/dist/protocol-embedding.js +195 -0
- package/dist/protocol-embedding.test.js +82 -0
- package/dist/protocol-extractor-v2.js +354 -0
- package/dist/protocol-extractor-v2.test.js +140 -0
- package/dist/protocol-extractor.js +310 -0
- package/dist/protocol-extractor.test.js +113 -0
- package/dist/protocol-foundation.js +322 -0
- package/dist/protocol-foundation.test.js +163 -0
- package/dist/protocol-frontier.js +243 -0
- package/dist/protocol-frontier.test.js +92 -0
- package/dist/protocol-gap-analyzer.js +228 -0
- package/dist/protocol-gap-analyzer.test.js +49 -0
- package/dist/protocol-invariants.js +276 -0
- package/dist/protocol-invariants.test.js +111 -0
- package/dist/protocol-knowledge.js +464 -0
- package/dist/protocol-miner.js +343 -0
- package/dist/protocol-mining.js +207 -0
- package/dist/protocol-mining.test.js +37 -0
- package/dist/protocol-registry.js +1 -1
- package/dist/protocol-security-benchmark.js +222 -0
- package/dist/protocol-vulnerability.js +257 -0
- package/dist/protocol-vulnerability.test.js +60 -0
- package/dist/python-benchmark.js +120 -0
- package/dist/python-emitter.js +163 -45
- package/dist/python-protocol-extractor.js +187 -0
- package/dist/python-protocol-extractor.test.js +116 -0
- package/dist/realworld-benchmark.js +646 -0
- package/dist/realworld-benchmark.test.js +36 -0
- package/dist/repair-arch.test.js +411 -0
- package/dist/repair-evolution.test.js +454 -0
- package/dist/repair-executor.js +719 -0
- package/dist/repair-proposal.js +4 -4
- package/dist/repair-ranker.js +141 -0
- package/dist/repair-strategies.js +419 -0
- package/dist/repair-taxonomy.js +234 -0
- package/dist/repair-types.js +12 -0
- package/dist/repo-evaluator.js +250 -0
- package/dist/repo-evaluator.test.js +128 -0
- package/dist/resource-abstraction.js +242 -0
- package/dist/resource-detector.js +211 -0
- package/dist/result.test.js +43 -0
- package/dist/reward-system.js +411 -0
- package/dist/reward-system.test.js +175 -0
- package/dist/risk-model.js +215 -0
- package/dist/rule-miner.js +234 -7
- package/dist/rule-specificity.js +254 -0
- package/dist/runtime-types.js +27 -0
- package/dist/scaffold.js +208 -0
- package/dist/scale-collector.test.js +101 -0
- package/dist/scale-trajectory-collector.js +128 -0
- package/dist/sdk.js +250 -0
- package/dist/search-planner.js +4 -41
- package/dist/semantic-snapshot.js +1 -1
- package/dist/semantic-topology.js +121 -0
- package/dist/semantic-trace.js +310 -317
- package/dist/sequence-extractor.js +343 -0
- package/dist/skill-library.js +245 -0
- package/dist/skill-planner.test.js +189 -0
- package/dist/software-physics.js +291 -0
- package/dist/software-physics.test.js +81 -0
- package/dist/ssg-precision.js +478 -0
- package/dist/ssg-validator.js +71 -21
- package/dist/state-inference-doubleblind.test.js +160 -0
- package/dist/state-inference.js +516 -0
- package/dist/state-inference.test.js +115 -0
- package/dist/state-machine-fingerprint.js +345 -0
- package/dist/state-machine-fingerprint.test.js +120 -0
- package/dist/state-miner.js +386 -0
- package/dist/state-name-inference.js +213 -0
- package/dist/state-name-inference.test.js +69 -0
- package/dist/strategy-planner.js +262 -96
- package/dist/strategy-planner.test.js +135 -0
- package/dist/telemetry-analytics.test.js +402 -0
- package/dist/terminal-format.js +68 -0
- package/dist/terminal-format.test.js +83 -0
- package/dist/topology-factory.js +196 -0
- package/dist/topology-representation.js +242 -0
- package/dist/topology-representation.test.js +27 -0
- package/dist/trajectory-augmentation.js +254 -0
- package/dist/trajectory-augmentation.test.js +63 -0
- package/dist/trajectory-corpus.js +440 -0
- package/dist/trajectory-corpus.test.js +32 -0
- package/dist/trajectory-feedback.test.js +116 -0
- package/dist/transition-synthesizer.js +286 -0
- package/dist/transition-synthesizer.test.js +123 -0
- package/dist/trust/api-semantic-mapper.js +809 -0
- package/dist/trust/call-graph-propagator.js +225 -0
- package/dist/trust/cli.js +122 -0
- package/dist/trust/compliance-scorer.js +283 -0
- package/dist/trust/confidence-calculator.js +261 -0
- package/dist/trust/engine.js +1145 -0
- package/dist/trust/explainability.js +85 -0
- package/dist/trust/formatters/ci.js +42 -0
- package/dist/trust/formatters/json.js +11 -0
- package/dist/trust/formatters/terminal.js +152 -0
- package/dist/trust/index.js +39 -0
- package/dist/trust/phase1-verify.js +171 -0
- package/dist/trust/protocol-domain-validator.js +697 -0
- package/dist/trust/score-calculator.js +282 -0
- package/dist/trust/ssg-bridge.js +641 -0
- package/dist/trust/ssg-bridge.test.js +269 -0
- package/dist/trust/types.js +67 -0
- package/dist/trust/violation-trace.js +335 -0
- package/dist/trust-api.js +179 -0
- package/dist/trust-calibration.js +279 -0
- package/dist/unknown-protocol-discovery.js +339 -0
- package/dist/unknown-protocol-discovery.test.js +102 -0
- package/dist/unsupervised-physics.js +230 -0
- package/dist/unsupervised-physics.test.js +95 -0
- package/dist/utils.test.js +37 -0
- package/dist/validator.js +187 -10
- package/dist/verification-intelligence.js +475 -0
- package/dist/verify-api.js +432 -0
- package/dist/vi-impact-report.js +293 -0
- package/dist/wl-fingerprint.js +162 -0
- package/dist/wl-fingerprint.test.js +130 -0
- package/dist/zeroshot-strategy.js +139 -0
- package/docs/Progmune_/346/212/225/350/265/204/344/272/272/347/231/275/347/232/256/344/271/246_v2.0.html +576 -0
- package/docs/Progmune_/351/241/271/347/233/256/345/205/250/350/247/243.html +710 -0
- package/package.json +74 -7
- package/protocols.json +1956 -50
- package/.dockerignore +0 -14
- package/.mcp.json +0 -11
- package/.progmune_allowlist +0 -50
- package/.test_report/test_report.md +0 -87
- package/Dockerfile +0 -9
- package/FAQ.md +0 -167
- package/WHITEPAPER.md +0 -540
- package/demo-project/auth.ts +0 -55
- package/demo-project/tsconfig.json +0 -8
- package/dist/acl-breakdown.js +0 -13
- package/dist/all-sessions.js +0 -11
- package/dist/antibody-stats.js +0 -11
- package/dist/branch-tree-count.js +0 -14
- package/dist/common-fixpath.js +0 -12
- package/dist/constraint-types.js +0 -12
- package/dist/exec-metrics.js +0 -11
- package/dist/failure-report.js +0 -11
- package/dist/fast-path-hits.js +0 -13
- package/dist/fingerprint-list.js +0 -15
- package/dist/gen-history-log.js +0 -13
- package/dist/heatmap-data.js +0 -11
- package/dist/recent-session.js +0 -12
- package/dist/svl-distribution.js +0 -11
- package/dist/terminal-status.js +0 -11
- package/dist/token-savings.js +0 -11
- package/dist/total-repairs.js +0 -12
- package/dist/unresolved-count.js +0 -12
- package/dist/valid-fingerprints.js +0 -13
- package/dist/verify-ledgers.js +0 -11
- package/docs/whitepaper-style.css +0 -77
- package/docs/whitepaper-v2.1.md +0 -609
- package/docs/whitepaper-v2.2.md +0 -1064
- package/docs/whitepaper-v2.2.pdf +0 -0
- package/fly.toml +0 -31
- package/public/dashboard.html +0 -119
- package/server/hub.js +0 -116
- package/test/replay-golden/sess_1780063202050_mgeld.json +0 -9
- package/test/replay-golden/sess_1780064032560_gocld.json +0 -354
- package/test/replay-golden/sess_1780064413331_s2709.json +0 -606
- package/test/replay-golden/sess_1780064792710_y3avo.json +0 -614
- package/test/replay-golden.ts +0 -84
- package/test_benchmark.js +0 -165
- package/test_comprehensive.mjs +0 -638
- package/test_concurrency.js +0 -129
- package/test_ir_robustness.js +0 -85
- package/test_semantic_contracts.js +0 -269
- package/test_ssg_stress.js +0 -156
- package/test_svl3.js +0 -58
- package/tsconfig.json +0 -17
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Sprint 13: Rule Specificity Analyzer — attack RULE_TOO_BROAD.
|
|
4
|
+
*
|
|
5
|
+
* Not "optimize VI." Not "add features."
|
|
6
|
+
* Identify the weakest rules and fix them. One sprint, one root cause.
|
|
7
|
+
*
|
|
8
|
+
* Target: RULE_TOO_BROAD 61% → 45%
|
|
9
|
+
*
|
|
10
|
+
* How it works:
|
|
11
|
+
* 1. Load SSG rules from benchmark data
|
|
12
|
+
* 2. Score each rule by discriminative power (specificity, cross-repo, FP rate)
|
|
13
|
+
* 3. Rank weakest rules → these are the FP factories
|
|
14
|
+
* 4. Suggest concrete fixes (add pre_states, add post_states, add invalidate)
|
|
15
|
+
* 5. Output Sprint 13 backlog
|
|
16
|
+
*
|
|
17
|
+
* Usage:
|
|
18
|
+
* npx ts-node --transpile-only src/rule-specificity.ts
|
|
19
|
+
* npx ts-node --transpile-only src/rule-specificity.ts --repo curl
|
|
20
|
+
*/
|
|
21
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
22
|
+
if (k2 === undefined) k2 = k;
|
|
23
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
24
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
25
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
26
|
+
}
|
|
27
|
+
Object.defineProperty(o, k2, desc);
|
|
28
|
+
}) : (function(o, m, k, k2) {
|
|
29
|
+
if (k2 === undefined) k2 = k;
|
|
30
|
+
o[k2] = m[k];
|
|
31
|
+
}));
|
|
32
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
33
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
34
|
+
}) : function(o, v) {
|
|
35
|
+
o["default"] = v;
|
|
36
|
+
});
|
|
37
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
38
|
+
var ownKeys = function(o) {
|
|
39
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
40
|
+
var ar = [];
|
|
41
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
42
|
+
return ar;
|
|
43
|
+
};
|
|
44
|
+
return ownKeys(o);
|
|
45
|
+
};
|
|
46
|
+
return function (mod) {
|
|
47
|
+
if (mod && mod.__esModule) return mod;
|
|
48
|
+
var result = {};
|
|
49
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
50
|
+
__setModuleDefault(result, mod);
|
|
51
|
+
return result;
|
|
52
|
+
};
|
|
53
|
+
})();
|
|
54
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
55
|
+
exports.generateSprint13Backlog = generateSprint13Backlog;
|
|
56
|
+
exports.formatSprint13Backlog = formatSprint13Backlog;
|
|
57
|
+
const fs = __importStar(require("fs"));
|
|
58
|
+
const path = __importStar(require("path"));
|
|
59
|
+
const auto_protocol_synthesizer_1 = require("./auto-protocol-synthesizer");
|
|
60
|
+
/**
|
|
61
|
+
* Score a single rule's discriminative power.
|
|
62
|
+
*
|
|
63
|
+
* Weak rules have:
|
|
64
|
+
* - Empty pre_states (matches ANY state)
|
|
65
|
+
* - Single or no post_states (no meaningful state transition)
|
|
66
|
+
* - No invalidate (no resource management)
|
|
67
|
+
*/
|
|
68
|
+
function scoreRule(fn, rule, fnFrequency) {
|
|
69
|
+
const preCount = rule.pre_states.length;
|
|
70
|
+
const postCount = rule.post_states.length;
|
|
71
|
+
const hasInvalidate = (rule.invalidate || []).length > 0;
|
|
72
|
+
// Specificity: more pre/post states = more specific = fewer FPs
|
|
73
|
+
// 0 states = 0 points, 1-2 = 30, 3-4 = 60, 5+ = 100
|
|
74
|
+
const totalStates = preCount + postCount + (hasInvalidate ? 1 : 0);
|
|
75
|
+
const specificityScore = Math.min(100, totalStates * 20);
|
|
76
|
+
// Cross-repo: not applicable at rule level — use frequency as proxy
|
|
77
|
+
const freq = fnFrequency.get(fn) || 1;
|
|
78
|
+
const crossRepoScore = Math.min(100, freq * 5); // 20+ occurrences = full score
|
|
79
|
+
// FP contribution estimate: lower specificity → more FPs
|
|
80
|
+
const fpContribution = Math.max(1, Math.round((100 - specificityScore) / 10));
|
|
81
|
+
// Diagnose weakness
|
|
82
|
+
let weakness = "";
|
|
83
|
+
let suggestedFix = "";
|
|
84
|
+
if (preCount === 0 && postCount === 0) {
|
|
85
|
+
weakness = "No states — matches everything";
|
|
86
|
+
suggestedFix = "Add at least 1 pre_state and 1 post_state";
|
|
87
|
+
}
|
|
88
|
+
else if (preCount === 0) {
|
|
89
|
+
weakness = "Empty pre_states — matches any initial state";
|
|
90
|
+
suggestedFix = "Add pre_state from call context (what must be true before this call?)";
|
|
91
|
+
}
|
|
92
|
+
else if (postCount === 0 && !hasInvalidate) {
|
|
93
|
+
weakness = "No post_states or invalidate — no state transition";
|
|
94
|
+
suggestedFix = "Add post_state (what changes after this call?) or invalidate (what does it release?)";
|
|
95
|
+
}
|
|
96
|
+
else if (totalStates <= 2) {
|
|
97
|
+
weakness = `Only ${totalStates} state${totalStates > 1 ? 's' : ''} — too broad`;
|
|
98
|
+
suggestedFix = `Add ${3 - totalStates} more pre/post/invalidate states`;
|
|
99
|
+
}
|
|
100
|
+
else {
|
|
101
|
+
weakness = "Adequate specificity but still producing FPs";
|
|
102
|
+
suggestedFix = "Add negative evidence (forbidden transitions) or context filter";
|
|
103
|
+
}
|
|
104
|
+
// Priority
|
|
105
|
+
let priority = "P2";
|
|
106
|
+
if (specificityScore <= 20)
|
|
107
|
+
priority = "P0";
|
|
108
|
+
else if (specificityScore <= 40)
|
|
109
|
+
priority = "P1";
|
|
110
|
+
return {
|
|
111
|
+
function: fn,
|
|
112
|
+
specificityScore,
|
|
113
|
+
crossRepoScore,
|
|
114
|
+
fpContribution,
|
|
115
|
+
weakness,
|
|
116
|
+
suggestedFix,
|
|
117
|
+
priority,
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
// ═══════════════════════════════════════════════════════════════
|
|
121
|
+
// Sprint 13 Backlog Generator
|
|
122
|
+
// ═══════════════════════════════════════════════════════════════
|
|
123
|
+
function generateSprint13Backlog(repoName = "curl") {
|
|
124
|
+
const labelFile = path.join(process.cwd(), "benchmarks", `${repoName}-labels.json`);
|
|
125
|
+
if (!fs.existsSync(labelFile)) {
|
|
126
|
+
throw new Error(`Labels not found: ${labelFile}`);
|
|
127
|
+
}
|
|
128
|
+
const data = JSON.parse(fs.readFileSync(labelFile, "utf-8"));
|
|
129
|
+
const labels = data.labels || {};
|
|
130
|
+
const sequences = data.sequences || {};
|
|
131
|
+
const labeledIndices = Object.keys(labels).map(Number);
|
|
132
|
+
// Get clean sequences
|
|
133
|
+
const cleanSeqs = [];
|
|
134
|
+
for (const idx of labeledIndices) {
|
|
135
|
+
if (labels[idx] === "clean" && sequences[idx]) {
|
|
136
|
+
cleanSeqs.push(sequences[idx]);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
// Generate rules
|
|
140
|
+
const protocols = (0, auto_protocol_synthesizer_1.synthesizeProtocols)(cleanSeqs);
|
|
141
|
+
// Build rules map
|
|
142
|
+
const rules = new Map();
|
|
143
|
+
for (const proto of protocols) {
|
|
144
|
+
for (const r of proto.rules) {
|
|
145
|
+
rules.set(r.function, {
|
|
146
|
+
pre_states: r.pre_states,
|
|
147
|
+
post_states: r.post_states,
|
|
148
|
+
invalidate: r.invalidate,
|
|
149
|
+
namespace: proto.inferredPattern || "discovered",
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
// Count function frequency across sequences
|
|
154
|
+
const fnFrequency = new Map();
|
|
155
|
+
for (const seq of cleanSeqs) {
|
|
156
|
+
const seen = new Set();
|
|
157
|
+
for (const fn of seq) {
|
|
158
|
+
if (!seen.has(fn)) {
|
|
159
|
+
fnFrequency.set(fn, (fnFrequency.get(fn) || 0) + 1);
|
|
160
|
+
seen.add(fn);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
// Score all rules
|
|
165
|
+
const scored = [];
|
|
166
|
+
for (const [fn, rule] of rules) {
|
|
167
|
+
scored.push(scoreRule(fn, rule, fnFrequency));
|
|
168
|
+
}
|
|
169
|
+
// Sort: weakest (lowest specificity) first
|
|
170
|
+
scored.sort((a, b) => a.specificityScore - b.specificityScore);
|
|
171
|
+
// Count weak rules (specificity < 40)
|
|
172
|
+
const weakRules = scored.filter(r => r.specificityScore < 40).length;
|
|
173
|
+
const estimatedFPImpact = scored
|
|
174
|
+
.filter(r => r.specificityScore < 40)
|
|
175
|
+
.reduce((s, r) => s + r.fpContribution, 0);
|
|
176
|
+
return {
|
|
177
|
+
repo: repoName,
|
|
178
|
+
totalRules: rules.size,
|
|
179
|
+
weakRules,
|
|
180
|
+
estimatedFPImpact,
|
|
181
|
+
backlog: scored,
|
|
182
|
+
sprintGoal: `Reduce RULE_TOO_BROAD FPs from 61% to 45% by fixing the ${weakRules} weakest rules (est. ${estimatedFPImpact} FP impact)`,
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
// ═══════════════════════════════════════════════════════════════
|
|
186
|
+
// Formatter
|
|
187
|
+
// ═══════════════════════════════════════════════════════════════
|
|
188
|
+
function bar(value, max, width = 15) {
|
|
189
|
+
const filled = Math.round((value / max) * width);
|
|
190
|
+
return "█".repeat(filled) + "░".repeat(width - filled);
|
|
191
|
+
}
|
|
192
|
+
function formatSprint13Backlog(b) {
|
|
193
|
+
const lines = [];
|
|
194
|
+
lines.push("");
|
|
195
|
+
lines.push("╔══════════════════════════════════════════════════════════════╗");
|
|
196
|
+
lines.push("║ Sprint 13: Attack RULE_TOO_BROAD ║");
|
|
197
|
+
lines.push("╠══════════════════════════════════════════════════════════════╣");
|
|
198
|
+
lines.push(`║ Repo: ${b.repo}`.padEnd(63) + "║");
|
|
199
|
+
lines.push(`║ Total rules: ${b.totalRules} | Weak rules: ${b.weakRules} | Est. FP impact: ${b.estimatedFPImpact}`.padEnd(63) + "║");
|
|
200
|
+
lines.push("╠══════════════════════════════════════════════════════════════╣");
|
|
201
|
+
lines.push(`║ Goal: ${b.sprintGoal.slice(0, 55)}`.padEnd(63) + "║");
|
|
202
|
+
lines.push("╚══════════════════════════════════════════════════════════════╝");
|
|
203
|
+
lines.push("");
|
|
204
|
+
// P0 — Critical (specificity ≤ 20)
|
|
205
|
+
const p0 = b.backlog.filter(r => r.priority === "P0");
|
|
206
|
+
if (p0.length > 0) {
|
|
207
|
+
lines.push("── P0: Critical (specificity ≤ 20) — Fix these first ──");
|
|
208
|
+
lines.push("");
|
|
209
|
+
for (const r of p0.slice(0, 15)) {
|
|
210
|
+
const specBar = bar(r.specificityScore, 100);
|
|
211
|
+
lines.push(` ${r.function.padEnd(35)} spec:${String(r.specificityScore).padStart(3)} ${specBar} est.${r.fpContribution} FP`);
|
|
212
|
+
lines.push(` Weakness: ${r.weakness}`);
|
|
213
|
+
lines.push(` Fix: ${r.suggestedFix}`);
|
|
214
|
+
lines.push("");
|
|
215
|
+
}
|
|
216
|
+
if (p0.length > 15) {
|
|
217
|
+
lines.push(` ... and ${p0.length - 15} more P0 rules`);
|
|
218
|
+
lines.push("");
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
// P1 — High (specificity 21-40)
|
|
222
|
+
const p1 = b.backlog.filter(r => r.priority === "P1");
|
|
223
|
+
if (p1.length > 0) {
|
|
224
|
+
lines.push("── P1: High (specificity 21-40) — Fix in Sprint 13-14 ──");
|
|
225
|
+
lines.push("");
|
|
226
|
+
for (const r of p1.slice(0, 10)) {
|
|
227
|
+
lines.push(` ${r.function.padEnd(35)} spec:${String(r.specificityScore).padStart(3)} ${bar(r.specificityScore, 100)} est.${r.fpContribution} FP`);
|
|
228
|
+
lines.push(` → ${r.suggestedFix}`);
|
|
229
|
+
}
|
|
230
|
+
if (p1.length > 10) {
|
|
231
|
+
lines.push(` ... and ${p1.length - 10} more P1 rules`);
|
|
232
|
+
}
|
|
233
|
+
lines.push("");
|
|
234
|
+
}
|
|
235
|
+
// Summary
|
|
236
|
+
const totalFPImpact = b.backlog.reduce((s, r) => s + r.fpContribution, 0);
|
|
237
|
+
lines.push("── Sprint 13 Completion Criteria ──");
|
|
238
|
+
lines.push(` Fix P0 rules (${p0.length} rules, est. ${p0.reduce((s, r) => s + r.fpContribution, 0)} FP impact)`);
|
|
239
|
+
lines.push(` Fix P1 rules (${p1.length} rules, est. ${p1.reduce((s, r) => s + r.fpContribution, 0)} FP impact)`);
|
|
240
|
+
lines.push(` Total estimated FP reduction: ${p0.reduce((s, r) => s + r.fpContribution, 0) + p1.reduce((s, r) => s + r.fpContribution, 0)}/${b.totalRules} rules`);
|
|
241
|
+
lines.push(` Dashboard K5: RULE_TOO_BROAD 61% → target 45%`);
|
|
242
|
+
lines.push("");
|
|
243
|
+
return lines.join("\n");
|
|
244
|
+
}
|
|
245
|
+
// ═══════════════════════════════════════════════════════════════
|
|
246
|
+
// CLI
|
|
247
|
+
// ═══════════════════════════════════════════════════════════════
|
|
248
|
+
if (require.main === module) {
|
|
249
|
+
const args = process.argv.slice(2);
|
|
250
|
+
const repoIdx = args.findIndex(a => a === "--repo");
|
|
251
|
+
const repo = repoIdx >= 0 ? args[repoIdx + 1] : "curl";
|
|
252
|
+
const backlog = generateSprint13Backlog(repo);
|
|
253
|
+
console.log(formatSprint13Backlog(backlog));
|
|
254
|
+
}
|
package/dist/runtime-types.js
CHANGED
|
@@ -37,6 +37,9 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
37
37
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
38
38
|
exports.replayLedger = exports.replaySession = exports.getMinimalFixSet = exports.generateRepairSummary = exports.validateProposal = exports.applyProposalAsBranch = exports.suggestInvariantRepair = exports.suggestProtocolRepair = exports.suggestRepairs = exports.describeBranchTree = exports.unwrapBranchTree = exports.wrapAsBranch = exports.findRootBranch = exports.buildBranchMap = exports.replayBranch = exports.getBranchPath = exports.flattenBranch = exports.mergeBranches = exports.forkBranch = exports.createBranch = exports.createRootBranch = exports.registerAllMissingFingerprints = exports.verifyAllFingerprints = exports.verifyFingerprint = exports.getFingerprintRegistry = exports.getFingerprint = exports.registerFingerprint = exports.assertLedgerInvariants = exports.assertTransitionOrder = exports.assertRuleHashMatch = exports.assertDeltaConsistency = exports.assertLedgerConsistency = exports.InvariantViolationError = exports.listAllStates = exports.findTransition = exports.findViolations = exports.findConsumer = exports.findProducer = exports.rejectionToJSON = exports.explainRejection = exports.diffLedgers = exports.hashLedger = exports.hashRules = exports.findFixPathStatic = exports.checkLedgerConsistency = exports.validateTransition = exports.applyTransitionDelta = exports.rebuildState = exports.parseProtocolsFromJSON = exports.StateMachineValidator = void 0;
|
|
39
39
|
exports.replayWithDetail = void 0;
|
|
40
|
+
exports.mapLegacyFCode = mapLegacyFCode;
|
|
41
|
+
exports.ok = ok;
|
|
42
|
+
exports.err = err;
|
|
40
43
|
exports.generateAttemptId = generateAttemptId;
|
|
41
44
|
exports.generateSessionId = generateSessionId;
|
|
42
45
|
exports.generatePlannerSeed = generatePlannerSeed;
|
|
@@ -105,6 +108,30 @@ var deterministic_replay_1 = require("./deterministic-replay");
|
|
|
105
108
|
Object.defineProperty(exports, "replaySession", { enumerable: true, get: function () { return deterministic_replay_1.replaySession; } });
|
|
106
109
|
Object.defineProperty(exports, "replayLedger", { enumerable: true, get: function () { return deterministic_replay_1.replayLedger; } });
|
|
107
110
|
Object.defineProperty(exports, "replayWithDetail", { enumerable: true, get: function () { return deterministic_replay_1.replayWithDetail; } });
|
|
111
|
+
/** Legacy F-code → ViolationType mapping. */
|
|
112
|
+
function mapLegacyFCode(fCode) {
|
|
113
|
+
const map = {
|
|
114
|
+
F01: "unexported_function",
|
|
115
|
+
F02: "wrong_import_path",
|
|
116
|
+
F03: "type_name_error",
|
|
117
|
+
F04: "wrong_arg_count",
|
|
118
|
+
F05: "wrong_arg_type",
|
|
119
|
+
F06: "undefined_variable",
|
|
120
|
+
F07: "planning_failure",
|
|
121
|
+
F08: "return_type_error",
|
|
122
|
+
F09: "protocol_violation",
|
|
123
|
+
F10: "other",
|
|
124
|
+
};
|
|
125
|
+
return map[fCode] || "other";
|
|
126
|
+
}
|
|
127
|
+
/** Create an Ok result. */
|
|
128
|
+
function ok(value) {
|
|
129
|
+
return { ok: true, value };
|
|
130
|
+
}
|
|
131
|
+
/** Create an Err result. */
|
|
132
|
+
function err(error) {
|
|
133
|
+
return { ok: false, error };
|
|
134
|
+
}
|
|
108
135
|
// ── ID生成工具 ──
|
|
109
136
|
function generateAttemptId() {
|
|
110
137
|
return `att_${Date.now()}_${Math.random().toString(36).slice(2, 7)}`;
|
package/dist/scaffold.js
ADDED
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Phase 9: Scaffold Engine
|
|
4
|
+
*
|
|
5
|
+
* Template-based code generation for full project files.
|
|
6
|
+
* Complements the function-call-chain model (planner) for
|
|
7
|
+
* architecture-level code: Express servers, CLI tools, static sites.
|
|
8
|
+
*
|
|
9
|
+
* Registered as `progmune_scaffold` MCP tool.
|
|
10
|
+
*/
|
|
11
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
12
|
+
if (k2 === undefined) k2 = k;
|
|
13
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
14
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
15
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
16
|
+
}
|
|
17
|
+
Object.defineProperty(o, k2, desc);
|
|
18
|
+
}) : (function(o, m, k, k2) {
|
|
19
|
+
if (k2 === undefined) k2 = k;
|
|
20
|
+
o[k2] = m[k];
|
|
21
|
+
}));
|
|
22
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
23
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
24
|
+
}) : function(o, v) {
|
|
25
|
+
o["default"] = v;
|
|
26
|
+
});
|
|
27
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
28
|
+
var ownKeys = function(o) {
|
|
29
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
30
|
+
var ar = [];
|
|
31
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
32
|
+
return ar;
|
|
33
|
+
};
|
|
34
|
+
return ownKeys(o);
|
|
35
|
+
};
|
|
36
|
+
return function (mod) {
|
|
37
|
+
if (mod && mod.__esModule) return mod;
|
|
38
|
+
var result = {};
|
|
39
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
40
|
+
__setModuleDefault(result, mod);
|
|
41
|
+
return result;
|
|
42
|
+
};
|
|
43
|
+
})();
|
|
44
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
45
|
+
exports.SCAFFOLD_TYPES = void 0;
|
|
46
|
+
exports.scaffold = scaffold;
|
|
47
|
+
exports.listScaffolds = listScaffolds;
|
|
48
|
+
const fs = __importStar(require("fs"));
|
|
49
|
+
const path = __importStar(require("path"));
|
|
50
|
+
const llm_1 = require("./llm");
|
|
51
|
+
const extract_ir_1 = require("./extract-ir");
|
|
52
|
+
const feedback_1 = require("./feedback");
|
|
53
|
+
const execute_1 = require("./execute");
|
|
54
|
+
// ── Scaffold types ──
|
|
55
|
+
exports.SCAFFOLD_TYPES = [
|
|
56
|
+
"express-api", // Express REST API with SQLite
|
|
57
|
+
"cli-tool", // CLI tool with argument parsing
|
|
58
|
+
"static-site", // HTML/CSS/JS static site
|
|
59
|
+
];
|
|
60
|
+
const TEMPLATES = {
|
|
61
|
+
"express-api": {
|
|
62
|
+
description: "Express REST API server with SQLite database",
|
|
63
|
+
systemPrompt: `You are a TypeScript Express server generator. Generate complete, production-ready code.
|
|
64
|
+
|
|
65
|
+
RULES:
|
|
66
|
+
- Use express, better-sqlite3
|
|
67
|
+
- Include input validation, proper HTTP status codes, error handling
|
|
68
|
+
- Use TypeScript types everywhere
|
|
69
|
+
- Generate ONLY the server file content, no explanation
|
|
70
|
+
- The code must be complete and runnable
|
|
71
|
+
- Use async/await where appropriate`,
|
|
72
|
+
prerequisiteHint: "Project should have database functions (init, CRUD) and validation utilities defined in separate files.",
|
|
73
|
+
},
|
|
74
|
+
"cli-tool": {
|
|
75
|
+
description: "CLI tool with argument parsing",
|
|
76
|
+
systemPrompt: `You are a TypeScript CLI tool generator. Generate complete, production-ready code.
|
|
77
|
+
|
|
78
|
+
RULES:
|
|
79
|
+
- Parse command-line arguments (process.argv or a simple arg parser)
|
|
80
|
+
- Support --help, --version flags
|
|
81
|
+
- Clear error messages for invalid input
|
|
82
|
+
- Use TypeScript types everywhere
|
|
83
|
+
- Generate ONLY the CLI file content, no explanation
|
|
84
|
+
- The code must be complete and runnable`,
|
|
85
|
+
prerequisiteHint: "Project should have utility functions for the CLI's domain logic.",
|
|
86
|
+
},
|
|
87
|
+
"static-site": {
|
|
88
|
+
description: "Static HTML site with CSS and vanilla JavaScript",
|
|
89
|
+
systemPrompt: `You are a frontend HTML/CSS/JS generator. Generate a complete, self-contained single-file HTML page.
|
|
90
|
+
|
|
91
|
+
RULES:
|
|
92
|
+
- Inline all CSS in <style> and JS in <script> tags
|
|
93
|
+
- Dark theme by default
|
|
94
|
+
- Mobile-responsive (max-width 640px)
|
|
95
|
+
- No external dependencies (no CDN, no framework)
|
|
96
|
+
- No social features, no images, no audio/video
|
|
97
|
+
- Clean, minimal design
|
|
98
|
+
- Generate ONLY the HTML file content, no explanation`,
|
|
99
|
+
prerequisiteHint: "Page should interact with a backend API if specified in the intent.",
|
|
100
|
+
},
|
|
101
|
+
};
|
|
102
|
+
// ── Scaffold engine ──
|
|
103
|
+
async function scaffold(scaffoldType, intent, projectPath, filePath) {
|
|
104
|
+
const template = TEMPLATES[scaffoldType];
|
|
105
|
+
if (!template) {
|
|
106
|
+
return {
|
|
107
|
+
success: false,
|
|
108
|
+
code: "",
|
|
109
|
+
scaffoldType,
|
|
110
|
+
error: `Unknown scaffold type: ${scaffoldType}. Available: ${exports.SCAFFOLD_TYPES.join(", ")}`,
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
// 1. Extract IR to understand project context
|
|
114
|
+
let irContext = "";
|
|
115
|
+
try {
|
|
116
|
+
const ir = (0, extract_ir_1.extractIR)(projectPath);
|
|
117
|
+
if (ir.length > 0) {
|
|
118
|
+
const funcList = ir
|
|
119
|
+
.map((f) => ` - ${f.name}(${(f.params || []).map((p) => `${p.name}: ${p.type || "any"}`).join(", ")}): ${f.returnType || "void"}`)
|
|
120
|
+
.join("\n");
|
|
121
|
+
irContext = `\n\nAvailable project functions (from IR):\n${funcList}\n\nYou MUST use these functions where applicable. For imports, use relative paths appropriate for the project structure.`;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
catch { /* IR extraction is best-effort */ }
|
|
125
|
+
// 2. Build prompt
|
|
126
|
+
const fileHint = filePath
|
|
127
|
+
? `Write the generated code to: ${filePath}`
|
|
128
|
+
: "Return the generated code as the response.";
|
|
129
|
+
const prompt = `${template.systemPrompt}
|
|
130
|
+
|
|
131
|
+
Project: ${path.basename(projectPath)}
|
|
132
|
+
File: ${filePath || "(auto-detect)"}
|
|
133
|
+
Intent: ${intent}
|
|
134
|
+
${irContext}
|
|
135
|
+
|
|
136
|
+
${fileHint}
|
|
137
|
+
|
|
138
|
+
Generate the complete file content now. Output ONLY the code, no markdown fences, no explanation.`;
|
|
139
|
+
// 3. Call LLM
|
|
140
|
+
let code;
|
|
141
|
+
try {
|
|
142
|
+
code = await (0, llm_1.generate)(prompt);
|
|
143
|
+
// Strip markdown fences if LLM adds them anyway
|
|
144
|
+
code = code.replace(/^```(?:typescript|javascript|html|ts|js)?\s*\n?/i, "").replace(/\n?```\s*$/i, "").trim();
|
|
145
|
+
}
|
|
146
|
+
catch (e) {
|
|
147
|
+
return {
|
|
148
|
+
success: false,
|
|
149
|
+
code: "",
|
|
150
|
+
scaffoldType,
|
|
151
|
+
error: `LLM generation failed: ${e.message}`,
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
if (!code || code.length < 50) {
|
|
155
|
+
return {
|
|
156
|
+
success: false,
|
|
157
|
+
code: "",
|
|
158
|
+
scaffoldType,
|
|
159
|
+
error: "LLM returned empty or too-short response",
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
// 4. Add Progmune marker
|
|
163
|
+
const sessionId = `scaffold_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
|
|
164
|
+
let marker = "";
|
|
165
|
+
if (filePath && (filePath.endsWith(".ts") || filePath.endsWith(".tsx"))) {
|
|
166
|
+
marker = `// @progmune-scaffolded type=${scaffoldType} session=${sessionId} timestamp=${new Date().toISOString()}\n\n`;
|
|
167
|
+
}
|
|
168
|
+
else if (filePath && filePath.endsWith(".html")) {
|
|
169
|
+
marker = `<!-- @progmune-scaffolded type=${scaffoldType} session=${sessionId} timestamp=${new Date().toISOString()} -->\n`;
|
|
170
|
+
}
|
|
171
|
+
code = marker + code;
|
|
172
|
+
// 5. Write to file
|
|
173
|
+
if (filePath) {
|
|
174
|
+
const resolved = path.isAbsolute(filePath) ? filePath : path.resolve(projectPath, filePath);
|
|
175
|
+
const dir = path.dirname(resolved);
|
|
176
|
+
if (!fs.existsSync(dir)) {
|
|
177
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
178
|
+
}
|
|
179
|
+
fs.writeFileSync(resolved, code, "utf-8");
|
|
180
|
+
// Record generation for metrics
|
|
181
|
+
(0, execute_1.recordGeneration)({
|
|
182
|
+
sessionId,
|
|
183
|
+
timestamp: Date.now(),
|
|
184
|
+
filePath: resolved,
|
|
185
|
+
repaired: false,
|
|
186
|
+
repairCount: 0,
|
|
187
|
+
irFunctionCount: irContext ? irContext.split("\n").filter(l => l.includes(" - ")).length : 0,
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
// Record for immune memory
|
|
191
|
+
try {
|
|
192
|
+
(0, feedback_1.recordRun)(intent, [{ kind: "scaffold", scaffoldType, filePath: filePath || "" }], true);
|
|
193
|
+
}
|
|
194
|
+
catch { /* non-critical */ }
|
|
195
|
+
return {
|
|
196
|
+
success: true,
|
|
197
|
+
code,
|
|
198
|
+
filePath: filePath || undefined,
|
|
199
|
+
scaffoldType,
|
|
200
|
+
};
|
|
201
|
+
}
|
|
202
|
+
/** List available scaffold types with descriptions */
|
|
203
|
+
function listScaffolds() {
|
|
204
|
+
return exports.SCAFFOLD_TYPES.map((t) => ({
|
|
205
|
+
type: t,
|
|
206
|
+
description: TEMPLATES[t].description,
|
|
207
|
+
}));
|
|
208
|
+
}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Scale Trajectory Collector + Reward Model Integration Tests
|
|
4
|
+
*/
|
|
5
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
6
|
+
if (k2 === undefined) k2 = k;
|
|
7
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
8
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
9
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
10
|
+
}
|
|
11
|
+
Object.defineProperty(o, k2, desc);
|
|
12
|
+
}) : (function(o, m, k, k2) {
|
|
13
|
+
if (k2 === undefined) k2 = k;
|
|
14
|
+
o[k2] = m[k];
|
|
15
|
+
}));
|
|
16
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
17
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
18
|
+
}) : function(o, v) {
|
|
19
|
+
o["default"] = v;
|
|
20
|
+
});
|
|
21
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
22
|
+
var ownKeys = function(o) {
|
|
23
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
24
|
+
var ar = [];
|
|
25
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
26
|
+
return ar;
|
|
27
|
+
};
|
|
28
|
+
return ownKeys(o);
|
|
29
|
+
};
|
|
30
|
+
return function (mod) {
|
|
31
|
+
if (mod && mod.__esModule) return mod;
|
|
32
|
+
var result = {};
|
|
33
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
34
|
+
__setModuleDefault(result, mod);
|
|
35
|
+
return result;
|
|
36
|
+
};
|
|
37
|
+
})();
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
const vitest_1 = require("vitest");
|
|
40
|
+
const scale_trajectory_collector_1 = require("./scale-trajectory-collector");
|
|
41
|
+
const learning_ranker_1 = require("./learning-ranker");
|
|
42
|
+
const logistic_reward_1 = require("./logistic-reward");
|
|
43
|
+
const planner_telemetry_1 = require("./planner-telemetry");
|
|
44
|
+
const repair_ranker_1 = require("./repair-ranker");
|
|
45
|
+
const fs = __importStar(require("fs"));
|
|
46
|
+
const path = __importStar(require("path"));
|
|
47
|
+
const SCALE_DIR = path.resolve(__dirname, "..", "test-scale-collector");
|
|
48
|
+
process.env.PROGMUNE_PROJECT_DIR = SCALE_DIR;
|
|
49
|
+
fs.mkdirSync(SCALE_DIR, { recursive: true });
|
|
50
|
+
fs.mkdirSync(path.join(SCALE_DIR, ".progmune_corpus", "telemetry"), { recursive: true });
|
|
51
|
+
fs.mkdirSync(path.join(SCALE_DIR, ".progmune_corpus", "trajectories"), { recursive: true });
|
|
52
|
+
(0, vitest_1.describe)("Scale Trajectory Collector", () => {
|
|
53
|
+
(0, vitest_1.it)("collects 200+ validated trajectories from all sources", () => {
|
|
54
|
+
const { sequences, report } = (0, scale_trajectory_collector_1.collectTrajectoriesAtScale)();
|
|
55
|
+
(0, vitest_1.expect)(report.sourceRepos).toBeGreaterThanOrEqual(20);
|
|
56
|
+
(0, vitest_1.expect)(report.sourceSequences).toBeGreaterThan(50);
|
|
57
|
+
(0, vitest_1.expect)(report.finalCorpusSize).toBeGreaterThan(50);
|
|
58
|
+
// All sequences should be valid physics patterns
|
|
59
|
+
for (const seq of sequences.slice(0, 10)) {
|
|
60
|
+
(0, vitest_1.expect)(seq.length).toBeGreaterThanOrEqual(2);
|
|
61
|
+
}
|
|
62
|
+
(0, scale_trajectory_collector_1.printCollectionReport)(report);
|
|
63
|
+
});
|
|
64
|
+
});
|
|
65
|
+
(0, vitest_1.describe)("Reward Model Integration", () => {
|
|
66
|
+
(0, vitest_1.it)("LearningRanker accepts optional LogisticRewardModel", () => {
|
|
67
|
+
const telemetry = new planner_telemetry_1.PlannerTelemetry(path.join(SCALE_DIR, ".progmune_corpus", "telemetry", `rl-${Date.now()}.jsonl`));
|
|
68
|
+
// Seed some telemetry data
|
|
69
|
+
for (let i = 0; i < 100; i++) {
|
|
70
|
+
const a = ["open_file", "write_file", "close_file"];
|
|
71
|
+
const fp = (0, planner_telemetry_1.candidateFingerprint)("FileProtocol", a, "resource_leak");
|
|
72
|
+
const id = telemetry.recordDecision({
|
|
73
|
+
goal: "write", protocol: "FileProtocol", violationType: "resource_leak",
|
|
74
|
+
candidates: [{ candidateId: fp, source: "protocol", evidenceSources: ["protocol"], actions: a, explanation: "full" }],
|
|
75
|
+
selectedCandidateId: fp,
|
|
76
|
+
});
|
|
77
|
+
telemetry.recordFeedback(id, {
|
|
78
|
+
decision: i < 80 ? "accepted" : "rejected",
|
|
79
|
+
executionResult: i < 80 ? { success: true, violations: [] } : { success: false, violations: ["leak"] },
|
|
80
|
+
timestamp: Date.now(),
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
// Train reward model
|
|
84
|
+
const model = logistic_reward_1.LogisticRewardModel.train(telemetry);
|
|
85
|
+
// Create LearningRanker with reward model
|
|
86
|
+
const base = (0, repair_ranker_1.createLinearRanker)();
|
|
87
|
+
const ranker = new learning_ranker_1.LearningRanker(base, telemetry, undefined, model, 0.5);
|
|
88
|
+
(0, vitest_1.expect)(ranker).toBeDefined();
|
|
89
|
+
// Rank candidates
|
|
90
|
+
const candidates = [
|
|
91
|
+
{ id: "safe", source: "protocol", actions: [{ kind: "call", function: "open_file", args: [] }, { kind: "call", function: "write_file", args: [] }, { kind: "call", function: "close_file", args: [] }], explanation: "safe" },
|
|
92
|
+
{ id: "leaky", source: "corpus", actions: [{ kind: "call", function: "open_file", args: [] }, { kind: "call", function: "write_file", args: [] }], explanation: "leaky" },
|
|
93
|
+
];
|
|
94
|
+
const ctx = { protocol: "FileProtocol", currentState: ["FILE_OPEN"], targetState: [], violationType: "resource_leak", constraints: [], rules: new Map() };
|
|
95
|
+
const features = candidates.map(c => (0, repair_ranker_1.extractFeatures)(c, ctx));
|
|
96
|
+
const ranked = ranker.rank(candidates, features, { protocol: "FileProtocol", violationType: "resource_leak" });
|
|
97
|
+
(0, vitest_1.expect)(ranked.length).toBe(2);
|
|
98
|
+
// Safe candidate should score higher (was accepted 80% vs leaky rejected)
|
|
99
|
+
(0, vitest_1.expect)(ranked[0].id).toBe("safe");
|
|
100
|
+
});
|
|
101
|
+
});
|