mirror of
https://github.com/pbakaus/impeccable.git
synced 2026-09-11 21:57:14 +03:00
From a forensics pass over twelve runs and two adversarial passes over the metrics: - comp-diff: detail is signed and penalizes invented energy; regions with structure under 0.3 (or painted regions under 0.45 / added detail over 0.4) are contradicted whatever the mean says; palette ramp tightened; region crops inherit the whole-image best translation so a shifted page is not eight contradicted regions. - hero gate: fails on any contradicted plate/image/text region (chrome and controls keep the one-third allowance), on a capture that is not the comp's frame, on a palette that is not the comp's, and on an organic clip-path drawn inside a raster region's box. - plates gate: scored against the comp crop with overlapping text/chrome painted out (comp-spec plateReference; generate-image uses it too), with a structure floor and an added-detail veto; the real plate passes, noise, mirrors, mosaics, and other regions do not. - comp-spec refuses a regions file that leaves comp ink unnamed. - The direction-choice ping is folded into build-phase.mjs start --direction --kind; the roll writes .impeccable/build/pending.json and context.mjs / detect.mjs report COMP_ROUND_OPEN until the hero gate passes. A code-led config makes start print the contract step and stop. AI-assisted (Claude). Co-Authored-By: Claude <noreply@anthropic.com>
31 lines
1.2 KiB
JavaScript
31 lines
1.2 KiB
JavaScript
#!/usr/bin/env node
|
|
|
|
import fs from 'node:fs';
|
|
import path from 'node:path';
|
|
import { pathToFileURL, fileURLToPath } from 'node:url';
|
|
|
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
const candidates = [
|
|
path.join(__dirname, 'detector', 'detect-antipatterns.mjs'),
|
|
path.join(__dirname, '..', '..', 'cli', 'engine', 'detect-antipatterns.mjs'),
|
|
];
|
|
const detectorPath = candidates.find(p => fs.existsSync(p));
|
|
|
|
if (!detectorPath) {
|
|
process.stderr.write('Error: bundled detector not found.\n');
|
|
process.exit(1);
|
|
}
|
|
|
|
const { detectCli } = await import(pathToFileURL(detectorPath));
|
|
|
|
// A comp-led build with its comp round or hero gate still open is not a page
|
|
// the detector can pass: say so after the scan (stderr, so --json stays
|
|
// parseable), on the same condition context.mjs reports at boot.
|
|
try {
|
|
const { compRoundOpen } = await import(pathToFileURL(path.join(__dirname, 'build-phase.mjs')));
|
|
const open = compRoundOpen(process.cwd());
|
|
if (open) process.stderr.write(`COMP_ROUND_OPEN: ${open.reason}. A detector pass is not a finish: run node ${__dirname}/build-phase.mjs status and follow its NEXT line before treating this page as built.\n`);
|
|
} catch { /* build-phase absent */ }
|
|
|
|
await detectCli();
|