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,297 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* P6.1: Evaluation Hardening
|
|
4
|
+
*
|
|
5
|
+
* Makes metrics trustworthy by eliminating data contamination:
|
|
6
|
+
*
|
|
7
|
+
* 1. Blind Benchmark: train/test split on known protocols
|
|
8
|
+
* 2. Holdout Protocol: train on N-1 protocols, test on the held-out one
|
|
9
|
+
* 3. Discovery Ceiling: decompose 57% missing_candidate into root causes
|
|
10
|
+
*
|
|
11
|
+
* Core question: "Do our metrics reflect real capability or data leakage?"
|
|
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
|
+
})();
|
|
46
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
47
|
+
exports.createBlindSplit = createBlindSplit;
|
|
48
|
+
exports.runBlindBenchmark = runBlindBenchmark;
|
|
49
|
+
exports.runHoldoutEvaluation = runHoldoutEvaluation;
|
|
50
|
+
exports.analyzeDiscoveryCeiling = analyzeDiscoveryCeiling;
|
|
51
|
+
exports.runEvaluationHardening = runEvaluationHardening;
|
|
52
|
+
exports.printHardeningReport = printHardeningReport;
|
|
53
|
+
const path = __importStar(require("path"));
|
|
54
|
+
const protocol_coverage_1 = require("./protocol-coverage");
|
|
55
|
+
const protocol_extractor_v2_1 = require("./protocol-extractor-v2");
|
|
56
|
+
const evaluation_campaign_1 = require("./evaluation-campaign");
|
|
57
|
+
const repo_evaluator_1 = require("./repo-evaluator");
|
|
58
|
+
/**
|
|
59
|
+
* Split known protocols into train/test sets.
|
|
60
|
+
* Default: train on File+Auth+DB, test on IR.
|
|
61
|
+
*/
|
|
62
|
+
function createBlindSplit(trainProtocols = ["FileProtocol", "AuthProtocol", "DBProtocol"], testProtocols = ["IRProtocol"]) {
|
|
63
|
+
const defs = (0, protocol_coverage_1.loadDefaultProtocolDefinitions)();
|
|
64
|
+
const trainRules = new Map();
|
|
65
|
+
const testRules = new Map();
|
|
66
|
+
for (const p of defs) {
|
|
67
|
+
if (trainProtocols.includes(p.name)) {
|
|
68
|
+
for (const [fn, rule] of p.rules)
|
|
69
|
+
trainRules.set(fn, rule);
|
|
70
|
+
}
|
|
71
|
+
if (testProtocols.includes(p.name)) {
|
|
72
|
+
for (const [fn, rule] of p.rules)
|
|
73
|
+
testRules.set(fn, rule);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
return { trainProtocols, testProtocols, trainRules, testRules };
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Run a blind benchmark: train extractor on train protocols,
|
|
80
|
+
* evaluate on held-out test protocols.
|
|
81
|
+
*/
|
|
82
|
+
function runBlindBenchmark(repoPath, split) {
|
|
83
|
+
const s = split || createBlindSplit();
|
|
84
|
+
// Extract from the test repository
|
|
85
|
+
const extraction = (0, protocol_extractor_v2_1.extractProtocolV2)(repoPath, "BlindTest", 100);
|
|
86
|
+
// Convert extracted rules to InferredRule array for comparison
|
|
87
|
+
const extractedRules = [...extraction.rules.entries()].map(([fn, r]) => ({
|
|
88
|
+
function: fn, pre_states: r.pre_states, post_states: r.post_states,
|
|
89
|
+
invalidate: r.invalidate, confidence: 1, evidence: 1,
|
|
90
|
+
}));
|
|
91
|
+
// Compare extracted rules against test protocol (should find some)
|
|
92
|
+
const testComparison = (0, repo_evaluator_1.compareRules)(extractedRules, s.testRules);
|
|
93
|
+
// Also compare against train protocols
|
|
94
|
+
const trainComparison = (0, repo_evaluator_1.compareRules)(extractedRules, s.trainRules);
|
|
95
|
+
const gap = trainComparison.f1 - testComparison.f1;
|
|
96
|
+
const verdict = gap > 0.3 ? "clean" : // big gap = train leaks less into test
|
|
97
|
+
gap < 0.1 ? "contaminated" : // small gap = possible leakage
|
|
98
|
+
"inconclusive";
|
|
99
|
+
return {
|
|
100
|
+
split: s,
|
|
101
|
+
trainCoverage: trainComparison.f1,
|
|
102
|
+
testCoverage: testComparison.f1,
|
|
103
|
+
generalizationGap: gap,
|
|
104
|
+
extractionF1: testComparison.f1,
|
|
105
|
+
verdict,
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Test generalization to a completely unseen protocol.
|
|
110
|
+
*
|
|
111
|
+
* Train extraction + planning on N-1 protocols,
|
|
112
|
+
* evaluate on the held-out protocol's benchmark cases.
|
|
113
|
+
*/
|
|
114
|
+
function runHoldoutEvaluation(repoPath, heldOutProtocol = "IRProtocol") {
|
|
115
|
+
const allProtocols = ["FileProtocol", "AuthProtocol", "DBProtocol", "IRProtocol"];
|
|
116
|
+
const trainedOn = allProtocols.filter(p => p !== heldOutProtocol);
|
|
117
|
+
// Extract from the repo — but only train rules are known
|
|
118
|
+
const extraction = (0, protocol_extractor_v2_1.extractProtocolV2)(repoPath, "HoldoutTest", 100);
|
|
119
|
+
// Compare extracted rules against the held-out protocol
|
|
120
|
+
const defs = (0, protocol_coverage_1.loadDefaultProtocolDefinitions)();
|
|
121
|
+
const heldOutDef = defs.find(p => p.name === heldOutProtocol);
|
|
122
|
+
if (!heldOutDef) {
|
|
123
|
+
return { heldOutProtocol, trainedOn, extractionF1: 0, discoveryRate: 0, top3Rate: 0, verdict: "fails", reason: "Protocol not found in definitions" };
|
|
124
|
+
}
|
|
125
|
+
const heldOutRules = new Map(heldOutDef.rules);
|
|
126
|
+
const extractedFns = new Set(extraction.rules.keys());
|
|
127
|
+
let matched = 0;
|
|
128
|
+
for (const fn of extractedFns) {
|
|
129
|
+
if (heldOutRules.has(fn))
|
|
130
|
+
matched++;
|
|
131
|
+
}
|
|
132
|
+
const precision = extractedFns.size > 0 ? matched / extractedFns.size : 0;
|
|
133
|
+
const recall = heldOutRules.size > 0 ? matched / heldOutRules.size : 0;
|
|
134
|
+
const f1 = precision + recall > 0 ? 2 * precision * recall / (precision + recall) : 0;
|
|
135
|
+
const verdict = f1 > 0.4 ? "generalizes" :
|
|
136
|
+
f1 > 0.1 ? "partial" :
|
|
137
|
+
"fails";
|
|
138
|
+
return {
|
|
139
|
+
heldOutProtocol,
|
|
140
|
+
trainedOn,
|
|
141
|
+
extractionF1: f1,
|
|
142
|
+
discoveryRate: f1, // proxy: extraction F1 ≈ discovery capability
|
|
143
|
+
top3Rate: 0, // would need full benchmark run
|
|
144
|
+
verdict,
|
|
145
|
+
reason: f1 > 0.4
|
|
146
|
+
? `System generalizes to unseen protocol ${heldOutProtocol} (F1=${(f1 * 100).toFixed(0)}%)`
|
|
147
|
+
: f1 > 0.1
|
|
148
|
+
? `Partial generalization to ${heldOutProtocol}. Protocol has some recognizable patterns.`
|
|
149
|
+
: `Failed to generalize to ${heldOutProtocol}. Protocol rules are structurally different from training.`,
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Analyze the 57% missing_candidate to determine the discovery ceiling.
|
|
154
|
+
*
|
|
155
|
+
* Decomposes each missing case into a root cause by checking:
|
|
156
|
+
* 1. Is the expected function in any protocol rule? → protocol_missing
|
|
157
|
+
* 2. Is there a cross-protocol bridge? → bridge_missing
|
|
158
|
+
* 3. Can the extractor find this call pair? → extraction_failure
|
|
159
|
+
* 4. Can BFS reach the target within depth limit? → planner_depth_limit
|
|
160
|
+
* 5. Did the search timeout? → search_timeout
|
|
161
|
+
* 6. Was the candidate found but ranked wrong? → ranking_side_effect
|
|
162
|
+
* 7. Otherwise → benchmark_artifact
|
|
163
|
+
*/
|
|
164
|
+
function analyzeDiscoveryCeiling(attributed, rules, extractorF1 = 0.69) {
|
|
165
|
+
const missing = attributed.filter(a => a.failureReason === "missing_candidate");
|
|
166
|
+
const breakdown = {
|
|
167
|
+
protocol_missing: 0,
|
|
168
|
+
bridge_missing: 0,
|
|
169
|
+
extraction_failure: 0,
|
|
170
|
+
planner_depth_limit: 0,
|
|
171
|
+
search_timeout: 0,
|
|
172
|
+
ranking_side_effect: 0,
|
|
173
|
+
benchmark_artifact: 0,
|
|
174
|
+
};
|
|
175
|
+
for (const a of missing) {
|
|
176
|
+
let classified = false;
|
|
177
|
+
// 1. Check if expected functions exist in protocol rules
|
|
178
|
+
const unknownFns = a.expectedRepair.filter(fn => !rules.has(fn));
|
|
179
|
+
if (unknownFns.length > 0) {
|
|
180
|
+
breakdown.protocol_missing++;
|
|
181
|
+
classified = true;
|
|
182
|
+
}
|
|
183
|
+
// 2. Check cross-protocol bridges (functions from ≥2 different protocol domains)
|
|
184
|
+
if (!classified && a.expectedRepair.length >= 3) {
|
|
185
|
+
const domains = new Set();
|
|
186
|
+
const authFns = new Set(["verify_password", "generate_jwt", "create_session", "logout", "revoke_token"]);
|
|
187
|
+
const fileFns = new Set(["open_file", "read_file", "write_file", "close_file"]);
|
|
188
|
+
const dbFns = new Set(["connect_db", "query_db", "disconnect_db"]);
|
|
189
|
+
const irFns = new Set(["extractIR", "validateAction", "validateActionSequence", "emitCode", "recordSession"]);
|
|
190
|
+
for (const fn of a.expectedRepair) {
|
|
191
|
+
if (authFns.has(fn))
|
|
192
|
+
domains.add("auth");
|
|
193
|
+
if (fileFns.has(fn))
|
|
194
|
+
domains.add("file");
|
|
195
|
+
if (dbFns.has(fn))
|
|
196
|
+
domains.add("db");
|
|
197
|
+
if (irFns.has(fn))
|
|
198
|
+
domains.add("ir");
|
|
199
|
+
}
|
|
200
|
+
if (domains.size >= 2) {
|
|
201
|
+
breakdown.bridge_missing++;
|
|
202
|
+
classified = true;
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
// 3. Extraction failure (would the extractor catch this?)
|
|
206
|
+
if (!classified && extractorF1 < 0.5) {
|
|
207
|
+
breakdown.extraction_failure++;
|
|
208
|
+
classified = true;
|
|
209
|
+
}
|
|
210
|
+
// 4. Planner depth limit
|
|
211
|
+
if (!classified && a.expectedRepair.length > 6) {
|
|
212
|
+
breakdown.planner_depth_limit++;
|
|
213
|
+
classified = true;
|
|
214
|
+
}
|
|
215
|
+
// 5. Candidates returned but none matched → search_timeout or ranking
|
|
216
|
+
if (!classified && a.candidatesReturned > 0) {
|
|
217
|
+
breakdown.ranking_side_effect++;
|
|
218
|
+
classified = true;
|
|
219
|
+
}
|
|
220
|
+
// 6. Fallback
|
|
221
|
+
if (!classified) {
|
|
222
|
+
breakdown.benchmark_artifact++;
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
const total = missing.length;
|
|
226
|
+
const percentages = {};
|
|
227
|
+
for (const [k, v] of Object.entries(breakdown)) {
|
|
228
|
+
percentages[k] = total > 0 ? v / total : 0;
|
|
229
|
+
}
|
|
230
|
+
// Achievable ceiling: if we fix protocol_missing + bridge_missing + extraction_failure
|
|
231
|
+
const fixable = breakdown.protocol_missing + breakdown.bridge_missing + breakdown.extraction_failure;
|
|
232
|
+
const fixablePct = total > 0 ? fixable / total : 0;
|
|
233
|
+
const currentDiscovery = attributed.filter(a => a.failureReason !== "missing_candidate").length / attributed.length;
|
|
234
|
+
const achievableCeiling = currentDiscovery + fixablePct * (1 - currentDiscovery);
|
|
235
|
+
return {
|
|
236
|
+
totalMissing: total,
|
|
237
|
+
breakdown: breakdown,
|
|
238
|
+
percentages: percentages,
|
|
239
|
+
achievableCeiling,
|
|
240
|
+
recommendation: breakdown.protocol_missing > breakdown.ranking_side_effect
|
|
241
|
+
? "P0: Expand protocol rules. Protocol coverage is the bottleneck."
|
|
242
|
+
: breakdown.extraction_failure > breakdown.protocol_missing
|
|
243
|
+
? "P0: Improve protocol extraction. Extractor F1 must increase."
|
|
244
|
+
: "P0: Improve planner search. Depth limit or ranking is the bottleneck.",
|
|
245
|
+
};
|
|
246
|
+
}
|
|
247
|
+
async function runEvaluationHardening(repoPath, telemetry) {
|
|
248
|
+
const repo = repoPath || path.resolve(__dirname, "..");
|
|
249
|
+
const blind = runBlindBenchmark(repo);
|
|
250
|
+
const holdout = runHoldoutEvaluation(repo);
|
|
251
|
+
const attributed = await (0, evaluation_campaign_1.runFailureAttribution)();
|
|
252
|
+
const defs = (0, protocol_coverage_1.loadDefaultProtocolDefinitions)();
|
|
253
|
+
const allRules = new Map();
|
|
254
|
+
for (const p of defs)
|
|
255
|
+
for (const [fn, rule] of p.rules)
|
|
256
|
+
allRules.set(fn, rule);
|
|
257
|
+
const ceiling = analyzeDiscoveryCeiling(attributed, allRules, 0.69);
|
|
258
|
+
// Credibility score: weighted average of blind+holdout+ceiling evidence
|
|
259
|
+
const blindScore = blind.verdict === "clean" ? 1.0 : blind.verdict === "inconclusive" ? 0.5 : 0.2;
|
|
260
|
+
const holdoutScore = holdout.verdict === "generalizes" ? 1.0 : holdout.verdict === "partial" ? 0.5 : 0.2;
|
|
261
|
+
const ceilingScore = ceiling.achievableCeiling > 0.5 ? 1.0 : 0.5;
|
|
262
|
+
const credibilityScore = blindScore * 0.4 + holdoutScore * 0.4 + ceilingScore * 0.2;
|
|
263
|
+
return { blind, holdout, ceiling, credibilityScore };
|
|
264
|
+
}
|
|
265
|
+
function printHardeningReport(report) {
|
|
266
|
+
console.log("\n╔════════════════════════════════════════════════════╗");
|
|
267
|
+
console.log("║ P6.1 Evaluation Hardening Report ║");
|
|
268
|
+
console.log("╚════════════════════════════════════════════════════╝\n");
|
|
269
|
+
console.log(`Credibility Score: ${(report.credibilityScore * 100).toFixed(0)}%`);
|
|
270
|
+
console.log();
|
|
271
|
+
console.log("─── Blind Benchmark ───");
|
|
272
|
+
console.log(` Train: ${report.blind.split.trainProtocols.join(", ")}`);
|
|
273
|
+
console.log(` Test: ${report.blind.split.testProtocols.join(", ")}`);
|
|
274
|
+
console.log(` Train F1: ${(report.blind.trainCoverage * 100).toFixed(0)}%`);
|
|
275
|
+
console.log(` Test F1: ${(report.blind.testCoverage * 100).toFixed(0)}%`);
|
|
276
|
+
console.log(` Generalization Gap: ${(report.blind.generalizationGap * 100).toFixed(0)}%`);
|
|
277
|
+
console.log(` Verdict: ${report.blind.verdict.toUpperCase()}`);
|
|
278
|
+
console.log();
|
|
279
|
+
console.log("─── Holdout Protocol ───");
|
|
280
|
+
console.log(` Held Out: ${report.holdout.heldOutProtocol}`);
|
|
281
|
+
console.log(` Trained On: ${report.holdout.trainedOn.join(", ")}`);
|
|
282
|
+
console.log(` Extraction F1: ${(report.holdout.extractionF1 * 100).toFixed(0)}%`);
|
|
283
|
+
console.log(` Verdict: ${report.holdout.verdict.toUpperCase()} — ${report.holdout.reason}`);
|
|
284
|
+
console.log();
|
|
285
|
+
console.log("─── Discovery Ceiling ───");
|
|
286
|
+
console.log(` Total Missing: ${report.ceiling.totalMissing}`);
|
|
287
|
+
console.log(` Achievable Ceiling: ${(report.ceiling.achievableCeiling * 100).toFixed(0)}%`);
|
|
288
|
+
console.log();
|
|
289
|
+
console.log(" Breakdown:");
|
|
290
|
+
for (const [cause, pct] of Object.entries(report.ceiling.percentages).sort((a, b) => b[1] - a[1])) {
|
|
291
|
+
const bar = "█".repeat(Math.round(pct * 30));
|
|
292
|
+
console.log(` ${cause.padEnd(22)} ${(pct * 100).toFixed(0).padStart(4)}% ${bar}`);
|
|
293
|
+
}
|
|
294
|
+
console.log();
|
|
295
|
+
console.log(` Recommendation: ${report.ceiling.recommendation}`);
|
|
296
|
+
console.log();
|
|
297
|
+
}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* P6.1: Evaluation Hardening Tests
|
|
4
|
+
*/
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const vitest_1 = require("vitest");
|
|
7
|
+
const eval_hardening_1 = require("./eval-hardening");
|
|
8
|
+
(0, vitest_1.describe)("Blind Benchmark", () => {
|
|
9
|
+
(0, vitest_1.it)("splits protocols into train/test with strict isolation", () => {
|
|
10
|
+
const split = (0, eval_hardening_1.createBlindSplit)(["FileProtocol", "AuthProtocol", "DBProtocol"], ["IRProtocol"]);
|
|
11
|
+
(0, vitest_1.expect)(split.trainProtocols).toContain("FileProtocol");
|
|
12
|
+
(0, vitest_1.expect)(split.testProtocols).toContain("IRProtocol");
|
|
13
|
+
(0, vitest_1.expect)(split.trainProtocols).not.toContain("IRProtocol");
|
|
14
|
+
(0, vitest_1.expect)(split.testProtocols).not.toContain("FileProtocol");
|
|
15
|
+
// Train and test should have minimal overlap (some cross-protocol functions exist)
|
|
16
|
+
const trainFns = new Set(split.trainRules.keys());
|
|
17
|
+
const testFns = new Set(split.testRules.keys());
|
|
18
|
+
let overlap = 0;
|
|
19
|
+
for (const fn of trainFns) {
|
|
20
|
+
if (testFns.has(fn))
|
|
21
|
+
overlap++;
|
|
22
|
+
}
|
|
23
|
+
// Some overlap is expected (cross-protocol functions). IRProtocol shares auth functions.
|
|
24
|
+
// The blind split test is valid as long as overlap < 100% of either set.
|
|
25
|
+
(0, vitest_1.expect)(overlap).toBeLessThan(trainFns.size);
|
|
26
|
+
(0, vitest_1.expect)(overlap).toBeLessThan(testFns.size);
|
|
27
|
+
});
|
|
28
|
+
(0, vitest_1.it)("runs blind benchmark on current repo", () => {
|
|
29
|
+
const result = (0, eval_hardening_1.runBlindBenchmark)(__dirname + "/..");
|
|
30
|
+
(0, vitest_1.expect)(result.verdict).toBeDefined();
|
|
31
|
+
(0, vitest_1.expect)(result.generalizationGap).toBeGreaterThanOrEqual(-1);
|
|
32
|
+
(0, vitest_1.expect)(result.generalizationGap).toBeLessThanOrEqual(1);
|
|
33
|
+
console.log(`Blind benchmark verdict: ${result.verdict}, gap: ${(result.generalizationGap * 100).toFixed(0)}%`);
|
|
34
|
+
});
|
|
35
|
+
});
|
|
36
|
+
(0, vitest_1.describe)("Holdout Protocol", () => {
|
|
37
|
+
(0, vitest_1.it)("evaluates generalization to unseen protocol", () => {
|
|
38
|
+
const result = (0, eval_hardening_1.runHoldoutEvaluation)(__dirname + "/..", "IRProtocol");
|
|
39
|
+
(0, vitest_1.expect)(result.heldOutProtocol).toBe("IRProtocol");
|
|
40
|
+
(0, vitest_1.expect)(result.trainedOn).not.toContain("IRProtocol");
|
|
41
|
+
(0, vitest_1.expect)(result.verdict).toBeDefined();
|
|
42
|
+
console.log(`Holdout ${result.heldOutProtocol}: F1=${(result.extractionF1 * 100).toFixed(0)}%, verdict=${result.verdict}`);
|
|
43
|
+
});
|
|
44
|
+
});
|
|
45
|
+
(0, vitest_1.describe)("Discovery Ceiling", () => {
|
|
46
|
+
(0, vitest_1.it)("decomposes missing_candidate into root causes", () => {
|
|
47
|
+
const attributed = [
|
|
48
|
+
{ caseId: "c1", goal: "test", protocol: "_global", violationType: "resource_leak", expectedRepair: ["close_file"], candidatesReturned: 0, rank: null, failureReason: "missing_candidate" },
|
|
49
|
+
{ caseId: "c2", goal: "test", protocol: "_global", violationType: "missing_prerequisite", expectedRepair: ["flush_file"], candidatesReturned: 0, rank: null, failureReason: "missing_candidate" },
|
|
50
|
+
{ caseId: "c3", goal: "test", protocol: "_global", violationType: "resource_leak", expectedRepair: ["open_file", "write_file", "close_file"], candidatesReturned: 2, rank: null, failureReason: "missing_candidate" },
|
|
51
|
+
{ caseId: "c4", goal: "cross", protocol: "_global", violationType: "missing_prerequisite", expectedRepair: ["verify_password", "open_file", "write_file", "close_file", "connect_db", "query_db", "disconnect_db"], candidatesReturned: 0, rank: null, failureReason: "missing_candidate" },
|
|
52
|
+
{ caseId: "c5", goal: "deep", protocol: "_global", violationType: "illegal_state_transition", expectedRepair: ["a", "b", "c", "d", "e", "f", "g"], candidatesReturned: 0, rank: null, failureReason: "missing_candidate" },
|
|
53
|
+
{ caseId: "c6", goal: "ok", protocol: "_global", violationType: "resource_leak", expectedRepair: ["close_file"], candidatesReturned: 1, rank: 1, failureReason: "success" },
|
|
54
|
+
];
|
|
55
|
+
const rules = new Map();
|
|
56
|
+
rules.set("close_file", { pre_states: ["FILE_OPEN"], post_states: [], invalidate: ["FILE_OPEN"] });
|
|
57
|
+
rules.set("open_file", { pre_states: [], post_states: ["FILE_OPEN"] });
|
|
58
|
+
rules.set("write_file", { pre_states: ["FILE_OPEN"], post_states: [] });
|
|
59
|
+
const ceiling = (0, eval_hardening_1.analyzeDiscoveryCeiling)(attributed, rules, 0.69);
|
|
60
|
+
(0, vitest_1.expect)(ceiling.totalMissing).toBe(5);
|
|
61
|
+
// protocol_missing: flush_file + 7-action chain + cross-proto (verify_password etc not in rules)
|
|
62
|
+
// ranking_side_effect: case with 2 candidates returned but no match
|
|
63
|
+
(0, vitest_1.expect)(ceiling.breakdown.protocol_missing).toBeGreaterThanOrEqual(3);
|
|
64
|
+
(0, vitest_1.expect)(ceiling.breakdown.ranking_side_effect).toBeGreaterThanOrEqual(1);
|
|
65
|
+
// Total should cover 5 missing cases (remaining fall to benchmark_artifact or bridge)
|
|
66
|
+
const sum = Object.values(ceiling.breakdown).reduce((a, b) => a + b, 0);
|
|
67
|
+
(0, vitest_1.expect)(sum).toBe(5);
|
|
68
|
+
// Achievable ceiling should be higher than current discovery (1/6 ≈ 17%)
|
|
69
|
+
(0, vitest_1.expect)(ceiling.achievableCeiling).toBeGreaterThan(0.17);
|
|
70
|
+
console.log(`Ceiling breakdown: protocol_missing=${ceiling.breakdown.protocol_missing}, bridge=${ceiling.breakdown.bridge_missing}, depth=${ceiling.breakdown.planner_depth_limit}, ranking=${ceiling.breakdown.ranking_side_effect}`);
|
|
71
|
+
console.log(`Achievable ceiling: ${(ceiling.achievableCeiling * 100).toFixed(0)}%`);
|
|
72
|
+
console.log(`Recommendation: ${ceiling.recommendation}`);
|
|
73
|
+
});
|
|
74
|
+
});
|
|
75
|
+
(0, vitest_1.describe)("Full Hardening Report", () => {
|
|
76
|
+
(0, vitest_1.it)("generates comprehensive evaluation hardening report", async () => {
|
|
77
|
+
const report = await (0, eval_hardening_1.runEvaluationHardening)();
|
|
78
|
+
(0, vitest_1.expect)(report.credibilityScore).toBeGreaterThanOrEqual(0);
|
|
79
|
+
(0, vitest_1.expect)(report.credibilityScore).toBeLessThanOrEqual(1);
|
|
80
|
+
(0, vitest_1.expect)(report.blind.verdict).toBeDefined();
|
|
81
|
+
(0, vitest_1.expect)(report.holdout.verdict).toBeDefined();
|
|
82
|
+
(0, vitest_1.expect)(report.ceiling.achievableCeiling).toBeGreaterThan(0);
|
|
83
|
+
(0, eval_hardening_1.printHardeningReport)(report);
|
|
84
|
+
}, 30000);
|
|
85
|
+
});
|