📦 deps(thirdparty): update snapshots
This commit is contained in:
+93
@@ -0,0 +1,93 @@
|
||||
#!/usr/bin/env node
|
||||
// CI gate: regenerate the reference docs in memory and diff against what's
|
||||
// checked in. Non-zero exit forces contributors to run build-docs.mjs.
|
||||
|
||||
import { readFile } from 'node:fs/promises';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
import { dirname, join } from 'node:path';
|
||||
import { scanners } from '../lib/scanners/index.mjs';
|
||||
import { gates, MAX_CODE_CANDIDATES, GATE_VERSION } from '../lib/gates/index.mjs';
|
||||
|
||||
const HERE = dirname(fileURLToPath(import.meta.url));
|
||||
const REFS = join(HERE, '..', 'references');
|
||||
|
||||
const GENERATED_BANNER =
|
||||
'<!-- THIS FILE IS GENERATED by scripts/build-docs.mjs. Do not edit by hand. -->\n' +
|
||||
'<!-- To change scanner descriptions, edit lib/scanners/*.mjs metadata exports. -->\n' +
|
||||
'<!-- To change gate thresholds, edit lib/gates/*.mjs metadata exports. -->\n\n';
|
||||
|
||||
async function main() {
|
||||
const expected = {
|
||||
'scanner-patterns.md': renderScanners(),
|
||||
'candidates.md': renderCandidates(),
|
||||
};
|
||||
|
||||
let stale = false;
|
||||
for (const [name, content] of Object.entries(expected)) {
|
||||
let actual;
|
||||
try { actual = await readFile(join(REFS, name), 'utf-8'); }
|
||||
catch {
|
||||
console.error(`[check-docs-fresh] ${name} does not exist. Run \`node scripts/build-docs.mjs\`.`);
|
||||
stale = true;
|
||||
continue;
|
||||
}
|
||||
if (actual !== content) {
|
||||
console.error(`[check-docs-fresh] ${name} is stale. Run \`node scripts/build-docs.mjs\` and commit.`);
|
||||
stale = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (stale) process.exit(1);
|
||||
console.error('[check-docs-fresh] OK — generated docs match source');
|
||||
}
|
||||
|
||||
// MUST stay byte-identical to build-docs.mjs renderers — duplication is the contract.
|
||||
function renderScanners() {
|
||||
const sorted = scanners.slice().sort((a, b) => a.metadata.id.localeCompare(b.metadata.id));
|
||||
let out = GENERATED_BANNER + '# Scanner patterns\n\n';
|
||||
out += 'AST/grep-style scanners run in parallel with metric-driven investigation. They find known anti-patterns. Findings on cold-path or unmappable files are dropped unless the scanner declares `trafficIndependent: true`.\n\n';
|
||||
out += `Total scanners: ${sorted.length}.\n\n`;
|
||||
out += '## Patterns\n\n';
|
||||
for (const s of sorted) {
|
||||
const m = s.metadata;
|
||||
out += `### \`${m.id}\` — ${m.title}\n\n`;
|
||||
out += `- **Severity**: ${m.severity}\n`;
|
||||
out += `- **Billing dimension**: ${m.billingDimension}\n`;
|
||||
out += `- **Traffic-independent**: ${m.trafficIndependent ? 'yes (cold-path findings survive the doctrine drop)' : 'no (cold-path findings get dropped)'}\n\n`;
|
||||
out += `**Description.** ${m.description}\n\n`;
|
||||
out += `**Fix.** ${m.fix}\n\n`;
|
||||
if (m.citations?.length) {
|
||||
out += `**Citations:**\n${m.citations.map((c) => `- \`${c}\``).join('\n')}\n\n`;
|
||||
}
|
||||
out += '---\n\n';
|
||||
}
|
||||
return trimTrailingBlankLine(out);
|
||||
}
|
||||
|
||||
function renderCandidates() {
|
||||
const sorted = gates.slice().sort((a, b) => a.metadata.id.localeCompare(b.metadata.id));
|
||||
let out = GENERATED_BANNER + '# Candidate gates\n\n';
|
||||
out += 'The deterministic threshold expressions that turn observability signals into investigation candidates. Pure JS, no LLM. Thresholds live in `lib/gates/*.mjs`.\n\n';
|
||||
out += `Total gates: ${sorted.length}. Budget cap: \`MAX_CODE_CANDIDATES = ${MAX_CODE_CANDIDATES}\`. Gate version: \`${GATE_VERSION}\`.\n\n`;
|
||||
out += '## Gates\n\n';
|
||||
for (const g of sorted) {
|
||||
const m = g.metadata;
|
||||
out += `### \`${m.id}\`\n\n`;
|
||||
out += `- **Threshold**: \`${m.threshold}\`\n`;
|
||||
out += `- **Billing dimension**: ${m.billingDimension}\n`;
|
||||
out += `- **Scope**: ${m.scope}\n`;
|
||||
out += `- **Source citation**: \`${m.sourceCitation}\`\n\n`;
|
||||
out += `${m.description}\n\n`;
|
||||
out += '---\n\n';
|
||||
}
|
||||
return trimTrailingBlankLine(out);
|
||||
}
|
||||
|
||||
function trimTrailingBlankLine(value) {
|
||||
return value.replace(/\n{2,}$/, '\n');
|
||||
}
|
||||
|
||||
main().catch((err) => {
|
||||
console.error('[check-docs-fresh] FAILED:', err.message);
|
||||
process.exit(1);
|
||||
});
|
||||
Reference in New Issue
Block a user