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,128 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Scale Trajectory Collector
|
|
4
|
+
*
|
|
5
|
+
* Generates 500+ validated trajectories from repo signatures
|
|
6
|
+
* using AST extraction + augmentation + Protocol VM validation.
|
|
7
|
+
*
|
|
8
|
+
* Pipeline:
|
|
9
|
+
* Repo Signatures → AST extraction → Synonym normalization
|
|
10
|
+
* → Random walks → Mutations → Validation → Dedup → Corpus
|
|
11
|
+
*/
|
|
12
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
+
exports.collectTrajectoriesAtScale = collectTrajectoriesAtScale;
|
|
14
|
+
exports.printCollectionReport = printCollectionReport;
|
|
15
|
+
const protocol_mining_1 = require("./protocol-mining");
|
|
16
|
+
const trajectory_corpus_1 = require("./trajectory-corpus");
|
|
17
|
+
const unsupervised_physics_1 = require("./experimental/unsupervised-physics");
|
|
18
|
+
const trajectory_augmentation_1 = require("./trajectory-augmentation");
|
|
19
|
+
const function_synonyms_1 = require("./function-synonyms");
|
|
20
|
+
const software_physics_1 = require("./experimental/software-physics");
|
|
21
|
+
const protocol_coverage_1 = require("./protocol-coverage");
|
|
22
|
+
const auto_protocol_synthesizer_1 = require("./auto-protocol-synthesizer");
|
|
23
|
+
/**
|
|
24
|
+
* Collect trajectories at scale from all available sources.
|
|
25
|
+
*
|
|
26
|
+
* Combines:
|
|
27
|
+
* 1. Mining signatures (21 repos, 64 sequences)
|
|
28
|
+
* 2. Expanded trajectories (10 libraries, 50 sequences)
|
|
29
|
+
* 3. Cross-repo sequences (5 repos, 15 sequences)
|
|
30
|
+
* 4. Random walks from protocol rules
|
|
31
|
+
* 5. Mutations of existing trajectories
|
|
32
|
+
*
|
|
33
|
+
* All sequences are normalized, validated, and deduplicated.
|
|
34
|
+
*/
|
|
35
|
+
function collectTrajectoriesAtScale() {
|
|
36
|
+
// Collect all source sequences
|
|
37
|
+
const sourceSeqs = [];
|
|
38
|
+
// Source 1: Mining signatures
|
|
39
|
+
for (const sig of protocol_mining_1.MINING_SIGNATURES) {
|
|
40
|
+
for (const p of sig.patterns) {
|
|
41
|
+
if (p.length >= 2)
|
|
42
|
+
sourceSeqs.push(p);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
// Source 2: Expanded trajectories
|
|
46
|
+
for (const lib of trajectory_corpus_1.EXPANDED_TRAJECTORIES) {
|
|
47
|
+
for (const seq of lib.sequences) {
|
|
48
|
+
if (seq.length >= 2)
|
|
49
|
+
sourceSeqs.push(seq);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
// Source 3: Cross-repo sequences
|
|
53
|
+
for (const seqs of Object.values(unsupervised_physics_1.CROSS_REPO_SEQUENCES)) {
|
|
54
|
+
for (const seq of seqs) {
|
|
55
|
+
if (seq.length >= 2)
|
|
56
|
+
sourceSeqs.push(seq);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
const sourceCount = sourceSeqs.length;
|
|
60
|
+
const uniqueSources = new Set(sourceSeqs.map(s => s.join("→")));
|
|
61
|
+
// Normalize all sequences
|
|
62
|
+
const normalized = sourceSeqs.map(seq => seq.map(function_synonyms_1.normalizeFunctionName));
|
|
63
|
+
// Build protocol rules for validation
|
|
64
|
+
const defs = (0, protocol_coverage_1.loadDefaultProtocolDefinitions)();
|
|
65
|
+
const rules = new Map();
|
|
66
|
+
const nsInit = new Map();
|
|
67
|
+
for (const p of defs) {
|
|
68
|
+
nsInit.set(p.name, p.initialState);
|
|
69
|
+
for (const [fn, rule] of p.rules)
|
|
70
|
+
rules.set(fn, rule);
|
|
71
|
+
}
|
|
72
|
+
const synthesized = (0, auto_protocol_synthesizer_1.synthesizeAllKnownProtocols)();
|
|
73
|
+
for (const sp of synthesized) {
|
|
74
|
+
for (const sr of sp.rules) {
|
|
75
|
+
rules.set(sr.function, {
|
|
76
|
+
pre_states: sr.pre_states,
|
|
77
|
+
post_states: sr.post_states,
|
|
78
|
+
invalidate: sr.invalidate,
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
// Generate random walks from all rules + synthesized (push to 200+)
|
|
83
|
+
const walks = (0, trajectory_augmentation_1.generateRandomWalks)(rules, 5000, 2, 10, nsInit);
|
|
84
|
+
const normalizedWalks = walks.map(seq => seq.map(function_synonyms_1.normalizeFunctionName));
|
|
85
|
+
// Generate mutations at scale
|
|
86
|
+
const seedForMutations = [...normalized, ...normalizedWalks];
|
|
87
|
+
const mutations = (0, trajectory_augmentation_1.mutateTrajectories)(seedForMutations.slice(0, 800), rules, 3000);
|
|
88
|
+
const normalizedMutations = mutations.map(seq => seq.map(function_synonyms_1.normalizeFunctionName));
|
|
89
|
+
// Combine all
|
|
90
|
+
const allSequences = [...normalized, ...normalizedWalks, ...normalizedMutations];
|
|
91
|
+
// Validate: only keep valid physics sequences
|
|
92
|
+
let valid = allSequences.filter(seq => (0, software_physics_1.isValidPhysicsSequence)(seq).valid);
|
|
93
|
+
// Deduplicate
|
|
94
|
+
const seen = new Set();
|
|
95
|
+
const unique = [];
|
|
96
|
+
for (const seq of valid) {
|
|
97
|
+
const key = seq.join("→");
|
|
98
|
+
if (!seen.has(key) && seq.length >= 2) {
|
|
99
|
+
seen.add(key);
|
|
100
|
+
unique.push(seq);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
return {
|
|
104
|
+
sequences: unique,
|
|
105
|
+
report: {
|
|
106
|
+
sourceRepos: protocol_mining_1.MINING_SIGNATURES.length + trajectory_corpus_1.EXPANDED_TRAJECTORIES.length,
|
|
107
|
+
sourceSequences: sourceCount,
|
|
108
|
+
randomWalks: walks.length,
|
|
109
|
+
mutations: mutations.length,
|
|
110
|
+
totalCollected: allSequences.length,
|
|
111
|
+
validSequences: valid.length,
|
|
112
|
+
duplicateRemoved: valid.length - unique.length,
|
|
113
|
+
finalCorpusSize: unique.length,
|
|
114
|
+
},
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
function printCollectionReport(report) {
|
|
118
|
+
console.log("\n─── Scale Trajectory Collection Report ───");
|
|
119
|
+
console.log(` Source Repos: ${report.sourceRepos}`);
|
|
120
|
+
console.log(` Source Sequences: ${report.sourceSequences}`);
|
|
121
|
+
console.log(` Random Walks: ${report.randomWalks}`);
|
|
122
|
+
console.log(` Mutations: ${report.mutations}`);
|
|
123
|
+
console.log(` Total Collected: ${report.totalCollected}`);
|
|
124
|
+
console.log(` Valid Sequences: ${report.validSequences}`);
|
|
125
|
+
console.log(` Duplicates Removed: ${report.duplicateRemoved}`);
|
|
126
|
+
console.log(` Final Corpus Size: ${report.finalCorpusSize}`);
|
|
127
|
+
console.log();
|
|
128
|
+
}
|
package/dist/sdk.js
ADDED
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Progmune SDK — Simple one-call API for AI Code Governance
|
|
4
|
+
*
|
|
5
|
+
* Usage:
|
|
6
|
+
* import { verify } from "@progmune/sdk"
|
|
7
|
+
* const result = await verify("./src/server.ts")
|
|
8
|
+
*
|
|
9
|
+
* Returns everything a developer needs in one call:
|
|
10
|
+
* certificate, knowledge version, stable protocols, risk level
|
|
11
|
+
*/
|
|
12
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
+
exports.RUNTIME_VERSION = void 0;
|
|
14
|
+
exports.verify = verify;
|
|
15
|
+
exports.fix = fix;
|
|
16
|
+
exports.explain = explain;
|
|
17
|
+
exports.getCompatibility = getCompatibility;
|
|
18
|
+
const certify_1 = require("./certify");
|
|
19
|
+
const risk_model_1 = require("./risk-model");
|
|
20
|
+
const protocol_knowledge_1 = require("./protocol-knowledge");
|
|
21
|
+
const evidence_repository_1 = require("./evidence-repository");
|
|
22
|
+
/** Runtime version — stable public identifier. Internal layers evolve underneath. */
|
|
23
|
+
exports.RUNTIME_VERSION = "1.0.0";
|
|
24
|
+
function verify(filePath) {
|
|
25
|
+
const cert = (0, certify_1.certify)(filePath);
|
|
26
|
+
const kb = (0, protocol_knowledge_1.buildKnowledgeBase)();
|
|
27
|
+
const er = (0, evidence_repository_1.buildEvidenceRepository)();
|
|
28
|
+
const risk = (0, risk_model_1.assessRisk)(["SSL_CTX_new", "SSL_connect"]);
|
|
29
|
+
// Decision: Risk → Policy → Decision
|
|
30
|
+
let decision;
|
|
31
|
+
if (risk.riskLevel === "Critical")
|
|
32
|
+
decision = "BLOCK";
|
|
33
|
+
else if (risk.riskLevel === "High")
|
|
34
|
+
decision = "WARN";
|
|
35
|
+
else
|
|
36
|
+
decision = "ALLOW";
|
|
37
|
+
// Knowledge Network context
|
|
38
|
+
let network;
|
|
39
|
+
try {
|
|
40
|
+
const { buildKnowledgeGraph, getDependencies, getDependents } = require("./knowledge-graph");
|
|
41
|
+
const g = buildKnowledgeGraph();
|
|
42
|
+
const related = [...new Set([
|
|
43
|
+
...getDependencies(g, "PROTO-TLS").map((n) => n.name),
|
|
44
|
+
...getDependents(g, "PROTO-TLS").map((n) => n.name),
|
|
45
|
+
])];
|
|
46
|
+
network = { totalNodes: g.nodes.length, totalEdges: g.edges.length, relatedProtocols: related };
|
|
47
|
+
}
|
|
48
|
+
catch { /* graph unavailable */ }
|
|
49
|
+
return {
|
|
50
|
+
runtimeVersion: exports.RUNTIME_VERSION,
|
|
51
|
+
decision,
|
|
52
|
+
certificate: cert,
|
|
53
|
+
knowledge: {
|
|
54
|
+
version: kb.version,
|
|
55
|
+
stableProtocols: kb.summary.byMaturity["stable"],
|
|
56
|
+
totalProtocols: kb.summary.totalUnits,
|
|
57
|
+
averageConfidence: kb.summary.averageConfidence,
|
|
58
|
+
},
|
|
59
|
+
evidence: {
|
|
60
|
+
totalRepos: er.summary.totalRepos,
|
|
61
|
+
totalSequences: er.summary.totalSequences,
|
|
62
|
+
topProtocols: er.summary.topProtocols.slice(0, 3).map(t => t.protocol),
|
|
63
|
+
},
|
|
64
|
+
risk: {
|
|
65
|
+
level: risk.riskLevel,
|
|
66
|
+
recommendation: risk.recommendation,
|
|
67
|
+
patterns: risk.patterns.map(p => ({
|
|
68
|
+
name: p.patternName, severity: p.severity, confidence: p.confidence,
|
|
69
|
+
concept: p.concept, detail: p.detail,
|
|
70
|
+
})),
|
|
71
|
+
},
|
|
72
|
+
network,
|
|
73
|
+
timestamp: new Date().toISOString(),
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Analyze a project and return actionable fix suggestions.
|
|
78
|
+
*
|
|
79
|
+
* Uses the Trust Engine (SSG state machine + Express/NestJS framework
|
|
80
|
+
* detectors) to find protocol violations, then extracts concrete
|
|
81
|
+
* repair steps — BFS-computed fix paths, middleware additions,
|
|
82
|
+
* decorator insertions, etc.
|
|
83
|
+
*
|
|
84
|
+
* Usage:
|
|
85
|
+
* const result = await fix("./my-project")
|
|
86
|
+
* if (result.possible) {
|
|
87
|
+
* for (const s of result.suggestions) {
|
|
88
|
+
* console.log(s.file, s.fix)
|
|
89
|
+
* }
|
|
90
|
+
* }
|
|
91
|
+
*/
|
|
92
|
+
async function fix(projectPath) {
|
|
93
|
+
try {
|
|
94
|
+
// Lazy-require trust engine to avoid circular deps at module load
|
|
95
|
+
const { evaluateTrust } = require("./trust/engine");
|
|
96
|
+
const decision = await evaluateTrust({
|
|
97
|
+
projectPath,
|
|
98
|
+
projectName: projectPath.split("/").pop() || "unknown",
|
|
99
|
+
commit: "working-tree",
|
|
100
|
+
language: "typescript",
|
|
101
|
+
});
|
|
102
|
+
const suggestions = [];
|
|
103
|
+
const seen = new Set(); // deduplicate by file + ruleId
|
|
104
|
+
for (const v of decision.violations) {
|
|
105
|
+
if (!v.fix)
|
|
106
|
+
continue;
|
|
107
|
+
// Deduplicate: same file + same rule → report once
|
|
108
|
+
const dedupKey = `${v.file}::${v.rule_id}`;
|
|
109
|
+
if (seen.has(dedupKey))
|
|
110
|
+
continue;
|
|
111
|
+
seen.add(dedupKey);
|
|
112
|
+
const source = v.rule_id.startsWith("SSG_") ? "ssg" :
|
|
113
|
+
v.policy_ref === "framework.express" ? "express" :
|
|
114
|
+
v.policy_ref === "framework.nestjs" ? "nestjs" :
|
|
115
|
+
v.policy_ref?.startsWith("protocol") ? "protocol" : "policy";
|
|
116
|
+
// Extract BFS fix path from SSG violations
|
|
117
|
+
let fixPath;
|
|
118
|
+
if (source === "ssg") {
|
|
119
|
+
const match = v.fix.match(/Insert before the violating call:\s*(.+)/);
|
|
120
|
+
if (match) {
|
|
121
|
+
fixPath = match[1].split(" → ").map((s) => s.trim()).filter(Boolean);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
suggestions.push({
|
|
125
|
+
file: v.file || projectPath,
|
|
126
|
+
severity: v.severity,
|
|
127
|
+
ruleId: v.rule_id,
|
|
128
|
+
message: v.message,
|
|
129
|
+
fix: v.fix,
|
|
130
|
+
fixPath: fixPath?.length ? fixPath : undefined,
|
|
131
|
+
source,
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
// Sort: critical first, then by file
|
|
135
|
+
suggestions.sort((a, b) => {
|
|
136
|
+
const sev = { critical: 0, high: 1, medium: 2, low: 3 };
|
|
137
|
+
const sa = sev[a.severity] ?? 4;
|
|
138
|
+
const sb = sev[b.severity] ?? 4;
|
|
139
|
+
if (sa !== sb)
|
|
140
|
+
return sa - sb;
|
|
141
|
+
return a.file.localeCompare(b.file);
|
|
142
|
+
});
|
|
143
|
+
return {
|
|
144
|
+
possible: suggestions.length > 0,
|
|
145
|
+
totalIssues: decision.violations.length,
|
|
146
|
+
fixableIssues: suggestions.length,
|
|
147
|
+
suggestions,
|
|
148
|
+
summary: suggestions.length > 0
|
|
149
|
+
? `Found ${suggestions.length} fixable issue(s) across ${new Set(suggestions.map(s => s.file)).size} file(s).`
|
|
150
|
+
: "No fixable issues found. The project passes all protocol checks.",
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
catch (e) {
|
|
154
|
+
return {
|
|
155
|
+
possible: false,
|
|
156
|
+
totalIssues: 0,
|
|
157
|
+
fixableIssues: 0,
|
|
158
|
+
suggestions: [],
|
|
159
|
+
summary: `Fix analysis failed: ${e.message || "unknown error"}`,
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* explain() — Human-readable governance explanation.
|
|
165
|
+
* Answers: WHY is this risk Critical? WHAT knowledge backs it?
|
|
166
|
+
*/
|
|
167
|
+
function explain(result) {
|
|
168
|
+
const lines = [];
|
|
169
|
+
lines.push("Progmune Governance Explanation");
|
|
170
|
+
lines.push(`Runtime v${result.runtimeVersion} | Decision: ${result.decision}`);
|
|
171
|
+
lines.push("================================\n");
|
|
172
|
+
lines.push(`Risk Level: ${result.risk.level}`);
|
|
173
|
+
lines.push(`Recommendation: ${result.risk.recommendation}\n`);
|
|
174
|
+
if (result.risk.patterns.length > 0) {
|
|
175
|
+
lines.push("Risk Patterns Detected:");
|
|
176
|
+
for (const p of result.risk.patterns) {
|
|
177
|
+
lines.push(` - ${p.name} (${p.severity}, ${p.confidence}% confidence)`);
|
|
178
|
+
if (p.concept)
|
|
179
|
+
lines.push(` Missing concept: ${p.concept}`);
|
|
180
|
+
lines.push(` ${p.detail}`);
|
|
181
|
+
}
|
|
182
|
+
lines.push("");
|
|
183
|
+
}
|
|
184
|
+
else {
|
|
185
|
+
lines.push("No risk patterns detected. Code appears protocol-compliant.\n");
|
|
186
|
+
}
|
|
187
|
+
lines.push("Knowledge Backing:");
|
|
188
|
+
lines.push(` Protocol Knowledge Base v${result.knowledge.version}`);
|
|
189
|
+
lines.push(` ${result.knowledge.stableProtocols} stable protocol domains with ${result.knowledge.averageConfidence}% avg confidence`);
|
|
190
|
+
lines.push(` Evidence from ${result.evidence.totalRepos} repositories (${result.evidence.totalSequences} validated sequences)`);
|
|
191
|
+
lines.push(` Top protocols: ${result.evidence.topProtocols.join(", ")}`);
|
|
192
|
+
if (result.certificate.kbAssets?.length) {
|
|
193
|
+
lines.push("\nVerified Against:");
|
|
194
|
+
for (const a of result.certificate.kbAssets) {
|
|
195
|
+
const rfc = a.rfc ? ` (${a.rfc})` : "";
|
|
196
|
+
lines.push(` ${a.name} v${a.version} — ${a.confidence}% confidence${rfc}`);
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
if (result.network && result.network.relatedProtocols.length > 0) {
|
|
200
|
+
lines.push(`\nProtocol Network Context:`);
|
|
201
|
+
lines.push(` ${result.network.totalNodes} nodes, ${result.network.totalEdges} edges in Knowledge Graph`);
|
|
202
|
+
lines.push(` Related: ${result.network.relatedProtocols.join(" · ")}`);
|
|
203
|
+
}
|
|
204
|
+
return lines.join("\n");
|
|
205
|
+
}
|
|
206
|
+
function getCompatibility() {
|
|
207
|
+
const kb = (0, protocol_knowledge_1.buildKnowledgeBase)();
|
|
208
|
+
return {
|
|
209
|
+
sdkVersion: "1.0.0",
|
|
210
|
+
knowledgeVersion: kb.version,
|
|
211
|
+
protocols: kb.units.filter((u) => u.maturity === "stable").map((u) => u.name),
|
|
212
|
+
compatibleWith: [
|
|
213
|
+
{ component: "Policy Engine", version: "2.0.0", compatible: true, notes: "All 8 rules operational" },
|
|
214
|
+
{ component: "Certificate", version: "2.0.0", compatible: true, notes: "Ontology-backed certificates" },
|
|
215
|
+
{ component: "GitHub Action", version: "1.0.0", compatible: true, notes: "CI deploy gate active" },
|
|
216
|
+
{ component: "Knowledge API", version: "1.0.0", compatible: true, notes: "All endpoints operational" },
|
|
217
|
+
{ component: "Dashboard", version: "1.0.0", compatible: true, notes: "Governance KPIs active" },
|
|
218
|
+
{ component: "Verification API", version: "1.0.0", compatible: true, notes: "External verification active" },
|
|
219
|
+
],
|
|
220
|
+
};
|
|
221
|
+
}
|
|
222
|
+
// ═══════════════════════════════════════════════════════════════
|
|
223
|
+
// CLI
|
|
224
|
+
// ═══════════════════════════════════════════════════════════════
|
|
225
|
+
if (require.main === module) {
|
|
226
|
+
const args = process.argv.slice(2);
|
|
227
|
+
if (args[0] === "compat") {
|
|
228
|
+
console.log(JSON.stringify(getCompatibility(), null, 2));
|
|
229
|
+
}
|
|
230
|
+
else if (args[0] === "explain" && args[1]) {
|
|
231
|
+
const result = verify(args[1]);
|
|
232
|
+
console.log(explain(result));
|
|
233
|
+
}
|
|
234
|
+
else {
|
|
235
|
+
const filePath = args[0] || ".";
|
|
236
|
+
try {
|
|
237
|
+
const result = verify(filePath);
|
|
238
|
+
if (args.includes("--explain")) {
|
|
239
|
+
console.log(explain(result));
|
|
240
|
+
}
|
|
241
|
+
else {
|
|
242
|
+
console.log(JSON.stringify(result, null, 2));
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
catch (e) {
|
|
246
|
+
console.error(JSON.stringify({ error: e.message }));
|
|
247
|
+
process.exit(1);
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
}
|
package/dist/search-planner.js
CHANGED
|
@@ -1,54 +1,17 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
-
var ownKeys = function(o) {
|
|
20
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
-
var ar = [];
|
|
22
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
-
return ar;
|
|
24
|
-
};
|
|
25
|
-
return ownKeys(o);
|
|
26
|
-
};
|
|
27
|
-
return function (mod) {
|
|
28
|
-
if (mod && mod.__esModule) return mod;
|
|
29
|
-
var result = {};
|
|
30
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
-
__setModuleDefault(result, mod);
|
|
32
|
-
return result;
|
|
33
|
-
};
|
|
34
|
-
})();
|
|
35
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
3
|
exports.searchPlan = searchPlan;
|
|
37
4
|
const validator_1 = require("./validator");
|
|
38
5
|
const llm_1 = require("./llm");
|
|
39
6
|
const feedback_1 = require("./feedback");
|
|
40
7
|
const utils_1 = require("./utils");
|
|
41
|
-
const
|
|
8
|
+
const ir_utils_1 = require("./ir-utils");
|
|
42
9
|
// ⚖️ 可调权重(修改这些值后重新运行压力测试即可)
|
|
43
10
|
const WEIGHT_STATIC_SCORE = 0.3; // 静态文本相似度的权重
|
|
44
11
|
const WEIGHT_LLM_SCORE = 0.7; // LLM 评分的权重
|
|
45
12
|
const WEIGHT_HISTORY = 0.4; // 反馈系统成功率的权重
|
|
46
13
|
const WEIGHT_GOAL_COMPLETION = 0.5; // 目标完成奖励
|
|
47
14
|
const STATIC_HIGH_THRESHOLD = 0.6; // 静态评分超过此值时,跳过LLM调用
|
|
48
|
-
function loadIR() {
|
|
49
|
-
const raw = JSON.parse(fs.readFileSync("ir.json", "utf-8"));
|
|
50
|
-
return Array.isArray(raw) ? raw : (raw.functions || []);
|
|
51
|
-
}
|
|
52
15
|
const staticScoreCache = new Map();
|
|
53
16
|
function getStaticScore(funcName, goal) {
|
|
54
17
|
const key = `${funcName}|${goal}`;
|
|
@@ -90,7 +53,7 @@ async function decomposeGoals(intent, functions) {
|
|
|
90
53
|
return result.slice(0, 3);
|
|
91
54
|
}
|
|
92
55
|
}
|
|
93
|
-
catch { }
|
|
56
|
+
catch { /* LLM score fallback */ }
|
|
94
57
|
return [intent];
|
|
95
58
|
}
|
|
96
59
|
/** 批量评分:将同一 goal 的所有候选函数打包为一次 LLM 调用 */
|
|
@@ -120,7 +83,7 @@ async function batchScoreFuncs(funcs, goal) {
|
|
|
120
83
|
}
|
|
121
84
|
}
|
|
122
85
|
}
|
|
123
|
-
catch { }
|
|
86
|
+
catch { /* LLM score fallback */ }
|
|
124
87
|
for (const f of needsLLM) {
|
|
125
88
|
if (!result.has(f.name))
|
|
126
89
|
result.set(f.name, 0.3);
|
|
@@ -131,7 +94,7 @@ async function batchScoreFuncs(funcs, goal) {
|
|
|
131
94
|
async function searchPlan(intent, beamWidth = 2, maxDepth = 6) {
|
|
132
95
|
(0, llm_1.resetCallCount)();
|
|
133
96
|
staticScoreCache.clear();
|
|
134
|
-
const ir = loadIR();
|
|
97
|
+
const ir = (0, ir_utils_1.loadIR)();
|
|
135
98
|
const goals = await decomposeGoals(intent, ir);
|
|
136
99
|
console.log("🎯 目标栈:", goals);
|
|
137
100
|
let beam = [{
|
|
@@ -96,7 +96,7 @@ function listSnapshots() {
|
|
|
96
96
|
try {
|
|
97
97
|
snapshots.push(JSON.parse(fs.readFileSync(path.join(SNAPSHOT_DIR, file), "utf-8")));
|
|
98
98
|
}
|
|
99
|
-
catch { }
|
|
99
|
+
catch { /* snapshot may be unavailable */ }
|
|
100
100
|
}
|
|
101
101
|
}
|
|
102
102
|
snapshots.sort((a, b) => b.timestamp.localeCompare(a.timestamp));
|
|
@@ -10,6 +10,39 @@
|
|
|
10
10
|
*
|
|
11
11
|
* Replaces simple string matching in capability search.
|
|
12
12
|
*/
|
|
13
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
14
|
+
if (k2 === undefined) k2 = k;
|
|
15
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
16
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
17
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
18
|
+
}
|
|
19
|
+
Object.defineProperty(o, k2, desc);
|
|
20
|
+
}) : (function(o, m, k, k2) {
|
|
21
|
+
if (k2 === undefined) k2 = k;
|
|
22
|
+
o[k2] = m[k];
|
|
23
|
+
}));
|
|
24
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
25
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
26
|
+
}) : function(o, v) {
|
|
27
|
+
o["default"] = v;
|
|
28
|
+
});
|
|
29
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
30
|
+
var ownKeys = function(o) {
|
|
31
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
32
|
+
var ar = [];
|
|
33
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
34
|
+
return ar;
|
|
35
|
+
};
|
|
36
|
+
return ownKeys(o);
|
|
37
|
+
};
|
|
38
|
+
return function (mod) {
|
|
39
|
+
if (mod && mod.__esModule) return mod;
|
|
40
|
+
var result = {};
|
|
41
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
42
|
+
__setModuleDefault(result, mod);
|
|
43
|
+
return result;
|
|
44
|
+
};
|
|
45
|
+
})();
|
|
13
46
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
47
|
exports.SemanticTopology = void 0;
|
|
15
48
|
exports.getTopology = getTopology;
|
|
@@ -144,17 +177,105 @@ class SemanticTopology {
|
|
|
144
177
|
get size() { return this.nodes.size; }
|
|
145
178
|
}
|
|
146
179
|
exports.SemanticTopology = SemanticTopology;
|
|
180
|
+
// ── Persistence cache: avoid O(n²) rebuild on every run ──
|
|
181
|
+
const crypto = __importStar(require("crypto"));
|
|
182
|
+
const fs = __importStar(require("fs"));
|
|
183
|
+
const path = __importStar(require("path"));
|
|
184
|
+
const CACHE_DIR = path.resolve(__dirname, "..", ".progmune");
|
|
185
|
+
const TOPO_CACHE = path.join(CACHE_DIR, "topology.json");
|
|
186
|
+
function irHash(ir) {
|
|
187
|
+
// Include protocol + capability metadata in hash — if annotations change,
|
|
188
|
+
// the cached topology must be invalidated even if function names stay same.
|
|
189
|
+
return crypto.createHash("md5")
|
|
190
|
+
.update(JSON.stringify(ir.map((f) => ({
|
|
191
|
+
name: f.name,
|
|
192
|
+
file: f.file,
|
|
193
|
+
protocol: f.protocol,
|
|
194
|
+
purpose: f.purpose,
|
|
195
|
+
requires: f.requires,
|
|
196
|
+
produces: f.produces,
|
|
197
|
+
}))))
|
|
198
|
+
.digest("hex");
|
|
199
|
+
}
|
|
200
|
+
function serializeTopology(topo, hash) {
|
|
201
|
+
try {
|
|
202
|
+
if (!fs.existsSync(CACHE_DIR))
|
|
203
|
+
fs.mkdirSync(CACHE_DIR, { recursive: true });
|
|
204
|
+
const data = {
|
|
205
|
+
hash,
|
|
206
|
+
nodes: [...topo["nodes"].entries()].map(([name, n]) => ({
|
|
207
|
+
name, file: n.file, tags: [...n.tags], purposeWords: [...n.purposeWords],
|
|
208
|
+
produces: [...n.produces], requires: [...n.requires],
|
|
209
|
+
})),
|
|
210
|
+
edges: [...topo["edges"].entries()].map(([name, edges]) => ({
|
|
211
|
+
name, edges: edges.map((e) => ({ source: e.source, target: e.target, weight: e.weight, reason: e.reason })),
|
|
212
|
+
})),
|
|
213
|
+
};
|
|
214
|
+
fs.writeFileSync(TOPO_CACHE, JSON.stringify(data));
|
|
215
|
+
}
|
|
216
|
+
catch { /* best-effort cache write */ }
|
|
217
|
+
}
|
|
218
|
+
function deserializeTopology() {
|
|
219
|
+
try {
|
|
220
|
+
if (!fs.existsSync(TOPO_CACHE))
|
|
221
|
+
return null;
|
|
222
|
+
const data = JSON.parse(fs.readFileSync(TOPO_CACHE, "utf-8"));
|
|
223
|
+
const topo = new SemanticTopology();
|
|
224
|
+
for (const n of data.nodes) {
|
|
225
|
+
topo["nodes"].set(n.name, {
|
|
226
|
+
name: n.name, file: n.file,
|
|
227
|
+
tags: new Set(n.tags), purposeWords: new Set(n.purposeWords),
|
|
228
|
+
produces: new Set(n.produces), requires: new Set(n.requires),
|
|
229
|
+
});
|
|
230
|
+
}
|
|
231
|
+
for (const e of data.edges) {
|
|
232
|
+
topo["edges"].set(e.name, e.edges);
|
|
233
|
+
for (const edge of e.edges) {
|
|
234
|
+
const key = edge.source < edge.target ? `${edge.source}::${edge.target}` : `${edge.target}::${edge.source}`;
|
|
235
|
+
topo["similarityCache"].set(key, Math.max(topo["similarityCache"].get(key) || 0, edge.weight));
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
return topo;
|
|
239
|
+
}
|
|
240
|
+
catch {
|
|
241
|
+
return null;
|
|
242
|
+
}
|
|
243
|
+
}
|
|
147
244
|
// Singleton
|
|
148
245
|
let _topology = null;
|
|
246
|
+
let _topoHash = null;
|
|
149
247
|
function getTopology(ir) {
|
|
150
248
|
if (!_topology && ir) {
|
|
249
|
+
const hash = irHash(ir);
|
|
250
|
+
// Try disk cache first
|
|
251
|
+
try {
|
|
252
|
+
if (fs.existsSync(TOPO_CACHE)) {
|
|
253
|
+
const cached = JSON.parse(fs.readFileSync(TOPO_CACHE, "utf-8"));
|
|
254
|
+
if (cached.hash === hash) {
|
|
255
|
+
_topology = deserializeTopology();
|
|
256
|
+
if (_topology) {
|
|
257
|
+
_topoHash = hash;
|
|
258
|
+
console.error("[Topology] 从缓存加载 (%d 节点)", _topology.size);
|
|
259
|
+
return _topology;
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
catch { /* fall through to build */ }
|
|
265
|
+
// Build from scratch
|
|
266
|
+
const start = Date.now();
|
|
151
267
|
_topology = new SemanticTopology();
|
|
152
268
|
_topology.build(ir);
|
|
269
|
+
_topoHash = hash;
|
|
270
|
+
console.error("[Topology] 构建完成 (%d 节点, %dms)", _topology.size, Date.now() - start);
|
|
271
|
+
serializeTopology(_topology, hash);
|
|
153
272
|
}
|
|
154
273
|
return _topology || new SemanticTopology();
|
|
155
274
|
}
|
|
156
275
|
function rebuildTopology(ir) {
|
|
157
276
|
_topology = new SemanticTopology();
|
|
158
277
|
_topology.build(ir);
|
|
278
|
+
_topoHash = irHash(ir);
|
|
279
|
+
serializeTopology(_topology, _topoHash);
|
|
159
280
|
return _topology;
|
|
160
281
|
}
|