diff --git a/scripts/sync-vsm-oss-metrics.cjs b/scripts/sync-vsm-oss-metrics.cjs index 71790ca..3ba178d 100644 --- a/scripts/sync-vsm-oss-metrics.cjs +++ b/scripts/sync-vsm-oss-metrics.cjs @@ -9,6 +9,8 @@ const pagePath = fs.existsSync(templatePath) ? templatePath : path.join(root, 'v const START = ''; const END = ''; const INDEX_METRICS_END = ''; +const PUBLIC_START = ''; +const PUBLIC_END = ''; const stylesheetVersion = 'vsm-index-metrics.css?v=20260922-vsm-oss'; function argValue(name) { @@ -197,8 +199,43 @@ if (updated.includes(START) || updated.includes(END)) { updated = updated.replace(INDEX_METRICS_END, `${INDEX_METRICS_END}\n${section}`); } + +// The source-only HTML template is omitted from Pages. Add just a bounded +// source-linked summary to the served page without violating its 18 KB budget. +const servedPage = path.join(root, 'vsm-index.html'); +const servedOriginal = pagePath === servedPage ? updated : requiredFile(servedPage); +const outcome = snapshot.repositories['opensiro/upstream'] && + snapshot.repositories['opensiro/upstream'].metrics.verified_external_outcomes; +const compactEvidence = outcomeEvidence ? ( + '

Verified merged changes: ' + + escapeHtml(String(outcome.value)) + ' (not measured benefit). ' + + outcome.accepted.slice(0, 2).map((record) => { + const parts = record.external_pr_url.split('/'); + return '' + + escapeHtml(parts[4] + ' #' + parts[6]) + ''; + }).join(' · ') + + ' · All PRs

' +) : '

Verified merges: evidence-gated. ' + + 'Other PR states

'; +const publicSection = PUBLIC_START + '\n' + compactEvidence + '\n' + PUBLIC_END; +let servedUpdated; +if (servedOriginal.includes(PUBLIC_START) || servedOriginal.includes(PUBLIC_END)) { + if (servedOriginal.split(PUBLIC_START).length !== 2 + || servedOriginal.split(PUBLIC_END).length !== 2 + || servedOriginal.indexOf(PUBLIC_START) > servedOriginal.indexOf(PUBLIC_END)) { + throw new Error('Missing or duplicate public Upstream markers'); + } + servedUpdated = servedOriginal.replace( + new RegExp(PUBLIC_START + '[\\s\\S]*?' + PUBLIC_END), publicSection); +} else { + if (servedOriginal.split('').length !== 2 + || !servedOriginal.includes('
', publicSection + '\n
'); +} if (checkOnly) { - if (updated !== original) { + if (updated !== original || servedUpdated !== servedOriginal) { console.error(`VSM OSS metrics are stale against ${sourcePath}. Run node scripts/sync-vsm-oss-metrics.cjs --source ${sourcePath}`); process.exitCode = 1; } else { @@ -206,5 +243,6 @@ if (checkOnly) { } } else { if (updated !== original) fs.writeFileSync(pagePath, updated); + if (servedUpdated !== servedOriginal) fs.writeFileSync(servedPage, servedUpdated); console.log(`Synced VSM OSS metrics for ${snapshot.scope.length} repository surfaces.`); } diff --git a/tests/vsm-oss-metrics-sync.test.cjs b/tests/vsm-oss-metrics-sync.test.cjs index 43c2454..7574714 100644 --- a/tests/vsm-oss-metrics-sync.test.cjs +++ b/tests/vsm-oss-metrics-sync.test.cjs @@ -34,7 +34,7 @@ test('VSM Index renders organization-owned VSM OSS activity without calculating const script = path.join(dir, 'scripts', 'sync-vsm-oss-metrics.cjs'); const source = path.join(dir, 'vsm-oss-metrics.json'); put(script, fs.readFileSync(path.join(root, 'scripts', 'sync-vsm-oss-metrics.cjs'), 'utf8')); - put(path.join(dir, 'vsm-index.html'), '
index
table
'); + put(path.join(dir, 'vsm-index.html'), '
index
table
'); const scope = [ 'opensiro/vsm-harness-profile', @@ -112,6 +112,8 @@ test('VSM Index renders organization-owned VSM OSS activity without calculating assert.match(page, /href="https:\/\/github.com\/chankov\/agent-fleet\/pull\/43"/); assert.match(page, /href="https:\/\/github.com\/SethGammon\/Citadel\/pull\/366"/); assert.match(page, /2 source-verified merged changes/); + assert.match(page, /id="upstream-verified"/); + assert.match(page, /All PRs/); assert.match(page, /not deployment or measured user benefit/); assert.match(page, /blob\/main\/docs\/METRICS.md/); assert.match(page, /Engineering activity non-KPI<\/span>/); @@ -129,7 +131,7 @@ test('renderer rejects snapshots that promote engineering activity to KPI', () = const script = path.join(dir, 'scripts', 'sync-vsm-oss-metrics.cjs'); const source = path.join(dir, 'snapshot.json'); put(script, fs.readFileSync(path.join(root, 'scripts', 'sync-vsm-oss-metrics.cjs'), 'utf8')); - put(path.join(dir, 'vsm-index.html'), ''); + put(path.join(dir, 'vsm-index.html'), '
'); put(source, JSON.stringify({ scope: ['opensiro/x'], repositories: {}, publication: { window_change_semantics: 'net canonical state change, not gross event count', engineering_activity_is_productivity_kpi: true } })); try { const run = spawnSync(process.execPath, [script, '--source', source], { cwd: dir, encoding: 'utf8' }); @@ -145,7 +147,7 @@ test('rendered merged-change evidence rejects benefit inflation or mutable recei const script = path.join(dir, 'scripts', 'sync-vsm-oss-metrics.cjs'); const source = path.join(dir, 'snapshot.json'); put(script, fs.readFileSync(path.join(root, 'scripts', 'sync-vsm-oss-metrics.cjs'), 'utf8')); - put(path.join(dir, 'vsm-index.html'), ''); + put(path.join(dir, 'vsm-index.html'), '
'); const row = repo('verified_external_outcomes', 1, { '24h': { status: 'source_unavailable_at_baseline', value: null }, '7d': { status: 'source_unavailable_at_baseline', value: null },