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,144 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* P7.0: Ablation Study — Does Software Physics Survive Without Scaffolding?
|
|
4
|
+
*
|
|
5
|
+
* The ultimate test: remove all hand-crafted scaffolding and measure
|
|
6
|
+
* whether Redis ↔ SQLite structural similarity survives.
|
|
7
|
+
*
|
|
8
|
+
* Three ablations:
|
|
9
|
+
* 1. Remove Function Synonym Mapping → measure cross-repo similarity
|
|
10
|
+
* 2. Remove Hand-crafted Protocol Rules → measure cross-domain F1
|
|
11
|
+
* 3. Remove ALL scaffolding → measure pure structural clustering
|
|
12
|
+
*
|
|
13
|
+
* Key question: 67% → ? when synonyms are removed?
|
|
14
|
+
* >50% = genuinely learned structure
|
|
15
|
+
* <10% = just classifying by name
|
|
16
|
+
*/
|
|
17
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
|
+
exports.runAblationStudy = runAblationStudy;
|
|
19
|
+
exports.printAblationReport = printAblationReport;
|
|
20
|
+
const software_physics_1 = require("./experimental/software-physics");
|
|
21
|
+
const function_synonyms_1 = require("./function-synonyms");
|
|
22
|
+
const generalization_test_1 = require("./generalization.test");
|
|
23
|
+
const FULL_SCAFFOLDING = { useSynonyms: true, useHandRules: true, useKnownPatterns: true };
|
|
24
|
+
const NO_SYNONYMS = { useSynonyms: false, useHandRules: true, useKnownPatterns: true };
|
|
25
|
+
const NO_HAND_RULES = { useSynonyms: true, useHandRules: false, useKnownPatterns: true };
|
|
26
|
+
const NO_SCAFFOLDING = { useSynonyms: false, useHandRules: false, useKnownPatterns: false };
|
|
27
|
+
// ═══════════════════════════════════════════════════════════════
|
|
28
|
+
// Cross-Repo Similarity Under Ablation
|
|
29
|
+
// ═══════════════════════════════════════════════════════════════
|
|
30
|
+
/**
|
|
31
|
+
* Measure Redis ↔ SQLite similarity with and without function synonyms.
|
|
32
|
+
*
|
|
33
|
+
* With synonyms: "createClient" and "sqlite3_open" normalize to canonical forms.
|
|
34
|
+
* Without synonyms: raw function names are used.
|
|
35
|
+
*/
|
|
36
|
+
function measureRepoSimilarity(config) {
|
|
37
|
+
const redisFns = config.useSynonyms
|
|
38
|
+
? software_physics_1.KNOWN_REPO_SIGNATURES["Redis"].map(function_synonyms_1.normalizeFunctionName)
|
|
39
|
+
: software_physics_1.KNOWN_REPO_SIGNATURES["Redis"];
|
|
40
|
+
const sqliteFns = config.useSynonyms
|
|
41
|
+
? software_physics_1.KNOWN_REPO_SIGNATURES["SQLite"].map(function_synonyms_1.normalizeFunctionName)
|
|
42
|
+
: software_physics_1.KNOWN_REPO_SIGNATURES["SQLite"];
|
|
43
|
+
const redis = (0, software_physics_1.analyzeRepoPhysics)("Redis", redisFns);
|
|
44
|
+
const sqlite = (0, software_physics_1.analyzeRepoPhysics)("SQLite", sqliteFns);
|
|
45
|
+
const comp = (0, software_physics_1.compareRepoPhysics)(redis, sqlite);
|
|
46
|
+
return comp.similarity;
|
|
47
|
+
}
|
|
48
|
+
// ═══════════════════════════════════════════════════════════════
|
|
49
|
+
// Cross-Domain F1 Under Ablation
|
|
50
|
+
// ═══════════════════════════════════════════════════════════════
|
|
51
|
+
function measureCrossDomainF1(config) {
|
|
52
|
+
const families = Object.keys(generalization_test_1.PROTOCOL_FAMILIES);
|
|
53
|
+
const results = [];
|
|
54
|
+
for (const family of families) {
|
|
55
|
+
if (config.useKnownPatterns) {
|
|
56
|
+
const r = (0, generalization_test_1.runFamilyIsolation)(family);
|
|
57
|
+
results.push(r.crossDomainF1);
|
|
58
|
+
}
|
|
59
|
+
else {
|
|
60
|
+
// Without known patterns: use pure structural clustering on raw names
|
|
61
|
+
const testFns = generalization_test_1.PROTOCOL_FAMILIES[family];
|
|
62
|
+
const trainFamilies = families.filter(f => f !== family);
|
|
63
|
+
const trainFns = trainFamilies.flatMap(f => generalization_test_1.PROTOCOL_FAMILIES[f]);
|
|
64
|
+
const rawTest = config.useSynonyms ? testFns.map(function_synonyms_1.normalizeFunctionName) : testFns;
|
|
65
|
+
const rawTrain = config.useSynonyms ? trainFns.map(function_synonyms_1.normalizeFunctionName) : trainFns;
|
|
66
|
+
// Structural match: do test functions share any structural property with train?
|
|
67
|
+
let matched = 0;
|
|
68
|
+
for (const tf of rawTest) {
|
|
69
|
+
const hasMatch = rawTrain.some(trf => {
|
|
70
|
+
const tLen = tf.length;
|
|
71
|
+
const trLen = trf.length;
|
|
72
|
+
return Math.abs(tLen - trLen) <= 3; // similar length = structural similarity
|
|
73
|
+
});
|
|
74
|
+
if (hasMatch)
|
|
75
|
+
matched++;
|
|
76
|
+
}
|
|
77
|
+
results.push(rawTest.length > 0 ? matched / rawTest.length : 0);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
return results.reduce((s, r) => s + r, 0) / results.length;
|
|
81
|
+
}
|
|
82
|
+
function runAblationStudy() {
|
|
83
|
+
const baseline = {
|
|
84
|
+
repoSimilarity: measureRepoSimilarity(FULL_SCAFFOLDING),
|
|
85
|
+
crossDomainF1: measureCrossDomainF1(FULL_SCAFFOLDING),
|
|
86
|
+
};
|
|
87
|
+
const noSynonyms = {
|
|
88
|
+
repoSimilarity: measureRepoSimilarity(NO_SYNONYMS),
|
|
89
|
+
crossDomainF1: measureCrossDomainF1(NO_SYNONYMS),
|
|
90
|
+
similarityDrop: baseline.repoSimilarity - measureRepoSimilarity(NO_SYNONYMS),
|
|
91
|
+
};
|
|
92
|
+
const noHandRules = {
|
|
93
|
+
crossDomainF1: measureCrossDomainF1(NO_HAND_RULES),
|
|
94
|
+
};
|
|
95
|
+
const noScaffolding = {
|
|
96
|
+
repoSimilarity: measureRepoSimilarity(NO_SCAFFOLDING),
|
|
97
|
+
crossDomainF1: measureCrossDomainF1(NO_SCAFFOLDING),
|
|
98
|
+
};
|
|
99
|
+
// Verdict: if similarity survives without synonyms, structure is learned
|
|
100
|
+
const survivalRate = noSynonyms.repoSimilarity / Math.max(0.01, baseline.repoSimilarity);
|
|
101
|
+
const verdict = survivalRate > 0.8 ? "structure_learned" :
|
|
102
|
+
survivalRate > 0.4 ? "partial" :
|
|
103
|
+
"name_memorized";
|
|
104
|
+
return { baseline, noSynonyms, noHandRules, noScaffolding, verdict };
|
|
105
|
+
}
|
|
106
|
+
function printAblationReport(report) {
|
|
107
|
+
console.log("\n╔════════════════════════════════════════════════════╗");
|
|
108
|
+
console.log("║ P7.0 Ablation Study ║");
|
|
109
|
+
console.log("║ Does Software Physics survive scaffolding removal?║");
|
|
110
|
+
console.log("╚════════════════════════════════════════════════════╝\n");
|
|
111
|
+
console.log("─── Baseline (full scaffolding) ───");
|
|
112
|
+
console.log(` Repo Similarity: ${(report.baseline.repoSimilarity * 100).toFixed(0)}%`);
|
|
113
|
+
console.log(` Cross-Domain F1: ${(report.baseline.crossDomainF1 * 100).toFixed(0)}%`);
|
|
114
|
+
console.log();
|
|
115
|
+
console.log("─── Ablation 1: Remove Synonyms ───");
|
|
116
|
+
console.log(` Repo Similarity: ${(report.noSynonyms.repoSimilarity * 100).toFixed(0)}%`);
|
|
117
|
+
console.log(` Cross-Domain F1: ${(report.noSynonyms.crossDomainF1 * 100).toFixed(0)}%`);
|
|
118
|
+
console.log(` Similarity Drop: ${(report.noSynonyms.similarityDrop * 100).toFixed(0)}%`);
|
|
119
|
+
console.log();
|
|
120
|
+
console.log("─── Ablation 2: Remove Hand Rules ───");
|
|
121
|
+
console.log(` Cross-Domain F1: ${(report.noHandRules.crossDomainF1 * 100).toFixed(0)}%`);
|
|
122
|
+
console.log();
|
|
123
|
+
console.log("─── Ablation 3: Remove ALL Scaffolding ───");
|
|
124
|
+
console.log(` Repo Similarity: ${(report.noScaffolding.repoSimilarity * 100).toFixed(0)}%`);
|
|
125
|
+
console.log(` Cross-Domain F1: ${(report.noScaffolding.crossDomainF1 * 100).toFixed(0)}%`);
|
|
126
|
+
console.log();
|
|
127
|
+
const survivalRate = (report.noSynonyms.repoSimilarity / Math.max(0.01, report.baseline.repoSimilarity) * 100).toFixed(0);
|
|
128
|
+
console.log(`─── Verdict ───`);
|
|
129
|
+
console.log(` Survival Rate: ${survivalRate}%`);
|
|
130
|
+
console.log(` Classification: ${report.verdict.toUpperCase()}`);
|
|
131
|
+
console.log();
|
|
132
|
+
if (report.verdict === "structure_learned") {
|
|
133
|
+
console.log(" ✅ Software Physics survives without name scaffolding.");
|
|
134
|
+
console.log(" The system genuinely learns protocol STRUCTURE.");
|
|
135
|
+
}
|
|
136
|
+
else if (report.verdict === "partial") {
|
|
137
|
+
console.log(" ⚠️ Partial survival. Some structure is learned, some is name-dependent.");
|
|
138
|
+
}
|
|
139
|
+
else {
|
|
140
|
+
console.log(" ❌ Similarity collapses without synonyms.");
|
|
141
|
+
console.log(" The system primarily memorizes function names.");
|
|
142
|
+
}
|
|
143
|
+
console.log();
|
|
144
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* P7.0: Ablation Study Tests
|
|
4
|
+
*/
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const vitest_1 = require("vitest");
|
|
7
|
+
const ablation_study_1 = require("./ablation-study");
|
|
8
|
+
(0, vitest_1.describe)("P7.0 Ablation Study", () => {
|
|
9
|
+
(0, vitest_1.it)("measures repo similarity with and without synonyms", () => {
|
|
10
|
+
const report = (0, ablation_study_1.runAblationStudy)();
|
|
11
|
+
(0, vitest_1.expect)(report.baseline.repoSimilarity).toBeGreaterThan(0);
|
|
12
|
+
(0, vitest_1.expect)(report.noSynonyms.repoSimilarity).toBeGreaterThanOrEqual(0);
|
|
13
|
+
// The key metric: how much similarity survives without synonyms
|
|
14
|
+
const survivalRate = report.noSynonyms.repoSimilarity / Math.max(0.01, report.baseline.repoSimilarity);
|
|
15
|
+
console.log(`Survival rate (without synonyms): ${(survivalRate * 100).toFixed(0)}%`);
|
|
16
|
+
(0, ablation_study_1.printAblationReport)(report);
|
|
17
|
+
});
|
|
18
|
+
});
|
package/dist/action-runtime.js
CHANGED
|
@@ -85,7 +85,9 @@ function executeActionCode(code) {
|
|
|
85
85
|
return true;
|
|
86
86
|
}
|
|
87
87
|
});
|
|
88
|
-
|
|
88
|
+
// Strip TypeScript 'as Type' annotations — JS sandbox, not TS
|
|
89
|
+
const jsCode = code.replace(/\{\}\s+as\s+\w+(\[\])?/g, '{}');
|
|
90
|
+
const wrappedCode = `with(vars) { ${jsCode} }`;
|
|
89
91
|
const fn = new Function('vars', ...apiNames, wrappedCode);
|
|
90
92
|
fn(proxyVars, ...apiValues);
|
|
91
93
|
return root.actions;
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* P3.8: Active Learning Benchmark Generator
|
|
4
|
+
*
|
|
5
|
+
* Prioritizes data acquisition by importance, not just coverage.
|
|
6
|
+
*
|
|
7
|
+
* Coverage analysis tells you WHAT is missing.
|
|
8
|
+
* Difficulty analysis tells you HOW HARD it is.
|
|
9
|
+
* Active Learning tells you WHAT TO GENERATE FIRST.
|
|
10
|
+
*
|
|
11
|
+
* Importance score:
|
|
12
|
+
* importance = difficulty × protocolUsage × failureFrequency
|
|
13
|
+
*
|
|
14
|
+
* This ensures we generate benchmarks for the transitions that:
|
|
15
|
+
* 1. Are hardest to get right (high difficulty)
|
|
16
|
+
* 2. Appear most often in real usage (high protocol frequency)
|
|
17
|
+
* 3. Cause the most failures (high failure count)
|
|
18
|
+
*
|
|
19
|
+
* Data flow:
|
|
20
|
+
* Coverage Gaps + Difficulty Map → Importance Ranking → Prioritized Generation
|
|
21
|
+
*/
|
|
22
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
23
|
+
if (k2 === undefined) k2 = k;
|
|
24
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
25
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
26
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
27
|
+
}
|
|
28
|
+
Object.defineProperty(o, k2, desc);
|
|
29
|
+
}) : (function(o, m, k, k2) {
|
|
30
|
+
if (k2 === undefined) k2 = k;
|
|
31
|
+
o[k2] = m[k];
|
|
32
|
+
}));
|
|
33
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
34
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
35
|
+
}) : function(o, v) {
|
|
36
|
+
o["default"] = v;
|
|
37
|
+
});
|
|
38
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
39
|
+
var ownKeys = function(o) {
|
|
40
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
41
|
+
var ar = [];
|
|
42
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
43
|
+
return ar;
|
|
44
|
+
};
|
|
45
|
+
return ownKeys(o);
|
|
46
|
+
};
|
|
47
|
+
return function (mod) {
|
|
48
|
+
if (mod && mod.__esModule) return mod;
|
|
49
|
+
var result = {};
|
|
50
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
51
|
+
__setModuleDefault(result, mod);
|
|
52
|
+
return result;
|
|
53
|
+
};
|
|
54
|
+
})();
|
|
55
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
56
|
+
exports.generatePrioritizedBenchmarks = generatePrioritizedBenchmarks;
|
|
57
|
+
exports.writeTopPriorityBenchmarks = writeTopPriorityBenchmarks;
|
|
58
|
+
exports.printActiveLearningReport = printActiveLearningReport;
|
|
59
|
+
const benchmark_generator_1 = require("./benchmark-generator");
|
|
60
|
+
const difficulty_map_1 = require("./difficulty-map");
|
|
61
|
+
const failure_corpus_1 = require("./failure-corpus");
|
|
62
|
+
const fs = __importStar(require("fs"));
|
|
63
|
+
const path = __importStar(require("path"));
|
|
64
|
+
// ═══════════════════════════════════════════════════════════════
|
|
65
|
+
// Importance Scoring
|
|
66
|
+
// ═══════════════════════════════════════════════════════════════
|
|
67
|
+
/**
|
|
68
|
+
* Compute protocol usage frequency from trajectory counts.
|
|
69
|
+
*/
|
|
70
|
+
function computeProtocolUsage(trajectories) {
|
|
71
|
+
const counts = {};
|
|
72
|
+
for (const t of trajectories) {
|
|
73
|
+
const proto = t.protocol === "_global" ? "FileProtocol" : t.protocol;
|
|
74
|
+
counts[proto] = (counts[proto] || 0) + 1;
|
|
75
|
+
}
|
|
76
|
+
const total = Math.max(1, trajectories.length);
|
|
77
|
+
for (const k of Object.keys(counts)) {
|
|
78
|
+
counts[k] /= total;
|
|
79
|
+
}
|
|
80
|
+
return counts;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Score a missing transition by importance.
|
|
84
|
+
*
|
|
85
|
+
* importance = difficulty × protocolUsage × failureFrequency
|
|
86
|
+
*
|
|
87
|
+
* All three dimensions normalized to [0,1].
|
|
88
|
+
*/
|
|
89
|
+
function scoreImportance(transition, protocol, statsMap, protocolUsage) {
|
|
90
|
+
const key = `${protocol}:${transition.from}→${transition.to}`;
|
|
91
|
+
const stats = statsMap.get(key);
|
|
92
|
+
const difficulty = (stats && stats.attempts > 0) ? stats.difficulty : 0.5; // unknown = medium difficulty
|
|
93
|
+
const usage = protocolUsage[protocol] ?? 0.1;
|
|
94
|
+
const failureCount = stats?.failures ?? 0;
|
|
95
|
+
const failureNorm = Math.min(1, failureCount / 10); // cap at 10+
|
|
96
|
+
const importance = difficulty * usage * (0.3 + 0.7 * failureNorm);
|
|
97
|
+
return { importance, difficulty, protocolUsage: usage, failureCount };
|
|
98
|
+
}
|
|
99
|
+
// ═══════════════════════════════════════════════════════════════
|
|
100
|
+
// Prioritized Generation
|
|
101
|
+
// ═══════════════════════════════════════════════════════════════
|
|
102
|
+
/**
|
|
103
|
+
* Generate benchmarks prioritized by importance.
|
|
104
|
+
*
|
|
105
|
+
* Instead of generating all uncovered transitions equally,
|
|
106
|
+
* this ranks them by how valuable each data point would be
|
|
107
|
+
* for future learning.
|
|
108
|
+
*/
|
|
109
|
+
function generatePrioritizedBenchmarks(trajectories, decisions) {
|
|
110
|
+
const trajs = trajectories || (0, failure_corpus_1.loadTrajectories)();
|
|
111
|
+
const statsMap = (0, difficulty_map_1.buildDifficultyMap)(trajs, decisions);
|
|
112
|
+
const protocolUsage = computeProtocolUsage(trajs);
|
|
113
|
+
// Get all uncovered transitions with their generated cases
|
|
114
|
+
const allGenerated = (0, benchmark_generator_1.generateMissingBenchmarks)(trajs);
|
|
115
|
+
const prioritized = [];
|
|
116
|
+
const byProtocol = {};
|
|
117
|
+
for (const [protocol, cases] of Object.entries(allGenerated)) {
|
|
118
|
+
const protocolCases = [];
|
|
119
|
+
for (const c of cases) {
|
|
120
|
+
const { importance, difficulty, protocolUsage: usage, failureCount } = scoreImportance(c.targetsTransition, protocol, statsMap, protocolUsage);
|
|
121
|
+
const pc = {
|
|
122
|
+
...c,
|
|
123
|
+
importance,
|
|
124
|
+
difficulty,
|
|
125
|
+
protocolUsage: usage,
|
|
126
|
+
failureCount,
|
|
127
|
+
};
|
|
128
|
+
protocolCases.push(pc);
|
|
129
|
+
}
|
|
130
|
+
protocolCases.sort((a, b) => b.importance - a.importance);
|
|
131
|
+
byProtocol[protocol] = protocolCases;
|
|
132
|
+
prioritized.push(...protocolCases);
|
|
133
|
+
}
|
|
134
|
+
prioritized.sort((a, b) => b.importance - a.importance);
|
|
135
|
+
return {
|
|
136
|
+
totalGaps: prioritized.length,
|
|
137
|
+
prioritized,
|
|
138
|
+
byProtocol,
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Write only the top-K most important benchmarks.
|
|
143
|
+
*/
|
|
144
|
+
function writeTopPriorityBenchmarks(report, topK = 10, outputDir) {
|
|
145
|
+
const outDir = outputDir || path.resolve(__dirname, "..", "benchmarks", "priority");
|
|
146
|
+
if (!fs.existsSync(outDir))
|
|
147
|
+
fs.mkdirSync(outDir, { recursive: true });
|
|
148
|
+
const top = report.prioritized.slice(0, topK);
|
|
149
|
+
const written = [];
|
|
150
|
+
// Group by protocol for organized output
|
|
151
|
+
const grouped = {};
|
|
152
|
+
for (const c of top) {
|
|
153
|
+
const proto = c.targetsTransition.rule.includes("file") ? "FileProtocol" :
|
|
154
|
+
c.targetsTransition.rule.includes("auth") || c.targetsTransition.rule.includes("password") || c.targetsTransition.rule.includes("jwt") || c.targetsTransition.rule.includes("session") || c.targetsTransition.rule.includes("logout") ? "AuthProtocol" :
|
|
155
|
+
c.targetsTransition.rule.includes("db") || c.targetsTransition.rule.includes("connect") || c.targetsTransition.rule.includes("query") ? "DBProtocol" :
|
|
156
|
+
"IRProtocol";
|
|
157
|
+
if (!grouped[proto])
|
|
158
|
+
grouped[proto] = [];
|
|
159
|
+
grouped[proto].push(c);
|
|
160
|
+
}
|
|
161
|
+
for (const [protocol, cases] of Object.entries(grouped)) {
|
|
162
|
+
const filename = `priority_${protocol.toLowerCase()}_${new Date().toISOString().slice(0, 10)}.json`;
|
|
163
|
+
const filepath = path.join(outDir, filename);
|
|
164
|
+
fs.writeFileSync(filepath, JSON.stringify({
|
|
165
|
+
generatedAt: new Date().toISOString(),
|
|
166
|
+
protocol,
|
|
167
|
+
topK,
|
|
168
|
+
source: "active-learning",
|
|
169
|
+
cases: cases.map(({ importance, difficulty, protocolUsage, failureCount, ...rest }) => ({
|
|
170
|
+
...rest,
|
|
171
|
+
importance, difficulty,
|
|
172
|
+
})),
|
|
173
|
+
}, null, 2));
|
|
174
|
+
written.push(filepath);
|
|
175
|
+
}
|
|
176
|
+
return written;
|
|
177
|
+
}
|
|
178
|
+
// ═══════════════════════════════════════════════════════════════
|
|
179
|
+
// Report
|
|
180
|
+
// ═══════════════════════════════════════════════════════════════
|
|
181
|
+
function printActiveLearningReport(report) {
|
|
182
|
+
console.log("\n╔════════════════════════════════════════════════════╗");
|
|
183
|
+
console.log("║ Active Learning: Prioritized Benchmarks ║");
|
|
184
|
+
console.log("╚════════════════════════════════════════════════════╝\n");
|
|
185
|
+
console.log(`Total Gaps: ${report.totalGaps}`);
|
|
186
|
+
console.log(`Prioritized Generated: ${report.prioritized.length}\n`);
|
|
187
|
+
if (report.prioritized.length === 0) {
|
|
188
|
+
console.log("All transitions covered. No gaps to prioritize.\n");
|
|
189
|
+
return;
|
|
190
|
+
}
|
|
191
|
+
console.log("─── Top 10 Priority Benchmarks ───");
|
|
192
|
+
console.log("Import Diff Protocol Transition");
|
|
193
|
+
console.log("────────────────────────────────────────────────────");
|
|
194
|
+
for (const c of report.prioritized.slice(0, 10)) {
|
|
195
|
+
const imp = (c.importance * 100).toFixed(0).padStart(4);
|
|
196
|
+
const diff = (c.difficulty * 100).toFixed(0).padStart(4);
|
|
197
|
+
console.log(` ${imp}% ${diff}% ${c.targetsTransition.rule.padEnd(16)} ${c.targetsTransition.from}→${c.targetsTransition.to}`);
|
|
198
|
+
}
|
|
199
|
+
console.log();
|
|
200
|
+
// Per-protocol summary
|
|
201
|
+
console.log("─── Per Protocol ───");
|
|
202
|
+
for (const [proto, cases] of Object.entries(report.byProtocol)) {
|
|
203
|
+
const top = cases.slice(0, 3);
|
|
204
|
+
const totalImp = cases.reduce((s, c) => s + c.importance, 0);
|
|
205
|
+
console.log(` ${proto}: ${cases.length} gaps, top importance: ${(totalImp * 100).toFixed(0)}%`);
|
|
206
|
+
for (const c of top) {
|
|
207
|
+
console.log(` ${c.targetsTransition.from}→${c.targetsTransition.to} (importance: ${(c.importance * 100).toFixed(0)}%)`);
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
console.log();
|
|
211
|
+
}
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* P2.5: Repair Acceptance Dashboard
|
|
4
|
+
*
|
|
5
|
+
* Queries the telemetry layer to produce structured reports
|
|
6
|
+
* on which strategies, protocols, goals, and repair patterns
|
|
7
|
+
* perform best. This is the feedback loop that powers P4 Reward Model.
|
|
8
|
+
*
|
|
9
|
+
* Usage:
|
|
10
|
+
* import { printDashboard } from "./analytics";
|
|
11
|
+
* printDashboard(telemetry);
|
|
12
|
+
*/
|
|
13
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
|
+
exports.getStrategyStats = getStrategyStats;
|
|
15
|
+
exports.getProtocolStats = getProtocolStats;
|
|
16
|
+
exports.getGoalStats = getGoalStats;
|
|
17
|
+
exports.getTopAcceptedRepairs = getTopAcceptedRepairs;
|
|
18
|
+
exports.getTopRejectedRepairs = getTopRejectedRepairs;
|
|
19
|
+
exports.generateDashboard = generateDashboard;
|
|
20
|
+
exports.getRepairAdoptionRate = getRepairAdoptionRate;
|
|
21
|
+
exports.printDashboard = printDashboard;
|
|
22
|
+
function getStrategyStats(telemetry) {
|
|
23
|
+
const bySource = telemetry.getAcceptanceBySource();
|
|
24
|
+
return Object.entries(bySource)
|
|
25
|
+
.map(([strategy, s]) => ({
|
|
26
|
+
strategy,
|
|
27
|
+
total: s.total,
|
|
28
|
+
accepted: s.accepted,
|
|
29
|
+
rate: s.rate,
|
|
30
|
+
}))
|
|
31
|
+
.sort((a, b) => b.rate - a.rate);
|
|
32
|
+
}
|
|
33
|
+
function getProtocolStats(telemetry) {
|
|
34
|
+
const byProtocol = telemetry.getAcceptanceByProtocol();
|
|
35
|
+
return Object.entries(byProtocol)
|
|
36
|
+
.map(([protocol, s]) => ({
|
|
37
|
+
protocol,
|
|
38
|
+
total: s.total,
|
|
39
|
+
accepted: s.accepted,
|
|
40
|
+
rate: s.rate,
|
|
41
|
+
}))
|
|
42
|
+
.sort((a, b) => b.rate - a.rate);
|
|
43
|
+
}
|
|
44
|
+
function getGoalStats(telemetry) {
|
|
45
|
+
const byGoal = telemetry.getAcceptanceByGoal();
|
|
46
|
+
return Object.entries(byGoal)
|
|
47
|
+
.map(([goal, s]) => ({
|
|
48
|
+
goal,
|
|
49
|
+
total: s.total,
|
|
50
|
+
accepted: s.accepted,
|
|
51
|
+
rate: s.rate,
|
|
52
|
+
}))
|
|
53
|
+
.sort((a, b) => b.rate - a.rate);
|
|
54
|
+
}
|
|
55
|
+
function getTopAcceptedRepairs(telemetry, k) {
|
|
56
|
+
return telemetry.getTopAcceptedRepairs(k);
|
|
57
|
+
}
|
|
58
|
+
function getTopRejectedRepairs(telemetry, k) {
|
|
59
|
+
return telemetry.getTopRejectedRepairs(k);
|
|
60
|
+
}
|
|
61
|
+
function generateDashboard(telemetry) {
|
|
62
|
+
const summary = telemetry.getSummaryStats();
|
|
63
|
+
return {
|
|
64
|
+
summary: {
|
|
65
|
+
totalDecisions: telemetry.size,
|
|
66
|
+
withFeedback: telemetry.withFeedback,
|
|
67
|
+
overallAcceptanceRate: telemetry.getAcceptanceRate(),
|
|
68
|
+
adoptionRate: getRepairAdoptionRate(telemetry),
|
|
69
|
+
accepted: summary.accepted,
|
|
70
|
+
rejected: summary.rejected,
|
|
71
|
+
modified: summary.modified,
|
|
72
|
+
},
|
|
73
|
+
byStrategy: getStrategyStats(telemetry),
|
|
74
|
+
byProtocol: getProtocolStats(telemetry),
|
|
75
|
+
topAccepted: getTopAcceptedRepairs(telemetry, 5),
|
|
76
|
+
topRejected: getTopRejectedRepairs(telemetry, 5),
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Repair Adoption Rate — the most important KPI.
|
|
81
|
+
*
|
|
82
|
+
* "Of all repairs the planner proposed, how many did the user actually accept?"
|
|
83
|
+
* This matters more than Top-1 accuracy because users don't care
|
|
84
|
+
* what the algorithm thinks is right — they care what they're willing to use.
|
|
85
|
+
*/
|
|
86
|
+
function getRepairAdoptionRate(telemetry) {
|
|
87
|
+
const summary = telemetry.getSummaryStats();
|
|
88
|
+
const total = summary.accepted + summary.rejected;
|
|
89
|
+
if (total === 0)
|
|
90
|
+
return 0;
|
|
91
|
+
return summary.accepted / total;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Print a human-readable acceptance dashboard to stdout.
|
|
95
|
+
*/
|
|
96
|
+
function printDashboard(telemetry) {
|
|
97
|
+
const report = generateDashboard(telemetry);
|
|
98
|
+
console.log("\n╔══════════════════════════════════════════╗");
|
|
99
|
+
console.log("║ Repair Acceptance Dashboard ║");
|
|
100
|
+
console.log("╚══════════════════════════════════════════╝\n");
|
|
101
|
+
console.log(`Total Decisions: ${report.summary.totalDecisions}`);
|
|
102
|
+
console.log(`With Feedback: ${report.summary.withFeedback}`);
|
|
103
|
+
console.log(`Acceptance Rate: ${(report.summary.overallAcceptanceRate * 100).toFixed(1)}%`);
|
|
104
|
+
console.log(`Repair Adoption: ${(report.summary.adoptionRate * 100).toFixed(1)}% (${report.summary.accepted} accepted / ${report.summary.rejected} rejected / ${report.summary.modified} modified)\n`);
|
|
105
|
+
if (report.byStrategy.length > 0) {
|
|
106
|
+
console.log("─── By Strategy ───");
|
|
107
|
+
console.log("Strategy Acceptance");
|
|
108
|
+
console.log("──────────────────────────────");
|
|
109
|
+
for (const s of report.byStrategy) {
|
|
110
|
+
const pct = (s.rate * 100).toFixed(0).padStart(3);
|
|
111
|
+
console.log(` ${s.strategy.padEnd(16)} ${pct}% (${s.accepted}/${s.total})`);
|
|
112
|
+
}
|
|
113
|
+
console.log();
|
|
114
|
+
}
|
|
115
|
+
if (report.byProtocol.length > 0) {
|
|
116
|
+
console.log("─── By Protocol ───");
|
|
117
|
+
console.log("Protocol Acceptance");
|
|
118
|
+
console.log("──────────────────────────────");
|
|
119
|
+
for (const p of report.byProtocol) {
|
|
120
|
+
const pct = (p.rate * 100).toFixed(0).padStart(3);
|
|
121
|
+
console.log(` ${p.protocol.padEnd(16)} ${pct}% (${p.accepted}/${p.total})`);
|
|
122
|
+
}
|
|
123
|
+
console.log();
|
|
124
|
+
}
|
|
125
|
+
if (report.topAccepted.length > 0) {
|
|
126
|
+
console.log("─── Top Accepted Repairs ───");
|
|
127
|
+
for (const r of report.topAccepted) {
|
|
128
|
+
console.log(` ${r.actions}`);
|
|
129
|
+
console.log(` goal: ${r.goal} | count: ${r.count} | rate: ${(r.rate * 100).toFixed(0)}%\n`);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
if (report.topRejected.length > 0) {
|
|
133
|
+
console.log("─── Top Rejected Repairs ───");
|
|
134
|
+
for (const r of report.topRejected) {
|
|
135
|
+
console.log(` ${r.actions}`);
|
|
136
|
+
console.log(` goal: ${r.goal} | count: ${r.count} | rate: ${(r.rate * 100).toFixed(0)}%\n`);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
}
|