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,382 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* P7: Unified Asset Promotion Pipeline
|
|
4
|
+
*
|
|
5
|
+
* Every asset in Progmune — whether a Knowledge Unit or a Verification Rule —
|
|
6
|
+
* follows the same lifecycle. One governance model, one promotion engine.
|
|
7
|
+
*
|
|
8
|
+
* Lifecycle:
|
|
9
|
+
* Evidence → Candidate → Observed → Validated → Stable → Deprecated → Archived
|
|
10
|
+
*
|
|
11
|
+
* This REPLACES the two separate lifecycles:
|
|
12
|
+
* - Knowledge lifecycle (knowledge-evolution.ts)
|
|
13
|
+
* - Rule lifecycle (verification-intelligence.ts)
|
|
14
|
+
*
|
|
15
|
+
* With ONE unified pipeline. Like GitHub PRs — assets are reviewed, merged, promoted.
|
|
16
|
+
*
|
|
17
|
+
* Core principles:
|
|
18
|
+
* 1. Observed ≠ Protocol. Observed patterns are Candidates, not Rules.
|
|
19
|
+
* 2. Frequency determines Confidence, NOT Importance.
|
|
20
|
+
* 3. Promotion requires evidence gates, not just counts.
|
|
21
|
+
* 4. Review happens on Candidates before they become Stable Assets.
|
|
22
|
+
*/
|
|
23
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
24
|
+
exports.AssetPromotionEngine = exports.PROMOTION_GATES = exports.STAGE_LABELS = exports.STAGE_ORDER = void 0;
|
|
25
|
+
exports.getAssetPromotionEngine = getAssetPromotionEngine;
|
|
26
|
+
exports.formatPipelineReport = formatPipelineReport;
|
|
27
|
+
exports.STAGE_ORDER = {
|
|
28
|
+
evidence: 0,
|
|
29
|
+
hypothesis: 1,
|
|
30
|
+
candidate: 2,
|
|
31
|
+
observed: 3,
|
|
32
|
+
validated: 4,
|
|
33
|
+
deployment: 5,
|
|
34
|
+
stable: 6,
|
|
35
|
+
deprecated: 7,
|
|
36
|
+
archived: 8,
|
|
37
|
+
};
|
|
38
|
+
exports.STAGE_LABELS = {
|
|
39
|
+
evidence: "Evidence",
|
|
40
|
+
hypothesis: "Hypothesis",
|
|
41
|
+
candidate: "Candidate",
|
|
42
|
+
observed: "Observed",
|
|
43
|
+
validated: "Validated",
|
|
44
|
+
deployment: "Deployment",
|
|
45
|
+
stable: "Stable",
|
|
46
|
+
deprecated: "Deprecated",
|
|
47
|
+
archived: "Archived",
|
|
48
|
+
};
|
|
49
|
+
exports.PROMOTION_GATES = {
|
|
50
|
+
/** Evidence → Candidate: requires ≥2 sequence observations */
|
|
51
|
+
"evidence→candidate": (a) => ({
|
|
52
|
+
passed: a.evidence.sequenceCount >= 2,
|
|
53
|
+
reason: a.evidence.sequenceCount >= 2
|
|
54
|
+
? `Observed in ${a.evidence.sequenceCount} sequences`
|
|
55
|
+
: `Only ${a.evidence.sequenceCount} sequences — need ≥2`,
|
|
56
|
+
}),
|
|
57
|
+
/** Evidence → Hypothesis: ≥3 sequences OR ≥2 repos with similar pattern */
|
|
58
|
+
"evidence→hypothesis": (a) => ({
|
|
59
|
+
passed: a.evidence.sequenceCount >= 3 || a.evidence.crossRepoCount >= 2,
|
|
60
|
+
reason: a.evidence.sequenceCount >= 3
|
|
61
|
+
? `Pattern observed in ${a.evidence.sequenceCount} sequences`
|
|
62
|
+
: a.evidence.crossRepoCount >= 2
|
|
63
|
+
? `Pattern observed across ${a.evidence.crossRepoCount} repos`
|
|
64
|
+
: `Only ${a.evidence.sequenceCount} sequences — need ≥3 for hypothesis`,
|
|
65
|
+
}),
|
|
66
|
+
/** Hypothesis → Candidate: hypothesis formalized with clear semantic role */
|
|
67
|
+
"hypothesis→candidate": (a) => ({
|
|
68
|
+
passed: a.evidence.sequenceCount >= 5 && a.evidence.crossRepoCount >= 1,
|
|
69
|
+
reason: a.evidence.sequenceCount >= 5
|
|
70
|
+
? `Formalized candidate: ${a.evidence.sequenceCount} sequences, ${a.evidence.crossRepoCount} repos`
|
|
71
|
+
: `Need ≥5 sequences to formalize candidate`,
|
|
72
|
+
}),
|
|
73
|
+
/** Candidate → Observed: cross-repo evidence ≥2 */
|
|
74
|
+
"candidate→observed": (a) => ({
|
|
75
|
+
passed: a.evidence.crossRepoCount >= 2,
|
|
76
|
+
reason: a.evidence.crossRepoCount >= 2
|
|
77
|
+
? `Validated across ${a.evidence.crossRepoCount} repos`
|
|
78
|
+
: `Only ${a.evidence.crossRepoCount} repos — need ≥2`,
|
|
79
|
+
}),
|
|
80
|
+
/** Observed → Validated: RFC alignment OR human review */
|
|
81
|
+
"observed→validated": (a) => ({
|
|
82
|
+
passed: a.evidence.rfcRefs.length > 0 || a.history.some(e => e.triggeredBy === "human"),
|
|
83
|
+
reason: a.evidence.rfcRefs.length > 0
|
|
84
|
+
? `Aligned with RFC ${a.evidence.rfcRefs.join(", ")}`
|
|
85
|
+
: a.history.some(e => e.triggeredBy === "human")
|
|
86
|
+
? "Human-reviewed"
|
|
87
|
+
: "Needs RFC alignment or human review",
|
|
88
|
+
}),
|
|
89
|
+
/** Validated → Deployment: ready for real-world validation */
|
|
90
|
+
"validated→deployment": (a) => ({
|
|
91
|
+
passed: a.confidence >= 0.70 && a.evidence.crossRepoCount >= 2,
|
|
92
|
+
reason: a.confidence >= 0.70
|
|
93
|
+
? `Ready for deployment validation: ${(a.confidence * 100).toFixed(0)}% confidence, ${a.evidence.crossRepoCount} repos`
|
|
94
|
+
: `Confidence ${(a.confidence * 100).toFixed(0)}% < 70% — not ready for deployment`,
|
|
95
|
+
}),
|
|
96
|
+
/** Deployment → Stable: deployed + FP rate acceptable + no regressions */
|
|
97
|
+
"deployment→stable": (a) => ({
|
|
98
|
+
passed: a.confidence >= 0.80,
|
|
99
|
+
reason: a.confidence >= 0.80
|
|
100
|
+
? `Production-validated: confidence ${(a.confidence * 100).toFixed(0)}% ≥ 80%`
|
|
101
|
+
: `Confidence ${(a.confidence * 100).toFixed(0)}% < 80% — deployment didn't confirm`,
|
|
102
|
+
}),
|
|
103
|
+
/** Stable → Deprecated: superseded OR confidence dropped below 40% */
|
|
104
|
+
"stable→deprecated": (a) => ({
|
|
105
|
+
passed: a.confidence < 0.40,
|
|
106
|
+
reason: a.confidence < 0.40
|
|
107
|
+
? `Confidence dropped to ${(a.confidence * 100).toFixed(0)}%`
|
|
108
|
+
: `Confidence still ${(a.confidence * 100).toFixed(0)}% — above deprecation threshold`,
|
|
109
|
+
}),
|
|
110
|
+
/** Deprecated → Archived: no active references for 90 days */
|
|
111
|
+
"deprecated→archived": (a) => {
|
|
112
|
+
const lastSeen = new Date(a.evidence.lastSeen).getTime();
|
|
113
|
+
const ninetyDays = 90 * 24 * 60 * 60 * 1000;
|
|
114
|
+
const inactive = Date.now() - lastSeen > ninetyDays;
|
|
115
|
+
return {
|
|
116
|
+
passed: inactive,
|
|
117
|
+
reason: inactive ? "Inactive for >90 days" : "Still referenced",
|
|
118
|
+
};
|
|
119
|
+
},
|
|
120
|
+
};
|
|
121
|
+
// ═══════════════════════════════════════════════════════════════
|
|
122
|
+
// Promotion Engine
|
|
123
|
+
// ═══════════════════════════════════════════════════════════════
|
|
124
|
+
class AssetPromotionEngine {
|
|
125
|
+
constructor() {
|
|
126
|
+
this.assets = new Map();
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Register a new observation as Evidence.
|
|
130
|
+
* If the asset doesn't exist, creates it at "evidence" stage.
|
|
131
|
+
* If it exists, updates evidence counts.
|
|
132
|
+
*/
|
|
133
|
+
observe(params) {
|
|
134
|
+
const id = `${params.kind}:${params.domain}:${params.name}`;
|
|
135
|
+
let asset = this.assets.get(id);
|
|
136
|
+
if (!asset) {
|
|
137
|
+
asset = {
|
|
138
|
+
id,
|
|
139
|
+
kind: params.kind,
|
|
140
|
+
name: params.name,
|
|
141
|
+
domain: params.domain,
|
|
142
|
+
stage: "evidence",
|
|
143
|
+
confidence: 0.1,
|
|
144
|
+
importance: this.estimateImportance(params.name, params.kind),
|
|
145
|
+
evidence: {
|
|
146
|
+
repos: [params.repo],
|
|
147
|
+
rfcRefs: params.rfcRefs || [],
|
|
148
|
+
sequenceCount: params.sequenceCount || 1,
|
|
149
|
+
crossRepoCount: 1,
|
|
150
|
+
firstSeen: new Date().toISOString(),
|
|
151
|
+
lastSeen: new Date().toISOString(),
|
|
152
|
+
},
|
|
153
|
+
history: [{
|
|
154
|
+
from: "evidence",
|
|
155
|
+
to: "evidence",
|
|
156
|
+
timestamp: new Date().toISOString(),
|
|
157
|
+
reason: `First observed in ${params.repo}`,
|
|
158
|
+
triggeredBy: "auto",
|
|
159
|
+
}],
|
|
160
|
+
createdAt: new Date().toISOString(),
|
|
161
|
+
updatedAt: new Date().toISOString(),
|
|
162
|
+
description: params.description || `${params.kind}: ${params.name}`,
|
|
163
|
+
payload: params.payload,
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
else {
|
|
167
|
+
// Update evidence
|
|
168
|
+
if (!asset.evidence.repos.includes(params.repo)) {
|
|
169
|
+
asset.evidence.repos.push(params.repo);
|
|
170
|
+
asset.evidence.crossRepoCount = asset.evidence.repos.length;
|
|
171
|
+
}
|
|
172
|
+
asset.evidence.sequenceCount += (params.sequenceCount || 1);
|
|
173
|
+
asset.evidence.lastSeen = new Date().toISOString();
|
|
174
|
+
// Merge RFC refs
|
|
175
|
+
for (const rfc of (params.rfcRefs || [])) {
|
|
176
|
+
if (!asset.evidence.rfcRefs.includes(rfc)) {
|
|
177
|
+
asset.evidence.rfcRefs.push(rfc);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
// Try auto-promotion
|
|
182
|
+
this.tryPromote(asset, "auto");
|
|
183
|
+
this.assets.set(id, asset);
|
|
184
|
+
return asset;
|
|
185
|
+
}
|
|
186
|
+
/**
|
|
187
|
+
* Try to promote an asset to the next stage.
|
|
188
|
+
* Returns the new stage if promotion succeeded, null otherwise.
|
|
189
|
+
*/
|
|
190
|
+
promote(assetId, triggeredBy = "human", reviewer) {
|
|
191
|
+
const asset = this.assets.get(assetId);
|
|
192
|
+
if (!asset)
|
|
193
|
+
return { promoted: false, from: "evidence", to: "evidence", reason: "Asset not found" };
|
|
194
|
+
return this.tryPromote(asset, triggeredBy, reviewer);
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Get the next stage in the lifecycle.
|
|
198
|
+
*/
|
|
199
|
+
getNextStage(current) {
|
|
200
|
+
const stages = ["evidence", "candidate", "observed", "validated", "stable", "deprecated", "archived"];
|
|
201
|
+
const idx = stages.indexOf(current);
|
|
202
|
+
if (idx < 0 || idx >= stages.length - 1)
|
|
203
|
+
return null;
|
|
204
|
+
return stages[idx + 1];
|
|
205
|
+
}
|
|
206
|
+
/**
|
|
207
|
+
* Get all assets at a given stage.
|
|
208
|
+
*/
|
|
209
|
+
getByStage(stage) {
|
|
210
|
+
return [...this.assets.values()].filter(a => a.stage === stage);
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* Get all assets of a given kind.
|
|
214
|
+
*/
|
|
215
|
+
getByKind(kind) {
|
|
216
|
+
return [...this.assets.values()].filter(a => a.kind === kind);
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* Get promotion candidates — assets at "candidate" stage ready for review.
|
|
220
|
+
*/
|
|
221
|
+
getReviewCandidates() {
|
|
222
|
+
return this.getByStage("candidate");
|
|
223
|
+
}
|
|
224
|
+
/**
|
|
225
|
+
* Get stable assets — production-ready.
|
|
226
|
+
*/
|
|
227
|
+
getStableAssets() {
|
|
228
|
+
return this.getByStage("stable");
|
|
229
|
+
}
|
|
230
|
+
/**
|
|
231
|
+
* Pipeline stats.
|
|
232
|
+
*/
|
|
233
|
+
getStats() {
|
|
234
|
+
const byStage = {};
|
|
235
|
+
const byKind = {};
|
|
236
|
+
for (const a of this.assets.values()) {
|
|
237
|
+
byStage[a.stage] = (byStage[a.stage] || 0) + 1;
|
|
238
|
+
byKind[a.kind] = (byKind[a.kind] || 0) + 1;
|
|
239
|
+
}
|
|
240
|
+
return {
|
|
241
|
+
total: this.assets.size,
|
|
242
|
+
byStage: byStage,
|
|
243
|
+
byKind: byKind,
|
|
244
|
+
reviewCandidates: this.getReviewCandidates().length,
|
|
245
|
+
stableAssets: this.getStableAssets().length,
|
|
246
|
+
};
|
|
247
|
+
}
|
|
248
|
+
// ═══════════════════════════════════════════════════════════
|
|
249
|
+
// Internal
|
|
250
|
+
// ═══════════════════════════════════════════════════════════
|
|
251
|
+
tryPromote(asset, triggeredBy, reviewer) {
|
|
252
|
+
const originalStage = asset.stage;
|
|
253
|
+
let anyPromoted = false;
|
|
254
|
+
let lastReason = "";
|
|
255
|
+
// Chain: keep promoting until a gate fails
|
|
256
|
+
while (true) {
|
|
257
|
+
const currentStage = asset.stage;
|
|
258
|
+
const nextStage = this.getNextStage(currentStage);
|
|
259
|
+
if (!nextStage)
|
|
260
|
+
break;
|
|
261
|
+
// Auto-promotion stops at deployment (requires real deployment data)
|
|
262
|
+
if (triggeredBy === "auto" && exports.STAGE_ORDER[nextStage] > exports.STAGE_ORDER.deployment) {
|
|
263
|
+
break;
|
|
264
|
+
}
|
|
265
|
+
const gateKey = `${currentStage}→${nextStage}`;
|
|
266
|
+
const gate = exports.PROMOTION_GATES[gateKey];
|
|
267
|
+
if (!gate)
|
|
268
|
+
break;
|
|
269
|
+
const { passed, reason } = gate(asset);
|
|
270
|
+
lastReason = reason;
|
|
271
|
+
// Human promotion bypasses the RFC/review gate (observed→validated only)
|
|
272
|
+
const isHumanReviewGate = gateKey === "observed→validated" && triggeredBy === "human";
|
|
273
|
+
const effectivePassed = isHumanReviewGate ? true : passed;
|
|
274
|
+
if (effectivePassed) {
|
|
275
|
+
const from = asset.stage;
|
|
276
|
+
asset.stage = nextStage;
|
|
277
|
+
asset.updatedAt = new Date().toISOString();
|
|
278
|
+
asset.history.push({
|
|
279
|
+
from, to: nextStage,
|
|
280
|
+
timestamp: new Date().toISOString(),
|
|
281
|
+
reason, triggeredBy, reviewer,
|
|
282
|
+
});
|
|
283
|
+
this.assets.set(asset.id, asset);
|
|
284
|
+
anyPromoted = true;
|
|
285
|
+
}
|
|
286
|
+
else {
|
|
287
|
+
break; // Gate failed — stop chaining
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
if (anyPromoted) {
|
|
291
|
+
return { promoted: true, from: originalStage, to: asset.stage, reason: lastReason };
|
|
292
|
+
}
|
|
293
|
+
return { promoted: false, from: originalStage, to: originalStage, reason: lastReason || "No promotions applied" };
|
|
294
|
+
}
|
|
295
|
+
/**
|
|
296
|
+
* Estimate importance — NOT frequency. Semantic significance.
|
|
297
|
+
*
|
|
298
|
+
* Rules that manage resources (init/open/close/free) are more important
|
|
299
|
+
* than utility functions (memcpy/strlen) regardless of frequency.
|
|
300
|
+
*/
|
|
301
|
+
estimateImportance(name, kind) {
|
|
302
|
+
const fn = name.toLowerCase();
|
|
303
|
+
// Resource management functions = high importance
|
|
304
|
+
if (/^(init_|create_|open_|close_|free_|destroy_|release_|acquire_)/i.test(fn)) {
|
|
305
|
+
return 0.9;
|
|
306
|
+
}
|
|
307
|
+
// Protocol entry/exit points = high importance
|
|
308
|
+
if (/_(init|cleanup|start|stop|begin|end|setup|teardown)$/i.test(fn)) {
|
|
309
|
+
return 0.85;
|
|
310
|
+
}
|
|
311
|
+
// Verification rules = medium importance
|
|
312
|
+
if (kind === "verification_rule")
|
|
313
|
+
return 0.6;
|
|
314
|
+
// Knowledge units = medium-high importance
|
|
315
|
+
if (kind === "knowledge_unit")
|
|
316
|
+
return 0.7;
|
|
317
|
+
return 0.4;
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
exports.AssetPromotionEngine = AssetPromotionEngine;
|
|
321
|
+
// ═══════════════════════════════════════════════════════════════
|
|
322
|
+
// Singleton
|
|
323
|
+
// ═══════════════════════════════════════════════════════════════
|
|
324
|
+
let _engine = null;
|
|
325
|
+
function getAssetPromotionEngine() {
|
|
326
|
+
if (!_engine)
|
|
327
|
+
_engine = new AssetPromotionEngine();
|
|
328
|
+
return _engine;
|
|
329
|
+
}
|
|
330
|
+
// ═══════════════════════════════════════════════════════════════
|
|
331
|
+
// Report Formatter
|
|
332
|
+
// ═══════════════════════════════════════════════════════════════
|
|
333
|
+
function formatPipelineReport(engine) {
|
|
334
|
+
const e = engine || getAssetPromotionEngine();
|
|
335
|
+
const stats = e.getStats();
|
|
336
|
+
const lines = [];
|
|
337
|
+
lines.push("");
|
|
338
|
+
lines.push("╔══════════════════════════════════════════════════════════════╗");
|
|
339
|
+
lines.push("║ Unified Asset Promotion Pipeline ║");
|
|
340
|
+
lines.push("╠══════════════════════════════════════════════════════════════╣");
|
|
341
|
+
lines.push(`║ Total Assets: ${String(stats.total).padStart(5)} | Review Candidates: ${String(stats.reviewCandidates).padStart(3)} | Stable: ${String(stats.stableAssets).padStart(3)} ║`);
|
|
342
|
+
lines.push("╚══════════════════════════════════════════════════════════════╝");
|
|
343
|
+
lines.push("");
|
|
344
|
+
// Pipeline visualization
|
|
345
|
+
const stages = ["evidence", "candidate", "observed", "validated", "stable", "deprecated", "archived"];
|
|
346
|
+
const maxCount = Math.max(1, ...stages.map(s => stats.byStage[s] || 0));
|
|
347
|
+
lines.push("── Pipeline ──");
|
|
348
|
+
for (const stage of stages) {
|
|
349
|
+
const count = stats.byStage[stage] || 0;
|
|
350
|
+
const bar = "█".repeat(Math.max(1, Math.round(count / maxCount * 30)));
|
|
351
|
+
const label = exports.STAGE_LABELS[stage].padEnd(12);
|
|
352
|
+
lines.push(` ${label} ${String(count).padStart(3)} ${bar}`);
|
|
353
|
+
}
|
|
354
|
+
lines.push("");
|
|
355
|
+
// By kind
|
|
356
|
+
lines.push("── By Asset Kind ──");
|
|
357
|
+
for (const [kind, count] of Object.entries(stats.byKind)) {
|
|
358
|
+
lines.push(` ${kind}: ${count}`);
|
|
359
|
+
}
|
|
360
|
+
lines.push("");
|
|
361
|
+
// Review candidates
|
|
362
|
+
const candidates = e.getReviewCandidates();
|
|
363
|
+
if (candidates.length > 0) {
|
|
364
|
+
lines.push("── Review Candidates (ready for promotion) ──");
|
|
365
|
+
for (const c of candidates.slice(0, 10)) {
|
|
366
|
+
const next = e.getNextStage(c.stage);
|
|
367
|
+
lines.push(` 📝 ${c.name.padEnd(35)} ${c.stage} → ${next || "?"} (${c.evidence.crossRepoCount} repos, conf=${(c.confidence * 100).toFixed(0)}%)`);
|
|
368
|
+
}
|
|
369
|
+
lines.push("");
|
|
370
|
+
}
|
|
371
|
+
// Stable assets
|
|
372
|
+
const stable = e.getStableAssets();
|
|
373
|
+
if (stable.length > 0) {
|
|
374
|
+
lines.push("── Stable Assets (production) ──");
|
|
375
|
+
for (const s of stable) {
|
|
376
|
+
const rfc = s.evidence.rfcRefs.length > 0 ? `RFC ${s.evidence.rfcRefs.join(",")}` : "no RFC";
|
|
377
|
+
lines.push(` ✅ ${s.name.padEnd(35)} ${s.domain} | ${rfc} | ${s.evidence.crossRepoCount} repos`);
|
|
378
|
+
}
|
|
379
|
+
lines.push("");
|
|
380
|
+
}
|
|
381
|
+
return lines.join("\n");
|
|
382
|
+
}
|