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,137 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Auto-benchmark Generator
|
|
4
|
+
*
|
|
5
|
+
* Generates benchmark cases from synthesized protocols + real-world defects.
|
|
6
|
+
* Expands the benchmark suite from 3 to 20+ cases, enabling meaningful
|
|
7
|
+
* behavioral equivalence measurement.
|
|
8
|
+
*
|
|
9
|
+
* Sources:
|
|
10
|
+
* 1. Synthesized protocols → typical lifecycle paths
|
|
11
|
+
* 2. Real-world defects → broken → expected pairs
|
|
12
|
+
* 3. Cross-repo sequences → protocol-specific test cases
|
|
13
|
+
*/
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.generateExpandedBenchmarks = generateExpandedBenchmarks;
|
|
16
|
+
exports.printExpandedBenchmarkReport = printExpandedBenchmarkReport;
|
|
17
|
+
const auto_protocol_synthesizer_1 = require("./auto-protocol-synthesizer");
|
|
18
|
+
const realworld_benchmark_1 = require("./realworld-benchmark");
|
|
19
|
+
const scale_trajectory_collector_1 = require("./scale-trajectory-collector");
|
|
20
|
+
const function_synonyms_1 = require("./function-synonyms");
|
|
21
|
+
/**
|
|
22
|
+
* Generate benchmarks from synthesized protocols.
|
|
23
|
+
* For each protocol, create a "missing the last step" test case.
|
|
24
|
+
*/
|
|
25
|
+
function generateFromProtocols(protocols) {
|
|
26
|
+
const cases = [];
|
|
27
|
+
for (const sp of protocols) {
|
|
28
|
+
if (sp.prototype.length < 2)
|
|
29
|
+
continue;
|
|
30
|
+
// Normalize the prototype
|
|
31
|
+
const norm = sp.prototype.map(function_synonyms_1.normalizeFunctionName);
|
|
32
|
+
// Case: broken = remove the last action (resource leak)
|
|
33
|
+
cases.push({
|
|
34
|
+
goal: `cover protocol: ${sp.prototype.join(" → ")}`,
|
|
35
|
+
protocol: "_global",
|
|
36
|
+
broken: norm.slice(0, -1),
|
|
37
|
+
expected: norm,
|
|
38
|
+
violationType: "resource_leak",
|
|
39
|
+
source: `synthesized:${sp.clusterId}`,
|
|
40
|
+
});
|
|
41
|
+
// Case: broken = remove the first action (missing prerequisite)
|
|
42
|
+
if (norm.length >= 3) {
|
|
43
|
+
cases.push({
|
|
44
|
+
goal: `cover prerrequisite: ${sp.prototype.join(" → ")}`,
|
|
45
|
+
protocol: "_global",
|
|
46
|
+
broken: norm.slice(1),
|
|
47
|
+
expected: norm,
|
|
48
|
+
violationType: "missing_prerequisite",
|
|
49
|
+
source: `synthesized:${sp.clusterId}`,
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
return cases;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Convert real-world defects to benchmark cases.
|
|
57
|
+
*/
|
|
58
|
+
function convertDefects() {
|
|
59
|
+
return realworld_benchmark_1.REAL_WORLD_DEFECTS.map(d => ({
|
|
60
|
+
goal: d.title,
|
|
61
|
+
protocol: d.protocol,
|
|
62
|
+
broken: d.broken.map(function_synonyms_1.normalizeFunctionName),
|
|
63
|
+
expected: d.expected.map(function_synonyms_1.normalizeFunctionName),
|
|
64
|
+
violationType: d.violationType,
|
|
65
|
+
source: `realworld:${d.id}`,
|
|
66
|
+
}));
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Generate benchmarks from the expanded corpus.
|
|
70
|
+
* Take representative sequences and create test cases.
|
|
71
|
+
*/
|
|
72
|
+
function generateFromCorpus(sequences) {
|
|
73
|
+
const cases = [];
|
|
74
|
+
const seen = new Set();
|
|
75
|
+
for (const seq of sequences) {
|
|
76
|
+
if (seq.length < 3)
|
|
77
|
+
continue;
|
|
78
|
+
const norm = seq.map(function_synonyms_1.normalizeFunctionName);
|
|
79
|
+
const key = norm.join("→");
|
|
80
|
+
if (seen.has(key))
|
|
81
|
+
continue;
|
|
82
|
+
seen.add(key);
|
|
83
|
+
// Take every 5th unique sequence as a benchmark case
|
|
84
|
+
if (seen.size % 5 === 0) {
|
|
85
|
+
cases.push({
|
|
86
|
+
goal: `corpus pattern: ${key}`,
|
|
87
|
+
protocol: "_global",
|
|
88
|
+
broken: norm.slice(0, -1),
|
|
89
|
+
expected: norm,
|
|
90
|
+
violationType: "resource_leak",
|
|
91
|
+
source: "corpus",
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
return cases;
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Generate an expanded benchmark suite from all available sources.
|
|
99
|
+
* Target: 20+ cases covering synthesized protocols, real defects, and corpus patterns.
|
|
100
|
+
*/
|
|
101
|
+
function generateExpandedBenchmarks() {
|
|
102
|
+
const protocols = (0, auto_protocol_synthesizer_1.synthesizeAllKnownProtocols)();
|
|
103
|
+
const { sequences } = (0, scale_trajectory_collector_1.collectTrajectoriesAtScale)();
|
|
104
|
+
const protocolCases = generateFromProtocols(protocols);
|
|
105
|
+
const defectCases = convertDefects();
|
|
106
|
+
const corpusCases = generateFromCorpus(sequences);
|
|
107
|
+
const allCases = [...protocolCases, ...defectCases, ...corpusCases];
|
|
108
|
+
// Deduplicate by expected sequence
|
|
109
|
+
const seen = new Set();
|
|
110
|
+
const unique = [];
|
|
111
|
+
for (const c of allCases) {
|
|
112
|
+
const key = c.expected.join("→");
|
|
113
|
+
if (!seen.has(key)) {
|
|
114
|
+
seen.add(key);
|
|
115
|
+
unique.push(c);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
const bySource = {};
|
|
119
|
+
for (const c of unique) {
|
|
120
|
+
const src = c.source.split(":")[0];
|
|
121
|
+
bySource[src] = (bySource[src] || 0) + 1;
|
|
122
|
+
}
|
|
123
|
+
return {
|
|
124
|
+
cases: unique,
|
|
125
|
+
bySource,
|
|
126
|
+
totalCases: unique.length,
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
function printExpandedBenchmarkReport(suite) {
|
|
130
|
+
console.log("\n─── Expanded Benchmark Suite ───");
|
|
131
|
+
console.log(` Total Cases: ${suite.totalCases}`);
|
|
132
|
+
console.log(" By Source:");
|
|
133
|
+
for (const [src, count] of Object.entries(suite.bySource)) {
|
|
134
|
+
console.log(` ${src.padEnd(14)} ${count}`);
|
|
135
|
+
}
|
|
136
|
+
console.log();
|
|
137
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Auto-benchmark Generator + Expanded Bootstrap Tests
|
|
4
|
+
*/
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const vitest_1 = require("vitest");
|
|
7
|
+
const auto_benchmark_generator_1 = require("./auto-benchmark-generator");
|
|
8
|
+
const bootstrap_validation_1 = require("./bootstrap-validation");
|
|
9
|
+
const scale_trajectory_collector_1 = require("./scale-trajectory-collector");
|
|
10
|
+
(0, vitest_1.describe)("Auto-benchmark Generator", () => {
|
|
11
|
+
(0, vitest_1.it)("generates 20+ benchmark cases from all sources", () => {
|
|
12
|
+
const suite = (0, auto_benchmark_generator_1.generateExpandedBenchmarks)();
|
|
13
|
+
(0, vitest_1.expect)(suite.totalCases).toBeGreaterThanOrEqual(20);
|
|
14
|
+
(0, vitest_1.expect)(suite.bySource["synthesized"]).toBeGreaterThan(0);
|
|
15
|
+
(0, vitest_1.expect)(suite.bySource["realworld"]).toBeGreaterThan(0);
|
|
16
|
+
(0, auto_benchmark_generator_1.printExpandedBenchmarkReport)(suite);
|
|
17
|
+
});
|
|
18
|
+
(0, vitest_1.it)("each benchmark case has valid structure", () => {
|
|
19
|
+
const suite = (0, auto_benchmark_generator_1.generateExpandedBenchmarks)();
|
|
20
|
+
for (const c of suite.cases) {
|
|
21
|
+
(0, vitest_1.expect)(c.broken.length).toBeGreaterThan(0);
|
|
22
|
+
(0, vitest_1.expect)(c.expected.length).toBeGreaterThan(0);
|
|
23
|
+
(0, vitest_1.expect)(c.expected.length).toBeGreaterThan(0);
|
|
24
|
+
(0, vitest_1.expect)(c.broken.length).toBeGreaterThan(0);
|
|
25
|
+
(0, vitest_1.expect)(["resource_leak", "missing_prerequisite", "illegal_state_transition"]).toContain(c.violationType);
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
});
|
|
29
|
+
(0, vitest_1.describe)("Expanded Bootstrap Validation", () => {
|
|
30
|
+
(0, vitest_1.it)("with expanded corpus + expanded benchmarks", async () => {
|
|
31
|
+
const { sequences } = (0, scale_trajectory_collector_1.collectTrajectoriesAtScale)();
|
|
32
|
+
const suite = (0, auto_benchmark_generator_1.generateExpandedBenchmarks)();
|
|
33
|
+
// Run bootstrap with expanded corpus
|
|
34
|
+
const result = await (0, bootstrap_validation_1.runBootstrapValidation)(undefined, sequences);
|
|
35
|
+
console.log(`\nExpanded Benchmark Suite: ${suite.totalCases} cases`);
|
|
36
|
+
console.log(`Corpus Size: ${sequences.length} sequences`);
|
|
37
|
+
console.log(`Regenerated Rules: ${result.regeneratedRuleCount}`);
|
|
38
|
+
console.log(`Function Overlap: ${(result.functionOverlap * 100).toFixed(0)}%`);
|
|
39
|
+
console.log(`State Overlap: ${(result.stateOverlap * 100).toFixed(0)}%`);
|
|
40
|
+
console.log(`Behavioral: ${result.behavioralMatch}/${result.behavioralTotal}`);
|
|
41
|
+
// With expanded benchmarks, regenerated rules should be substantial
|
|
42
|
+
(0, vitest_1.expect)(result.regeneratedRuleCount).toBeGreaterThanOrEqual(5);
|
|
43
|
+
(0, vitest_1.expect)(result.functionOverlap).toBeGreaterThan(0.1);
|
|
44
|
+
}, 30000);
|
|
45
|
+
});
|
|
@@ -0,0 +1,362 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* P6.4: Auto Protocol Synthesizer
|
|
4
|
+
*
|
|
5
|
+
* Converts unsupervised protocol clusters into executable Protocol VM rules.
|
|
6
|
+
* Zero human intervention: trajectories → clusters → state machines → patches.
|
|
7
|
+
*
|
|
8
|
+
* Pipeline:
|
|
9
|
+
* 1. Take DiscoveredClusters from P6.3
|
|
10
|
+
* 2. Extract prototype sequence per cluster (centroid by edit distance)
|
|
11
|
+
* 3. Generate state machine: S0→a1→S1→a2→S2...→Sn→∅
|
|
12
|
+
* 4. Infer pre/post/invalidation from state transitions
|
|
13
|
+
* 5. Output as KnowledgePatch (compatible with KnowledgePatchStore)
|
|
14
|
+
* 6. Conflict detection with existing protocol rules
|
|
15
|
+
*
|
|
16
|
+
* This is the bridge from "pattern discovery" to "self-extending knowledge."
|
|
17
|
+
*/
|
|
18
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
19
|
+
exports.findPrototype = findPrototype;
|
|
20
|
+
exports.synthesizeProtocols = synthesizeProtocols;
|
|
21
|
+
exports.synthesizeAllKnownProtocols = synthesizeAllKnownProtocols;
|
|
22
|
+
exports.detectConflicts = detectConflicts;
|
|
23
|
+
exports.runAutoSynthesis = runAutoSynthesis;
|
|
24
|
+
exports.printSynthesisReport = printSynthesisReport;
|
|
25
|
+
const unsupervised_physics_1 = require("./experimental/unsupervised-physics");
|
|
26
|
+
const protocol_coverage_1 = require("./protocol-coverage");
|
|
27
|
+
const protocol_foundation_1 = require("./protocol-foundation");
|
|
28
|
+
const function_synonyms_1 = require("./function-synonyms");
|
|
29
|
+
// ═══════════════════════════════════════════════════════════════
|
|
30
|
+
// Prototype Selection
|
|
31
|
+
// ═══════════════════════════════════════════════════════════════
|
|
32
|
+
/** Levenshtein edit distance between two string arrays. */
|
|
33
|
+
function editDistance(a, b) {
|
|
34
|
+
const m = a.length, n = b.length;
|
|
35
|
+
const dp = Array.from({ length: m + 1 }, () => new Array(n + 1).fill(0));
|
|
36
|
+
for (let i = 0; i <= m; i++)
|
|
37
|
+
dp[i][0] = i;
|
|
38
|
+
for (let j = 0; j <= n; j++)
|
|
39
|
+
dp[0][j] = j;
|
|
40
|
+
for (let i = 1; i <= m; i++) {
|
|
41
|
+
for (let j = 1; j <= n; j++) {
|
|
42
|
+
dp[i][j] = a[i - 1] === b[j - 1] ? dp[i - 1][j - 1] : 1 + Math.min(dp[i - 1][j], dp[i][j - 1], dp[i - 1][j - 1]);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
return dp[m][n];
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Find the prototype (centroid) sequence in a cluster.
|
|
49
|
+
* The prototype is the sequence with minimum average edit distance to all others.
|
|
50
|
+
*/
|
|
51
|
+
function findPrototype(sequences) {
|
|
52
|
+
if (sequences.length <= 1)
|
|
53
|
+
return sequences[0] || [];
|
|
54
|
+
let bestSeq = sequences[0];
|
|
55
|
+
let bestDist = Infinity;
|
|
56
|
+
for (const seq of sequences) {
|
|
57
|
+
const totalDist = sequences.reduce((s, other) => s + editDistance(seq, other), 0);
|
|
58
|
+
const avgDist = totalDist / sequences.length;
|
|
59
|
+
if (avgDist < bestDist) {
|
|
60
|
+
bestDist = avgDist;
|
|
61
|
+
bestSeq = seq;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
return bestSeq;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Generate a state machine from a prototype action sequence.
|
|
68
|
+
*
|
|
69
|
+
* For a sequence [A, B, C]:
|
|
70
|
+
* S0 → A → S1 → B → S2 → C → S3
|
|
71
|
+
*
|
|
72
|
+
* Rules:
|
|
73
|
+
* A: pre=[S0], post=[S1]
|
|
74
|
+
* B: pre=[S1], post=[S2]
|
|
75
|
+
* C: pre=[S2], post=[S3], invalidate=[S0,S1,S2,S3] (cleanup)
|
|
76
|
+
*/
|
|
77
|
+
function generateStateMachine(prototype, clusterId) {
|
|
78
|
+
if (prototype.length === 0)
|
|
79
|
+
return [];
|
|
80
|
+
const rules = [];
|
|
81
|
+
const statePrefix = clusterId.replace(/[^a-zA-Z0-9]/g, "_");
|
|
82
|
+
// Generate semantic state names from action functions
|
|
83
|
+
const stateNames = [];
|
|
84
|
+
for (let i = 0; i < prototype.length; i++) {
|
|
85
|
+
const fn = prototype[i];
|
|
86
|
+
// Use domain-aware naming: "open"→FILE_OPEN, "close"→FILE_CLOSED
|
|
87
|
+
const role = i === 0 ? "post" : i === prototype.length - 1 ? "invalidate" : "post";
|
|
88
|
+
const semanticName = (0, protocol_foundation_1.inferStateName)(fn, role);
|
|
89
|
+
// Deduplicate: if same semantic name appears, add index
|
|
90
|
+
let finalName = semanticName;
|
|
91
|
+
let suffix = 1;
|
|
92
|
+
while (stateNames.includes(finalName)) {
|
|
93
|
+
finalName = `${semanticName}_${suffix++}`;
|
|
94
|
+
}
|
|
95
|
+
stateNames.push(finalName);
|
|
96
|
+
}
|
|
97
|
+
for (let i = 0; i < prototype.length; i++) {
|
|
98
|
+
const fn = prototype[i];
|
|
99
|
+
const preState = i === 0 ? "INIT" : stateNames[i - 1];
|
|
100
|
+
const postState = i < prototype.length - 1 ? stateNames[i] : `${statePrefix}_DONE`;
|
|
101
|
+
const rule = {
|
|
102
|
+
function: fn,
|
|
103
|
+
pre_states: [preState],
|
|
104
|
+
post_states: [postState],
|
|
105
|
+
};
|
|
106
|
+
// Last action: invalidate all intermediate states (cleanup / release)
|
|
107
|
+
if (i === prototype.length - 1) {
|
|
108
|
+
rule.invalidate = [...stateNames, postState];
|
|
109
|
+
}
|
|
110
|
+
rules.push(rule);
|
|
111
|
+
}
|
|
112
|
+
return rules;
|
|
113
|
+
}
|
|
114
|
+
// ═══════════════════════════════════════════════════════════════
|
|
115
|
+
// Protocol Synthesis
|
|
116
|
+
// ═══════════════════════════════════════════════════════════════
|
|
117
|
+
/**
|
|
118
|
+
* Synthesize protocol rules from unsupervised clusters.
|
|
119
|
+
*
|
|
120
|
+
* For each cluster with inferred pattern, generates a state machine
|
|
121
|
+
* and exportable rule set.
|
|
122
|
+
*/
|
|
123
|
+
function synthesizeProtocols(sequences) {
|
|
124
|
+
// P6.9: Normalize function names before clustering (DB_Open→open, createClient→create_client)
|
|
125
|
+
const normalized = sequences.map(seq => seq.map(function_synonyms_1.normalizeFunctionName));
|
|
126
|
+
const clusters = (0, unsupervised_physics_1.clusterByStructure)(normalized);
|
|
127
|
+
const results = [];
|
|
128
|
+
for (const c of clusters) {
|
|
129
|
+
if (!c.inferredPattern || c.sequences.length < 2)
|
|
130
|
+
continue;
|
|
131
|
+
const prototype = findPrototype(c.sequences);
|
|
132
|
+
// P9.2p: Use V2 state machine generation for richer rules
|
|
133
|
+
const rules = generateStateMachineV2(c.sequences, c.id);
|
|
134
|
+
results.push({
|
|
135
|
+
clusterId: c.id,
|
|
136
|
+
prototype,
|
|
137
|
+
rules,
|
|
138
|
+
stateCount: prototype.length + 1,
|
|
139
|
+
inferredPattern: c.inferredPattern,
|
|
140
|
+
confidence: c.closedLoopRate,
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
return results;
|
|
144
|
+
}
|
|
145
|
+
// ═══════════════════════════════════════════════════════════════
|
|
146
|
+
// P9.2p: State Machine V2 — frequency-based, multi-path rules
|
|
147
|
+
// ═══════════════════════════════════════════════════════════════
|
|
148
|
+
/**
|
|
149
|
+
* Generate richer protocol rules using ALL sequences in a cluster,
|
|
150
|
+
* not just the centroid prototype.
|
|
151
|
+
*
|
|
152
|
+
* Improvements over V1 (linear chain only):
|
|
153
|
+
* 1. Frequency-based pre_states: each function can have multiple
|
|
154
|
+
* valid pre_states based on what actually precedes it in the data.
|
|
155
|
+
* 2. Self-transitions: functions that appear consecutively with
|
|
156
|
+
* themselves (e.g., process→process) get self-loops.
|
|
157
|
+
* 3. Multiple exit paths: any function that appears as the last
|
|
158
|
+
* call in a sequence is allowed to invalidate states.
|
|
159
|
+
* 4. Entry points: functions that appear as first call in sequences
|
|
160
|
+
* get empty pre_states (always callable).
|
|
161
|
+
*/
|
|
162
|
+
function generateStateMachineV2(sequences, clusterId) {
|
|
163
|
+
if (sequences.length === 0)
|
|
164
|
+
return [];
|
|
165
|
+
// Collect frequency data
|
|
166
|
+
const fnPositions = new Map();
|
|
167
|
+
const transitions = new Map(); // from → {to → count}
|
|
168
|
+
for (const seq of sequences) {
|
|
169
|
+
if (seq.length === 0)
|
|
170
|
+
continue;
|
|
171
|
+
for (let i = 0; i < seq.length; i++) {
|
|
172
|
+
const fn = seq[i];
|
|
173
|
+
if (!fnPositions.has(fn))
|
|
174
|
+
fnPositions.set(fn, { first: 0, last: 0, mid: 0, total: 0 });
|
|
175
|
+
const pos = fnPositions.get(fn);
|
|
176
|
+
pos.total++;
|
|
177
|
+
if (i === 0)
|
|
178
|
+
pos.first++;
|
|
179
|
+
if (i === seq.length - 1)
|
|
180
|
+
pos.last++;
|
|
181
|
+
if (i > 0 && i < seq.length - 1)
|
|
182
|
+
pos.mid++;
|
|
183
|
+
// Track transitions
|
|
184
|
+
if (i < seq.length - 1) {
|
|
185
|
+
const from = fn;
|
|
186
|
+
const to = seq[i + 1];
|
|
187
|
+
if (!transitions.has(from))
|
|
188
|
+
transitions.set(from, new Map());
|
|
189
|
+
const toMap = transitions.get(from);
|
|
190
|
+
toMap.set(to, (toMap.get(to) || 0) + 1);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
const totalSeqs = sequences.length;
|
|
195
|
+
const rules = [];
|
|
196
|
+
const statePrefix = clusterId.replace(/[^a-zA-Z0-9]/g, "_");
|
|
197
|
+
let stateCounter = 0;
|
|
198
|
+
const fnToState = new Map();
|
|
199
|
+
// Assign states to functions
|
|
200
|
+
for (const [fn, pos] of fnPositions) {
|
|
201
|
+
const stateName = pos.first / pos.total > 0.5 ? "INIT"
|
|
202
|
+
: pos.last / pos.total > 0.5 ? `${statePrefix}_EXIT`
|
|
203
|
+
: `${statePrefix}_S${stateCounter++}`;
|
|
204
|
+
fnToState.set(fn, stateName);
|
|
205
|
+
}
|
|
206
|
+
// Generate rules
|
|
207
|
+
for (const [fn, pos] of fnPositions) {
|
|
208
|
+
const preStates = new Set();
|
|
209
|
+
const postStates = new Set();
|
|
210
|
+
const invalidateStates = new Set();
|
|
211
|
+
// PRE_STATES: collect all unique predecessors
|
|
212
|
+
for (const seq of sequences) {
|
|
213
|
+
for (let i = 0; i < seq.length; i++) {
|
|
214
|
+
if (seq[i] === fn) {
|
|
215
|
+
if (i === 0) {
|
|
216
|
+
preStates.add("INIT");
|
|
217
|
+
}
|
|
218
|
+
else {
|
|
219
|
+
const predState = fnToState.get(seq[i - 1]);
|
|
220
|
+
if (predState)
|
|
221
|
+
preStates.add(predState);
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
// POST_STATES: from fnToState, and from successors
|
|
227
|
+
postStates.add(fnToState.get(fn) || `${statePrefix}_S${stateCounter++}`);
|
|
228
|
+
const toMap = transitions.get(fn);
|
|
229
|
+
if (toMap) {
|
|
230
|
+
for (const [toFn] of toMap) {
|
|
231
|
+
const toState = fnToState.get(toFn);
|
|
232
|
+
if (toState && toState !== fnToState.get(fn))
|
|
233
|
+
postStates.add(toState);
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
// INVALIDATE: functions that frequently end sequences
|
|
237
|
+
if (pos.last / Math.max(1, pos.total) > 0.3) {
|
|
238
|
+
// This function often ends sequences — it should invalidate accumulated states
|
|
239
|
+
for (const pred of findPredecessors(fn, sequences)) {
|
|
240
|
+
const predState = fnToState.get(pred);
|
|
241
|
+
if (predState && predState !== "INIT")
|
|
242
|
+
invalidateStates.add(predState);
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
// ENTRY POINTS: functions that frequently start sequences
|
|
246
|
+
const preStatesArr = pos.first / Math.max(1, pos.total) > 0.5 ? [] : [...preStates];
|
|
247
|
+
rules.push({
|
|
248
|
+
function: fn,
|
|
249
|
+
pre_states: preStatesArr,
|
|
250
|
+
post_states: [...postStates],
|
|
251
|
+
invalidate: invalidateStates.size > 0 ? [...invalidateStates] : undefined,
|
|
252
|
+
});
|
|
253
|
+
}
|
|
254
|
+
return rules;
|
|
255
|
+
}
|
|
256
|
+
function findPredecessors(fn, sequences) {
|
|
257
|
+
const preds = new Set();
|
|
258
|
+
for (const seq of sequences) {
|
|
259
|
+
for (let i = 1; i < seq.length; i++) {
|
|
260
|
+
if (seq[i] === fn)
|
|
261
|
+
preds.add(seq[i - 1]);
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
return [...preds];
|
|
265
|
+
}
|
|
266
|
+
/**
|
|
267
|
+
* Synthesize protocols from all known cross-repo sequences.
|
|
268
|
+
*/
|
|
269
|
+
function synthesizeAllKnownProtocols() {
|
|
270
|
+
const allSeqs = [];
|
|
271
|
+
for (const seqs of Object.values(unsupervised_physics_1.CROSS_REPO_SEQUENCES)) {
|
|
272
|
+
allSeqs.push(...seqs);
|
|
273
|
+
}
|
|
274
|
+
return synthesizeProtocols(allSeqs);
|
|
275
|
+
}
|
|
276
|
+
/**
|
|
277
|
+
* Detect conflicts between synthesized rules and existing protocol rules.
|
|
278
|
+
*
|
|
279
|
+
* A conflict = same function name but different pre/post states.
|
|
280
|
+
*/
|
|
281
|
+
function detectConflicts(synthesized, existingRules) {
|
|
282
|
+
const reports = [];
|
|
283
|
+
for (const sp of synthesized) {
|
|
284
|
+
const conflicts = [];
|
|
285
|
+
for (const sr of sp.rules) {
|
|
286
|
+
const existing = existingRules.get(sr.function);
|
|
287
|
+
if (existing) {
|
|
288
|
+
// Check if rules are consistent
|
|
289
|
+
const preMatch = sr.pre_states.length === existing.pre_states.length &&
|
|
290
|
+
sr.pre_states.every(s => existing.pre_states.includes(s));
|
|
291
|
+
const postMatch = sr.post_states.length === existing.post_states.length &&
|
|
292
|
+
sr.post_states.every(s => existing.post_states.includes(s));
|
|
293
|
+
if (!preMatch || !postMatch) {
|
|
294
|
+
conflicts.push({ fn: sr.function, existingRule: existing, synthesizedRule: sr });
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
reports.push({
|
|
299
|
+
synthesized: sp,
|
|
300
|
+
conflicts,
|
|
301
|
+
hasConflicts: conflicts.length > 0,
|
|
302
|
+
});
|
|
303
|
+
}
|
|
304
|
+
return reports;
|
|
305
|
+
}
|
|
306
|
+
/**
|
|
307
|
+
* Full auto-synthesis pipeline:
|
|
308
|
+
* Sequences → Clusters → State Machines → Conflict Detection → Governance-ready
|
|
309
|
+
*/
|
|
310
|
+
function runAutoSynthesis(existingRules) {
|
|
311
|
+
const protocols = synthesizeAllKnownProtocols();
|
|
312
|
+
const defs = (0, protocol_coverage_1.loadDefaultProtocolDefinitions)();
|
|
313
|
+
const rules = existingRules || new Map();
|
|
314
|
+
for (const p of defs)
|
|
315
|
+
for (const [fn, rule] of p.rules)
|
|
316
|
+
rules.set(fn, rule);
|
|
317
|
+
const conflicts = detectConflicts(protocols, rules);
|
|
318
|
+
const totalRules = protocols.reduce((s, p) => s + p.rules.length, 0);
|
|
319
|
+
const newFunctions = protocols.reduce((s, p) => {
|
|
320
|
+
const newFns = p.rules.filter(r => !rules.has(r.function));
|
|
321
|
+
return s + newFns.length;
|
|
322
|
+
}, 0);
|
|
323
|
+
const conflictCount = conflicts.filter(c => c.hasConflicts).length;
|
|
324
|
+
return {
|
|
325
|
+
protocols,
|
|
326
|
+
conflicts,
|
|
327
|
+
totalRules,
|
|
328
|
+
newFunctions,
|
|
329
|
+
conflictCount,
|
|
330
|
+
readyForGovernance: conflictCount === 0 && newFunctions > 0,
|
|
331
|
+
};
|
|
332
|
+
}
|
|
333
|
+
function printSynthesisReport(report) {
|
|
334
|
+
console.log("\n╔════════════════════════════════════════════════════╗");
|
|
335
|
+
console.log("║ P6.4 Auto Protocol Synthesizer ║");
|
|
336
|
+
console.log("╚════════════════════════════════════════════════════╝\n");
|
|
337
|
+
console.log(`Protocols Synthesized: ${report.protocols.length}`);
|
|
338
|
+
console.log(`Total Rules: ${report.totalRules}`);
|
|
339
|
+
console.log(`New Functions: ${report.newFunctions}`);
|
|
340
|
+
console.log(`Conflicts: ${report.conflictCount}`);
|
|
341
|
+
console.log(`Ready for Governance: ${report.readyForGovernance ? "✅ YES" : "❌ NO"}`);
|
|
342
|
+
console.log();
|
|
343
|
+
for (const p of report.protocols) {
|
|
344
|
+
console.log(` ${p.clusterId}: ${p.prototype.join(" → ")}`);
|
|
345
|
+
console.log(` Pattern: ${p.inferredPattern}, States: ${p.stateCount}, Rules: ${p.rules.length}`);
|
|
346
|
+
for (const r of p.rules) {
|
|
347
|
+
const inv = r.invalidate ? ` [inv: ${r.invalidate.join(",")}]` : "";
|
|
348
|
+
console.log(` ${r.function}: [${r.pre_states.join(",")}] → [${r.post_states.join(",")}]${inv}`);
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
console.log();
|
|
352
|
+
if (report.conflictCount > 0) {
|
|
353
|
+
console.log("─── Conflicts ───");
|
|
354
|
+
for (const c of report.conflicts.filter(c => c.hasConflicts)) {
|
|
355
|
+
console.log(` ${c.synthesized.clusterId}:`);
|
|
356
|
+
for (const cf of c.conflicts) {
|
|
357
|
+
console.log(` ${cf.fn}: existing≠synthesized — needs governance review`);
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
console.log();
|
|
361
|
+
}
|
|
362
|
+
}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* P6.4: Auto Protocol Synthesizer Tests
|
|
4
|
+
*
|
|
5
|
+
* Validates the full zero-intervention pipeline:
|
|
6
|
+
* Trajectories → Clusters → State Machines → Governance-Ready Rules
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
const vitest_1 = require("vitest");
|
|
10
|
+
const auto_protocol_synthesizer_1 = require("./auto-protocol-synthesizer");
|
|
11
|
+
const protocol_coverage_1 = require("./protocol-coverage");
|
|
12
|
+
(0, vitest_1.describe)("Prototype Selection", () => {
|
|
13
|
+
(0, vitest_1.it)("finds centroid by minimum average edit distance", () => {
|
|
14
|
+
const seqs = [
|
|
15
|
+
["open", "read", "close"],
|
|
16
|
+
["open", "write", "close"],
|
|
17
|
+
["open", "read", "write", "close"],
|
|
18
|
+
];
|
|
19
|
+
const proto = (0, auto_protocol_synthesizer_1.findPrototype)(seqs);
|
|
20
|
+
(0, vitest_1.expect)(proto.length).toBeGreaterThanOrEqual(2);
|
|
21
|
+
// The prototype should be one of the 3-step sequences (more central)
|
|
22
|
+
(0, vitest_1.expect)(proto.length).toBeLessThanOrEqual(3);
|
|
23
|
+
});
|
|
24
|
+
});
|
|
25
|
+
(0, vitest_1.describe)("Protocol Synthesis", () => {
|
|
26
|
+
(0, vitest_1.it)("generates state machine from prototype sequence", () => {
|
|
27
|
+
const seqs = [
|
|
28
|
+
["fopen", "fread", "fclose"],
|
|
29
|
+
["sqlite3_open", "sqlite3_exec", "sqlite3_close"],
|
|
30
|
+
["DB_Open", "DB_Get", "DB_Close"],
|
|
31
|
+
];
|
|
32
|
+
const protocols = (0, auto_protocol_synthesizer_1.synthesizeProtocols)(seqs);
|
|
33
|
+
(0, vitest_1.expect)(protocols.length).toBeGreaterThan(0);
|
|
34
|
+
// The main cluster should have Acquire-Use-Release structure
|
|
35
|
+
const mainProto = protocols[0];
|
|
36
|
+
(0, vitest_1.expect)(mainProto.inferredPattern).toBe("RESOURCE_ACQUIRE");
|
|
37
|
+
// V2 generates frequency-based multi-path rules (≥3, typically 5 for this dataset)
|
|
38
|
+
(0, vitest_1.expect)(mainProto.rules.length).toBeGreaterThanOrEqual(3);
|
|
39
|
+
(0, vitest_1.expect)(mainProto.stateCount).toBeGreaterThanOrEqual(3);
|
|
40
|
+
// Last rule should have invalidation
|
|
41
|
+
const lastRule = mainProto.rules[mainProto.rules.length - 1];
|
|
42
|
+
(0, vitest_1.expect)(lastRule.invalidate).toBeDefined();
|
|
43
|
+
(0, vitest_1.expect)(lastRule.invalidate.length).toBeGreaterThan(0);
|
|
44
|
+
});
|
|
45
|
+
(0, vitest_1.it)("synthesizes from all known cross-repo sequences", () => {
|
|
46
|
+
const protocols = (0, auto_protocol_synthesizer_1.synthesizeAllKnownProtocols)();
|
|
47
|
+
(0, vitest_1.expect)(protocols.length).toBeGreaterThan(0);
|
|
48
|
+
// Should have at least Acquire-Release (len=3 closed) and Lock-Unlock (len=2 closed)
|
|
49
|
+
(0, vitest_1.expect)(protocols.some(p => p.inferredPattern === "RESOURCE_ACQUIRE")).toBe(true);
|
|
50
|
+
(0, vitest_1.expect)(protocols.some(p => p.prototype.length === 2)).toBe(true);
|
|
51
|
+
});
|
|
52
|
+
});
|
|
53
|
+
(0, vitest_1.describe)("Conflict Detection", () => {
|
|
54
|
+
(0, vitest_1.it)("detects conflicts with existing protocol rules", () => {
|
|
55
|
+
const seqs = [
|
|
56
|
+
["open_file", "read_file", "close_file"],
|
|
57
|
+
["open_file", "write_file", "close_file"],
|
|
58
|
+
];
|
|
59
|
+
const protocols = (0, auto_protocol_synthesizer_1.synthesizeProtocols)(seqs);
|
|
60
|
+
const defs = (0, protocol_coverage_1.loadDefaultProtocolDefinitions)();
|
|
61
|
+
const existingRules = new Map();
|
|
62
|
+
for (const p of defs)
|
|
63
|
+
for (const [fn, rule] of p.rules)
|
|
64
|
+
existingRules.set(fn, rule);
|
|
65
|
+
const conflicts = (0, auto_protocol_synthesizer_1.detectConflicts)(protocols, existingRules);
|
|
66
|
+
// Synthesized open_file may conflict with existing open_file definition
|
|
67
|
+
// That's expected and correctly flagged
|
|
68
|
+
(0, vitest_1.expect)(conflicts.length).toBeGreaterThan(0);
|
|
69
|
+
});
|
|
70
|
+
});
|
|
71
|
+
(0, vitest_1.describe)("Full Synthesis Pipeline", () => {
|
|
72
|
+
(0, vitest_1.it)("runs auto-synthesis and produces governance-ready report", () => {
|
|
73
|
+
const report = (0, auto_protocol_synthesizer_1.runAutoSynthesis)();
|
|
74
|
+
(0, vitest_1.expect)(report.protocols.length).toBeGreaterThan(0);
|
|
75
|
+
(0, vitest_1.expect)(report.totalRules).toBeGreaterThan(0);
|
|
76
|
+
(0, vitest_1.expect)(report.newFunctions).toBeGreaterThan(0);
|
|
77
|
+
// Some conflicts expected (synthesized rules may differ from hand-written)
|
|
78
|
+
// The system correctly flags these for governance review
|
|
79
|
+
(0, vitest_1.expect)(report.conflictCount).toBeGreaterThanOrEqual(0);
|
|
80
|
+
(0, auto_protocol_synthesizer_1.printSynthesisReport)(report);
|
|
81
|
+
});
|
|
82
|
+
});
|