progmune-runtime 2.1.6 → 3.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +119 -461
- package/dist/ablation-study.js +144 -0
- package/dist/ablation-study.test.js +18 -0
- package/dist/action-runtime.js +3 -1
- package/dist/active-learning.js +211 -0
- package/dist/analytics.js +139 -0
- package/dist/asset-factory.js +309 -0
- package/dist/asset-growth.js +244 -0
- package/dist/asset-promotion.js +382 -0
- package/dist/asset-quality.js +550 -0
- package/dist/audit/business-translator.js +285 -0
- package/dist/audit/cli.js +66 -0
- package/dist/audit/formatters/html.js +379 -0
- package/dist/audit/formatters/json.js +11 -0
- package/dist/audit/formatters/markdown.js +192 -0
- package/dist/audit/formatters/terminal.js +189 -0
- package/dist/audit/index.js +25 -0
- package/dist/audit/report-builder.js +318 -0
- package/dist/audit/types.js +8 -0
- package/dist/audit.js +3 -3
- package/dist/auto-benchmark-generator.js +137 -0
- package/dist/auto-benchmark-generator.test.js +45 -0
- package/dist/auto-protocol-synthesizer.js +362 -0
- package/dist/auto-protocol-synthesizer.test.js +82 -0
- package/dist/autonomous-patch.js +175 -0
- package/dist/autonomous-patch.test.js +128 -0
- package/dist/badge/badge-server.js +98 -0
- package/dist/behavior-miner.js +442 -0
- package/dist/belief-layer.js +475 -0
- package/dist/benchmark-count.js +5 -0
- package/dist/benchmark-generator.js +211 -0
- package/dist/benchmark-harness.js +201 -0
- package/dist/benchmark-pass-rate.js +7 -0
- package/dist/benchmark-report.js +8 -3
- package/dist/benchmark-save.js +14 -1
- package/dist/bootstrap-validation.js +197 -0
- package/dist/bootstrap-validation.test.js +51 -0
- package/dist/branch-ledger.js +1 -1
- package/dist/capability-gap.js +130 -0
- package/dist/certify-html.js +351 -0
- package/dist/certify.js +326 -0
- package/dist/check.js +4 -4
- package/dist/compliance-miner.js +447 -0
- package/dist/continuous-benchmark.js +194 -0
- package/dist/continuous-benchmark.test.js +116 -0
- package/dist/corpus-stats.js +173 -0
- package/dist/counterfactual-engine.js +288 -0
- package/dist/coverage-dashboard.js +109 -0
- package/dist/coverage-system.test.js +205 -0
- package/dist/cross-repo-precision.js +352 -0
- package/dist/cve-benchmark.js +180 -0
- package/dist/cve-benchmark.test.js +28 -0
- package/dist/cve-collector.js +73 -0
- package/dist/data-quality.js +141 -0
- package/dist/decision-engine.js +388 -0
- package/dist/derive-metadata.js +250 -0
- package/dist/difficulty-active.test.js +198 -0
- package/dist/difficulty-map.js +244 -0
- package/dist/discovery-analytics.js +125 -0
- package/dist/discovery-model.js +149 -0
- package/dist/discovery-optimize.test.js +199 -0
- package/dist/discovery-trace.js +276 -0
- package/dist/discovery-trace.test.js +97 -0
- package/dist/emitter.js +83 -1
- package/dist/enterprise-dashboard.js +405 -0
- package/dist/eval-hardening.js +297 -0
- package/dist/eval-hardening.test.js +85 -0
- package/dist/evaluation-campaign.js +359 -0
- package/dist/evaluation-campaign.test.js +181 -0
- package/dist/evidence-growth.js +143 -0
- package/dist/evidence-repository.js +209 -0
- package/dist/evidence-system.js +441 -0
- package/dist/execute.js +15 -7
- package/dist/experimental/software-physics.js +291 -0
- package/dist/experimental/state-inference.js +516 -0
- package/dist/experimental/unsupervised-physics.js +230 -0
- package/dist/extract-ir-python.js +54 -7
- package/dist/extract-ir.js +376 -12
- package/dist/failure-collector.js +2 -2
- package/dist/failure-corpus.js +322 -9
- package/dist/feedback.js +16 -5
- package/dist/feedback.test.js +49 -0
- package/dist/file-lock.js +1 -1
- package/dist/flywheel-batch.js +292 -0
- package/dist/frameworks/express-cli.js +237 -0
- package/dist/frameworks/express-detector.js +445 -0
- package/dist/frameworks/express-detector.test.js +206 -0
- package/dist/frameworks/index.js +30 -0
- package/dist/frameworks/nestjs-detector.js +302 -0
- package/dist/frameworks/trpc-detector.js +161 -0
- package/dist/frameworks/version-awareness.js +179 -0
- package/dist/function-synonyms.js +164 -0
- package/dist/function-synonyms.test.js +68 -0
- package/dist/generalization.test.js +352 -0
- package/dist/goal-annotator.js +113 -0
- package/dist/goal-planner.js +563 -0
- package/dist/gold-cve.js +164 -0
- package/dist/gold-cve.test.js +104 -0
- package/dist/gold-quality.js +206 -0
- package/dist/gold-tiers.js +241 -0
- package/dist/governance-dashboard.js +327 -0
- package/dist/graph-viz.js +240 -0
- package/dist/guided-frontier.js +195 -0
- package/dist/hierarchical-planner.js +148 -0
- package/dist/identifier-parser.js +260 -0
- package/dist/immune-metrics.js +93 -0
- package/dist/immune-receiver.js +158 -0
- package/dist/immune-reporter.js +1 -1
- package/dist/improvement-orchestrator.js +206 -0
- package/dist/inject-p0-vocabulary.js +300 -0
- package/dist/intent-parser.js +218 -0
- package/dist/invariant-algebra.js +476 -0
- package/dist/invariant-calculus.js +533 -0
- package/dist/ir-utils.js +70 -0
- package/dist/ir-utils.test.js +50 -0
- package/dist/knowledge-api.js +312 -0
- package/dist/knowledge-evolution.js +452 -0
- package/dist/knowledge-explorer.js +506 -0
- package/dist/knowledge-flywheel.js +274 -0
- package/dist/knowledge-governance.js +338 -0
- package/dist/knowledge-governance.test.js +150 -0
- package/dist/knowledge-graph.js +181 -0
- package/dist/knowledge-guided-synth.js +246 -0
- package/dist/knowledge-loop.test.js +77 -0
- package/dist/knowledge-object.js +316 -0
- package/dist/knowledge-package.js +98 -0
- package/dist/kpi-dashboard.js +561 -0
- package/dist/l3-cross-function.js +280 -0
- package/dist/learning-ranker.js +148 -0
- package/dist/learning-ranker.test.js +291 -0
- package/dist/ledger/accountability.js +322 -0
- package/dist/ledger/chain-builder.js +185 -0
- package/dist/ledger/cli.js +222 -0
- package/dist/ledger/index.js +13 -0
- package/dist/ledger/signatures.js +193 -0
- package/dist/ledger/types.js +9 -0
- package/dist/llm.js +74 -3
- package/dist/load-benchmarks.js +8 -3
- package/dist/logger.js +66 -0
- package/dist/logger.test.js +37 -0
- package/dist/logistic-reward.js +339 -0
- package/dist/logistic-reward.test.js +180 -0
- package/dist/macro-graph.js +193 -0
- package/dist/macro-repair.js +183 -0
- package/dist/mcp-server.mjs +1202 -483
- package/dist/memory-layer.js +42 -5
- package/dist/multi-repo-precision.js +422 -0
- package/dist/name-free-protocol.js +425 -0
- package/dist/name-free-protocol.test.js +170 -0
- package/dist/name-scrambling.js +138 -0
- package/dist/name-scrambling.test.js +16 -0
- package/dist/p3-observability.test.js +281 -0
- package/dist/p5-orchestrator.test.js +225 -0
- package/dist/pairwise-preference.js +294 -0
- package/dist/pairwise-preference.test.js +140 -0
- package/dist/planner-constraints.js +104 -0
- package/dist/planner-prompts.js +155 -0
- package/dist/planner-telemetry.js +415 -0
- package/dist/planner-trace.js +214 -0
- package/dist/planner.js +162 -167
- package/dist/plsb/artifact.js +116 -0
- package/dist/plsb/cli.js +71 -0
- package/dist/plsb/index.js +19 -0
- package/dist/plsb/leaderboard.js +249 -0
- package/dist/plsb/report-md.js +156 -0
- package/dist/plsb/schema.js +179 -0
- package/dist/plsb-benchmark.js +284 -0
- package/dist/plsb-benchmark.test.js +119 -0
- package/dist/policy/cli.js +134 -0
- package/dist/policy/engine.js +333 -0
- package/dist/policy/index.js +12 -0
- package/dist/policy/types.js +59 -0
- package/dist/policy-miner.js +505 -0
- package/dist/precision-analyze.js +229 -0
- package/dist/precision-benchmark.js +147 -0
- package/dist/precision-label-c.js +134 -0
- package/dist/precision-label.js +193 -0
- package/dist/precision-report-c.js +149 -0
- package/dist/precision-report.js +246 -0
- package/dist/progmune-status.js +108 -0
- package/dist/proof-engine.js +479 -0
- package/dist/proof-provenance.js +315 -0
- package/dist/protocol-coverage.js +294 -0
- package/dist/protocol-detector.js +1189 -0
- package/dist/protocol-embedding-expanded.js +297 -0
- package/dist/protocol-embedding-expanded.test.js +97 -0
- package/dist/protocol-embedding.js +195 -0
- package/dist/protocol-embedding.test.js +82 -0
- package/dist/protocol-extractor-v2.js +354 -0
- package/dist/protocol-extractor-v2.test.js +140 -0
- package/dist/protocol-extractor.js +310 -0
- package/dist/protocol-extractor.test.js +113 -0
- package/dist/protocol-foundation.js +322 -0
- package/dist/protocol-foundation.test.js +163 -0
- package/dist/protocol-frontier.js +243 -0
- package/dist/protocol-frontier.test.js +92 -0
- package/dist/protocol-gap-analyzer.js +228 -0
- package/dist/protocol-gap-analyzer.test.js +49 -0
- package/dist/protocol-invariants.js +276 -0
- package/dist/protocol-invariants.test.js +111 -0
- package/dist/protocol-knowledge.js +464 -0
- package/dist/protocol-miner.js +343 -0
- package/dist/protocol-mining.js +207 -0
- package/dist/protocol-mining.test.js +37 -0
- package/dist/protocol-registry.js +1 -1
- package/dist/protocol-security-benchmark.js +222 -0
- package/dist/protocol-vulnerability.js +257 -0
- package/dist/protocol-vulnerability.test.js +60 -0
- package/dist/python-benchmark.js +120 -0
- package/dist/python-emitter.js +163 -45
- package/dist/python-protocol-extractor.js +187 -0
- package/dist/python-protocol-extractor.test.js +116 -0
- package/dist/realworld-benchmark.js +646 -0
- package/dist/realworld-benchmark.test.js +36 -0
- package/dist/repair-arch.test.js +411 -0
- package/dist/repair-evolution.test.js +454 -0
- package/dist/repair-executor.js +719 -0
- package/dist/repair-proposal.js +4 -4
- package/dist/repair-ranker.js +141 -0
- package/dist/repair-strategies.js +419 -0
- package/dist/repair-taxonomy.js +234 -0
- package/dist/repair-types.js +12 -0
- package/dist/repo-evaluator.js +250 -0
- package/dist/repo-evaluator.test.js +128 -0
- package/dist/resource-abstraction.js +242 -0
- package/dist/resource-detector.js +211 -0
- package/dist/result.test.js +43 -0
- package/dist/reward-system.js +411 -0
- package/dist/reward-system.test.js +175 -0
- package/dist/risk-model.js +215 -0
- package/dist/rule-miner.js +234 -7
- package/dist/rule-specificity.js +254 -0
- package/dist/runtime-types.js +27 -0
- package/dist/scaffold.js +208 -0
- package/dist/scale-collector.test.js +101 -0
- package/dist/scale-trajectory-collector.js +128 -0
- package/dist/sdk.js +250 -0
- package/dist/search-planner.js +4 -41
- package/dist/semantic-snapshot.js +1 -1
- package/dist/semantic-topology.js +121 -0
- package/dist/semantic-trace.js +310 -317
- package/dist/sequence-extractor.js +343 -0
- package/dist/skill-library.js +245 -0
- package/dist/skill-planner.test.js +189 -0
- package/dist/software-physics.js +291 -0
- package/dist/software-physics.test.js +81 -0
- package/dist/ssg-precision.js +478 -0
- package/dist/ssg-validator.js +71 -21
- package/dist/state-inference-doubleblind.test.js +160 -0
- package/dist/state-inference.js +516 -0
- package/dist/state-inference.test.js +115 -0
- package/dist/state-machine-fingerprint.js +345 -0
- package/dist/state-machine-fingerprint.test.js +120 -0
- package/dist/state-miner.js +386 -0
- package/dist/state-name-inference.js +213 -0
- package/dist/state-name-inference.test.js +69 -0
- package/dist/strategy-planner.js +262 -96
- package/dist/strategy-planner.test.js +135 -0
- package/dist/telemetry-analytics.test.js +402 -0
- package/dist/terminal-format.js +68 -0
- package/dist/terminal-format.test.js +83 -0
- package/dist/topology-factory.js +196 -0
- package/dist/topology-representation.js +242 -0
- package/dist/topology-representation.test.js +27 -0
- package/dist/trajectory-augmentation.js +254 -0
- package/dist/trajectory-augmentation.test.js +63 -0
- package/dist/trajectory-corpus.js +440 -0
- package/dist/trajectory-corpus.test.js +32 -0
- package/dist/trajectory-feedback.test.js +116 -0
- package/dist/transition-synthesizer.js +286 -0
- package/dist/transition-synthesizer.test.js +123 -0
- package/dist/trust/api-semantic-mapper.js +809 -0
- package/dist/trust/call-graph-propagator.js +225 -0
- package/dist/trust/cli.js +122 -0
- package/dist/trust/compliance-scorer.js +283 -0
- package/dist/trust/confidence-calculator.js +261 -0
- package/dist/trust/engine.js +1145 -0
- package/dist/trust/explainability.js +85 -0
- package/dist/trust/formatters/ci.js +42 -0
- package/dist/trust/formatters/json.js +11 -0
- package/dist/trust/formatters/terminal.js +152 -0
- package/dist/trust/index.js +39 -0
- package/dist/trust/phase1-verify.js +171 -0
- package/dist/trust/protocol-domain-validator.js +697 -0
- package/dist/trust/score-calculator.js +282 -0
- package/dist/trust/ssg-bridge.js +641 -0
- package/dist/trust/ssg-bridge.test.js +269 -0
- package/dist/trust/types.js +67 -0
- package/dist/trust/violation-trace.js +335 -0
- package/dist/trust-api.js +179 -0
- package/dist/trust-calibration.js +279 -0
- package/dist/unknown-protocol-discovery.js +339 -0
- package/dist/unknown-protocol-discovery.test.js +102 -0
- package/dist/unsupervised-physics.js +230 -0
- package/dist/unsupervised-physics.test.js +95 -0
- package/dist/utils.test.js +37 -0
- package/dist/validator.js +187 -10
- package/dist/verification-intelligence.js +475 -0
- package/dist/verify-api.js +432 -0
- package/dist/vi-impact-report.js +293 -0
- package/dist/wl-fingerprint.js +162 -0
- package/dist/wl-fingerprint.test.js +130 -0
- package/dist/zeroshot-strategy.js +139 -0
- package/docs/Progmune_/346/212/225/350/265/204/344/272/272/347/231/275/347/232/256/344/271/246_v2.0.html +576 -0
- package/docs/Progmune_/351/241/271/347/233/256/345/205/250/350/247/243.html +721 -0
- package/package.json +73 -6
- package/protocols.json +1956 -50
- package/.dockerignore +0 -14
- package/.mcp.json +0 -11
- package/.progmune_allowlist +0 -50
- package/.test_report/test_report.md +0 -87
- package/Dockerfile +0 -9
- package/FAQ.md +0 -167
- package/WHITEPAPER.md +0 -540
- package/demo-project/auth.ts +0 -55
- package/demo-project/tsconfig.json +0 -8
- package/dist/acl-breakdown.js +0 -13
- package/dist/all-sessions.js +0 -11
- package/dist/antibody-stats.js +0 -11
- package/dist/branch-tree-count.js +0 -14
- package/dist/common-fixpath.js +0 -12
- package/dist/constraint-types.js +0 -12
- package/dist/exec-metrics.js +0 -11
- package/dist/failure-report.js +0 -11
- package/dist/fast-path-hits.js +0 -13
- package/dist/fingerprint-list.js +0 -15
- package/dist/gen-history-log.js +0 -13
- package/dist/heatmap-data.js +0 -11
- package/dist/recent-session.js +0 -12
- package/dist/svl-distribution.js +0 -11
- package/dist/terminal-status.js +0 -11
- package/dist/token-savings.js +0 -11
- package/dist/total-repairs.js +0 -12
- package/dist/unresolved-count.js +0 -12
- package/dist/valid-fingerprints.js +0 -13
- package/dist/verify-ledgers.js +0 -11
- package/docs/whitepaper-style.css +0 -77
- package/docs/whitepaper-v2.1.md +0 -609
- package/docs/whitepaper-v2.2.md +0 -1064
- package/docs/whitepaper-v2.2.pdf +0 -0
- package/fly.toml +0 -31
- package/public/dashboard.html +0 -119
- package/server/hub.js +0 -116
- package/test/replay-golden/sess_1780063202050_mgeld.json +0 -9
- package/test/replay-golden/sess_1780064032560_gocld.json +0 -354
- package/test/replay-golden/sess_1780064413331_s2709.json +0 -606
- package/test/replay-golden/sess_1780064792710_y3avo.json +0 -614
- package/test/replay-golden.ts +0 -84
- package/test_benchmark.js +0 -165
- package/test_comprehensive.mjs +0 -638
- package/test_concurrency.js +0 -129
- package/test_ir_robustness.js +0 -85
- package/test_semantic_contracts.js +0 -269
- package/test_ssg_stress.js +0 -156
- package/test_svl3.js +0 -58
- package/tsconfig.json +0 -17
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Phase 1: Trust API Server
|
|
4
|
+
*
|
|
5
|
+
* Standalone HTTP REST API for the AI Trust Decision Engine.
|
|
6
|
+
* Primary endpoint: POST /trust/check
|
|
7
|
+
*
|
|
8
|
+
* Port: PROGMUNE_TRUST_PORT (default 3301)
|
|
9
|
+
* Auth: PROGMUNE_TRUST_API_KEY (optional)
|
|
10
|
+
*
|
|
11
|
+
* Usage:
|
|
12
|
+
* npx ts-node src/trust-api.ts
|
|
13
|
+
* PROGMUNE_TRUST_PORT=3301 npx ts-node src/trust-api.ts
|
|
14
|
+
*/
|
|
15
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
16
|
+
if (k2 === undefined) k2 = k;
|
|
17
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
18
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
19
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
20
|
+
}
|
|
21
|
+
Object.defineProperty(o, k2, desc);
|
|
22
|
+
}) : (function(o, m, k, k2) {
|
|
23
|
+
if (k2 === undefined) k2 = k;
|
|
24
|
+
o[k2] = m[k];
|
|
25
|
+
}));
|
|
26
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
27
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
28
|
+
}) : function(o, v) {
|
|
29
|
+
o["default"] = v;
|
|
30
|
+
});
|
|
31
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
32
|
+
var ownKeys = function(o) {
|
|
33
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
34
|
+
var ar = [];
|
|
35
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
36
|
+
return ar;
|
|
37
|
+
};
|
|
38
|
+
return ownKeys(o);
|
|
39
|
+
};
|
|
40
|
+
return function (mod) {
|
|
41
|
+
if (mod && mod.__esModule) return mod;
|
|
42
|
+
var result = {};
|
|
43
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
44
|
+
__setModuleDefault(result, mod);
|
|
45
|
+
return result;
|
|
46
|
+
};
|
|
47
|
+
})();
|
|
48
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
49
|
+
exports.server = void 0;
|
|
50
|
+
const http = __importStar(require("http"));
|
|
51
|
+
const path = __importStar(require("path"));
|
|
52
|
+
const PORT = parseInt(process.env.PROGMUNE_TRUST_PORT || "3301", 10);
|
|
53
|
+
const API_KEY = process.env.PROGMUNE_TRUST_API_KEY || "";
|
|
54
|
+
const RATE_LIMIT = parseInt(process.env.PROGMUNE_TRUST_RATE_LIMIT || "100", 10);
|
|
55
|
+
const RATE_WINDOW = parseInt(process.env.PROGMUNE_TRUST_RATE_WINDOW || "3600000", 10);
|
|
56
|
+
// Rate limiting
|
|
57
|
+
const rateMap = new Map();
|
|
58
|
+
function checkRateLimit(ip) {
|
|
59
|
+
if (!API_KEY)
|
|
60
|
+
return true;
|
|
61
|
+
const now = Date.now();
|
|
62
|
+
const entry = rateMap.get(ip);
|
|
63
|
+
if (!entry || now > entry.resetAt) {
|
|
64
|
+
rateMap.set(ip, { count: 1, resetAt: now + RATE_WINDOW });
|
|
65
|
+
return true;
|
|
66
|
+
}
|
|
67
|
+
if (entry.count >= RATE_LIMIT)
|
|
68
|
+
return false;
|
|
69
|
+
entry.count++;
|
|
70
|
+
return true;
|
|
71
|
+
}
|
|
72
|
+
// ═══════════════════════════════════════════════════════════════
|
|
73
|
+
// Helpers
|
|
74
|
+
// ═══════════════════════════════════════════════════════════════
|
|
75
|
+
function json(res, data, status = 200) {
|
|
76
|
+
res.writeHead(status, {
|
|
77
|
+
"Content-Type": "application/json",
|
|
78
|
+
"Access-Control-Allow-Origin": "*",
|
|
79
|
+
"Access-Control-Allow-Methods": "POST, GET, OPTIONS",
|
|
80
|
+
"Access-Control-Allow-Headers": "Content-Type, Authorization",
|
|
81
|
+
});
|
|
82
|
+
res.end(JSON.stringify(data));
|
|
83
|
+
}
|
|
84
|
+
function getClientIp(req) {
|
|
85
|
+
const forwarded = req.headers["x-forwarded-for"];
|
|
86
|
+
if (typeof forwarded === "string")
|
|
87
|
+
return forwarded.split(",")[0].trim();
|
|
88
|
+
return req.socket?.remoteAddress || "unknown";
|
|
89
|
+
}
|
|
90
|
+
// ═══════════════════════════════════════════════════════════════
|
|
91
|
+
// Server
|
|
92
|
+
// ═══════════════════════════════════════════════════════════════
|
|
93
|
+
const server = http.createServer((req, res) => {
|
|
94
|
+
// CORS preflight
|
|
95
|
+
if (req.method === "OPTIONS") {
|
|
96
|
+
res.writeHead(204, {
|
|
97
|
+
"Access-Control-Allow-Origin": "*",
|
|
98
|
+
"Access-Control-Allow-Methods": "POST, GET, OPTIONS",
|
|
99
|
+
"Access-Control-Allow-Headers": "Content-Type, Authorization",
|
|
100
|
+
});
|
|
101
|
+
res.end();
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
const url = req.url || "/";
|
|
105
|
+
const ip = getClientIp(req);
|
|
106
|
+
// ── Health ──
|
|
107
|
+
if (url === "/health" && req.method === "GET") {
|
|
108
|
+
json(res, {
|
|
109
|
+
status: "healthy",
|
|
110
|
+
service: "progmune-trust-api",
|
|
111
|
+
version: "1.0.0",
|
|
112
|
+
timestamp: new Date().toISOString(),
|
|
113
|
+
});
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
// ── Trust Check ──
|
|
117
|
+
if (url === "/trust/check" && req.method === "POST") {
|
|
118
|
+
// API key auth
|
|
119
|
+
if (API_KEY) {
|
|
120
|
+
const auth = req.headers["authorization"] || "";
|
|
121
|
+
if (!auth.includes(API_KEY)) {
|
|
122
|
+
json(res, { error: "Unauthorized — invalid or missing API key" }, 401);
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
// Rate limit
|
|
127
|
+
if (!checkRateLimit(ip)) {
|
|
128
|
+
json(res, { error: "Rate limit exceeded" }, 429);
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
let body = "";
|
|
132
|
+
req.on("data", (chunk) => (body += chunk));
|
|
133
|
+
req.on("end", () => {
|
|
134
|
+
try {
|
|
135
|
+
const input = JSON.parse(body);
|
|
136
|
+
if (!input.project) {
|
|
137
|
+
json(res, { error: "Missing required field: project" }, 400);
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
140
|
+
const { evaluateTrust } = require("./trust");
|
|
141
|
+
const decision = evaluateTrust({
|
|
142
|
+
projectPath: input.project,
|
|
143
|
+
projectName: path.basename(input.project),
|
|
144
|
+
commit: input.commit || "unknown",
|
|
145
|
+
branch: input.branch,
|
|
146
|
+
policyName: input.policy,
|
|
147
|
+
language: input.context?.language,
|
|
148
|
+
previousCommit: input.context?.previousCommit,
|
|
149
|
+
});
|
|
150
|
+
json(res, decision);
|
|
151
|
+
}
|
|
152
|
+
catch (e) {
|
|
153
|
+
json(res, {
|
|
154
|
+
error: `Trust evaluation failed: ${e.message}`,
|
|
155
|
+
timestamp: new Date().toISOString(),
|
|
156
|
+
}, 500);
|
|
157
|
+
}
|
|
158
|
+
});
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
161
|
+
// ── 404 ──
|
|
162
|
+
json(res, {
|
|
163
|
+
error: "Not Found",
|
|
164
|
+
availableEndpoints: [
|
|
165
|
+
"POST /trust/check",
|
|
166
|
+
"GET /health",
|
|
167
|
+
],
|
|
168
|
+
}, 404);
|
|
169
|
+
});
|
|
170
|
+
exports.server = server;
|
|
171
|
+
server.listen(PORT, () => {
|
|
172
|
+
console.log(`🔒 Progmune Trust API server running on http://localhost:${PORT}`);
|
|
173
|
+
console.log(` Endpoints:`);
|
|
174
|
+
console.log(` POST /trust/check — Evaluate trust for a project`);
|
|
175
|
+
console.log(` GET /health — Service health check`);
|
|
176
|
+
if (API_KEY)
|
|
177
|
+
console.log(` API key auth: enabled`);
|
|
178
|
+
console.log("");
|
|
179
|
+
});
|
|
@@ -0,0 +1,279 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* P6: Trust Calibration — Explainable Confidence
|
|
4
|
+
*
|
|
5
|
+
* Every verification decision carries a confidence score.
|
|
6
|
+
* This module decomposes that score into its evidence components.
|
|
7
|
+
*
|
|
8
|
+
* Not: "confidence = 85%"
|
|
9
|
+
* But: "85% because:
|
|
10
|
+
* RFC 8446 alignment (+30%)
|
|
11
|
+
* 3 repos validated (+25%)
|
|
12
|
+
* FP history clean (+20%)
|
|
13
|
+
* Rule specificity high (+10%)
|
|
14
|
+
* "
|
|
15
|
+
*
|
|
16
|
+
* Architecture:
|
|
17
|
+
* Confidence = Σ(evidence_weight × evidence_strength) / Σ(weights)
|
|
18
|
+
*
|
|
19
|
+
* Evidence sources:
|
|
20
|
+
* 1. RFC_ALIGNMENT — Does this rule trace to a standard?
|
|
21
|
+
* 2. REPO_VALIDATION — How many repos support this rule?
|
|
22
|
+
* 3. FP_HISTORY — Is this rule's FP rate low?
|
|
23
|
+
* 4. RULE_SPECIFICITY — How specific are the pre/post conditions?
|
|
24
|
+
* 5. REPAIR_VERIFIED — Has the repair been validated?
|
|
25
|
+
* 6. DEPLOYMENT_OBS — Has this been observed in real deployments?
|
|
26
|
+
* 7. HUMAN_REVIEWED — Has a human approved this rule?
|
|
27
|
+
*/
|
|
28
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
29
|
+
exports.TrustCalibrator = void 0;
|
|
30
|
+
exports.getTrustCalibrator = getTrustCalibrator;
|
|
31
|
+
exports.formatConfidenceTree = formatConfidenceTree;
|
|
32
|
+
// ═══════════════════════════════════════════════════════════════
|
|
33
|
+
// Trust Calibrator
|
|
34
|
+
// ═══════════════════════════════════════════════════════════════
|
|
35
|
+
class TrustCalibrator {
|
|
36
|
+
/**
|
|
37
|
+
* Decompose a confidence score into its evidence components.
|
|
38
|
+
*
|
|
39
|
+
* This is the "explain why" behind every verification decision.
|
|
40
|
+
*/
|
|
41
|
+
explainConfidence(params) {
|
|
42
|
+
const components = [];
|
|
43
|
+
// 1. RFC Alignment (weight: 0.25)
|
|
44
|
+
const rfcRefs = params.rfcRefs || [];
|
|
45
|
+
const rfcStrength = rfcRefs.length > 0
|
|
46
|
+
? Math.min(1.0, rfcRefs.length * 0.5)
|
|
47
|
+
: 0;
|
|
48
|
+
components.push({
|
|
49
|
+
source: "RFC_ALIGNMENT",
|
|
50
|
+
label: "RFC Alignment",
|
|
51
|
+
weight: 0.25,
|
|
52
|
+
strength: rfcStrength,
|
|
53
|
+
contribution: 0.25 * rfcStrength,
|
|
54
|
+
detail: rfcRefs.length > 0
|
|
55
|
+
? `Traces to ${rfcRefs.map(r => `RFC ${r}`).join(", ")}`
|
|
56
|
+
: "No RFC reference — rule is empirically derived",
|
|
57
|
+
references: rfcRefs,
|
|
58
|
+
});
|
|
59
|
+
// 2. Repo Validation (weight: 0.20)
|
|
60
|
+
const repos = params.validatedRepos || [];
|
|
61
|
+
const repoStrength = Math.min(1.0, repos.length / 5); // 5 repos = full strength
|
|
62
|
+
components.push({
|
|
63
|
+
source: "REPO_VALIDATION",
|
|
64
|
+
label: "Repository Validation",
|
|
65
|
+
weight: 0.20,
|
|
66
|
+
strength: repoStrength,
|
|
67
|
+
contribution: 0.20 * repoStrength,
|
|
68
|
+
detail: repos.length > 0
|
|
69
|
+
? `Validated across ${repos.length} repos: ${repos.join(", ")}`
|
|
70
|
+
: "Not yet validated across repositories",
|
|
71
|
+
references: repos,
|
|
72
|
+
});
|
|
73
|
+
// 3. FP History (weight: 0.20)
|
|
74
|
+
const fpCount = params.fpCount || 0;
|
|
75
|
+
const tpCount = params.tpCount || 0;
|
|
76
|
+
const total = fpCount + tpCount;
|
|
77
|
+
const fpRate = total > 0 ? fpCount / total : 0;
|
|
78
|
+
const fpStrength = total === 0 ? 0.5 // No data = neutral
|
|
79
|
+
: fpRate === 0 ? 1.0 // Perfect
|
|
80
|
+
: fpRate < 0.1 ? 0.8
|
|
81
|
+
: fpRate < 0.3 ? 0.5
|
|
82
|
+
: fpRate < 0.5 ? 0.3
|
|
83
|
+
: 0.1;
|
|
84
|
+
components.push({
|
|
85
|
+
source: "FP_HISTORY",
|
|
86
|
+
label: "False Positive History",
|
|
87
|
+
weight: 0.20,
|
|
88
|
+
strength: fpStrength,
|
|
89
|
+
contribution: 0.20 * fpStrength,
|
|
90
|
+
detail: total === 0
|
|
91
|
+
? "No alert history yet — confidence is neutral"
|
|
92
|
+
: fpRate === 0
|
|
93
|
+
? `Perfect: ${tpCount} TP, 0 FP`
|
|
94
|
+
: `${fpCount} FP / ${total} total alerts (${(fpRate * 100).toFixed(0)}% FP rate)`,
|
|
95
|
+
references: [],
|
|
96
|
+
});
|
|
97
|
+
// 4. Rule Specificity (weight: 0.15)
|
|
98
|
+
const preCount = (params.rulePreStates || []).length;
|
|
99
|
+
const postCount = (params.rulePostStates || []).length;
|
|
100
|
+
const specificityStrength = preCount + postCount >= 4 ? 1.0
|
|
101
|
+
: preCount + postCount >= 2 ? 0.7
|
|
102
|
+
: 0.3;
|
|
103
|
+
components.push({
|
|
104
|
+
source: "RULE_SPECIFICITY",
|
|
105
|
+
label: "Rule Specificity",
|
|
106
|
+
weight: 0.15,
|
|
107
|
+
strength: specificityStrength,
|
|
108
|
+
contribution: 0.15 * specificityStrength,
|
|
109
|
+
detail: `${preCount} pre-states + ${postCount} post-states — ${specificityStrength >= 0.7 ? "well-specified" : "broad match"}`,
|
|
110
|
+
references: [],
|
|
111
|
+
});
|
|
112
|
+
// 5. Repair Verified (weight: 0.10)
|
|
113
|
+
const repairStrength = params.repairVerified ? 1.0 : 0;
|
|
114
|
+
components.push({
|
|
115
|
+
source: "REPAIR_VERIFIED",
|
|
116
|
+
label: "Repair Verified",
|
|
117
|
+
weight: 0.10,
|
|
118
|
+
strength: repairStrength,
|
|
119
|
+
contribution: 0.10 * repairStrength,
|
|
120
|
+
detail: params.repairVerified
|
|
121
|
+
? "Automatic repair has been tested and verified"
|
|
122
|
+
: "Repair not yet validated for this rule",
|
|
123
|
+
references: [],
|
|
124
|
+
});
|
|
125
|
+
// 6. Deployment Observations (weight: 0.05)
|
|
126
|
+
const deployObs = params.deploymentObservations || 0;
|
|
127
|
+
const deployStrength = Math.min(1.0, deployObs / 100);
|
|
128
|
+
components.push({
|
|
129
|
+
source: "DEPLOYMENT_OBS",
|
|
130
|
+
label: "Deployment Observations",
|
|
131
|
+
weight: 0.05,
|
|
132
|
+
strength: deployStrength,
|
|
133
|
+
contribution: 0.05 * deployStrength,
|
|
134
|
+
detail: deployObs > 0
|
|
135
|
+
? `Observed in ${deployObs} production deployments`
|
|
136
|
+
: "No production deployment data yet",
|
|
137
|
+
references: [],
|
|
138
|
+
});
|
|
139
|
+
// 7. Human Reviewed (weight: 0.05)
|
|
140
|
+
const humanStrength = params.humanReviewed ? 1.0 : 0;
|
|
141
|
+
components.push({
|
|
142
|
+
source: "HUMAN_REVIEWED",
|
|
143
|
+
label: "Human Reviewed",
|
|
144
|
+
weight: 0.05,
|
|
145
|
+
strength: humanStrength,
|
|
146
|
+
contribution: 0.05 * humanStrength,
|
|
147
|
+
detail: params.humanReviewed
|
|
148
|
+
? "Reviewed and approved by a human expert"
|
|
149
|
+
: "Not yet human-reviewed",
|
|
150
|
+
references: [],
|
|
151
|
+
});
|
|
152
|
+
// Calculate total confidence
|
|
153
|
+
const totalWeight = components.reduce((s, c) => s + c.weight, 0);
|
|
154
|
+
const totalConfidence = components.reduce((s, c) => s + c.contribution, 0) / totalWeight;
|
|
155
|
+
// Build explanation chain
|
|
156
|
+
const explanation = components
|
|
157
|
+
.filter(c => c.strength > 0)
|
|
158
|
+
.sort((a, b) => b.contribution - a.contribution)
|
|
159
|
+
.map(c => ` ${c.label}: ${c.detail}`);
|
|
160
|
+
// Improvement suggestions
|
|
161
|
+
const suggestions = [];
|
|
162
|
+
if (rfcStrength === 0)
|
|
163
|
+
suggestions.push("Link rule to an RFC standard");
|
|
164
|
+
if (repoStrength < 0.6)
|
|
165
|
+
suggestions.push(`Validate on ${Math.max(0, 5 - repos.length)} more repos`);
|
|
166
|
+
if (fpRate >= 0.3)
|
|
167
|
+
suggestions.push("Investigate and reduce false positive rate");
|
|
168
|
+
if (specificityStrength < 0.7)
|
|
169
|
+
suggestions.push("Add more specific pre/post states to narrow the rule");
|
|
170
|
+
if (!params.repairVerified)
|
|
171
|
+
suggestions.push("Validate automatic repair for this rule");
|
|
172
|
+
if (deployObs < 10)
|
|
173
|
+
suggestions.push("Collect production deployment observations");
|
|
174
|
+
if (!params.humanReviewed)
|
|
175
|
+
suggestions.push("Submit for human expert review");
|
|
176
|
+
return {
|
|
177
|
+
ruleName: params.ruleName,
|
|
178
|
+
protocol: params.protocol,
|
|
179
|
+
totalConfidence,
|
|
180
|
+
components,
|
|
181
|
+
summary: `Confidence ${(totalConfidence * 100).toFixed(0)}% — ${explanation.length} evidence sources`,
|
|
182
|
+
explanation,
|
|
183
|
+
improvementSuggestions: suggestions,
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
exports.TrustCalibrator = TrustCalibrator;
|
|
188
|
+
// ═══════════════════════════════════════════════════════════════
|
|
189
|
+
// Singleton
|
|
190
|
+
// ═══════════════════════════════════════════════════════════════
|
|
191
|
+
let _calibrator = null;
|
|
192
|
+
function getTrustCalibrator() {
|
|
193
|
+
if (!_calibrator)
|
|
194
|
+
_calibrator = new TrustCalibrator();
|
|
195
|
+
return _calibrator;
|
|
196
|
+
}
|
|
197
|
+
// ═══════════════════════════════════════════════════════════════
|
|
198
|
+
// Report Formatter
|
|
199
|
+
// ═══════════════════════════════════════════════════════════════
|
|
200
|
+
function formatConfidenceTree(tree) {
|
|
201
|
+
const lines = [];
|
|
202
|
+
lines.push("");
|
|
203
|
+
lines.push("╔══════════════════════════════════════════════════════════════╗");
|
|
204
|
+
lines.push("║ Trust Calibration — Explainable Confidence ║");
|
|
205
|
+
lines.push("╠══════════════════════════════════════════════════════════════╣");
|
|
206
|
+
lines.push(`║ Rule: ${tree.protocol}:${tree.ruleName}`.padEnd(63) + "║");
|
|
207
|
+
lines.push(`║ Confidence: ${(tree.totalConfidence * 100).toFixed(0)}%`.padEnd(63) + "║");
|
|
208
|
+
lines.push("╚══════════════════════════════════════════════════════════════╝");
|
|
209
|
+
lines.push("");
|
|
210
|
+
// Evidence breakdown
|
|
211
|
+
lines.push("── Evidence Breakdown ──");
|
|
212
|
+
lines.push("┌─────────────────────────┬────────┬──────────┬──────────────────────────────────┐");
|
|
213
|
+
lines.push("│ Evidence Source │ Weight │ Strength │ Detail │");
|
|
214
|
+
lines.push("├─────────────────────────┼────────┼──────────┼──────────────────────────────────┤");
|
|
215
|
+
const sorted = [...tree.components].sort((a, b) => b.contribution - a.contribution);
|
|
216
|
+
for (const c of sorted) {
|
|
217
|
+
const bar = "█".repeat(Math.round(c.strength * 10)) + "░".repeat(10 - Math.round(c.strength * 10));
|
|
218
|
+
const detail = c.detail.slice(0, 32);
|
|
219
|
+
lines.push(`│ ${c.label.padEnd(23)} │ ${(c.weight * 100).toFixed(0).padStart(2)}% │ ${bar} │ ${detail.padEnd(32)} │`);
|
|
220
|
+
}
|
|
221
|
+
lines.push("└─────────────────────────┴────────┴──────────┴──────────────────────────────────┘");
|
|
222
|
+
lines.push("");
|
|
223
|
+
// Explanation chain
|
|
224
|
+
lines.push("── Why This Confidence? ──");
|
|
225
|
+
if (tree.explanation.length === 0) {
|
|
226
|
+
lines.push(" No evidence available yet.");
|
|
227
|
+
}
|
|
228
|
+
else {
|
|
229
|
+
for (const e of tree.explanation) {
|
|
230
|
+
lines.push(e);
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
lines.push("");
|
|
234
|
+
// Improvement suggestions
|
|
235
|
+
if (tree.improvementSuggestions.length > 0) {
|
|
236
|
+
lines.push("── To Increase Confidence ──");
|
|
237
|
+
for (const s of tree.improvementSuggestions) {
|
|
238
|
+
lines.push(` • ${s}`);
|
|
239
|
+
}
|
|
240
|
+
lines.push("");
|
|
241
|
+
}
|
|
242
|
+
return lines.join("\n");
|
|
243
|
+
}
|
|
244
|
+
// ═══════════════════════════════════════════════════════════════
|
|
245
|
+
// CLI Demo
|
|
246
|
+
// ═══════════════════════════════════════════════════════════════
|
|
247
|
+
if (require.main === module) {
|
|
248
|
+
const calibrator = new TrustCalibrator();
|
|
249
|
+
// Demo: TLS Handshake rule
|
|
250
|
+
const tls = calibrator.explainConfidence({
|
|
251
|
+
ruleName: "tls_handshake",
|
|
252
|
+
protocol: "TLS",
|
|
253
|
+
rfcRefs: ["8446"],
|
|
254
|
+
validatedRepos: ["curl", "nginx", "openssl"],
|
|
255
|
+
fpCount: 2,
|
|
256
|
+
tpCount: 18,
|
|
257
|
+
rulePreStates: ["TLS_INIT", "CIPHER_NEGOTIATED"],
|
|
258
|
+
rulePostStates: ["HANDSHAKE_COMPLETE", "SESSION_ESTABLISHED"],
|
|
259
|
+
repairVerified: true,
|
|
260
|
+
deploymentObservations: 45,
|
|
261
|
+
humanReviewed: true,
|
|
262
|
+
});
|
|
263
|
+
console.log(formatConfidenceTree(tls));
|
|
264
|
+
// Demo: Low-confidence rule
|
|
265
|
+
const low = calibrator.explainConfidence({
|
|
266
|
+
ruleName: "unknown_pattern",
|
|
267
|
+
protocol: "CustomProtocol",
|
|
268
|
+
rfcRefs: [],
|
|
269
|
+
validatedRepos: ["test-only"],
|
|
270
|
+
fpCount: 15,
|
|
271
|
+
tpCount: 3,
|
|
272
|
+
rulePreStates: [],
|
|
273
|
+
rulePostStates: ["SOME_STATE"],
|
|
274
|
+
repairVerified: false,
|
|
275
|
+
deploymentObservations: 0,
|
|
276
|
+
humanReviewed: false,
|
|
277
|
+
});
|
|
278
|
+
console.log(formatConfidenceTree(low));
|
|
279
|
+
}
|