Skip to content

Commit 25c0a5e

Browse files
Initial dedicated platform signal build
0 parents  commit 25c0a5e

8 files changed

Lines changed: 182 additions & 0 deletions

File tree

.github/workflows/ci.yml

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
name: ci
2+
3+
on:
4+
push:
5+
branches: [main]
6+
pull_request:
7+
8+
permissions:
9+
contents: read
10+
11+
jobs:
12+
test:
13+
runs-on: ubuntu-latest
14+
steps:
15+
- uses: actions/checkout@v4
16+
- uses: actions/setup-node@v4
17+
with:
18+
node-version: 22
19+
- run: npm test
20+
- run: npm run build

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
node_modules/
2+
site/report.json

README.md

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
# gitlab-release-governance-console
2+
3+
Board-readable Kinetic Gain proof repo for **GitLab** signal coverage.
4+
5+
## Signal lane
6+
7+
- Vendor / platform: GitLab
8+
- Domain: DevOps / Platform Engineering
9+
- Executive question: Where is this system creating exposure, waste, or decision latency?
10+
- Proof posture: synthetic fixture, deterministic CLI, static report, and CI gate.
11+
12+
## Why this exists
13+
14+
Release governance, pipeline evidence, merge risk, and delivery control posture.
15+
16+
This repo is intentionally small and explicit. It gives the portfolio atlas a named, inspectable proof artifact for GitLab without needing another hosted subdomain or exposing live customer data.
17+
18+
## Local run
19+
20+
`ash
21+
npm install
22+
npm test
23+
npm run build
24+
npm run demo
25+
`
26+
27+
## Security posture
28+
29+
- No secrets, tokens, customer records, or live API calls.
30+
- Fixture data is synthetic and stored in ixtures/sample.json.
31+
- Output is deterministic and safe for public portfolio inspection.

fixtures/sample.json

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
{
2+
"vendor": "GitLab",
3+
"domain": "DevOps / Platform Engineering",
4+
"lanes": [
5+
{
6+
"name": "Ownership clarity",
7+
"risk": 68,
8+
"evidence": 7,
9+
"owner": "Platform owner",
10+
"nextAction": "Confirm one accountable owner and one board-readable evidence packet."
11+
},
12+
{
13+
"name": "Spend and exposure posture",
14+
"risk": 74,
15+
"evidence": 6,
16+
"owner": "Finance and risk lead",
17+
"nextAction": "Tie cost, access, or workflow exceptions to a remediation queue."
18+
},
19+
{
20+
"name": "Decision readiness",
21+
"risk": 61,
22+
"evidence": 8,
23+
"owner": "Executive sponsor",
24+
"nextAction": "Summarize whether to invest, consolidate, remediate, or monitor."
25+
}
26+
]
27+
}

package.json

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
{
2+
"name": "@kineticgain/gitlab-release-governance-console",
3+
"version": "1.0.0",
4+
"private": false,
5+
"type": "module",
6+
"description": "Kinetic Gain proof repo for GitLab platform and company signal coverage.",
7+
"scripts": {
8+
"demo": "node src/index.mjs fixtures/sample.json",
9+
"build": "node src/index.mjs fixtures/sample.json --site site/report.json",
10+
"test": "node --test"
11+
},
12+
"license": "AGPL-3.0-or-later"
13+
}

site/index.html

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
<!doctype html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="utf-8" />
5+
<meta name="viewport" content="width=device-width, initial-scale=1" />
6+
<title>GitLab Signal Brief | Kinetic Gain</title>
7+
<style>
8+
:root { color-scheme: dark; --bg: #070b12; --panel: #101827; --line: #243249; --text: #f5f1e8; --muted: #aeb8ca; --aqua: #25d9f2; --mint: #39e7aa; }
9+
body { margin: 0; font-family: Inter, ui-sans-serif, system-ui, sans-serif; background: radial-gradient(circle at top right, rgba(37,217,242,.14), transparent 34%), var(--bg); color: var(--text); }
10+
main { max-width: 980px; margin: 0 auto; padding: 56px 22px; }
11+
.card { border: 1px solid var(--line); border-radius: 28px; background: linear-gradient(145deg, rgba(16,24,39,.94), rgba(7,11,18,.98)); padding: clamp(24px, 5vw, 52px); box-shadow: 0 24px 80px rgba(0,0,0,.32); }
12+
.eyebrow { color: var(--mint); text-transform: uppercase; letter-spacing: .16em; font: 700 12px/1.2 ui-monospace, SFMono-Regular, Consolas, monospace; }
13+
h1 { margin: 18px 0; font-size: clamp(42px, 8vw, 88px); line-height: .92; letter-spacing: -.06em; }
14+
p { color: var(--muted); font-size: 18px; line-height: 1.7; max-width: 720px; }
15+
.grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); gap: 14px; margin-top: 28px; }
16+
.metric { border: 1px solid var(--line); border-radius: 18px; padding: 18px; background: rgba(255,255,255,.035); }
17+
.metric b { display: block; color: var(--aqua); font-size: 28px; margin-top: 8px; }
18+
code { color: var(--mint); }
19+
</style>
20+
</head>
21+
<body>
22+
<main>
23+
<section class="card">
24+
<div class="eyebrow">Kinetic Gain signal proof</div>
25+
<h1>GitLab<br />control evidence.</h1>
26+
<p>Release governance, pipeline evidence, merge risk, and delivery control posture.</p>
27+
<div class="grid">
28+
<div class="metric">Domain<b>DevOps / Platform Engineering</b></div>
29+
<div class="metric">Fixture posture<b>Synthetic</b></div>
30+
<div class="metric">Output<b>Board brief</b></div>
31+
</div>
32+
<p>Run <code>npm test</code> and <code>npm run build</code> to regenerate the deterministic proof packet.</p>
33+
</section>
34+
</main>
35+
</body>
36+
</html>

src/index.mjs

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import fs from 'node:fs';
2+
3+
export function summarizeSignal(input) {
4+
const lanes = input.lanes ?? [];
5+
const averageRisk = Math.round(lanes.reduce((sum, lane) => sum + lane.risk, 0) / Math.max(lanes.length, 1));
6+
const averageEvidence = Math.round(lanes.reduce((sum, lane) => sum + lane.evidence, 0) / Math.max(lanes.length, 1));
7+
const priorityLane = [...lanes].sort((a, b) => b.risk - a.risk)[0] ?? null;
8+
return {
9+
vendor: input.vendor,
10+
domain: input.domain,
11+
averageRisk,
12+
averageEvidence,
13+
priorityLane: priorityLane?.name ?? 'None',
14+
recommendation: priorityLane
15+
? input.vendor + ': start with ' + priorityLane.name.toLowerCase() + ' because it has the highest board-visible risk.'
16+
: input.vendor + ': no lanes available for scoring.'
17+
};
18+
}
19+
20+
export function formatSummary(summary) {
21+
return [
22+
summary.vendor + ' signal brief',
23+
'Domain: ' + summary.domain,
24+
'Average risk: ' + summary.averageRisk,
25+
'Evidence depth: ' + summary.averageEvidence,
26+
'Priority lane: ' + summary.priorityLane,
27+
'Recommendation: ' + summary.recommendation
28+
].join('\n');
29+
}
30+
31+
if (import.meta.url === 'file://' + process.argv[1]) {
32+
const fixturePath = process.argv[2] ?? 'fixtures/sample.json';
33+
const siteIndex = process.argv.indexOf('--site');
34+
const input = JSON.parse(fs.readFileSync(fixturePath, 'utf8'));
35+
const summary = summarizeSignal(input);
36+
if (siteIndex >= 0) {
37+
fs.writeFileSync(process.argv[siteIndex + 1], JSON.stringify(summary, null, 2));
38+
}
39+
console.log(formatSummary(summary));
40+
}

test/index.test.mjs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import assert from 'node:assert/strict';
2+
import { test } from 'node:test';
3+
import fixture from '../fixtures/sample.json' with { type: 'json' };
4+
import { summarizeSignal } from '../src/index.mjs';
5+
6+
test('GitLab signal fixture summarizes deterministically', () => {
7+
const summary = summarizeSignal(fixture);
8+
assert.equal(summary.vendor, 'GitLab');
9+
assert.equal(summary.domain, 'DevOps / Platform Engineering');
10+
assert.equal(summary.averageRisk, 68);
11+
assert.equal(summary.averageEvidence, 7);
12+
assert.equal(summary.priorityLane, 'Spend and exposure posture');
13+
});

0 commit comments

Comments
 (0)