progmune-runtime 2.1.5 → 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 +326 -59
- 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,286 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* P3.18-20: Transition Synthesizer + Candidate Discovery 2.0
|
|
4
|
+
*
|
|
5
|
+
* P3.18: Infer missing protocol transitions from benchmark failures.
|
|
6
|
+
* When verify_password produces PASSWORD_VERIFIED and generate_jwt
|
|
7
|
+
* consumes PASSWORD_VERIFIED, the synthesizer detects the connection.
|
|
8
|
+
*
|
|
9
|
+
* P3.19: Gap-driven benchmark generation — each inferred transition
|
|
10
|
+
* becomes a benchmark case that tests the Planner's ability to use it.
|
|
11
|
+
*
|
|
12
|
+
* P3.20: CandidateOrigin tracking — classify where each candidate came from
|
|
13
|
+
* so the Error Budget can decompose missing_candidate into root causes.
|
|
14
|
+
*
|
|
15
|
+
* Target: Top-1 ≥25%, Top-3 ≥60%, Missing Candidate ≤30%.
|
|
16
|
+
*/
|
|
17
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
18
|
+
if (k2 === undefined) k2 = k;
|
|
19
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
20
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
21
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
22
|
+
}
|
|
23
|
+
Object.defineProperty(o, k2, desc);
|
|
24
|
+
}) : (function(o, m, k, k2) {
|
|
25
|
+
if (k2 === undefined) k2 = k;
|
|
26
|
+
o[k2] = m[k];
|
|
27
|
+
}));
|
|
28
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
29
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
30
|
+
}) : function(o, v) {
|
|
31
|
+
o["default"] = v;
|
|
32
|
+
});
|
|
33
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
34
|
+
var ownKeys = function(o) {
|
|
35
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
36
|
+
var ar = [];
|
|
37
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
38
|
+
return ar;
|
|
39
|
+
};
|
|
40
|
+
return ownKeys(o);
|
|
41
|
+
};
|
|
42
|
+
return function (mod) {
|
|
43
|
+
if (mod && mod.__esModule) return mod;
|
|
44
|
+
var result = {};
|
|
45
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
46
|
+
__setModuleDefault(result, mod);
|
|
47
|
+
return result;
|
|
48
|
+
};
|
|
49
|
+
})();
|
|
50
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
51
|
+
exports.trackCandidateOrigin = trackCandidateOrigin;
|
|
52
|
+
exports.synthesizeTransitions = synthesizeTransitions;
|
|
53
|
+
exports.augmentRulesWithInferences = augmentRulesWithInferences;
|
|
54
|
+
exports.generateGapBenchmarks = generateGapBenchmarks;
|
|
55
|
+
exports.writeGapBenchmarks = writeGapBenchmarks;
|
|
56
|
+
exports.computeEnhancedScores = computeEnhancedScores;
|
|
57
|
+
exports.printSynthesizerReport = printSynthesizerReport;
|
|
58
|
+
exports.printCandidateOriginStats = printCandidateOriginStats;
|
|
59
|
+
const fs = __importStar(require("fs"));
|
|
60
|
+
const path = __importStar(require("path"));
|
|
61
|
+
const protocol_coverage_1 = require("./protocol-coverage");
|
|
62
|
+
function trackCandidateOrigin(candidates, expectedRepair) {
|
|
63
|
+
const stats = new Map();
|
|
64
|
+
for (const c of candidates) {
|
|
65
|
+
const origin = c.metadata?.source || "protocol_bfs";
|
|
66
|
+
const existing = stats.get(origin) || { count: 0, successCount: 0 };
|
|
67
|
+
existing.count++;
|
|
68
|
+
if (expectedRepair) {
|
|
69
|
+
const actions = c.fixPath || c.actions?.map((a) => a.function) || [];
|
|
70
|
+
const match = expectedRepair.every(fn => actions.includes(fn));
|
|
71
|
+
if (match)
|
|
72
|
+
existing.successCount++;
|
|
73
|
+
}
|
|
74
|
+
stats.set(origin, existing);
|
|
75
|
+
}
|
|
76
|
+
return [...stats.entries()].map(([origin, s]) => ({
|
|
77
|
+
origin,
|
|
78
|
+
count: s.count,
|
|
79
|
+
successCount: s.successCount,
|
|
80
|
+
successRate: s.count > 0 ? s.successCount / s.count : 0,
|
|
81
|
+
})).sort((a, b) => b.count - a.count);
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Analyze benchmark failures to infer missing protocol transitions.
|
|
85
|
+
*
|
|
86
|
+
* For each expected repair chain, checks whether consecutive function
|
|
87
|
+
* pairs have a valid state transition in the protocol rules. If not,
|
|
88
|
+
* the pair is recorded as an inferred transition.
|
|
89
|
+
*
|
|
90
|
+
* Confidence = evidenceCount / maxEvidence across all inferences.
|
|
91
|
+
*/
|
|
92
|
+
function synthesizeTransitions(failures, protocols) {
|
|
93
|
+
const defs = protocols || (0, protocol_coverage_1.loadDefaultProtocolDefinitions)();
|
|
94
|
+
const ruleMap = new Map();
|
|
95
|
+
for (const p of defs)
|
|
96
|
+
ruleMap.set(p.name, p.rules);
|
|
97
|
+
const inferred = new Map();
|
|
98
|
+
for (const f of failures) {
|
|
99
|
+
const chain = f.expectedRepair;
|
|
100
|
+
for (let i = 0; i < chain.length - 1; i++) {
|
|
101
|
+
const fnA = chain[i];
|
|
102
|
+
const fnB = chain[i + 1];
|
|
103
|
+
// Find which protocol these functions belong to
|
|
104
|
+
for (const [protoName, rules] of ruleMap) {
|
|
105
|
+
const ruleA = rules.get(fnA);
|
|
106
|
+
const ruleB = rules.get(fnB);
|
|
107
|
+
if (!ruleA || !ruleB)
|
|
108
|
+
continue;
|
|
109
|
+
// Check if transition exists: post_states of A → pre_states of B
|
|
110
|
+
const postA = ruleA.post_states;
|
|
111
|
+
const preB = ruleB.pre_states;
|
|
112
|
+
const connected = postA.some(s => preB.includes(s));
|
|
113
|
+
if (connected)
|
|
114
|
+
continue; // transition already exists
|
|
115
|
+
const key = `${protoName}:${fnA}→${fnB}`;
|
|
116
|
+
const existing = inferred.get(key);
|
|
117
|
+
if (existing) {
|
|
118
|
+
existing.evidenceCount++;
|
|
119
|
+
if (!existing.examples.includes(f.goal))
|
|
120
|
+
existing.examples.push(f.goal);
|
|
121
|
+
}
|
|
122
|
+
else {
|
|
123
|
+
// Use the first post_state of A as the from-state
|
|
124
|
+
const fromState = postA[0] || "?";
|
|
125
|
+
const toState = preB[0] || "?";
|
|
126
|
+
inferred.set(key, {
|
|
127
|
+
action: `${fnA} → ${fnB}`,
|
|
128
|
+
protocol: protoName,
|
|
129
|
+
evidenceCount: 1,
|
|
130
|
+
examples: [f.goal],
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
const maxEvidence = Math.max(1, ...[...inferred.values()].map(v => v.evidenceCount));
|
|
137
|
+
const results = [];
|
|
138
|
+
for (const [key, entry] of inferred) {
|
|
139
|
+
const parts = key.split(":");
|
|
140
|
+
const protoAndPair = parts.slice(1).join(":");
|
|
141
|
+
const [fnA, fnB] = entry.action.split(" → ");
|
|
142
|
+
const protoName = entry.protocol;
|
|
143
|
+
const rules = ruleMap.get(protoName);
|
|
144
|
+
const ruleA = rules?.get(fnA);
|
|
145
|
+
const ruleB = rules?.get(fnB);
|
|
146
|
+
const fromState = ruleA?.post_states[0] || "?";
|
|
147
|
+
const toState = ruleB?.pre_states[0] || "?";
|
|
148
|
+
results.push({
|
|
149
|
+
from: fromState,
|
|
150
|
+
to: toState,
|
|
151
|
+
action: entry.action,
|
|
152
|
+
protocol: protoName,
|
|
153
|
+
confidence: entry.evidenceCount / maxEvidence,
|
|
154
|
+
evidenceCount: entry.evidenceCount,
|
|
155
|
+
examples: entry.examples.slice(0, 3),
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
return results.sort((a, b) => b.confidence - a.confidence);
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Apply inferred transitions to augment protocol rules.
|
|
162
|
+
* Returns augmented rules with inferred edges added as virtual rules.
|
|
163
|
+
*/
|
|
164
|
+
function augmentRulesWithInferences(rules, inferences, minConfidence = 0.5) {
|
|
165
|
+
const augmented = new Map(rules);
|
|
166
|
+
for (const inf of inferences) {
|
|
167
|
+
if (inf.confidence < minConfidence)
|
|
168
|
+
continue;
|
|
169
|
+
const [fnA, fnB] = inf.action.split(" → ");
|
|
170
|
+
// Add a virtual bridge rule: fnA_inferred → produces the state fnB needs
|
|
171
|
+
const bridgeName = `_inferred_${fnA}_to_${fnB}`;
|
|
172
|
+
if (!augmented.has(bridgeName)) {
|
|
173
|
+
augmented.set(bridgeName, {
|
|
174
|
+
pre_states: [inf.from],
|
|
175
|
+
post_states: [inf.to],
|
|
176
|
+
namespace: "inferred",
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
return augmented;
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* Generate benchmark cases from inferred transitions.
|
|
184
|
+
* Each inferred transition becomes a test case that validates
|
|
185
|
+
* the Planner can use the newly discovered edge.
|
|
186
|
+
*/
|
|
187
|
+
function generateGapBenchmarks(inferences, minConfidence = 0.3) {
|
|
188
|
+
const cases = [];
|
|
189
|
+
for (const inf of inferences) {
|
|
190
|
+
if (inf.confidence < minConfidence)
|
|
191
|
+
continue;
|
|
192
|
+
const [fnA, fnB] = inf.action.split(" → ");
|
|
193
|
+
// Broken: just fnA (missing the connecting edge)
|
|
194
|
+
cases.push({
|
|
195
|
+
goal: `verify transition: ${inf.action}`,
|
|
196
|
+
protocol: "_global",
|
|
197
|
+
broken: [fnA],
|
|
198
|
+
expected: [fnA, fnB],
|
|
199
|
+
violationType: "missing_prerequisite",
|
|
200
|
+
targetsGap: inf.action,
|
|
201
|
+
confidence: inf.confidence,
|
|
202
|
+
});
|
|
203
|
+
// Also generate the resource-cleanup variant if fnB invalidates something
|
|
204
|
+
if (inf.to === "∅" || inf.from === inf.to) {
|
|
205
|
+
cases.push({
|
|
206
|
+
goal: `verify cleanup after: ${inf.action}`,
|
|
207
|
+
protocol: "_global",
|
|
208
|
+
broken: [fnA, fnB],
|
|
209
|
+
expected: [fnA, fnB],
|
|
210
|
+
violationType: "resource_leak",
|
|
211
|
+
targetsGap: `cleanup:${inf.action}`,
|
|
212
|
+
confidence: inf.confidence,
|
|
213
|
+
});
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
return cases.sort((a, b) => b.confidence - a.confidence);
|
|
217
|
+
}
|
|
218
|
+
/** Write generated gap benchmarks to disk. */
|
|
219
|
+
function writeGapBenchmarks(cases, outputDir) {
|
|
220
|
+
const outDir = outputDir || path.resolve(__dirname, "..", "benchmarks", "synthesized");
|
|
221
|
+
if (!fs.existsSync(outDir))
|
|
222
|
+
fs.mkdirSync(outDir, { recursive: true });
|
|
223
|
+
const filepath = path.join(outDir, `transition_gaps_${new Date().toISOString().slice(0, 10)}.json`);
|
|
224
|
+
fs.writeFileSync(filepath, JSON.stringify({
|
|
225
|
+
generatedAt: new Date().toISOString(),
|
|
226
|
+
source: "transition-synthesizer",
|
|
227
|
+
count: cases.length,
|
|
228
|
+
cases,
|
|
229
|
+
}, null, 2));
|
|
230
|
+
return filepath;
|
|
231
|
+
}
|
|
232
|
+
/**
|
|
233
|
+
* Enhanced knowledge score including candidate discovery rate.
|
|
234
|
+
*
|
|
235
|
+
* score = 0.30*coverage + 0.25*success + 0.20*benchmark
|
|
236
|
+
* + 0.10*corpus + 0.15*discoveryRate
|
|
237
|
+
*/
|
|
238
|
+
function computeEnhancedScores(protocolNames, coverageReport, benchmarkStats, candidateStats = {}) {
|
|
239
|
+
return protocolNames.map(name => {
|
|
240
|
+
const cov = coverageReport.find(c => c.protocol === name);
|
|
241
|
+
const bench = benchmarkStats[name] || { total: 0, passed: 0 };
|
|
242
|
+
const cand = candidateStats[name] || { total: 0, found: 0 };
|
|
243
|
+
const coverage = cov ? (cov.stateCoverage + cov.transitionCoverage) / 2 : 0;
|
|
244
|
+
const successRate = bench.total > 0 ? bench.passed / bench.total : 0;
|
|
245
|
+
const benchmarkPassRate = bench.total > 0 ? bench.passed / bench.total : 0;
|
|
246
|
+
const corpusSupport = Math.min(1, bench.total / 50);
|
|
247
|
+
const discoveryRate = cand.total > 0 ? cand.found / cand.total : 0;
|
|
248
|
+
const score = 0.30 * coverage +
|
|
249
|
+
0.25 * successRate +
|
|
250
|
+
0.20 * benchmarkPassRate +
|
|
251
|
+
0.10 * corpusSupport +
|
|
252
|
+
0.15 * discoveryRate;
|
|
253
|
+
return { protocol: name, coverage, successRate, benchmarkPassRate, corpusSupport, discoveryRate, score };
|
|
254
|
+
}).sort((a, b) => b.score - a.score);
|
|
255
|
+
}
|
|
256
|
+
// ═══════════════════════════════════════════════════════════════
|
|
257
|
+
// Dashboard
|
|
258
|
+
// ═══════════════════════════════════════════════════════════════
|
|
259
|
+
function printSynthesizerReport(inferences) {
|
|
260
|
+
console.log("\n╔════════════════════════════════════════════════════╗");
|
|
261
|
+
console.log("║ Transition Synthesizer Report ║");
|
|
262
|
+
console.log("╚════════════════════════════════════════════════════╝\n");
|
|
263
|
+
console.log(`Inferred Transitions: ${inferences.length}\n`);
|
|
264
|
+
if (inferences.length === 0) {
|
|
265
|
+
console.log(" All transitions covered. No gaps to infer.\n");
|
|
266
|
+
return;
|
|
267
|
+
}
|
|
268
|
+
console.log("─── Top Inferred Transitions ───");
|
|
269
|
+
console.log("Conf Evidence Transition");
|
|
270
|
+
console.log("────────────────────────────────────────────────");
|
|
271
|
+
for (const inf of inferences.slice(0, 15)) {
|
|
272
|
+
const conf = (inf.confidence * 100).toFixed(0).padStart(4);
|
|
273
|
+
console.log(` ${conf}% ${String(inf.evidenceCount).padStart(2)} ${inf.protocol}: ${inf.action} (${inf.from} → ${inf.to})`);
|
|
274
|
+
}
|
|
275
|
+
console.log();
|
|
276
|
+
}
|
|
277
|
+
function printCandidateOriginStats(stats) {
|
|
278
|
+
console.log("\n─── Candidate Origin Contribution ───");
|
|
279
|
+
console.log("Origin Count SuccessRate");
|
|
280
|
+
console.log("────────────────────────────────────────");
|
|
281
|
+
for (const s of stats) {
|
|
282
|
+
const rate = (s.successRate * 100).toFixed(0).padStart(4);
|
|
283
|
+
console.log(` ${s.origin.padEnd(18)} ${String(s.count).padStart(5)} ${rate}%`);
|
|
284
|
+
}
|
|
285
|
+
console.log();
|
|
286
|
+
}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* P3.18-20: Transition Synthesizer Tests
|
|
4
|
+
*/
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const vitest_1 = require("vitest");
|
|
7
|
+
const transition_synthesizer_1 = require("./transition-synthesizer");
|
|
8
|
+
function makeProtocols() {
|
|
9
|
+
const rules = new Map();
|
|
10
|
+
rules.set("verify_password", { pre_states: ["UNAUTHENTICATED"], post_states: ["PASSWORD_VERIFIED"] });
|
|
11
|
+
rules.set("generate_jwt", { pre_states: ["PASSWORD_VERIFIED"], post_states: ["TOKEN_ISSUED"], invalidate: ["PASSWORD_VERIFIED"] });
|
|
12
|
+
rules.set("create_session", { pre_states: ["TOKEN_ISSUED"], post_states: ["SESSION_ACTIVE"], invalidate: ["TOKEN_ISSUED"] });
|
|
13
|
+
rules.set("logout", { pre_states: ["SESSION_ACTIVE"], post_states: ["UNAUTHENTICATED"], invalidate: ["SESSION_ACTIVE"] });
|
|
14
|
+
rules.set("open_file", { pre_states: [], post_states: ["FILE_OPEN"] });
|
|
15
|
+
rules.set("write_file", { pre_states: ["FILE_OPEN"], post_states: ["FILE_DIRTY"] });
|
|
16
|
+
rules.set("flush_file", { pre_states: ["FILE_DIRTY"], post_states: ["FILE_FLUSHED"] });
|
|
17
|
+
rules.set("close_file", { pre_states: ["FILE_OPEN", "FILE_DIRTY", "FILE_FLUSHED"], post_states: [], invalidate: ["FILE_OPEN", "FILE_DIRTY", "FILE_FLUSHED"] });
|
|
18
|
+
rules.set("connect_db", { pre_states: [], post_states: ["DB_CONNECTED"] });
|
|
19
|
+
rules.set("query_db", { pre_states: ["DB_CONNECTED"], post_states: [] });
|
|
20
|
+
rules.set("disconnect_db", { pre_states: ["DB_CONNECTED"], post_states: [], invalidate: ["DB_CONNECTED"] });
|
|
21
|
+
return [{
|
|
22
|
+
name: "AuthProtocol", states: ["UNAUTHENTICATED", "PASSWORD_VERIFIED", "TOKEN_ISSUED", "SESSION_ACTIVE"],
|
|
23
|
+
initialState: "UNAUTHENTICATED",
|
|
24
|
+
transitions: [], rules: new Map([...rules].filter(([k]) => ["verify_password", "generate_jwt", "create_session", "logout"].includes(k))),
|
|
25
|
+
}, {
|
|
26
|
+
name: "FileProtocol", states: ["FILE_OPEN", "FILE_DIRTY", "FILE_FLUSHED"],
|
|
27
|
+
initialState: "INIT",
|
|
28
|
+
transitions: [], rules: new Map([...rules].filter(([k]) => ["open_file", "write_file", "flush_file", "close_file"].includes(k))),
|
|
29
|
+
}, {
|
|
30
|
+
name: "DBProtocol", states: ["DB_CONNECTED"],
|
|
31
|
+
initialState: "INIT",
|
|
32
|
+
transitions: [], rules: new Map([...rules].filter(([k]) => ["connect_db", "query_db", "disconnect_db"].includes(k))),
|
|
33
|
+
}];
|
|
34
|
+
}
|
|
35
|
+
(0, vitest_1.describe)("Transition Synthesizer", () => {
|
|
36
|
+
(0, vitest_1.it)("infers transitions from benchmark failures", () => {
|
|
37
|
+
// open_file→flush_file: FILE_OPEN ≠ FILE_DIRTY → genuinely missing transition
|
|
38
|
+
// write_file→close_file: FILE_DIRTY → close_file needs FILE_OPEN/FILE_DIRTY/FILE_FLUSHED → connected
|
|
39
|
+
// But open_file→flush_file is NOT connected (FILE_OPEN vs FILE_DIRTY)
|
|
40
|
+
const failures = [
|
|
41
|
+
{ goal: "flush after open without write", protocol: "FileProtocol", expectedRepair: ["open_file", "flush_file"] },
|
|
42
|
+
{ goal: "flush after open v2", protocol: "FileProtocol", expectedRepair: ["open_file", "flush_file"] },
|
|
43
|
+
];
|
|
44
|
+
const inferences = (0, transition_synthesizer_1.synthesizeTransitions)(failures, makeProtocols());
|
|
45
|
+
(0, vitest_1.expect)(inferences.length).toBeGreaterThan(0);
|
|
46
|
+
// open_file→flush_file should be inferred (FILE_OPEN → FILE_DIRTY gap)
|
|
47
|
+
const hasOpenFlush = inferences.some(i => i.action.includes("open_file → flush_file"));
|
|
48
|
+
(0, vitest_1.expect)(hasOpenFlush).toBe(true);
|
|
49
|
+
// Confidence: appears 2x
|
|
50
|
+
const top = inferences[0];
|
|
51
|
+
(0, vitest_1.expect)(top.confidence).toBeGreaterThan(0.5);
|
|
52
|
+
(0, transition_synthesizer_1.printSynthesizerReport)(inferences);
|
|
53
|
+
});
|
|
54
|
+
(0, vitest_1.it)("augments rules with inferred transitions", () => {
|
|
55
|
+
const failures = [
|
|
56
|
+
{ goal: "flush after open", protocol: "FileProtocol", expectedRepair: ["open_file", "flush_file"] },
|
|
57
|
+
];
|
|
58
|
+
const inferences = (0, transition_synthesizer_1.synthesizeTransitions)(failures, makeProtocols());
|
|
59
|
+
const fileProto = makeProtocols().find(p => p.name === "FileProtocol");
|
|
60
|
+
const augmented = (0, transition_synthesizer_1.augmentRulesWithInferences)(fileProto.rules, inferences);
|
|
61
|
+
// Should have the original rules plus inferred bridges
|
|
62
|
+
(0, vitest_1.expect)(augmented.size).toBeGreaterThan(fileProto.rules.size);
|
|
63
|
+
// Should contain an inferred bridge
|
|
64
|
+
const hasBridge = [...augmented.keys()].some(k => k.startsWith("_inferred_"));
|
|
65
|
+
(0, vitest_1.expect)(hasBridge).toBe(true);
|
|
66
|
+
});
|
|
67
|
+
(0, vitest_1.it)("generates gap-driven benchmarks", () => {
|
|
68
|
+
const failures = [
|
|
69
|
+
{ goal: "flush after open", protocol: "FileProtocol", expectedRepair: ["open_file", "flush_file"] },
|
|
70
|
+
];
|
|
71
|
+
const inferences = (0, transition_synthesizer_1.synthesizeTransitions)(failures, makeProtocols());
|
|
72
|
+
const cases = (0, transition_synthesizer_1.generateGapBenchmarks)(inferences);
|
|
73
|
+
(0, vitest_1.expect)(cases.length).toBeGreaterThan(0);
|
|
74
|
+
// Each case targets a specific gap
|
|
75
|
+
for (const c of cases) {
|
|
76
|
+
(0, vitest_1.expect)(c.targetsGap.length).toBeGreaterThan(0);
|
|
77
|
+
(0, vitest_1.expect)(c.broken.length).toBeGreaterThan(0);
|
|
78
|
+
(0, vitest_1.expect)(c.expected.length).toBeGreaterThan(0);
|
|
79
|
+
}
|
|
80
|
+
// Write to disk
|
|
81
|
+
const fp = (0, transition_synthesizer_1.writeGapBenchmarks)(cases);
|
|
82
|
+
(0, vitest_1.expect)(fp).toContain("transition_gaps_");
|
|
83
|
+
});
|
|
84
|
+
});
|
|
85
|
+
(0, vitest_1.describe)("Candidate Origin Tracking", () => {
|
|
86
|
+
(0, vitest_1.it)("tracks origin stats", () => {
|
|
87
|
+
const candidates = [
|
|
88
|
+
{ metadata: { source: "frontier" }, fixPath: ["close_file"] },
|
|
89
|
+
{ metadata: { source: "goal_template" }, fixPath: ["verify_password", "generate_jwt"] },
|
|
90
|
+
{ metadata: { source: "frontier" }, fixPath: ["open_file", "close_file"] },
|
|
91
|
+
{ metadata: { source: "corpus" }, fixPath: ["connect_db", "query_db", "disconnect_db"] },
|
|
92
|
+
];
|
|
93
|
+
const stats = (0, transition_synthesizer_1.trackCandidateOrigin)(candidates);
|
|
94
|
+
(0, vitest_1.expect)(stats.length).toBe(3); // frontier, goal_template, corpus
|
|
95
|
+
const frontier = stats.find(s => s.origin === "frontier");
|
|
96
|
+
(0, vitest_1.expect)(frontier.count).toBe(2);
|
|
97
|
+
(0, transition_synthesizer_1.printCandidateOriginStats)(stats);
|
|
98
|
+
});
|
|
99
|
+
});
|
|
100
|
+
(0, vitest_1.describe)("Enhanced Knowledge Score", () => {
|
|
101
|
+
(0, vitest_1.it)("includes discoveryRate", () => {
|
|
102
|
+
const scores = (0, transition_synthesizer_1.computeEnhancedScores)(["FileProtocol", "AuthProtocol", "DBProtocol"], [
|
|
103
|
+
{ protocol: "FileProtocol", stateCoverage: 0.6, transitionCoverage: 0.5 },
|
|
104
|
+
{ protocol: "AuthProtocol", stateCoverage: 0.8, transitionCoverage: 0.7 },
|
|
105
|
+
{ protocol: "DBProtocol", stateCoverage: 0.3, transitionCoverage: 0.2 },
|
|
106
|
+
], {
|
|
107
|
+
FileProtocol: { total: 20, passed: 10 },
|
|
108
|
+
AuthProtocol: { total: 15, passed: 8 },
|
|
109
|
+
DBProtocol: { total: 10, passed: 2 },
|
|
110
|
+
}, {
|
|
111
|
+
FileProtocol: { total: 20, found: 15 },
|
|
112
|
+
AuthProtocol: { total: 15, found: 12 },
|
|
113
|
+
DBProtocol: { total: 10, found: 3 },
|
|
114
|
+
});
|
|
115
|
+
(0, vitest_1.expect)(scores.length).toBe(3);
|
|
116
|
+
// AuthProtocol should have highest score (better coverage + success)
|
|
117
|
+
(0, vitest_1.expect)(scores[0].protocol).toBe("AuthProtocol");
|
|
118
|
+
(0, vitest_1.expect)(scores[0].discoveryRate).toBeGreaterThan(0.5);
|
|
119
|
+
// DBProtocol should have lowest discovery rate
|
|
120
|
+
const db = scores.find(s => s.protocol === "DBProtocol");
|
|
121
|
+
(0, vitest_1.expect)(db.discoveryRate).toBe(0.3);
|
|
122
|
+
});
|
|
123
|
+
});
|