feat(humanizer): wire humanizer into scan-orchestrator main with --raw bypass

Adds --json and --raw flags to scan-orchestrator CLI main(). Default mode
runs humanizeEnvelope(env) before serialization; --json and --raw bypass
the humanizer for v5.0.0 byte-equal output (SC-6 / SC-7 paths).

Save-baseline path always writes the raw v5.0.0-shape envelope so future
humanizer-data updates do not trigger false-positive drift findings.

runAllScanners() unchanged — it remains the v5.0.0-shape source of truth
for in-process callers (posture, scoring, drift, etc.).

Wave 3 / Step 5 of v5.1.0 humanizer.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
Kjell Tore Guttormsen 2026-05-01 17:31:37 +02:00
commit 5ff6594976
2 changed files with 158 additions and 2 deletions

View file

@ -13,6 +13,7 @@ import { resetCounter } from './lib/output.mjs';
import { envelope } from './lib/output.mjs';
import { discoverConfigFiles, discoverConfigFilesMulti, discoverFullMachinePaths } from './lib/file-discovery.mjs';
import { loadSuppressions, applySuppressions, formatSuppressionSummary } from './lib/suppression.mjs';
import { humanizeEnvelope } from './lib/humanizer.mjs';
// Scanner registry — import order determines execution order
import { scan as scanClaudeMd } from './claude-md-linter.mjs';
@ -201,6 +202,10 @@ async function main() {
// handled below
} else if (args[i] === '--include-fixtures') {
// handled below
} else if (args[i] === '--json') {
// handled below — explicit machine-readable mode (bypass humanizer)
} else if (args[i] === '--raw') {
// handled below — v5.0.0 verbatim mode (bypass humanizer)
} else if (!args[i].startsWith('-')) {
targetPath = args[i];
}
@ -210,6 +215,8 @@ async function main() {
const fullMachine = args.includes('--full-machine');
const suppress = !args.includes('--no-suppress');
const filterFixtures = !args.includes('--include-fixtures');
const jsonMode = args.includes('--json');
const rawMode = args.includes('--raw');
process.stderr.write(`Config-Audit Scanner v2.2.0\n`);
process.stderr.write(`Target: ${resolve(targetPath)}\n`);
@ -218,7 +225,9 @@ async function main() {
const result = await runAllScanners(targetPath, { includeGlobal, fullMachine, suppress, filterFixtures });
const json = JSON.stringify(result, null, 2);
// Default mode runs the humanizer; --json and --raw bypass for v5.0.0 byte-equal output.
const output = (jsonMode || rawMode) ? result : humanizeEnvelope(result);
const json = JSON.stringify(output, null, 2);
if (outputFile) {
await writeFile(outputFile, json, 'utf-8');
@ -229,7 +238,9 @@ async function main() {
if (saveBaseline) {
const bPath = baselinePath || resolve(targetPath, '.config-audit-baseline.json');
await writeFile(bPath, json, 'utf-8');
// Always save baselines as raw v5.0.0-shape envelope so future humanizer
// changes don't trigger false-positive drift findings.
await writeFile(bPath, JSON.stringify(result, null, 2), 'utf-8');
process.stderr.write(`Baseline saved to ${bPath}\n`);
}