aibvf-check 0.1.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Craig Horton
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,73 @@
1
+ # aibvf-check
2
+
3
+ **SonarQube for AI initiatives.** A CI/CD pre-flight gate that fails the build when a declared AI initiative would not survive a board review — using the deterministic [AI BVF v1.0](https://www.aibvf.com/protocol) engine.
4
+
5
+ The scoring belongs upstream of the slide deck. `aibvf-check` puts it in the one place a team already trusts to block bad work: the pipeline.
6
+
7
+ ## 30-second use
8
+
9
+ Add a manifest at your repo root, `.aibvf.json`:
10
+
11
+ ```json
12
+ {
13
+ "bvf_version": "1.0",
14
+ "organization": { "industry": "financial", "revenue_eur": 400000000 },
15
+ "policy": { "fail_on": ["Stop"], "max_governance_risk": 60, "min_decision_confidence": 50 },
16
+ "initiatives": [
17
+ { "id": "cx-genai-assistant", "function": "cx", "ai_tier": "gen2", "readiness": "traditional",
18
+ "scores": { "strategic_alignment": 70, "financial_return": 55, "change_enablement": 55, "governance_risk": 45 },
19
+ "signal_completeness": 0.8 }
20
+ ]
21
+ }
22
+ ```
23
+
24
+ Run it:
25
+
26
+ ```bash
27
+ npx aibvf-check
28
+ ```
29
+
30
+ It scores every initiative, prints a scorecard, and **exits non-zero if any trips the policy** — so CI goes red.
31
+
32
+ ## GitHub Action
33
+
34
+ ```yaml
35
+ - uses: Bahamas1717/ai-bvf@v0.7.0
36
+ with:
37
+ manifest: .aibvf.json # optional, this is the default
38
+ ```
39
+
40
+ The step fails the workflow on any policy violation.
41
+
42
+ ## Policy
43
+
44
+ | Field | Effect |
45
+ |---|---|
46
+ | `fail_on` | Classifications that fail the gate. Default `["Stop"]`. Add `"Fix"` to be strict. |
47
+ | `max_governance_risk` | Optional hard ceiling (0–100). A higher `governance_risk` fails, regardless of verdict. |
48
+ | `min_decision_confidence` | Optional floor (0–100). A lower decision confidence fails. |
49
+
50
+ `signal_completeness` (0–1, per initiative) forwards to the engine: estimated inputs honestly haircut confidence and surface a caveat, so a low-evidence initiative can't sail through on a confident-looking number.
51
+
52
+ ## Exit codes
53
+
54
+ | Code | Meaning |
55
+ |---|---|
56
+ | `0` | All initiatives cleared the policy. |
57
+ | `1` | One or more policy violations — the gate failed. |
58
+ | `2` | Config error (manifest missing, malformed, or a bad enum value). |
59
+
60
+ ## Options
61
+
62
+ ```
63
+ aibvf-check [--manifest <path>] [--json]
64
+ -m, --manifest <path> Manifest file (default: .aibvf.json)
65
+ --json Machine-readable JSON instead of the table
66
+ -h, --help Help
67
+ ```
68
+
69
+ Deterministic, no network, no telemetry. Same inputs → same verdict, every run. Built on [`@aibvf/core`](https://www.npmjs.com/package/@aibvf/core).
70
+
71
+ ## License
72
+
73
+ MIT.
package/dist/cli.js ADDED
@@ -0,0 +1,116 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * aibvf-check CLI entry. Owns all side effects: read the manifest, print the
4
+ * scorecard, and exit with a code CI can gate on.
5
+ *
6
+ * exit 0 all initiatives pass the policy
7
+ * exit 1 one or more initiatives violate the policy (the gate "fails")
8
+ * exit 2 usage / config error (manifest missing, malformed, bad enum)
9
+ *
10
+ * Usage:
11
+ * aibvf-check [--manifest <path>] [--json]
12
+ * Defaults to ./.aibvf.json.
13
+ */
14
+ import { readFileSync } from 'node:fs';
15
+ import { runCheck, lintManifest } from './index.js';
16
+ const BVF_VERSION = '1.0';
17
+ function parseArgs(argv) {
18
+ let manifest = '.aibvf.json';
19
+ let json = false;
20
+ for (let i = 0; i < argv.length; i++) {
21
+ const a = argv[i];
22
+ if (a === '--manifest' || a === '-m')
23
+ manifest = argv[++i];
24
+ else if (a === '--json')
25
+ json = true;
26
+ else if (a === '--help' || a === '-h') {
27
+ printHelp();
28
+ process.exit(0);
29
+ }
30
+ }
31
+ return { manifest, json };
32
+ }
33
+ function printHelp() {
34
+ console.log(`aibvf-check — the AI BVF CI/CD pre-flight gate ("SonarQube for AI")
35
+
36
+ Scores the AI initiatives declared in a manifest and fails the build when any
37
+ would not survive a board review.
38
+
39
+ Usage:
40
+ aibvf-check [--manifest <path>] [--json]
41
+
42
+ Options:
43
+ -m, --manifest <path> Manifest file (default: .aibvf.json)
44
+ --json Emit machine-readable JSON instead of a table
45
+ -h, --help Show this help
46
+
47
+ Exit codes: 0 pass 1 gate failed 2 config error
48
+ Docs: https://www.aibvf.com/protocol`);
49
+ }
50
+ function fail(msg) {
51
+ console.error(`aibvf-check: ${msg}`);
52
+ process.exit(2);
53
+ }
54
+ const { manifest: manifestPath, json } = parseArgs(process.argv.slice(2));
55
+ let raw;
56
+ try {
57
+ raw = readFileSync(manifestPath, 'utf8');
58
+ }
59
+ catch {
60
+ fail(`could not read manifest '${manifestPath}'. Create one or pass --manifest <path>.`);
61
+ }
62
+ let parsed;
63
+ try {
64
+ parsed = JSON.parse(raw);
65
+ }
66
+ catch (e) {
67
+ fail(`manifest '${manifestPath}' is not valid JSON: ${e instanceof Error ? e.message : e}`);
68
+ }
69
+ const lintErrors = lintManifest(parsed);
70
+ if (lintErrors.length) {
71
+ fail(`manifest '${manifestPath}' is malformed:\n - ${lintErrors.join('\n - ')}`);
72
+ }
73
+ let result;
74
+ try {
75
+ result = runCheck(parsed);
76
+ }
77
+ catch (e) {
78
+ // score() throws on unknown industry/function/ai_tier/readiness enum values.
79
+ fail(`scoring failed: ${e instanceof Error ? e.message : e}. Check the manifest enums against list_taxonomy.`);
80
+ }
81
+ if (json) {
82
+ console.log(JSON.stringify({ bvf_version: BVF_VERSION, ...result }, null, 2));
83
+ process.exit(result.ok ? 0 : 1);
84
+ }
85
+ // Human-readable scorecard.
86
+ const eur = (n) => `€${Math.round(n / 1e6 * 10) / 10}M`;
87
+ console.log('');
88
+ console.log('AI BVF pre-flight gate · bvf v' + BVF_VERSION);
89
+ console.log('─'.repeat(72));
90
+ for (const r of result.results) {
91
+ const tag = r.violations.length ? '✗' : '✓';
92
+ console.log(`${tag} ${r.id} [${r.classification}] conf ${r.decision_confidence} ${eur(r.net_value_eur.low)}–${eur(r.net_value_eur.high)}`);
93
+ if (r.caveat)
94
+ console.log(` ⚠ ${r.caveat}`);
95
+ for (const v of r.violations)
96
+ console.log(` ✗ ${v}`);
97
+ }
98
+ console.log('─'.repeat(72));
99
+ const policyBits = [
100
+ `fail_on=[${result.policy.fail_on.join(', ')}]`,
101
+ result.policy.max_governance_risk != null ? `max_governance_risk=${result.policy.max_governance_risk}` : null,
102
+ result.policy.min_decision_confidence != null ? `min_decision_confidence=${result.policy.min_decision_confidence}` : null,
103
+ ].filter(Boolean).join(' ');
104
+ console.log(`policy: ${policyBits}`);
105
+ if (result.ok) {
106
+ console.log(`\n✓ PASS — ${result.results.length} initiative(s) cleared the gate.`);
107
+ process.exit(0);
108
+ }
109
+ else {
110
+ console.log(`\n✗ FAIL — ${result.failures.length} policy violation(s):`);
111
+ for (const f of result.failures)
112
+ console.log(` - ${f}`);
113
+ console.log('\nRaise the weak pillars (or rescope the initiative) and re-run. See recommend_improvements.');
114
+ process.exit(1);
115
+ }
116
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;GAWG;AACH,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAiB,MAAM,YAAY,CAAC;AAEnE,MAAM,WAAW,GAAG,KAAK,CAAC;AAE1B,SAAS,SAAS,CAAC,IAAc;IAC/B,IAAI,QAAQ,GAAG,aAAa,CAAC;IAC7B,IAAI,IAAI,GAAG,KAAK,CAAC;IACjB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACrC,MAAM,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,IAAI,CAAC,KAAK,YAAY,IAAI,CAAC,KAAK,IAAI;YAAE,QAAQ,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;aACtD,IAAI,CAAC,KAAK,QAAQ;YAAE,IAAI,GAAG,IAAI,CAAC;aAChC,IAAI,CAAC,KAAK,QAAQ,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC;YAAC,SAAS,EAAE,CAAC;YAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAAC,CAAC;IAC1E,CAAC;IACD,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;AAC5B,CAAC;AAED,SAAS,SAAS;IAChB,OAAO,CAAC,GAAG,CAAC;;;;;;;;;;;;;;qCAcuB,CAAC,CAAC;AACvC,CAAC;AAED,SAAS,IAAI,CAAC,GAAW;IACvB,OAAO,CAAC,KAAK,CAAC,gBAAgB,GAAG,EAAE,CAAC,CAAC;IACrC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC;AAED,MAAM,EAAE,QAAQ,EAAE,YAAY,EAAE,IAAI,EAAE,GAAG,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;AAE1E,IAAI,GAAW,CAAC;AAChB,IAAI,CAAC;IACH,GAAG,GAAG,YAAY,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC;AAC3C,CAAC;AAAC,MAAM,CAAC;IACP,IAAI,CAAC,4BAA4B,YAAY,0CAA0C,CAAC,CAAC;AAC3F,CAAC;AAED,IAAI,MAAe,CAAC;AACpB,IAAI,CAAC;IACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;AAC3B,CAAC;AAAC,OAAO,CAAC,EAAE,CAAC;IACX,IAAI,CAAC,aAAa,YAAY,wBAAwB,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;AAC9F,CAAC;AAED,MAAM,UAAU,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC;AACxC,IAAI,UAAU,CAAC,MAAM,EAAE,CAAC;IACtB,IAAI,CAAC,aAAa,YAAY,wBAAwB,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AACrF,CAAC;AAED,IAAI,MAAM,CAAC;AACX,IAAI,CAAC;IACH,MAAM,GAAG,QAAQ,CAAC,MAAkB,CAAC,CAAC;AACxC,CAAC;AAAC,OAAO,CAAC,EAAE,CAAC;IACX,6EAA6E;IAC7E,IAAI,CAAC,mBAAmB,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,mDAAmD,CAAC,CAAC;AACjH,CAAC;AAED,IAAI,IAAI,EAAE,CAAC;IACT,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,WAAW,EAAE,WAAW,EAAE,GAAG,MAAM,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;IAC9E,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAClC,CAAC;AAED,4BAA4B;AAC5B,MAAM,GAAG,GAAG,CAAC,CAAS,EAAE,EAAE,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,GAAG,GAAG,EAAE,CAAC,GAAG,EAAE,GAAG,CAAC;AAChE,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;AAChB,OAAO,CAAC,GAAG,CAAC,gCAAgC,GAAG,WAAW,CAAC,CAAC;AAC5D,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC;AAC5B,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;IAC/B,MAAM,GAAG,GAAG,CAAC,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;IAC5C,OAAO,CAAC,GAAG,CAAC,GAAG,GAAG,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,cAAc,WAAW,CAAC,CAAC,mBAAmB,KAAK,GAAG,CAAC,CAAC,CAAC,aAAa,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,aAAa,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAC9I,IAAI,CAAC,CAAC,MAAM;QAAE,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC;IAC/C,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,UAAU;QAAE,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;AAC1D,CAAC;AACD,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC;AAC5B,MAAM,UAAU,GAAG;IACjB,YAAY,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG;IAC/C,MAAM,CAAC,MAAM,CAAC,mBAAmB,IAAI,IAAI,CAAC,CAAC,CAAC,uBAAuB,MAAM,CAAC,MAAM,CAAC,mBAAmB,EAAE,CAAC,CAAC,CAAC,IAAI;IAC7G,MAAM,CAAC,MAAM,CAAC,uBAAuB,IAAI,IAAI,CAAC,CAAC,CAAC,2BAA2B,MAAM,CAAC,MAAM,CAAC,uBAAuB,EAAE,CAAC,CAAC,CAAC,IAAI;CAC1H,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC7B,OAAO,CAAC,GAAG,CAAC,WAAW,UAAU,EAAE,CAAC,CAAC;AAErC,IAAI,MAAM,CAAC,EAAE,EAAE,CAAC;IACd,OAAO,CAAC,GAAG,CAAC,cAAc,MAAM,CAAC,OAAO,CAAC,MAAM,kCAAkC,CAAC,CAAC;IACnF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC;KAAM,CAAC;IACN,OAAO,CAAC,GAAG,CAAC,cAAc,MAAM,CAAC,QAAQ,CAAC,MAAM,uBAAuB,CAAC,CAAC;IACzE,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,QAAQ;QAAE,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IACzD,OAAO,CAAC,GAAG,CAAC,8FAA8F,CAAC,CAAC;IAC5G,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,110 @@
1
+ /**
2
+ * aibvf-check — the AI BVF CI/CD pre-flight gate.
3
+ *
4
+ * Reads a declared manifest of AI initiatives, scores each one with the
5
+ * deterministic AI BVF engine (@aibvf/core), applies a policy, and reports
6
+ * which initiatives violate it. The executable (cli.ts) turns a violation
7
+ * into a non-zero exit so the build goes red — "SonarQube for AI".
8
+ *
9
+ * This module is pure: no file IO, no process.exit, no console. That keeps
10
+ * the gate logic unit-testable; cli.ts owns the side effects.
11
+ */
12
+ import { score } from '@aibvf/core';
13
+ const DEFAULT_FAIL_ON = ['Stop'];
14
+ /**
15
+ * Validate the manifest shape enough to score it. Returns a list of human
16
+ * error strings; empty means well-formed. Kept deliberately light — score()
17
+ * itself rejects unknown enums, so this only catches structural gaps.
18
+ */
19
+ export function lintManifest(m) {
20
+ const errors = [];
21
+ if (typeof m !== 'object' || m === null)
22
+ return ['Manifest must be a JSON object.'];
23
+ const man = m;
24
+ const org = man.organization;
25
+ if (!org || typeof org !== 'object')
26
+ errors.push('organization is required.');
27
+ else {
28
+ if (typeof org.industry !== 'string')
29
+ errors.push('organization.industry is required.');
30
+ if (typeof org.revenue_eur !== 'number')
31
+ errors.push('organization.revenue_eur (number) is required.');
32
+ }
33
+ if (!Array.isArray(man.initiatives) || man.initiatives.length === 0) {
34
+ errors.push('initiatives must be a non-empty array.');
35
+ }
36
+ else {
37
+ man.initiatives.forEach((init, i) => {
38
+ const it = init;
39
+ if (typeof it.id !== 'string')
40
+ errors.push(`initiatives[${i}].id is required.`);
41
+ if (typeof it.function !== 'string')
42
+ errors.push(`initiatives[${i}].function is required.`);
43
+ if (typeof it.ai_tier !== 'string')
44
+ errors.push(`initiatives[${i}].ai_tier is required.`);
45
+ if (typeof it.readiness !== 'string')
46
+ errors.push(`initiatives[${i}].readiness is required.`);
47
+ const sc = it.scores;
48
+ if (!sc || typeof sc !== 'object')
49
+ errors.push(`initiatives[${i}].scores is required.`);
50
+ else {
51
+ for (const p of ['strategic_alignment', 'financial_return', 'change_enablement', 'governance_risk']) {
52
+ if (typeof sc[p] !== 'number')
53
+ errors.push(`initiatives[${i}].scores.${p} (number) is required.`);
54
+ }
55
+ }
56
+ });
57
+ }
58
+ return errors;
59
+ }
60
+ /**
61
+ * Score every initiative in the manifest and apply the policy.
62
+ * Pure: deterministic, no IO. Throws only if score() rejects an enum value.
63
+ */
64
+ export function runCheck(manifest) {
65
+ const fail_on = manifest.policy?.fail_on ?? DEFAULT_FAIL_ON;
66
+ const maxGov = manifest.policy?.max_governance_risk;
67
+ const minConf = manifest.policy?.min_decision_confidence;
68
+ const { industry, revenue_eur } = manifest.organization;
69
+ const results = manifest.initiatives.map((init) => {
70
+ const r = score({
71
+ industry,
72
+ revenue_eur,
73
+ function: init.function,
74
+ ai_tier: init.ai_tier,
75
+ readiness: init.readiness,
76
+ scores: init.scores,
77
+ signal_completeness: init.signal_completeness,
78
+ });
79
+ const violations = [];
80
+ if (fail_on.includes(r.classification)) {
81
+ violations.push(`classification ${r.classification} is blocked by policy.fail_on`);
82
+ }
83
+ if (typeof maxGov === 'number' && init.scores.governance_risk > maxGov) {
84
+ violations.push(`governance_risk ${init.scores.governance_risk} exceeds max_governance_risk ${maxGov}`);
85
+ }
86
+ if (typeof minConf === 'number' && r.confidence < minConf) {
87
+ violations.push(`decision_confidence ${r.confidence} below min_decision_confidence ${minConf}`);
88
+ }
89
+ return {
90
+ id: init.id,
91
+ function: init.function,
92
+ ai_tier: init.ai_tier,
93
+ classification: r.classification,
94
+ decision_confidence: r.confidence,
95
+ governance_risk: init.scores.governance_risk,
96
+ net_value_eur: { low: r.net_low_eur, high: r.net_high_eur },
97
+ reason: r.reason,
98
+ ...(r.caveat ? { caveat: r.caveat } : {}),
99
+ violations,
100
+ };
101
+ });
102
+ const failures = results.flatMap((res) => res.violations.map((v) => `${res.id}: ${v}`));
103
+ return {
104
+ ok: failures.length === 0,
105
+ policy: { fail_on, max_governance_risk: maxGov, min_decision_confidence: minConf },
106
+ results,
107
+ failures,
108
+ };
109
+ }
110
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,96 @@
1
+ import { test } from 'node:test';
2
+ import assert from 'node:assert/strict';
3
+ import { runCheck, lintManifest } from './index.js';
4
+ const baseManifest = {
5
+ bvf_version: '1.0',
6
+ organization: { industry: 'financial', revenue_eur: 400_000_000 },
7
+ policy: { fail_on: ['Stop'], max_governance_risk: 60, min_decision_confidence: 50 },
8
+ initiatives: [
9
+ {
10
+ id: 'cx-genai-bot', function: 'cx', ai_tier: 'gen2', readiness: 'traditional',
11
+ scores: { strategic_alignment: 70, financial_return: 50, change_enablement: 55, governance_risk: 45 },
12
+ },
13
+ ],
14
+ };
15
+ test('a healthy initiative passes the gate', () => {
16
+ const r = runCheck(baseManifest);
17
+ assert.equal(r.ok, true);
18
+ assert.equal(r.failures.length, 0);
19
+ assert.equal(r.results[0].violations.length, 0);
20
+ });
21
+ test('a Stop initiative fails on fail_on', () => {
22
+ const m = {
23
+ ...baseManifest,
24
+ initiatives: [{
25
+ id: 'doomed', function: 'finance', ai_tier: 'gen1', readiness: 'siloed',
26
+ // governance_risk 75 → score() returns Stop
27
+ scores: { strategic_alignment: 30, financial_return: 15, change_enablement: 20, governance_risk: 75 },
28
+ }],
29
+ };
30
+ const r = runCheck(m);
31
+ assert.equal(r.ok, false);
32
+ assert.equal(r.results[0].classification, 'Stop');
33
+ assert.ok(r.failures.some((f) => f.includes('Stop')));
34
+ });
35
+ test('max_governance_risk ceiling is enforced independently of classification', () => {
36
+ const m = {
37
+ ...baseManifest,
38
+ policy: { fail_on: [], max_governance_risk: 40 },
39
+ initiatives: [{
40
+ id: 'risky', function: 'cx', ai_tier: 'gen2', readiness: 'traditional',
41
+ scores: { strategic_alignment: 80, financial_return: 80, change_enablement: 80, governance_risk: 55 },
42
+ }],
43
+ };
44
+ const r = runCheck(m);
45
+ assert.equal(r.ok, false);
46
+ assert.ok(r.failures.some((f) => f.includes('governance_risk 55 exceeds')));
47
+ });
48
+ test('min_decision_confidence floor catches low-confidence verdicts', () => {
49
+ const m = {
50
+ ...baseManifest,
51
+ policy: { fail_on: [], min_decision_confidence: 60 },
52
+ initiatives: [{
53
+ id: 'soft', function: 'cx', ai_tier: 'gen2', readiness: 'traditional',
54
+ scores: { strategic_alignment: 70, financial_return: 50, change_enablement: 55, governance_risk: 45 },
55
+ signal_completeness: 0.4, // haircuts confidence below 60
56
+ }],
57
+ };
58
+ const r = runCheck(m);
59
+ assert.equal(r.ok, false);
60
+ assert.ok(r.failures.some((f) => f.includes('below min_decision_confidence')));
61
+ assert.ok(r.results[0].caveat, 'low signal_completeness should surface a caveat');
62
+ });
63
+ test('policy defaults to fail_on Stop when omitted', () => {
64
+ const m = {
65
+ organization: { industry: 'retail', revenue_eur: 100_000_000 },
66
+ initiatives: [{
67
+ id: 'ok', function: 'sales', ai_tier: 'gen2', readiness: 'agile',
68
+ scores: { strategic_alignment: 75, financial_return: 70, change_enablement: 70, governance_risk: 20 },
69
+ }],
70
+ };
71
+ const r = runCheck(m);
72
+ assert.deepEqual(r.policy.fail_on, ['Stop']);
73
+ assert.equal(r.ok, true);
74
+ });
75
+ test('failures aggregate across multiple initiatives, ids preserved', () => {
76
+ const m = {
77
+ ...baseManifest,
78
+ policy: { fail_on: ['Stop'], max_governance_risk: 50 },
79
+ initiatives: [
80
+ { id: 'good', function: 'cx', ai_tier: 'gen2', readiness: 'agile',
81
+ scores: { strategic_alignment: 80, financial_return: 75, change_enablement: 70, governance_risk: 25 } },
82
+ { id: 'bad', function: 'finance', ai_tier: 'gen1', readiness: 'siloed',
83
+ scores: { strategic_alignment: 30, financial_return: 15, change_enablement: 20, governance_risk: 80 } },
84
+ ],
85
+ };
86
+ const r = runCheck(m);
87
+ assert.equal(r.ok, false);
88
+ assert.ok(r.failures.every((f) => f.startsWith('good:') || f.startsWith('bad:')));
89
+ assert.ok(r.failures.some((f) => f.startsWith('bad:')));
90
+ });
91
+ test('lintManifest catches structural gaps', () => {
92
+ assert.ok(lintManifest({}).length > 0);
93
+ assert.ok(lintManifest({ organization: { industry: 'retail', revenue_eur: 1 }, initiatives: [] }).length > 0);
94
+ assert.equal(lintManifest(baseManifest).length, 0);
95
+ });
96
+ //# sourceMappingURL=index.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.test.js","sourceRoot":"","sources":["../src/index.test.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,30 @@
1
+ {
2
+ "name": "aibvf-check",
3
+ "version": "0.1.0",
4
+ "description": "SonarQube for AI initiatives — a CI/CD pre-flight gate that fails the build when an AI initiative would not survive a board review. Deterministic, runs on AI BVF v1.0.",
5
+ "keywords": [
6
+ "ai-bvf", "bvf", "ci", "ci-cd", "pre-flight", "gate", "ai-governance",
7
+ "ai-roi", "policy", "eu-ai-act", "github-action", "sonarqube-for-ai"
8
+ ],
9
+ "homepage": "https://www.aibvf.com/protocol",
10
+ "repository": "github:Bahamas1717/ai-bvf",
11
+ "license": "MIT",
12
+ "author": "Craig Horton",
13
+ "type": "module",
14
+ "main": "dist/index.js",
15
+ "bin": {
16
+ "aibvf-check": "dist/cli.js"
17
+ },
18
+ "files": ["dist", "README.md", "LICENSE"],
19
+ "scripts": {
20
+ "build": "tsc && node -e \"require('fs').chmodSync('dist/cli.js', 0o755)\"",
21
+ "test": "node --test dist/*.test.js"
22
+ },
23
+ "dependencies": {
24
+ "@aibvf/core": "^0.3.4"
25
+ },
26
+ "devDependencies": {
27
+ "typescript": "^5.4.0",
28
+ "@types/node": "^20.0.0"
29
+ }
30
+ }