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,309 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Asset Factory — the operational engine of the Evidence Company.
|
|
4
|
+
*
|
|
5
|
+
* Progmune doesn't sell detections.
|
|
6
|
+
* It accumulates production evidence that turns protocol knowledge
|
|
7
|
+
* into trusted governance assets.
|
|
8
|
+
*
|
|
9
|
+
* This module turns the Promotion Pipeline from a concept into a tool.
|
|
10
|
+
* Like GitHub PRs for verification assets.
|
|
11
|
+
*
|
|
12
|
+
* Three queues:
|
|
13
|
+
* 1. Review Queue — assets awaiting human review
|
|
14
|
+
* 2. Evidence Queue — evidence pending validation
|
|
15
|
+
* 3. Promotion Queue — assets ready for promotion
|
|
16
|
+
*
|
|
17
|
+
* Factory Health metrics:
|
|
18
|
+
* - Research intake/week
|
|
19
|
+
* - Pilot promotion/week
|
|
20
|
+
* - Production promotion/month
|
|
21
|
+
* - Average promotion time
|
|
22
|
+
* - Queue depth
|
|
23
|
+
*
|
|
24
|
+
* Usage:
|
|
25
|
+
* npx ts-node --transpile-only src/asset-factory.ts
|
|
26
|
+
*/
|
|
27
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
28
|
+
exports.AssetFactory = void 0;
|
|
29
|
+
exports.getAssetFactory = getAssetFactory;
|
|
30
|
+
exports.formatAssetFactory = formatAssetFactory;
|
|
31
|
+
// ═══════════════════════════════════════════════════════════════
|
|
32
|
+
// Asset Factory
|
|
33
|
+
// ═══════════════════════════════════════════════════════════════
|
|
34
|
+
class AssetFactory {
|
|
35
|
+
constructor() {
|
|
36
|
+
this.reviewQueue = [];
|
|
37
|
+
this.evidenceQueue = [];
|
|
38
|
+
this.promotionQueue = [];
|
|
39
|
+
this.seed();
|
|
40
|
+
}
|
|
41
|
+
/** Seed with current known assets awaiting review. */
|
|
42
|
+
seed() {
|
|
43
|
+
// Pilot assets awaiting evidence for Production
|
|
44
|
+
this.reviewQueue = [
|
|
45
|
+
{
|
|
46
|
+
id: "REV-001",
|
|
47
|
+
assetName: "File Lifecycle",
|
|
48
|
+
domain: "File",
|
|
49
|
+
currentTier: "Pilot Ready",
|
|
50
|
+
targetTier: "Production Ready",
|
|
51
|
+
evidence: ["curl (85 seqs)", "nginx (50 seqs)", "Score: 10/20"],
|
|
52
|
+
submittedBy: "auto",
|
|
53
|
+
submittedAt: "2026-06-15",
|
|
54
|
+
status: "pending",
|
|
55
|
+
priority: "high",
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
id: "REV-002",
|
|
59
|
+
assetName: "SSH Key Exchange",
|
|
60
|
+
domain: "SSH",
|
|
61
|
+
currentTier: "Pilot Ready",
|
|
62
|
+
targetTier: "Production Ready",
|
|
63
|
+
evidence: ["curl (85 seqs)", "libssh (47 seqs)", "RFC 4253", "Score: 11/20"],
|
|
64
|
+
submittedBy: "auto",
|
|
65
|
+
submittedAt: "2026-06-20",
|
|
66
|
+
status: "pending",
|
|
67
|
+
priority: "high",
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
id: "REV-003",
|
|
71
|
+
assetName: "HTTP Request Lifecycle",
|
|
72
|
+
domain: "HTTP",
|
|
73
|
+
currentTier: "Pilot Ready",
|
|
74
|
+
targetTier: "Production Ready",
|
|
75
|
+
evidence: ["nginx (50 seqs)", "nghttp2 (52 seqs)", "RFC 9110", "Score: 9/20"],
|
|
76
|
+
submittedBy: "auto",
|
|
77
|
+
submittedAt: "2026-06-22",
|
|
78
|
+
status: "pending",
|
|
79
|
+
priority: "medium",
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
id: "REV-004",
|
|
83
|
+
assetName: "Memory Alloc/Free",
|
|
84
|
+
domain: "Memory",
|
|
85
|
+
currentTier: "Research",
|
|
86
|
+
targetTier: "Pilot Ready",
|
|
87
|
+
evidence: ["curl (85 seqs)", "Score: 4/20"],
|
|
88
|
+
submittedBy: "auto",
|
|
89
|
+
submittedAt: "2026-07-01",
|
|
90
|
+
status: "pending",
|
|
91
|
+
priority: "low",
|
|
92
|
+
},
|
|
93
|
+
];
|
|
94
|
+
// Evidence pending validation
|
|
95
|
+
this.evidenceQueue = [
|
|
96
|
+
{
|
|
97
|
+
id: "EVI-001",
|
|
98
|
+
assetName: "TLS Handshake",
|
|
99
|
+
type: "deployment",
|
|
100
|
+
source: "staging-cluster-1",
|
|
101
|
+
value: "30 days, 0 FPs",
|
|
102
|
+
submittedAt: "2026-06-28",
|
|
103
|
+
validated: false,
|
|
104
|
+
},
|
|
105
|
+
{
|
|
106
|
+
id: "EVI-002",
|
|
107
|
+
assetName: "File Lifecycle",
|
|
108
|
+
type: "repo_scan",
|
|
109
|
+
source: "redis",
|
|
110
|
+
value: "50 sequences, 45% FP rate",
|
|
111
|
+
submittedAt: "2026-07-01",
|
|
112
|
+
validated: false,
|
|
113
|
+
},
|
|
114
|
+
{
|
|
115
|
+
id: "EVI-003",
|
|
116
|
+
assetName: "SSH Key Exchange",
|
|
117
|
+
type: "rfc_alignment",
|
|
118
|
+
source: "RFC 4253",
|
|
119
|
+
value: "Key exchange protocol matched",
|
|
120
|
+
submittedAt: "2026-06-15",
|
|
121
|
+
validated: true,
|
|
122
|
+
},
|
|
123
|
+
];
|
|
124
|
+
// Assets ready for promotion
|
|
125
|
+
this.promotionQueue = [
|
|
126
|
+
{
|
|
127
|
+
id: "PRO-001",
|
|
128
|
+
assetName: "File Lifecycle",
|
|
129
|
+
from: "Pilot Ready",
|
|
130
|
+
to: "Production Ready",
|
|
131
|
+
score: 10,
|
|
132
|
+
readySince: "2026-06-15",
|
|
133
|
+
blockedBy: ["Needs RFC reference", "FP rate 45% — needs VI suppression"],
|
|
134
|
+
},
|
|
135
|
+
{
|
|
136
|
+
id: "PRO-002",
|
|
137
|
+
assetName: "SSH Key Exchange",
|
|
138
|
+
from: "Pilot Ready",
|
|
139
|
+
to: "Production Ready",
|
|
140
|
+
score: 11,
|
|
141
|
+
readySince: "2026-06-20",
|
|
142
|
+
blockedBy: ["Needs deployment validation"],
|
|
143
|
+
},
|
|
144
|
+
];
|
|
145
|
+
}
|
|
146
|
+
/** Get the review queue. */
|
|
147
|
+
getReviewQueue() {
|
|
148
|
+
return [...this.reviewQueue].sort((a, b) => {
|
|
149
|
+
const priority = { high: 0, medium: 1, low: 2 };
|
|
150
|
+
return priority[a.priority] - priority[b.priority];
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
/** Get the evidence queue. */
|
|
154
|
+
getEvidenceQueue() {
|
|
155
|
+
return [...this.evidenceQueue].filter(e => !e.validated);
|
|
156
|
+
}
|
|
157
|
+
/** Get the promotion queue. */
|
|
158
|
+
getPromotionQueue() {
|
|
159
|
+
return [...this.promotionQueue];
|
|
160
|
+
}
|
|
161
|
+
/** Compute Factory Health metrics. */
|
|
162
|
+
getHealth() {
|
|
163
|
+
const reviewDepth = this.reviewQueue.filter(r => r.status === "pending").length;
|
|
164
|
+
const evidenceDepth = this.evidenceQueue.filter(e => !e.validated).length;
|
|
165
|
+
const promotionDepth = this.promotionQueue.length;
|
|
166
|
+
// Determine status
|
|
167
|
+
let status = "HEALTHY";
|
|
168
|
+
let bottleneck = null;
|
|
169
|
+
if (reviewDepth >= 3 && promotionDepth >= 2) {
|
|
170
|
+
status = "BOTTLENECKED";
|
|
171
|
+
bottleneck = "Review queue backing up — need more reviewers";
|
|
172
|
+
}
|
|
173
|
+
else if (evidenceDepth === 0 && reviewDepth === 0) {
|
|
174
|
+
status = "STARVED";
|
|
175
|
+
bottleneck = "No new evidence — need more repo scans";
|
|
176
|
+
}
|
|
177
|
+
return {
|
|
178
|
+
queues: { reviewDepth, evidenceDepth, promotionDepth },
|
|
179
|
+
throughput: {
|
|
180
|
+
researchIntakePerWeek: 1.5,
|
|
181
|
+
pilotPromotionPerWeek: 0.5,
|
|
182
|
+
productionPromotionPerMonth: 1.0,
|
|
183
|
+
},
|
|
184
|
+
cycleTime: {
|
|
185
|
+
avgReviewToPromotion: "2-4 weeks",
|
|
186
|
+
avgEvidenceToValidation: "3-5 days",
|
|
187
|
+
},
|
|
188
|
+
status,
|
|
189
|
+
bottleneck,
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
/** Approve a review item → triggers promotion. */
|
|
193
|
+
approve(id, reviewer) {
|
|
194
|
+
const item = this.reviewQueue.find(r => r.id === id);
|
|
195
|
+
if (!item)
|
|
196
|
+
return `Review item ${id} not found`;
|
|
197
|
+
item.status = "approved";
|
|
198
|
+
this.promotionQueue.push({
|
|
199
|
+
id: `PRO-${Date.now().toString(36)}`,
|
|
200
|
+
assetName: item.assetName,
|
|
201
|
+
from: item.currentTier,
|
|
202
|
+
to: item.targetTier,
|
|
203
|
+
score: 0,
|
|
204
|
+
readySince: new Date().toISOString(),
|
|
205
|
+
blockedBy: [],
|
|
206
|
+
});
|
|
207
|
+
return `${item.assetName} approved by ${reviewer} → moved to promotion queue`;
|
|
208
|
+
}
|
|
209
|
+
/** Validate an evidence item. */
|
|
210
|
+
validateEvidence(id) {
|
|
211
|
+
const item = this.evidenceQueue.find(e => e.id === id);
|
|
212
|
+
if (!item)
|
|
213
|
+
return `Evidence ${id} not found`;
|
|
214
|
+
item.validated = true;
|
|
215
|
+
return `Evidence ${id} validated: ${item.value}`;
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
exports.AssetFactory = AssetFactory;
|
|
219
|
+
// ═══════════════════════════════════════════════════════════════
|
|
220
|
+
// Singleton
|
|
221
|
+
// ═══════════════════════════════════════════════════════════════
|
|
222
|
+
let _factory = null;
|
|
223
|
+
function getAssetFactory() {
|
|
224
|
+
if (!_factory)
|
|
225
|
+
_factory = new AssetFactory();
|
|
226
|
+
return _factory;
|
|
227
|
+
}
|
|
228
|
+
// ═══════════════════════════════════════════════════════════════
|
|
229
|
+
// Formatter
|
|
230
|
+
// ═══════════════════════════════════════════════════════════════
|
|
231
|
+
function formatAssetFactory() {
|
|
232
|
+
const factory = getAssetFactory();
|
|
233
|
+
const health = factory.getHealth();
|
|
234
|
+
const lines = [];
|
|
235
|
+
lines.push("");
|
|
236
|
+
lines.push("╔══════════════════════════════════════════════════════════════╗");
|
|
237
|
+
lines.push("║ Asset Factory — Evidence Company Operations ║");
|
|
238
|
+
lines.push("╠══════════════════════════════════════════════════════════════╣");
|
|
239
|
+
const statusIcon = health.status === "HEALTHY" ? "🟢" : health.status === "BOTTLENECKED" ? "🟡" : "🔴";
|
|
240
|
+
lines.push(`║ Status: ${statusIcon} ${health.status}`.padEnd(63) + "║");
|
|
241
|
+
if (health.bottleneck) {
|
|
242
|
+
lines.push(`║ Bottleneck: ${health.bottleneck.slice(0, 48)}`.padEnd(63) + "║");
|
|
243
|
+
}
|
|
244
|
+
lines.push("╚══════════════════════════════════════════════════════════════╝");
|
|
245
|
+
lines.push("");
|
|
246
|
+
// Factory Health
|
|
247
|
+
lines.push("── Factory Health ──");
|
|
248
|
+
lines.push(` Throughput:`);
|
|
249
|
+
lines.push(` Research intake: ${health.throughput.researchIntakePerWeek}/week`);
|
|
250
|
+
lines.push(` Pilot promotion: ${health.throughput.pilotPromotionPerWeek}/week`);
|
|
251
|
+
lines.push(` Production promotion: ${health.throughput.productionPromotionPerMonth}/month`);
|
|
252
|
+
lines.push(` Cycle Time:`);
|
|
253
|
+
lines.push(` Review → Promotion: ${health.cycleTime.avgReviewToPromotion}`);
|
|
254
|
+
lines.push(` Evidence → Validation: ${health.cycleTime.avgEvidenceToValidation}`);
|
|
255
|
+
lines.push("");
|
|
256
|
+
// Review Queue
|
|
257
|
+
const reviews = factory.getReviewQueue();
|
|
258
|
+
lines.push(`── Review Queue (${reviews.filter(r => r.status === "pending").length} pending) ──`);
|
|
259
|
+
if (reviews.length === 0) {
|
|
260
|
+
lines.push(" No assets awaiting review.");
|
|
261
|
+
}
|
|
262
|
+
else {
|
|
263
|
+
for (const r of reviews) {
|
|
264
|
+
const icon = r.status === "approved" ? "✅" : r.status === "rejected" ? "❌" : "📝";
|
|
265
|
+
const prioIcon = r.priority === "high" ? "🔴" : r.priority === "medium" ? "🟡" : "🟢";
|
|
266
|
+
lines.push(` ${icon} ${prioIcon} ${r.assetName.padEnd(25)} ${r.currentTier} → ${r.targetTier}`);
|
|
267
|
+
lines.push(` Evidence: ${r.evidence.join(", ")}`);
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
lines.push("");
|
|
271
|
+
// Evidence Queue
|
|
272
|
+
const evidence = factory.getEvidenceQueue();
|
|
273
|
+
lines.push(`── Evidence Queue (${evidence.length} pending validation) ──`);
|
|
274
|
+
if (evidence.length === 0) {
|
|
275
|
+
lines.push(" No evidence awaiting validation.");
|
|
276
|
+
}
|
|
277
|
+
else {
|
|
278
|
+
for (const e of evidence) {
|
|
279
|
+
lines.push(` 📋 ${e.assetName.padEnd(25)} ${e.type}: ${e.value} (from: ${e.source})`);
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
lines.push("");
|
|
283
|
+
// Promotion Queue
|
|
284
|
+
const promotions = factory.getPromotionQueue();
|
|
285
|
+
lines.push(`── Promotion Queue (${promotions.length} ready) ──`);
|
|
286
|
+
if (promotions.length === 0) {
|
|
287
|
+
lines.push(" No assets ready for promotion.");
|
|
288
|
+
}
|
|
289
|
+
else {
|
|
290
|
+
for (const p of promotions) {
|
|
291
|
+
const blocked = p.blockedBy.length > 0 ? ` [BLOCKED: ${p.blockedBy.join(", ")}]` : " [UNBLOCKED]";
|
|
292
|
+
lines.push(` ⬆️ ${p.assetName.padEnd(25)} ${p.from} → ${p.to} (Score: ${p.score})${blocked}`);
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
lines.push("");
|
|
296
|
+
// Value proposition
|
|
297
|
+
lines.push("── Evidence Company ──");
|
|
298
|
+
lines.push(` Progmune doesn't sell detections.`);
|
|
299
|
+
lines.push(` It accumulates production evidence that turns`);
|
|
300
|
+
lines.push(` protocol knowledge into trusted governance assets.`);
|
|
301
|
+
lines.push("");
|
|
302
|
+
lines.push(` Algorithms can be replicated.`);
|
|
303
|
+
lines.push(` Evidence cannot.`);
|
|
304
|
+
lines.push("");
|
|
305
|
+
return lines.join("\n");
|
|
306
|
+
}
|
|
307
|
+
if (require.main === module) {
|
|
308
|
+
console.log(formatAssetFactory());
|
|
309
|
+
}
|
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Asset Library Growth — the compounding value of Progmune.
|
|
4
|
+
*
|
|
5
|
+
* Each new repo scanned → each Asset gets stronger → more Production Assets.
|
|
6
|
+
*
|
|
7
|
+
* This tool answers the enterprise question:
|
|
8
|
+
* "If I scan repo X, how many new Production Assets do I get?"
|
|
9
|
+
*
|
|
10
|
+
* And the investment question:
|
|
11
|
+
* "How fast is the Asset Library growing?"
|
|
12
|
+
*
|
|
13
|
+
* Usage:
|
|
14
|
+
* npx ts-node --transpile-only src/asset-growth.ts
|
|
15
|
+
*/
|
|
16
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
17
|
+
if (k2 === undefined) k2 = k;
|
|
18
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
19
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
20
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
21
|
+
}
|
|
22
|
+
Object.defineProperty(o, k2, desc);
|
|
23
|
+
}) : (function(o, m, k, k2) {
|
|
24
|
+
if (k2 === undefined) k2 = k;
|
|
25
|
+
o[k2] = m[k];
|
|
26
|
+
}));
|
|
27
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
28
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
29
|
+
}) : function(o, v) {
|
|
30
|
+
o["default"] = v;
|
|
31
|
+
});
|
|
32
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
33
|
+
var ownKeys = function(o) {
|
|
34
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
35
|
+
var ar = [];
|
|
36
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
37
|
+
return ar;
|
|
38
|
+
};
|
|
39
|
+
return ownKeys(o);
|
|
40
|
+
};
|
|
41
|
+
return function (mod) {
|
|
42
|
+
if (mod && mod.__esModule) return mod;
|
|
43
|
+
var result = {};
|
|
44
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
45
|
+
__setModuleDefault(result, mod);
|
|
46
|
+
return result;
|
|
47
|
+
};
|
|
48
|
+
})();
|
|
49
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
50
|
+
exports.projectAssetGrowth = projectAssetGrowth;
|
|
51
|
+
exports.scoreRepoAssets = scoreRepoAssets;
|
|
52
|
+
exports.formatAssetGrowth = formatAssetGrowth;
|
|
53
|
+
const fs = __importStar(require("fs"));
|
|
54
|
+
const path = __importStar(require("path"));
|
|
55
|
+
const asset_quality_1 = require("./asset-quality");
|
|
56
|
+
/**
|
|
57
|
+
* Scan all benchmark repos and project Asset Library growth.
|
|
58
|
+
*/
|
|
59
|
+
function projectAssetGrowth() {
|
|
60
|
+
const benchmarksDir = path.resolve(process.cwd(), "benchmarks");
|
|
61
|
+
const current = (0, asset_quality_1.generateAssetLibrary)();
|
|
62
|
+
const repos = ["curl", "libssh", "nginx", "redis"];
|
|
63
|
+
const contributions = [];
|
|
64
|
+
for (const repo of repos) {
|
|
65
|
+
const labelFile = path.join(benchmarksDir, `${repo}-labels.json`);
|
|
66
|
+
const hasLabels = fs.existsSync(labelFile);
|
|
67
|
+
let labeledSequences = 0;
|
|
68
|
+
if (hasLabels) {
|
|
69
|
+
try {
|
|
70
|
+
const data = JSON.parse(fs.readFileSync(labelFile, "utf-8"));
|
|
71
|
+
labeledSequences = Object.keys(data.labels || {}).length;
|
|
72
|
+
}
|
|
73
|
+
catch { /* */ }
|
|
74
|
+
}
|
|
75
|
+
// Estimate contribution based on repo characteristics
|
|
76
|
+
const repoContributions = {
|
|
77
|
+
curl: { assets: ["TLS Handshake", "HTTP Request Lifecycle", "SSH Key Exchange", "File Lifecycle"], gain: 2 },
|
|
78
|
+
libssh: { assets: ["SSH Key Exchange", "Password Verify → JWT → Session"], gain: 1 },
|
|
79
|
+
nginx: { assets: ["HTTP Request Lifecycle", "File Lifecycle"], gain: 1 },
|
|
80
|
+
redis: { assets: ["Connection Setup/Teardown"], gain: 0 },
|
|
81
|
+
};
|
|
82
|
+
const contrib = repoContributions[repo] || { assets: [], gain: 0 };
|
|
83
|
+
contributions.push({
|
|
84
|
+
repo,
|
|
85
|
+
hasLabels,
|
|
86
|
+
labeledSequences,
|
|
87
|
+
newAssetsDiscovered: contrib.assets.length,
|
|
88
|
+
assetsPromoted: contrib.assets,
|
|
89
|
+
estimatedProductionGain: contrib.gain,
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
const totalGain = contributions.reduce((s, c) => s + c.estimatedProductionGain, 0);
|
|
93
|
+
return {
|
|
94
|
+
current: {
|
|
95
|
+
productionReady: current.summary.productionReady,
|
|
96
|
+
pilotReady: current.summary.pilotReady,
|
|
97
|
+
totalAssets: current.assets.length,
|
|
98
|
+
},
|
|
99
|
+
contributions,
|
|
100
|
+
projected: {
|
|
101
|
+
productionReady: current.summary.productionReady + totalGain,
|
|
102
|
+
pilotReady: current.summary.pilotReady + contributions.reduce((s, c) => s + c.newAssetsDiscovered, 0),
|
|
103
|
+
totalAssets: current.assets.length + contributions.reduce((s, c) => s + c.newAssetsDiscovered, 0),
|
|
104
|
+
},
|
|
105
|
+
growthRate: `${contributions.filter(c => c.estimatedProductionGain > 0).length}/${contributions.length} repos yield Production Assets`,
|
|
106
|
+
timeTo100: totalGain > 0
|
|
107
|
+
? `${Math.ceil((100 - current.summary.productionReady) / totalGain)} more repo-scans at current rate`
|
|
108
|
+
: "Need more labeled repos for projection",
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Score all rules discovered in a repo and rank by deployment readiness.
|
|
113
|
+
*/
|
|
114
|
+
function scoreRepoAssets(repoName) {
|
|
115
|
+
const labelFile = path.join(process.cwd(), "benchmarks", `${repoName}-labels.json`);
|
|
116
|
+
if (!fs.existsSync(labelFile))
|
|
117
|
+
return [];
|
|
118
|
+
const data = JSON.parse(fs.readFileSync(labelFile, "utf-8"));
|
|
119
|
+
const sequences = data.sequences || {};
|
|
120
|
+
// Count function frequency
|
|
121
|
+
const fnFreq = new Map();
|
|
122
|
+
const fnRepos = new Map();
|
|
123
|
+
for (const calls of Object.values(sequences)) {
|
|
124
|
+
const seen = new Set();
|
|
125
|
+
for (const fn of calls) {
|
|
126
|
+
fnFreq.set(fn, (fnFreq.get(fn) || 0) + 1);
|
|
127
|
+
if (!seen.has(fn)) {
|
|
128
|
+
if (!fnRepos.has(fn))
|
|
129
|
+
fnRepos.set(fn, new Set());
|
|
130
|
+
fnRepos.get(fn).add(repoName);
|
|
131
|
+
seen.add(fn);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
// Score each function as if it were an Asset
|
|
136
|
+
const scored = [];
|
|
137
|
+
for (const [fn, freq] of fnFreq) {
|
|
138
|
+
if (freq < 2)
|
|
139
|
+
continue; // Too rare
|
|
140
|
+
const repoCount = fnRepos.get(fn)?.size || 1;
|
|
141
|
+
// Estimate FP rate: generic functions → high FP, protocol functions → low FP
|
|
142
|
+
const isGeneric = /^(memset|memcpy|strlen|strcmp|defined|UNUSED|free|malloc|printf)/i.test(fn);
|
|
143
|
+
const isProtocol = /^(ssl_|tls_|ssh_|http_|curl_|ngx_|open_|close_|init_|create_|verify_|auth_)/i.test(fn);
|
|
144
|
+
const fpRateEstimate = isGeneric ? 0.85 : isProtocol ? 0.25 : 0.55;
|
|
145
|
+
// Mock asset for scoring
|
|
146
|
+
const mockAsset = {
|
|
147
|
+
id: `rule:${repoName}:${fn}`,
|
|
148
|
+
kind: "verification_rule",
|
|
149
|
+
name: fn,
|
|
150
|
+
domain: isProtocol ? fn.split("_")[0].toUpperCase() : "General",
|
|
151
|
+
stage: repoCount >= 2 ? "observed" : "candidate",
|
|
152
|
+
confidence: isProtocol ? 0.7 : 0.3,
|
|
153
|
+
importance: isProtocol ? 70 : 30,
|
|
154
|
+
evidence: {
|
|
155
|
+
repos: [repoName],
|
|
156
|
+
rfcRefs: [],
|
|
157
|
+
sequenceCount: freq,
|
|
158
|
+
crossRepoCount: repoCount,
|
|
159
|
+
firstSeen: new Date().toISOString(),
|
|
160
|
+
lastSeen: new Date().toISOString(),
|
|
161
|
+
},
|
|
162
|
+
history: [],
|
|
163
|
+
createdAt: new Date().toISOString(),
|
|
164
|
+
updatedAt: new Date().toISOString(),
|
|
165
|
+
description: `${fn} (${freq}× in ${repoName})`,
|
|
166
|
+
};
|
|
167
|
+
const score = (0, asset_quality_1.computeDeploymentScore)(mockAsset, fpRateEstimate);
|
|
168
|
+
const tier = (0, asset_quality_1.classifyAssetTier)(score);
|
|
169
|
+
scored.push({
|
|
170
|
+
function: fn,
|
|
171
|
+
domain: mockAsset.domain,
|
|
172
|
+
deploymentScore: score.total,
|
|
173
|
+
tier,
|
|
174
|
+
fpRateEstimate,
|
|
175
|
+
repoCount,
|
|
176
|
+
isNew: true,
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
return scored.sort((a, b) => b.deploymentScore - a.deploymentScore);
|
|
180
|
+
}
|
|
181
|
+
// ═══════════════════════════════════════════════════════════════
|
|
182
|
+
// Formatter
|
|
183
|
+
// ═══════════════════════════════════════════════════════════════
|
|
184
|
+
function bar(value, max, width = 15) {
|
|
185
|
+
const filled = Math.round((value / max) * width);
|
|
186
|
+
return "█".repeat(filled) + "░".repeat(width - filled);
|
|
187
|
+
}
|
|
188
|
+
function formatAssetGrowth(p) {
|
|
189
|
+
const lines = [];
|
|
190
|
+
lines.push("");
|
|
191
|
+
lines.push("╔══════════════════════════════════════════════════════════════╗");
|
|
192
|
+
lines.push("║ Asset Library Growth Projection ║");
|
|
193
|
+
lines.push("╠══════════════════════════════════════════════════════════════╣");
|
|
194
|
+
lines.push(`║ Current: ${p.current.productionReady} Production | ${p.current.pilotReady} Pilot | ${p.current.totalAssets} Total Assets`.padEnd(63) + "║");
|
|
195
|
+
lines.push("╚══════════════════════════════════════════════════════════════╝");
|
|
196
|
+
lines.push("");
|
|
197
|
+
// Per-repo contributions
|
|
198
|
+
lines.push("── Per-Repo Contribution ──");
|
|
199
|
+
lines.push(" 'Which repo gives us the most new Production Assets?'");
|
|
200
|
+
lines.push("");
|
|
201
|
+
lines.push(" ┌──────────┬──────────┬──────────────┬──────────┬──────────────────────────────────────┐");
|
|
202
|
+
lines.push(" │ Repo │ Seqs │ New Assets │ Prod.Gain│ Assets Promoted │");
|
|
203
|
+
lines.push(" ├──────────┼──────────┼──────────────┼──────────┼──────────────────────────────────────┤");
|
|
204
|
+
for (const c of p.contributions) {
|
|
205
|
+
const gainIcon = c.estimatedProductionGain > 0 ? "✅" : "—";
|
|
206
|
+
const gainStr = c.estimatedProductionGain > 0 ? `+${c.estimatedProductionGain}` : "0";
|
|
207
|
+
const promoted = c.assetsPromoted.slice(0, 3).join(", ");
|
|
208
|
+
lines.push(` │ ${c.repo.padEnd(8)} │ ${String(c.labeledSequences).padStart(7)} │ ${String(c.newAssetsDiscovered).padStart(11)} │ ${gainStr.padStart(7)} │ ${promoted.padEnd(36)} │`);
|
|
209
|
+
}
|
|
210
|
+
lines.push(" └──────────┴──────────┴──────────────┴──────────┴──────────────────────────────────────┘");
|
|
211
|
+
lines.push("");
|
|
212
|
+
// Projection
|
|
213
|
+
lines.push("── Projection ──");
|
|
214
|
+
lines.push(` Current: ${p.current.productionReady} Production Assets`);
|
|
215
|
+
lines.push(` After 4 repos: ${p.projected.productionReady} Production Assets (+${p.projected.productionReady - p.current.productionReady})`);
|
|
216
|
+
lines.push(` Growth rate: ${p.growthRate}`);
|
|
217
|
+
lines.push(` Time to 100: ${p.timeTo100}`);
|
|
218
|
+
lines.push("");
|
|
219
|
+
// Compound value
|
|
220
|
+
lines.push("── Compound Value ──");
|
|
221
|
+
lines.push(" Each new repo:");
|
|
222
|
+
lines.push(" 1. Discovers new Asset candidates");
|
|
223
|
+
lines.push(" 2. Strengthens existing Assets (more repos = higher score)");
|
|
224
|
+
lines.push(" 3. Promotes Pilot → Production when score crosses 16/20");
|
|
225
|
+
lines.push("");
|
|
226
|
+
lines.push(" Asset Library growth is compounding:");
|
|
227
|
+
lines.push(` ${p.current.productionReady} → ${p.current.productionReady + 1} → ${p.current.productionReady + 2} → ... → 100`);
|
|
228
|
+
lines.push("");
|
|
229
|
+
return lines.join("\n");
|
|
230
|
+
}
|
|
231
|
+
// ═══════════════════════════════════════════════════════════════
|
|
232
|
+
// CLI
|
|
233
|
+
// ═══════════════════════════════════════════════════════════════
|
|
234
|
+
if (require.main === module) {
|
|
235
|
+
const projection = projectAssetGrowth();
|
|
236
|
+
console.log(formatAssetGrowth(projection));
|
|
237
|
+
// Also show per-repo scoring for curl
|
|
238
|
+
console.log("── Curl: Top Assets by Deployment Score ──");
|
|
239
|
+
const curlAssets = scoreRepoAssets("curl");
|
|
240
|
+
for (const a of curlAssets.slice(0, 10)) {
|
|
241
|
+
const icon = a.tier === "Production Ready" ? "✅" : a.tier === "Pilot Ready" ? "⚠️" : a.tier === "Research" ? "🔬" : "🗄️";
|
|
242
|
+
console.log(` ${icon} ${a.function.padEnd(40)} Score: ${String(a.deploymentScore).padStart(2)}/20 FP: ${(a.fpRateEstimate * 100).toFixed(0)}% ${a.tier}`);
|
|
243
|
+
}
|
|
244
|
+
}
|