progmune-runtime 2.1.6 → 3.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +119 -461
- 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 +721 -0
- package/package.json +73 -6
- 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,310 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* P5.5: Protocol Extraction Engine
|
|
4
|
+
*
|
|
5
|
+
* Auto-extracts protocol state machines from real code patterns.
|
|
6
|
+
* No hand-written rules — the code IS the specification.
|
|
7
|
+
*
|
|
8
|
+
* Algorithm:
|
|
9
|
+
* 1. Parse source code to extract function call sequences
|
|
10
|
+
* 2. Build transition frequency matrix: count fnA→fnB pairs
|
|
11
|
+
* 3. For frequent pairs, infer states and pre/post conditions
|
|
12
|
+
* 4. Output ProtocolDefinition compatible with SSG validator
|
|
13
|
+
*
|
|
14
|
+
* This addresses the biggest remaining bottleneck:
|
|
15
|
+
* Knowledge Acquisition (57% missing_candidate)
|
|
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.extractCallPairs = extractCallPairs;
|
|
52
|
+
exports.inferProtocolRules = inferProtocolRules;
|
|
53
|
+
exports.extractProtocol = extractProtocol;
|
|
54
|
+
exports.extractProtocolFromFiles = extractProtocolFromFiles;
|
|
55
|
+
exports.rulesToAnnotationMap = rulesToAnnotationMap;
|
|
56
|
+
exports.printExtractionReport = printExtractionReport;
|
|
57
|
+
const fs = __importStar(require("fs"));
|
|
58
|
+
/**
|
|
59
|
+
* Extract function call pairs from source code.
|
|
60
|
+
*
|
|
61
|
+
* Matches patterns like:
|
|
62
|
+
* obj.open(); ... obj.read(); ... obj.close();
|
|
63
|
+
* connect(); ... query(); ... disconnect();
|
|
64
|
+
*
|
|
65
|
+
* Uses a sliding window: any two function calls within
|
|
66
|
+
* the same scope block are considered a potential pair.
|
|
67
|
+
*/
|
|
68
|
+
function extractCallPairs(source, file = "<input>") {
|
|
69
|
+
const pairs = [];
|
|
70
|
+
// Match function calls: identifier(args) OR obj.identifier(args)
|
|
71
|
+
const callRegex = /\b([a-zA-Z_]\w*(?:\.[a-zA-Z_]\w*)?)\s*\(/g;
|
|
72
|
+
const lines = source.split("\n");
|
|
73
|
+
// Track calls per scope block (delimited by { })
|
|
74
|
+
let scopeDepth = 0;
|
|
75
|
+
let scopeCalls = [];
|
|
76
|
+
for (let li = 0; li < lines.length; li++) {
|
|
77
|
+
const line = lines[li];
|
|
78
|
+
// Track scope depth
|
|
79
|
+
for (const ch of line) {
|
|
80
|
+
if (ch === "{")
|
|
81
|
+
scopeDepth++;
|
|
82
|
+
if (ch === "}") {
|
|
83
|
+
scopeDepth--;
|
|
84
|
+
if (scopeDepth === 0) {
|
|
85
|
+
// End of top-level scope: flush pairs
|
|
86
|
+
for (let i = 0; i < scopeCalls.length - 1; i++) {
|
|
87
|
+
for (let j = i + 1; j < scopeCalls.length; j++) {
|
|
88
|
+
pairs.push({
|
|
89
|
+
from: normalizeFn(scopeCalls[i].name),
|
|
90
|
+
to: normalizeFn(scopeCalls[j].name),
|
|
91
|
+
file,
|
|
92
|
+
line: 0 + 1,
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
scopeCalls = [];
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
// Extract function calls on this line
|
|
101
|
+
let match;
|
|
102
|
+
callRegex.lastIndex = 0;
|
|
103
|
+
while ((match = callRegex.exec(line)) !== null) {
|
|
104
|
+
const fnName = match[1];
|
|
105
|
+
// Filter out common language builtins and keywords
|
|
106
|
+
if (!isBuiltin(fnName)) {
|
|
107
|
+
scopeCalls.push({ name: fnName, line: 0 + 1 });
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
// Flush remaining calls
|
|
112
|
+
for (let i = 0; i < scopeCalls.length - 1; i++) {
|
|
113
|
+
for (let j = i + 1; j < scopeCalls.length; j++) {
|
|
114
|
+
pairs.push({
|
|
115
|
+
from: normalizeFn(scopeCalls[i].name),
|
|
116
|
+
to: normalizeFn(scopeCalls[j].name),
|
|
117
|
+
file,
|
|
118
|
+
line: 0,
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
return pairs;
|
|
123
|
+
}
|
|
124
|
+
function normalizeFn(fn) {
|
|
125
|
+
// obj.method → method (strip object prefix)
|
|
126
|
+
const parts = fn.split(".");
|
|
127
|
+
return parts[parts.length - 1];
|
|
128
|
+
}
|
|
129
|
+
function isBuiltin(name) {
|
|
130
|
+
const builtins = new Set([
|
|
131
|
+
"if", "for", "while", "switch", "return", "console", "log",
|
|
132
|
+
"require", "import", "export", "print", "len", "push", "pop",
|
|
133
|
+
"map", "filter", "reduce", "forEach", "toString", "valueOf",
|
|
134
|
+
"assert", "expect", "test", "describe", "it",
|
|
135
|
+
"main", "printf", "write_config", "sprintf", "fprintf",
|
|
136
|
+
"setup", "teardown", "init", "destroy", "cleanup",
|
|
137
|
+
]);
|
|
138
|
+
const normalized = normalizeFn(name);
|
|
139
|
+
return builtins.has(normalized) || normalized.length <= 2;
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Infer protocol rules from call pairs.
|
|
143
|
+
*
|
|
144
|
+
* For each frequent pair fnA→fnB:
|
|
145
|
+
* 1. Create a shared state connecting them
|
|
146
|
+
* 2. fnA produces the state, fnB requires it
|
|
147
|
+
* 3. Track invalidations: if a state producer is followed
|
|
148
|
+
* by a function with no downstream consumer, the last
|
|
149
|
+
* consumer invalidates it
|
|
150
|
+
*/
|
|
151
|
+
function inferProtocolRules(pairs, minFrequency = 3) {
|
|
152
|
+
// Count transition frequencies
|
|
153
|
+
const transitions = new Map();
|
|
154
|
+
const fnSet = new Set();
|
|
155
|
+
for (const p of pairs) {
|
|
156
|
+
const key = `${p.from}→${p.to}`;
|
|
157
|
+
transitions.set(key, (transitions.get(key) || 0) + 1);
|
|
158
|
+
fnSet.add(p.from);
|
|
159
|
+
fnSet.add(p.to);
|
|
160
|
+
}
|
|
161
|
+
const maxFreq = Math.max(1, ...[...transitions.values()]);
|
|
162
|
+
const rules = [];
|
|
163
|
+
const fnStates = new Map();
|
|
164
|
+
// For each frequent transition, infer a shared state
|
|
165
|
+
for (const [key, freq] of transitions) {
|
|
166
|
+
if (freq < minFrequency)
|
|
167
|
+
continue;
|
|
168
|
+
const [fnA, fnB] = key.split("→");
|
|
169
|
+
const confidence = freq / maxFreq;
|
|
170
|
+
// Create a shared state name from the function pair
|
|
171
|
+
const stateName = inferStateName(fnA, fnB);
|
|
172
|
+
// fnA produces this state
|
|
173
|
+
const aStates = fnStates.get(fnA) || { produced: new Set(), required: new Set() };
|
|
174
|
+
aStates.produced.add(stateName);
|
|
175
|
+
fnStates.set(fnA, aStates);
|
|
176
|
+
// fnB requires this state
|
|
177
|
+
const bStates = fnStates.get(fnB) || { produced: new Set(), required: new Set() };
|
|
178
|
+
bStates.required.add(stateName);
|
|
179
|
+
fnStates.set(fnB, bStates);
|
|
180
|
+
}
|
|
181
|
+
// Infer invalidations: the "closing" function of a group invalidates
|
|
182
|
+
// the state that the "opening" function produced
|
|
183
|
+
const closingKeywords = ["close", "disconnect", "logout", "destroy", "free", "release", "stop", "end", "finish"];
|
|
184
|
+
const openingKeywords = ["open", "connect", "login", "create", "alloc", "init", "start", "begin"];
|
|
185
|
+
// Convert to rules
|
|
186
|
+
for (const [fn, states] of fnStates) {
|
|
187
|
+
const rule = {
|
|
188
|
+
function: fn,
|
|
189
|
+
pre_states: [...states.required],
|
|
190
|
+
post_states: [...states.produced],
|
|
191
|
+
confidence: 0.5,
|
|
192
|
+
evidence: 1,
|
|
193
|
+
};
|
|
194
|
+
// Check if this is a "closing" function — it should invalidate opening states
|
|
195
|
+
const isCloser = closingKeywords.some(kw => fn.includes(kw));
|
|
196
|
+
const isOpener = openingKeywords.some(kw => fn.includes(kw));
|
|
197
|
+
if (isCloser) {
|
|
198
|
+
// Find what state this closes (the corresponding opener's produced state)
|
|
199
|
+
for (const [otherFn, otherStates] of fnStates) {
|
|
200
|
+
if (openingKeywords.some(kw => otherFn.includes(kw))) {
|
|
201
|
+
const sharedState = [...otherStates.produced].find(s => states.required.has(s));
|
|
202
|
+
if (sharedState) {
|
|
203
|
+
rule.invalidate = [sharedState];
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
// Estimate confidence from evidence count
|
|
209
|
+
const prodCount = states.produced.size + states.required.size;
|
|
210
|
+
rule.evidence = prodCount;
|
|
211
|
+
rule.confidence = Math.min(1, prodCount / 5);
|
|
212
|
+
rules.push(rule);
|
|
213
|
+
}
|
|
214
|
+
return rules.sort((a, b) => b.confidence - a.confidence);
|
|
215
|
+
}
|
|
216
|
+
function inferStateName(fnA, fnB) {
|
|
217
|
+
// Create a meaningful state name from the function pair
|
|
218
|
+
const domain = fnA.includes("file") || fnB.includes("file") ? "FILE" :
|
|
219
|
+
fnA.includes("auth") || fnB.includes("auth") || fnA.includes("login") || fnB.includes("login") ? "AUTH" :
|
|
220
|
+
fnA.includes("db") || fnB.includes("db") || fnA.includes("connect") || fnB.includes("connect") ? "DB" :
|
|
221
|
+
"STATE";
|
|
222
|
+
const action = fnA.includes("open") || fnB.includes("open") ? "_OPEN" :
|
|
223
|
+
fnA.includes("close") || fnB.includes("close") ? "_CLOSED" :
|
|
224
|
+
fnA.includes("connect") || fnB.includes("connect") ? "_CONNECTED" :
|
|
225
|
+
fnA.includes("create") || fnB.includes("create") ? "_CREATED" :
|
|
226
|
+
fnA.includes("init") || fnB.includes("init") ? "_INITIALIZED" :
|
|
227
|
+
"";
|
|
228
|
+
return `${domain}${action}`.toUpperCase();
|
|
229
|
+
}
|
|
230
|
+
/**
|
|
231
|
+
* Extract protocol rules from one or more source files.
|
|
232
|
+
*/
|
|
233
|
+
function extractProtocol(sources, protocolName = "ExtractedProtocol", minFrequency = 3) {
|
|
234
|
+
const allPairs = [];
|
|
235
|
+
const sourceFiles = [];
|
|
236
|
+
for (const src of sources) {
|
|
237
|
+
const pairs = extractCallPairs(src.code, src.file);
|
|
238
|
+
allPairs.push(...pairs);
|
|
239
|
+
sourceFiles.push(src.file);
|
|
240
|
+
}
|
|
241
|
+
const rules = inferProtocolRules(allPairs, minFrequency);
|
|
242
|
+
const states = new Set();
|
|
243
|
+
for (const r of rules) {
|
|
244
|
+
for (const s of r.pre_states)
|
|
245
|
+
states.add(s);
|
|
246
|
+
for (const s of r.post_states)
|
|
247
|
+
states.add(s);
|
|
248
|
+
}
|
|
249
|
+
const avgConfidence = rules.length > 0
|
|
250
|
+
? rules.reduce((s, r) => s + r.confidence, 0) / rules.length
|
|
251
|
+
: 0;
|
|
252
|
+
return {
|
|
253
|
+
protocol: protocolName,
|
|
254
|
+
rules,
|
|
255
|
+
inferredStates: [...states],
|
|
256
|
+
sourceFiles,
|
|
257
|
+
totalPairs: allPairs.length,
|
|
258
|
+
confidence: avgConfidence,
|
|
259
|
+
};
|
|
260
|
+
}
|
|
261
|
+
/**
|
|
262
|
+
* Extract from file paths (reads files from disk).
|
|
263
|
+
*/
|
|
264
|
+
function extractProtocolFromFiles(filePaths, protocolName = "ExtractedProtocol", minFrequency = 3) {
|
|
265
|
+
const sources = filePaths.map(fp => ({
|
|
266
|
+
code: fs.readFileSync(fp, "utf-8"),
|
|
267
|
+
file: fp,
|
|
268
|
+
}));
|
|
269
|
+
return extractProtocol(sources, protocolName, minFrequency);
|
|
270
|
+
}
|
|
271
|
+
/**
|
|
272
|
+
* Convert extracted rules to SSG-compatible StateAnnotation map.
|
|
273
|
+
*/
|
|
274
|
+
function rulesToAnnotationMap(rules) {
|
|
275
|
+
const map = new Map();
|
|
276
|
+
for (const r of rules) {
|
|
277
|
+
map.set(r.function, {
|
|
278
|
+
pre_states: r.pre_states,
|
|
279
|
+
post_states: r.post_states,
|
|
280
|
+
invalidate: r.invalidate,
|
|
281
|
+
});
|
|
282
|
+
}
|
|
283
|
+
return map;
|
|
284
|
+
}
|
|
285
|
+
function printExtractionReport(result) {
|
|
286
|
+
console.log("\n╔════════════════════════════════════════════════════╗");
|
|
287
|
+
console.log("║ P5.5 Protocol Extraction Report ║");
|
|
288
|
+
console.log("╚════════════════════════════════════════════════════╝\n");
|
|
289
|
+
console.log(`Protocol: ${result.protocol}`);
|
|
290
|
+
console.log(`Source Files: ${result.sourceFiles.length}`);
|
|
291
|
+
console.log(`Call Pairs: ${result.totalPairs}`);
|
|
292
|
+
console.log(`Rules Inferred: ${result.rules.length}`);
|
|
293
|
+
console.log(`States Inferred: ${result.inferredStates.length}`);
|
|
294
|
+
console.log(`Avg Confidence: ${(result.confidence * 100).toFixed(0)}%`);
|
|
295
|
+
console.log();
|
|
296
|
+
if (result.rules.length > 0) {
|
|
297
|
+
console.log("─── Inferred Rules ───");
|
|
298
|
+
console.log("Conf Function Pre → Post Invalidate");
|
|
299
|
+
console.log("──────────────────────────────────────────────────────────────────");
|
|
300
|
+
for (const r of result.rules.slice(0, 20)) {
|
|
301
|
+
const conf = (r.confidence * 100).toFixed(0).padStart(4);
|
|
302
|
+
const fn = r.function.padEnd(22);
|
|
303
|
+
const pre = `[${r.pre_states.join(",") || "none"}]`.padEnd(22);
|
|
304
|
+
const post = `[${r.post_states.join(",") || "none"}]`.padEnd(22);
|
|
305
|
+
const inv = r.invalidate ? `[${r.invalidate.join(",")}]` : "—";
|
|
306
|
+
console.log(` ${conf}% ${fn} ${pre} → ${post} ${inv}`);
|
|
307
|
+
}
|
|
308
|
+
console.log();
|
|
309
|
+
}
|
|
310
|
+
}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* P5.5: Protocol Extraction Engine Tests
|
|
4
|
+
*/
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const vitest_1 = require("vitest");
|
|
7
|
+
const protocol_extractor_1 = require("./protocol-extractor");
|
|
8
|
+
const SAMPLE_C_CODE = `
|
|
9
|
+
int main() {
|
|
10
|
+
FILE* f = fopen("config.txt", "r");
|
|
11
|
+
char buf[1024];
|
|
12
|
+
fread(buf, 1, 1024, f);
|
|
13
|
+
printf("%s", buf);
|
|
14
|
+
fclose(f);
|
|
15
|
+
return 0;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
void write_config() {
|
|
19
|
+
FILE* f = fopen("output.txt", "w");
|
|
20
|
+
fwrite(data, 1, len, f);
|
|
21
|
+
fflush(f);
|
|
22
|
+
fclose(f);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
void db_work() {
|
|
26
|
+
DB* db = db_connect("localhost");
|
|
27
|
+
db_query(db, "SELECT * FROM users");
|
|
28
|
+
db_close(db);
|
|
29
|
+
}
|
|
30
|
+
`;
|
|
31
|
+
const SAMPLE_JS_CODE = `
|
|
32
|
+
function processFile(path) {
|
|
33
|
+
const fd = openFile(path);
|
|
34
|
+
const data = readFile(fd);
|
|
35
|
+
const result = transform(data);
|
|
36
|
+
writeFile(fd, result);
|
|
37
|
+
closeFile(fd);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
async function authFlow() {
|
|
41
|
+
const user = await verifyPassword(credentials);
|
|
42
|
+
const token = generateJWT(user);
|
|
43
|
+
const session = createSession(token);
|
|
44
|
+
return session;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function dbQuery() {
|
|
48
|
+
const conn = connectDb(host);
|
|
49
|
+
const rows = queryDb(conn, sql);
|
|
50
|
+
disconnectDb(conn);
|
|
51
|
+
}
|
|
52
|
+
`;
|
|
53
|
+
(0, vitest_1.describe)("Protocol Extraction", () => {
|
|
54
|
+
(0, vitest_1.it)("extracts call pairs from C code", () => {
|
|
55
|
+
const pairs = (0, protocol_extractor_1.extractCallPairs)(SAMPLE_C_CODE, "test.c");
|
|
56
|
+
(0, vitest_1.expect)(pairs.length).toBeGreaterThan(0);
|
|
57
|
+
// Should find fopen → fread, fread → fclose pairs
|
|
58
|
+
const hasFopenClose = pairs.some(p => p.from === "fopen" && p.to === "fclose");
|
|
59
|
+
(0, vitest_1.expect)(hasFopenClose).toBe(true);
|
|
60
|
+
// Should find db_connect → db_query → db_close chain
|
|
61
|
+
const hasDbChain = pairs.some(p => p.from === "db_connect" && p.to === "db_query");
|
|
62
|
+
(0, vitest_1.expect)(hasDbChain).toBe(true);
|
|
63
|
+
});
|
|
64
|
+
(0, vitest_1.it)("extracts call pairs from JS code", () => {
|
|
65
|
+
const pairs = (0, protocol_extractor_1.extractCallPairs)(SAMPLE_JS_CODE, "test.js");
|
|
66
|
+
(0, vitest_1.expect)(pairs.length).toBeGreaterThan(0);
|
|
67
|
+
// openFile → readFile → writeFile → closeFile
|
|
68
|
+
const hasFileChain = pairs.some(p => p.from === "openFile" && p.to === "readFile");
|
|
69
|
+
(0, vitest_1.expect)(hasFileChain).toBe(true);
|
|
70
|
+
// verifyPassword → generateJWT → createSession
|
|
71
|
+
const hasAuthChain = pairs.some(p => p.from === "verifyPassword" && p.to === "generateJWT");
|
|
72
|
+
(0, vitest_1.expect)(hasAuthChain).toBe(true);
|
|
73
|
+
});
|
|
74
|
+
(0, vitest_1.it)("infers protocol rules from call pairs", () => {
|
|
75
|
+
const pairs = (0, protocol_extractor_1.extractCallPairs)(SAMPLE_C_CODE + SAMPLE_JS_CODE, "combined");
|
|
76
|
+
const rules = (0, protocol_extractor_1.inferProtocolRules)(pairs, 1); // min freq 1 for test
|
|
77
|
+
(0, vitest_1.expect)(rules.length).toBeGreaterThan(0);
|
|
78
|
+
// fopen should have post_states (produces something)
|
|
79
|
+
const fopen = rules.find(r => r.function === "fopen");
|
|
80
|
+
(0, vitest_1.expect)(fopen).toBeDefined();
|
|
81
|
+
(0, vitest_1.expect)(fopen.post_states.length).toBeGreaterThan(0);
|
|
82
|
+
// fclose should invalidate something
|
|
83
|
+
const fclose = rules.find(r => r.function === "fclose");
|
|
84
|
+
(0, vitest_1.expect)(fclose).toBeDefined();
|
|
85
|
+
// fclose should have pre_states (needs FILE_OPEN or similar)
|
|
86
|
+
(0, vitest_1.expect)(fclose.pre_states.length).toBeGreaterThan(0);
|
|
87
|
+
// verifyPassword → generateJWT should produce AUTH state
|
|
88
|
+
const verifyPw = rules.find(r => r.function === "verifyPassword");
|
|
89
|
+
(0, vitest_1.expect)(verifyPw).toBeDefined();
|
|
90
|
+
});
|
|
91
|
+
(0, vitest_1.it)("full extraction pipeline from multiple files", () => {
|
|
92
|
+
const result = (0, protocol_extractor_1.extractProtocol)([
|
|
93
|
+
{ code: SAMPLE_C_CODE, file: "test.c" },
|
|
94
|
+
{ code: SAMPLE_JS_CODE, file: "test.js" },
|
|
95
|
+
], "FileProtocol", 1);
|
|
96
|
+
(0, vitest_1.expect)(result.rules.length).toBeGreaterThan(0);
|
|
97
|
+
(0, vitest_1.expect)(result.inferredStates.length).toBeGreaterThan(0);
|
|
98
|
+
(0, vitest_1.expect)(result.totalPairs).toBeGreaterThan(0);
|
|
99
|
+
(0, vitest_1.expect)(result.confidence).toBeGreaterThan(0);
|
|
100
|
+
(0, protocol_extractor_1.printExtractionReport)(result);
|
|
101
|
+
});
|
|
102
|
+
(0, vitest_1.it)("converts rules to SSG-compatible annotation map", () => {
|
|
103
|
+
const pairs = (0, protocol_extractor_1.extractCallPairs)(SAMPLE_C_CODE, "test.c");
|
|
104
|
+
const rules = (0, protocol_extractor_1.inferProtocolRules)(pairs, 1);
|
|
105
|
+
const map = (0, protocol_extractor_1.rulesToAnnotationMap)(rules);
|
|
106
|
+
(0, vitest_1.expect)(map.size).toBeGreaterThan(0);
|
|
107
|
+
// Every rule should have pre_states and post_states arrays
|
|
108
|
+
for (const [fn, annotation] of map) {
|
|
109
|
+
(0, vitest_1.expect)(Array.isArray(annotation.pre_states)).toBe(true);
|
|
110
|
+
(0, vitest_1.expect)(Array.isArray(annotation.post_states)).toBe(true);
|
|
111
|
+
}
|
|
112
|
+
});
|
|
113
|
+
});
|