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,274 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Knowledge Flywheel — Self-reinforcing knowledge growth pipeline
|
|
4
|
+
*
|
|
5
|
+
* Repo → Scan → Evidence → Confidence → Version Suggestion → Human Review → Merge
|
|
6
|
+
* ↑ │
|
|
7
|
+
* └──────────── More Repos ←────────────────────────┘
|
|
8
|
+
*
|
|
9
|
+
* Usage:
|
|
10
|
+
* npx ts-node src/knowledge-flywheel.ts scan benchmarks/nginx
|
|
11
|
+
* npx ts-node src/knowledge-flywheel.ts status
|
|
12
|
+
* npx ts-node src/knowledge-flywheel.ts metrics
|
|
13
|
+
*/
|
|
14
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
15
|
+
if (k2 === undefined) k2 = k;
|
|
16
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
17
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
18
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
19
|
+
}
|
|
20
|
+
Object.defineProperty(o, k2, desc);
|
|
21
|
+
}) : (function(o, m, k, k2) {
|
|
22
|
+
if (k2 === undefined) k2 = k;
|
|
23
|
+
o[k2] = m[k];
|
|
24
|
+
}));
|
|
25
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
26
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
27
|
+
}) : function(o, v) {
|
|
28
|
+
o["default"] = v;
|
|
29
|
+
});
|
|
30
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
31
|
+
var ownKeys = function(o) {
|
|
32
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
33
|
+
var ar = [];
|
|
34
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
35
|
+
return ar;
|
|
36
|
+
};
|
|
37
|
+
return ownKeys(o);
|
|
38
|
+
};
|
|
39
|
+
return function (mod) {
|
|
40
|
+
if (mod && mod.__esModule) return mod;
|
|
41
|
+
var result = {};
|
|
42
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
43
|
+
__setModuleDefault(result, mod);
|
|
44
|
+
return result;
|
|
45
|
+
};
|
|
46
|
+
})();
|
|
47
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
48
|
+
exports.scanRepo = scanRepo;
|
|
49
|
+
exports.loadMetrics = loadMetrics;
|
|
50
|
+
const fs = __importStar(require("fs"));
|
|
51
|
+
const path = __importStar(require("path"));
|
|
52
|
+
const protocol_detector_1 = require("./protocol-detector");
|
|
53
|
+
const protocol_knowledge_1 = require("./protocol-knowledge");
|
|
54
|
+
// ═══════════════════════════════════════════════════════════════
|
|
55
|
+
// Scanner
|
|
56
|
+
// ═══════════════════════════════════════════════════════════════
|
|
57
|
+
const PROPOSALS_DIR = ".progmune_corpus/flywheel";
|
|
58
|
+
function scanRepo(repoPath) {
|
|
59
|
+
const repoName = path.basename(repoPath);
|
|
60
|
+
const seqFile = path.join(path.dirname(repoPath), `${repoName}-sequences.json`);
|
|
61
|
+
if (!fs.existsSync(seqFile))
|
|
62
|
+
throw new Error(`No sequences: ${seqFile}`);
|
|
63
|
+
const sequences = JSON.parse(fs.readFileSync(seqFile, "utf-8"));
|
|
64
|
+
const kb = (0, protocol_knowledge_1.buildKnowledgeBase)();
|
|
65
|
+
const proposals = [];
|
|
66
|
+
// Match sequences against KB
|
|
67
|
+
const matchCounts = {};
|
|
68
|
+
for (const seq of sequences.slice(0, 50)) {
|
|
69
|
+
const result = (0, protocol_detector_1.validateProtocolState)(seq.calls || []);
|
|
70
|
+
for (const p of result.matchedProtocols)
|
|
71
|
+
matchCounts[p] = (matchCounts[p] || 0) + 1;
|
|
72
|
+
}
|
|
73
|
+
for (const [proto, count] of Object.entries(matchCounts)) {
|
|
74
|
+
const unit = kb.units.find(u => u.name === proto);
|
|
75
|
+
if (!unit || count < 3)
|
|
76
|
+
continue;
|
|
77
|
+
const alreadyEvidenced = (unit.evidence || []).some(e => e.repo === repoName);
|
|
78
|
+
if (alreadyEvidenced)
|
|
79
|
+
continue;
|
|
80
|
+
let suggestion;
|
|
81
|
+
let proposedVersion = unit.currentVersion;
|
|
82
|
+
let proposedConf = unit.confidence;
|
|
83
|
+
let reason = "";
|
|
84
|
+
if (count >= 10 && unit.maturity !== "stable") {
|
|
85
|
+
// Enough evidence to promote
|
|
86
|
+
suggestion = "promote";
|
|
87
|
+
const [major, minor] = unit.currentVersion.split(".").map(Number);
|
|
88
|
+
proposedVersion = `${major + 1}.0.0`;
|
|
89
|
+
proposedConf = Math.min(95, unit.confidence + 15);
|
|
90
|
+
reason = `${count}/50 sequences matched — strong evidence for promotion to stable. Would add ${repoName} as ${(unit.validatedRepos.length + 1)}th validated repo.`;
|
|
91
|
+
}
|
|
92
|
+
else if (count >= 5 && unit.confidence < 80) {
|
|
93
|
+
suggestion = "bump";
|
|
94
|
+
const [major, minor, patch] = unit.currentVersion.split(".").map(Number);
|
|
95
|
+
proposedVersion = `${major}.${minor}.${(patch || 0) + 1}`;
|
|
96
|
+
proposedConf = Math.min(90, unit.confidence + 8);
|
|
97
|
+
reason = `${count}/50 sequences matched — confidence bump warranted.`;
|
|
98
|
+
}
|
|
99
|
+
else if (count >= 3) {
|
|
100
|
+
suggestion = "evidence_only";
|
|
101
|
+
proposedConf = Math.min(90, unit.confidence + 3);
|
|
102
|
+
reason = `${count}/50 matched — evidence addition only. Confidence +3%.`;
|
|
103
|
+
}
|
|
104
|
+
else {
|
|
105
|
+
suggestion = "insufficient";
|
|
106
|
+
reason = `Only ${count}/50 matched — insufficient for any action.`;
|
|
107
|
+
}
|
|
108
|
+
const proposal = {
|
|
109
|
+
id: `FLY-${Date.now().toString(36)}-${unit.id}`,
|
|
110
|
+
repo: repoName,
|
|
111
|
+
timestamp: new Date().toISOString(),
|
|
112
|
+
unitId: unit.id,
|
|
113
|
+
unitName: unit.name,
|
|
114
|
+
currentVersion: unit.currentVersion,
|
|
115
|
+
proposedVersion,
|
|
116
|
+
currentConfidence: unit.confidence,
|
|
117
|
+
proposedConfidence: proposedConf,
|
|
118
|
+
evidenceCount: count,
|
|
119
|
+
matchRate: `${count}/50`,
|
|
120
|
+
suggestion,
|
|
121
|
+
reason,
|
|
122
|
+
status: "pending",
|
|
123
|
+
};
|
|
124
|
+
proposals.push(proposal);
|
|
125
|
+
}
|
|
126
|
+
// Save proposals
|
|
127
|
+
if (!fs.existsSync(PROPOSALS_DIR))
|
|
128
|
+
fs.mkdirSync(PROPOSALS_DIR, { recursive: true });
|
|
129
|
+
for (const p of proposals) {
|
|
130
|
+
fs.writeFileSync(path.join(PROPOSALS_DIR, `${p.id}.json`), JSON.stringify(p, null, 2));
|
|
131
|
+
}
|
|
132
|
+
// Update metrics
|
|
133
|
+
updateMetrics(repoName, proposals);
|
|
134
|
+
return proposals.sort((a, b) => b.evidenceCount - a.evidenceCount);
|
|
135
|
+
}
|
|
136
|
+
// ═══════════════════════════════════════════════════════════════
|
|
137
|
+
// Metrics
|
|
138
|
+
// ═══════════════════════════════════════════════════════════════
|
|
139
|
+
const METRICS_FILE = ".progmune_corpus/flywheel-metrics.json";
|
|
140
|
+
function loadMetrics() {
|
|
141
|
+
try {
|
|
142
|
+
return JSON.parse(fs.readFileSync(METRICS_FILE, "utf-8"));
|
|
143
|
+
}
|
|
144
|
+
catch {
|
|
145
|
+
return { totalScans: 0, totalProposals: 0, acceptedProposals: 0, rejectedProposals: 0, pendingProposals: 0, knowledgeVelocity: 0, averageConfidenceGain: 0, reposScanned: [], history: [] };
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
function updateMetrics(repo, proposals) {
|
|
149
|
+
const m = loadMetrics();
|
|
150
|
+
if (!m.reposScanned.includes(repo))
|
|
151
|
+
m.reposScanned.push(repo);
|
|
152
|
+
m.totalScans++;
|
|
153
|
+
m.totalProposals += proposals.length;
|
|
154
|
+
m.pendingProposals += proposals.filter(p => p.suggestion !== "insufficient").length;
|
|
155
|
+
m.history.push(...proposals);
|
|
156
|
+
if (m.totalScans > 0)
|
|
157
|
+
m.knowledgeVelocity = Math.round((m.totalProposals / m.totalScans) * 10) / 10;
|
|
158
|
+
m.averageConfidenceGain = m.history.filter(p => p.suggestion !== "insufficient").reduce((s, p) => s + (p.proposedConfidence - p.currentConfidence), 0) / Math.max(1, m.history.filter(p => p.suggestion !== "insufficient").length);
|
|
159
|
+
if (!fs.existsSync(".progmune_corpus"))
|
|
160
|
+
fs.mkdirSync(".progmune_corpus");
|
|
161
|
+
fs.writeFileSync(METRICS_FILE, JSON.stringify(m, null, 2));
|
|
162
|
+
}
|
|
163
|
+
// ═══════════════════════════════════════════════════════════════
|
|
164
|
+
// CLI
|
|
165
|
+
// ═══════════════════════════════════════════════════════════════
|
|
166
|
+
if (require.main === module) {
|
|
167
|
+
const args = process.argv.slice(2);
|
|
168
|
+
const C = { r: "\x1b[0m", b: "\x1b[1m", d: "\x1b[2m", g: "\x1b[32m", y: "\x1b[33m", r2: "\x1b[31m", c: "\x1b[36m" };
|
|
169
|
+
if (args[0] === "scan" && args[1]) {
|
|
170
|
+
console.error(`\n${C.b}${C.c}Flywheel: Scanning ${args[1]}${C.r}\n`);
|
|
171
|
+
const proposals = scanRepo(args[1]);
|
|
172
|
+
const actionable = proposals.filter(p => p.suggestion !== "insufficient");
|
|
173
|
+
for (const p of proposals) {
|
|
174
|
+
const icon = p.suggestion === "promote" ? "⭐" : p.suggestion === "bump" ? "📈" : p.suggestion === "evidence_only" ? "✅" : "—";
|
|
175
|
+
console.log(` ${icon} ${p.unitName}: ${p.matchRate} → ${p.suggestion}`);
|
|
176
|
+
console.log(` v${p.currentVersion} → v${p.proposedVersion} | ${p.currentConfidence}% → ${p.proposedConfidence}%`);
|
|
177
|
+
console.log(` ${p.reason}`);
|
|
178
|
+
if (p.suggestion !== "insufficient")
|
|
179
|
+
console.log(` ${C.d}Review: ${PROPOSALS_DIR}/${p.id}.json${C.r}`);
|
|
180
|
+
}
|
|
181
|
+
if (actionable.length > 0) {
|
|
182
|
+
console.log(`\n ${C.g}${actionable.length} actionable proposal(s) saved.${C.r}`);
|
|
183
|
+
console.log(` ${C.d}Review proposals in ${PROPOSALS_DIR}/ and accept to grow Knowledge Base.${C.r}`);
|
|
184
|
+
}
|
|
185
|
+
console.log("");
|
|
186
|
+
}
|
|
187
|
+
else if (args[0] === "status") {
|
|
188
|
+
const m = loadMetrics();
|
|
189
|
+
console.log(`\n${C.b}${C.c}Knowledge Flywheel${C.r}\n`);
|
|
190
|
+
console.log(` Scans: ${m.totalScans} repos (${m.reposScanned.join(", ") || "none"})`);
|
|
191
|
+
console.log(` Proposals: ${m.totalProposals} total, ${m.acceptedProposals} accepted, ${m.rejectedProposals} rejected, ${m.pendingProposals} pending`);
|
|
192
|
+
console.log(` Velocity: ${m.knowledgeVelocity} proposals/scan`);
|
|
193
|
+
console.log(` Avg Gain: +${m.averageConfidenceGain.toFixed(1)}% confidence per proposal`);
|
|
194
|
+
const recent = m.history.slice(-5);
|
|
195
|
+
if (recent.length > 0) {
|
|
196
|
+
console.log(`\n Recent proposals:`);
|
|
197
|
+
for (const p of recent) {
|
|
198
|
+
const icon = p.status === "accepted" ? C.g + "✓" : p.status === "rejected" ? C.r2 + "✗" : C.y + "⏳";
|
|
199
|
+
console.log(` ${icon}${C.r} ${p.unitName}: ${p.matchRate} → ${p.suggestion} (${p.repo})`);
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
console.log("");
|
|
203
|
+
}
|
|
204
|
+
else if (args[0] === "debt") {
|
|
205
|
+
const kb = (0, protocol_knowledge_1.buildKnowledgeBase)();
|
|
206
|
+
console.log(`\n${C.b}${C.c}Knowledge Debt Dashboard${C.r}\n`);
|
|
207
|
+
for (const u of kb.units.filter(u => u.maturity === "stable" || u.maturity === "validated")) {
|
|
208
|
+
const b = u.confidenceBreakdown;
|
|
209
|
+
if (!b)
|
|
210
|
+
continue;
|
|
211
|
+
const sDebt = 100 - b.structural;
|
|
212
|
+
const cDebt = 100 - b.crossRepo;
|
|
213
|
+
const dDebt = 100 - b.deployment;
|
|
214
|
+
const total = Math.round(sDebt * 0.3 + cDebt * 0.3 + dDebt * 0.4);
|
|
215
|
+
const bar = "█".repeat(Math.min(10, Math.round(total / 10))) + "░".repeat(Math.max(0, 10 - Math.round(total / 10)));
|
|
216
|
+
const rec = dDebt > 30 ? "Need more deployment observations" : sDebt > 10 ? "Refine state machine" : "Healthy";
|
|
217
|
+
console.log(` ${bar} ${C.b}${u.name}${C.r} Debt: ${total}%`);
|
|
218
|
+
console.log(` Structural: ${b.structural}% (gap: ${sDebt}%) | Cross-Repo: ${b.crossRepo}% (gap: ${cDebt}%) | Deployment: ${b.deployment}% (gap: ${dDebt}%)`);
|
|
219
|
+
console.log(` → ${rec}`);
|
|
220
|
+
}
|
|
221
|
+
console.log(`\n ${C.d}Debt = weighted gap from 100%. Fix deployment debt first — it's the weakest link.${C.r}\n`);
|
|
222
|
+
}
|
|
223
|
+
else if (args[0] === "roi") {
|
|
224
|
+
const m = loadMetrics();
|
|
225
|
+
const kb = (0, protocol_knowledge_1.buildKnowledgeBase)();
|
|
226
|
+
console.log(`\n${C.b}${C.c}Knowledge ROI Report${C.r}\n`);
|
|
227
|
+
console.log(` Flywheel Stats:`);
|
|
228
|
+
console.log(` Scans: ${m.totalScans} repos`);
|
|
229
|
+
console.log(` Proposals: ${m.totalProposals} generated, ${m.acceptedProposals} accepted`);
|
|
230
|
+
console.log(` Velocity: ${m.knowledgeVelocity} proposals/scan`);
|
|
231
|
+
console.log(` Avg Gain: +${m.averageConfidenceGain.toFixed(1)}% per proposal`);
|
|
232
|
+
console.log(`\n Knowledge Growth:`);
|
|
233
|
+
const stableCount = kb.units.filter(u => u.maturity === "stable").length;
|
|
234
|
+
console.log(` Stable Units: ${stableCount} (from 0)`);
|
|
235
|
+
console.log(` Repos: ${kb.summary.totalValidatedRepos} validated`);
|
|
236
|
+
console.log(` Evidence: ${kb.summary.totalValidatedSequences} sequences`);
|
|
237
|
+
console.log(`\n Per-Unit ROI:`);
|
|
238
|
+
for (const u of kb.units.filter(u => u.maturity === "stable")) {
|
|
239
|
+
const breakdown = u.confidenceBreakdown;
|
|
240
|
+
console.log(` ${C.b}${u.name}${C.r} v${u.currentVersion}`);
|
|
241
|
+
if (breakdown) {
|
|
242
|
+
console.log(` Structural: ${breakdown.structural}% (state machine stability)`);
|
|
243
|
+
console.log(` Cross-Repo: ${breakdown.crossRepo}% (multi-repo validation)`);
|
|
244
|
+
console.log(` Deployment: ${breakdown.deployment}% (real-world acceptance)`);
|
|
245
|
+
}
|
|
246
|
+
const obs = u.observations?.length || 0;
|
|
247
|
+
console.log(` Observations: ${obs} deployment feedback events`);
|
|
248
|
+
}
|
|
249
|
+
console.log(`\n ${C.d}Flywheel: ${m.totalScans} scans → ${m.totalProposals} proposals → ${m.acceptedProposals} accepted → ${stableCount} stable → +${m.averageConfidenceGain.toFixed(1)}% avg confidence${C.r}\n`);
|
|
250
|
+
}
|
|
251
|
+
else if (args[0] === "metrics") {
|
|
252
|
+
console.log(JSON.stringify(loadMetrics(), null, 2));
|
|
253
|
+
}
|
|
254
|
+
else {
|
|
255
|
+
console.log(`
|
|
256
|
+
${C.b}Knowledge Flywheel${C.r}
|
|
257
|
+
|
|
258
|
+
${C.d}Usage:${C.r}
|
|
259
|
+
npx ts-node src/knowledge-flywheel.ts scan <repoPath>
|
|
260
|
+
Scan a repo and generate evidence proposals
|
|
261
|
+
|
|
262
|
+
npx ts-node src/knowledge-flywheel.ts status
|
|
263
|
+
View flywheel metrics and recent proposals
|
|
264
|
+
|
|
265
|
+
npx ts-node src/knowledge-flywheel.ts metrics
|
|
266
|
+
Export full metrics as JSON
|
|
267
|
+
|
|
268
|
+
${C.d}The Flywheel:${C.r}
|
|
269
|
+
Repo → Scan → Evidence → Confidence → Version → Review → Merge
|
|
270
|
+
↑ │
|
|
271
|
+
└──────────────── More Repos ←─────────────────────────┘
|
|
272
|
+
`);
|
|
273
|
+
}
|
|
274
|
+
}
|
|
@@ -0,0 +1,338 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* P3.21-23: Knowledge Governance Layer
|
|
4
|
+
*
|
|
5
|
+
* P3.21: Multi-source inference validation.
|
|
6
|
+
* benchark support + trajectory support - contradiction = trustworthiness.
|
|
7
|
+
* Status: proposed → verified → rejected.
|
|
8
|
+
*
|
|
9
|
+
* P3.22: Knowledge versioning.
|
|
10
|
+
* Every inferred transition is a versioned patch with audit trail.
|
|
11
|
+
* Planner reads Base Rules + Approved Patches (never modifies originals).
|
|
12
|
+
*
|
|
13
|
+
* P3.23: Regression testing.
|
|
14
|
+
* Run benchmark suite against proposed patches. Auto-approve only
|
|
15
|
+
* if Top-1 and Top-3 don't regress.
|
|
16
|
+
*
|
|
17
|
+
* Philosophy:
|
|
18
|
+
* Wrong knowledge + perfect Reward Model = confidently wrong.
|
|
19
|
+
* Right knowledge + basic Ranker = steadily improving.
|
|
20
|
+
*/
|
|
21
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
22
|
+
if (k2 === undefined) k2 = k;
|
|
23
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
24
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
25
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
26
|
+
}
|
|
27
|
+
Object.defineProperty(o, k2, desc);
|
|
28
|
+
}) : (function(o, m, k, k2) {
|
|
29
|
+
if (k2 === undefined) k2 = k;
|
|
30
|
+
o[k2] = m[k];
|
|
31
|
+
}));
|
|
32
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
33
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
34
|
+
}) : function(o, v) {
|
|
35
|
+
o["default"] = v;
|
|
36
|
+
});
|
|
37
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
38
|
+
var ownKeys = function(o) {
|
|
39
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
40
|
+
var ar = [];
|
|
41
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
42
|
+
return ar;
|
|
43
|
+
};
|
|
44
|
+
return ownKeys(o);
|
|
45
|
+
};
|
|
46
|
+
return function (mod) {
|
|
47
|
+
if (mod && mod.__esModule) return mod;
|
|
48
|
+
var result = {};
|
|
49
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
50
|
+
__setModuleDefault(result, mod);
|
|
51
|
+
return result;
|
|
52
|
+
};
|
|
53
|
+
})();
|
|
54
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
55
|
+
exports.KnowledgePatchStore = void 0;
|
|
56
|
+
exports.validateInferences = validateInferences;
|
|
57
|
+
exports.regressionTestPatch = regressionTestPatch;
|
|
58
|
+
exports.autoApprovePatch = autoApprovePatch;
|
|
59
|
+
exports.runKnowledgeGovernance = runKnowledgeGovernance;
|
|
60
|
+
exports.printGovernanceReport = printGovernanceReport;
|
|
61
|
+
const fs = __importStar(require("fs"));
|
|
62
|
+
const path = __importStar(require("path"));
|
|
63
|
+
const transition_synthesizer_1 = require("./transition-synthesizer");
|
|
64
|
+
const protocol_frontier_1 = require("./protocol-frontier");
|
|
65
|
+
const protocol_coverage_1 = require("./protocol-coverage");
|
|
66
|
+
const VALIDATION_THRESHOLDS = {
|
|
67
|
+
benchmarkMin: 3,
|
|
68
|
+
trajectoryMin: 5,
|
|
69
|
+
contradictionMax: 0,
|
|
70
|
+
};
|
|
71
|
+
/**
|
|
72
|
+
* Validate inferred transitions against multi-source evidence.
|
|
73
|
+
*
|
|
74
|
+
* - benchmarkSupport: how many benchmark cases need this transition
|
|
75
|
+
* - trajectorySupport: how many real trajectory records show this pattern
|
|
76
|
+
* - contradictionCount: how many counter-examples exist
|
|
77
|
+
*
|
|
78
|
+
* Status logic:
|
|
79
|
+
* proposed — insufficient evidence yet
|
|
80
|
+
* verified — ≥3 benchmark + ≥5 trajectory + 0 contradictions
|
|
81
|
+
* rejected — contradictionCount > 0
|
|
82
|
+
*/
|
|
83
|
+
function validateInferences(inferences, trajectoryCount = 0) {
|
|
84
|
+
return inferences.map(inf => {
|
|
85
|
+
const benchmarkSupport = inf.evidenceCount;
|
|
86
|
+
const trajectorySupport = trajectoryCount;
|
|
87
|
+
const contradictionCount = 0; // no contradiction detection yet
|
|
88
|
+
let status;
|
|
89
|
+
if (contradictionCount > VALIDATION_THRESHOLDS.contradictionMax) {
|
|
90
|
+
status = "rejected";
|
|
91
|
+
}
|
|
92
|
+
else if (benchmarkSupport >= VALIDATION_THRESHOLDS.benchmarkMin &&
|
|
93
|
+
trajectorySupport >= VALIDATION_THRESHOLDS.trajectoryMin) {
|
|
94
|
+
status = "verified";
|
|
95
|
+
}
|
|
96
|
+
else {
|
|
97
|
+
status = "proposed";
|
|
98
|
+
}
|
|
99
|
+
return {
|
|
100
|
+
...inf,
|
|
101
|
+
validation: { benchmarkSupport, trajectorySupport, contradictionCount, status },
|
|
102
|
+
};
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
const KNOWLEDGE_DIR = path.resolve(process.env.PROGMUNE_PROJECT_DIR || process.cwd(), ".progmune_corpus", "knowledge");
|
|
106
|
+
class KnowledgePatchStore {
|
|
107
|
+
constructor(persistPath) {
|
|
108
|
+
this.patches = [];
|
|
109
|
+
this.persistPath = persistPath || path.join(KNOWLEDGE_DIR, "patches.json");
|
|
110
|
+
this.load();
|
|
111
|
+
}
|
|
112
|
+
/** Propose a new knowledge patch from an inferred transition. */
|
|
113
|
+
propose(inference) {
|
|
114
|
+
const id = `KP-${Date.now()}-${Math.random().toString(36).slice(2, 6)}`;
|
|
115
|
+
const patch = {
|
|
116
|
+
id,
|
|
117
|
+
generatedBy: "transition-synthesizer",
|
|
118
|
+
protocol: inference.protocol,
|
|
119
|
+
change: inference.action,
|
|
120
|
+
fromState: inference.from,
|
|
121
|
+
toState: inference.to,
|
|
122
|
+
confidence: inference.confidence,
|
|
123
|
+
evidenceCount: inference.evidenceCount,
|
|
124
|
+
createdAt: new Date().toISOString(),
|
|
125
|
+
status: "proposed",
|
|
126
|
+
};
|
|
127
|
+
this.patches.push(patch);
|
|
128
|
+
this.save();
|
|
129
|
+
return patch;
|
|
130
|
+
}
|
|
131
|
+
/** Approve a patch (with benchmark metrics). */
|
|
132
|
+
approve(id, metrics) {
|
|
133
|
+
const patch = this.patches.find(p => p.id === id);
|
|
134
|
+
if (!patch || patch.status !== "proposed")
|
|
135
|
+
return false;
|
|
136
|
+
patch.status = "approved";
|
|
137
|
+
patch.approvedAt = new Date().toISOString();
|
|
138
|
+
patch.approvalMetrics = metrics;
|
|
139
|
+
this.save();
|
|
140
|
+
return true;
|
|
141
|
+
}
|
|
142
|
+
/** Reject a patch. */
|
|
143
|
+
reject(id) {
|
|
144
|
+
const patch = this.patches.find(p => p.id === id);
|
|
145
|
+
if (!patch || patch.status !== "proposed")
|
|
146
|
+
return false;
|
|
147
|
+
patch.status = "rejected";
|
|
148
|
+
this.save();
|
|
149
|
+
return true;
|
|
150
|
+
}
|
|
151
|
+
/** Rollback an approved patch. */
|
|
152
|
+
rollback(id) {
|
|
153
|
+
const patch = this.patches.find(p => p.id === id);
|
|
154
|
+
if (!patch || patch.status !== "approved")
|
|
155
|
+
return false;
|
|
156
|
+
patch.status = "rolled_back";
|
|
157
|
+
patch.rolledBackAt = new Date().toISOString();
|
|
158
|
+
this.save();
|
|
159
|
+
return true;
|
|
160
|
+
}
|
|
161
|
+
/** Get all approved patches (these augment the base rules). */
|
|
162
|
+
get approved() {
|
|
163
|
+
return this.patches.filter(p => p.status === "approved");
|
|
164
|
+
}
|
|
165
|
+
/** Get all proposed patches. */
|
|
166
|
+
get proposed() {
|
|
167
|
+
return this.patches.filter(p => p.status === "proposed");
|
|
168
|
+
}
|
|
169
|
+
/** Build augmented rules: base rules + approved patches as virtual rules. */
|
|
170
|
+
buildAugmentedRules(baseRules) {
|
|
171
|
+
const augmented = new Map(baseRules);
|
|
172
|
+
for (const patch of this.approved) {
|
|
173
|
+
const [fnA, fnB] = patch.change.split(" → ");
|
|
174
|
+
const bridgeName = `_patch_${fnA}_to_${fnB}`;
|
|
175
|
+
augmented.set(bridgeName, {
|
|
176
|
+
pre_states: [patch.fromState],
|
|
177
|
+
post_states: [patch.toState],
|
|
178
|
+
namespace: "knowledge-patch",
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
return augmented;
|
|
182
|
+
}
|
|
183
|
+
get all() { return this.patches; }
|
|
184
|
+
get size() { return this.patches.length; }
|
|
185
|
+
save() {
|
|
186
|
+
try {
|
|
187
|
+
if (!fs.existsSync(path.dirname(this.persistPath))) {
|
|
188
|
+
fs.mkdirSync(path.dirname(this.persistPath), { recursive: true });
|
|
189
|
+
}
|
|
190
|
+
fs.writeFileSync(this.persistPath, JSON.stringify(this.patches, null, 2));
|
|
191
|
+
}
|
|
192
|
+
catch { /* best-effort */ }
|
|
193
|
+
}
|
|
194
|
+
load() {
|
|
195
|
+
try {
|
|
196
|
+
if (fs.existsSync(this.persistPath)) {
|
|
197
|
+
this.patches = JSON.parse(fs.readFileSync(this.persistPath, "utf-8"));
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
catch { /* start fresh */ }
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
exports.KnowledgePatchStore = KnowledgePatchStore;
|
|
204
|
+
/**
|
|
205
|
+
* Test whether a proposed patch improves or degrades benchmark performance.
|
|
206
|
+
*
|
|
207
|
+
* Uses the frontier explorer to simulate: given currentState, can the Planner
|
|
208
|
+
* find paths that it couldn't before? If the augmented rules produce more
|
|
209
|
+
* successful paths without breaking existing ones, the patch passes.
|
|
210
|
+
*/
|
|
211
|
+
function regressionTestPatch(patch, baseRules, testCases, store) {
|
|
212
|
+
// Top-1/Top-3 BEFORE patch (using base rules only)
|
|
213
|
+
let top1Before = 0;
|
|
214
|
+
let top3Before = 0;
|
|
215
|
+
for (const tc of testCases) {
|
|
216
|
+
const result = (0, protocol_frontier_1.searchFrontier)(baseRules, tc.currentState, tc.targetState, 8);
|
|
217
|
+
if (result.found && result.cost <= 1)
|
|
218
|
+
top1Before++;
|
|
219
|
+
if (result.found && result.cost <= 3)
|
|
220
|
+
top3Before++;
|
|
221
|
+
}
|
|
222
|
+
const top1RateBefore = testCases.length > 0 ? top1Before / testCases.length : 0;
|
|
223
|
+
const top3RateBefore = testCases.length > 0 ? top3Before / testCases.length : 0;
|
|
224
|
+
// Top-1/Top-3 AFTER patch (base + this patch)
|
|
225
|
+
const augmented = store.buildAugmentedRules(baseRules);
|
|
226
|
+
let top1After = 0;
|
|
227
|
+
let top3After = 0;
|
|
228
|
+
for (const tc of testCases) {
|
|
229
|
+
const result = (0, protocol_frontier_1.searchFrontier)(augmented, tc.currentState, tc.targetState, 8);
|
|
230
|
+
if (result.found && result.cost <= 1)
|
|
231
|
+
top1After++;
|
|
232
|
+
if (result.found && result.cost <= 3)
|
|
233
|
+
top3After++;
|
|
234
|
+
}
|
|
235
|
+
const top1RateAfter = testCases.length > 0 ? top1After / testCases.length : 0;
|
|
236
|
+
const top3RateAfter = testCases.length > 0 ? top3After / testCases.length : 0;
|
|
237
|
+
// Patch passes if: Top-1 doesn't decrease AND Top-3 doesn't decrease
|
|
238
|
+
const passed = top1RateAfter >= top1RateBefore && top3RateAfter >= top3RateBefore;
|
|
239
|
+
const reason = passed
|
|
240
|
+
? `Top-1: ${(top1RateBefore * 100).toFixed(0)}% → ${(top1RateAfter * 100).toFixed(0)}%, Top-3: ${(top3RateBefore * 100).toFixed(0)}% → ${(top3RateAfter * 100).toFixed(0)}%`
|
|
241
|
+
: `Degradation detected. Top-1: ${(top1RateBefore * 100).toFixed(0)}% → ${(top1RateAfter * 100).toFixed(0)}%`;
|
|
242
|
+
return {
|
|
243
|
+
patchId: patch.id,
|
|
244
|
+
change: patch.change,
|
|
245
|
+
top1Before: top1RateBefore,
|
|
246
|
+
top1After: top1RateAfter,
|
|
247
|
+
top3Before: top3RateBefore,
|
|
248
|
+
top3After: top3RateAfter,
|
|
249
|
+
passed,
|
|
250
|
+
reason,
|
|
251
|
+
};
|
|
252
|
+
}
|
|
253
|
+
/**
|
|
254
|
+
* Full auto-approval pipeline:
|
|
255
|
+
* 1. Validate proposal against all test cases
|
|
256
|
+
* 2. Auto-approve if no regression
|
|
257
|
+
* 3. Record approval metrics
|
|
258
|
+
*/
|
|
259
|
+
function autoApprovePatch(patch, baseRules, testCases, store) {
|
|
260
|
+
const result = regressionTestPatch(patch, baseRules, testCases, store);
|
|
261
|
+
if (result.passed) {
|
|
262
|
+
store.approve(patch.id, {
|
|
263
|
+
top1Before: result.top1Before,
|
|
264
|
+
top1After: result.top1After,
|
|
265
|
+
top3Before: result.top3Before,
|
|
266
|
+
top3After: result.top3After,
|
|
267
|
+
});
|
|
268
|
+
}
|
|
269
|
+
else {
|
|
270
|
+
store.reject(patch.id);
|
|
271
|
+
}
|
|
272
|
+
return result;
|
|
273
|
+
}
|
|
274
|
+
/**
|
|
275
|
+
* Run the full knowledge governance pipeline:
|
|
276
|
+
* Synthesize → Validate → Propose → Regression Test → Auto-Approve
|
|
277
|
+
*/
|
|
278
|
+
function runKnowledgeGovernance(failures, testCases, store) {
|
|
279
|
+
const patchStore = store || new KnowledgePatchStore();
|
|
280
|
+
// 1. Synthesize
|
|
281
|
+
const inferences = (0, transition_synthesizer_1.synthesizeTransitions)(failures);
|
|
282
|
+
// 2. Validate
|
|
283
|
+
const validated = validateInferences(inferences);
|
|
284
|
+
// 3. Propose verified inferences
|
|
285
|
+
let proposed = 0;
|
|
286
|
+
let approved = 0;
|
|
287
|
+
let rejected = 0;
|
|
288
|
+
const regressionResults = [];
|
|
289
|
+
const defs = (0, protocol_coverage_1.loadDefaultProtocolDefinitions)();
|
|
290
|
+
const baseRules = new Map();
|
|
291
|
+
for (const p of defs)
|
|
292
|
+
for (const [fn, rule] of p.rules)
|
|
293
|
+
baseRules.set(fn, rule);
|
|
294
|
+
for (const inf of validated) {
|
|
295
|
+
if (inf.validation.status === "rejected") {
|
|
296
|
+
rejected++;
|
|
297
|
+
continue;
|
|
298
|
+
}
|
|
299
|
+
// 4. Propose
|
|
300
|
+
const patch = patchStore.propose(inf);
|
|
301
|
+
proposed++;
|
|
302
|
+
// 5. Regression test and auto-approve
|
|
303
|
+
const result = autoApprovePatch(patch, baseRules, testCases, patchStore);
|
|
304
|
+
regressionResults.push(result);
|
|
305
|
+
if (result.passed)
|
|
306
|
+
approved++;
|
|
307
|
+
else
|
|
308
|
+
rejected++;
|
|
309
|
+
}
|
|
310
|
+
return {
|
|
311
|
+
proposed,
|
|
312
|
+
verified: validated.filter(v => v.validation.status === "verified").length,
|
|
313
|
+
approved,
|
|
314
|
+
rejected,
|
|
315
|
+
rolledBack: patchStore.all.filter(p => p.status === "rolled_back").length,
|
|
316
|
+
regressionResults,
|
|
317
|
+
};
|
|
318
|
+
}
|
|
319
|
+
function printGovernanceReport(report) {
|
|
320
|
+
console.log("\n╔════════════════════════════════════════════════════╗");
|
|
321
|
+
console.log("║ Knowledge Governance Report ║");
|
|
322
|
+
console.log("╚════════════════════════════════════════════════════╝\n");
|
|
323
|
+
console.log(`Proposed: ${report.proposed}`);
|
|
324
|
+
console.log(`Verified: ${report.verified}`);
|
|
325
|
+
console.log(`Approved: ${report.approved}`);
|
|
326
|
+
console.log(`Rejected: ${report.rejected}`);
|
|
327
|
+
console.log(`Rolled Back: ${report.rolledBack}`);
|
|
328
|
+
console.log();
|
|
329
|
+
if (report.regressionResults.length > 0) {
|
|
330
|
+
console.log("─── Regression Results ───");
|
|
331
|
+
for (const r of report.regressionResults) {
|
|
332
|
+
const icon = r.passed ? "✅" : "❌";
|
|
333
|
+
console.log(` ${icon} ${r.change}`);
|
|
334
|
+
console.log(` ${r.reason}`);
|
|
335
|
+
}
|
|
336
|
+
console.log();
|
|
337
|
+
}
|
|
338
|
+
}
|