Hero gate: text and chrome regions read as drift once structure and palette hold; scripts run through symlinks

Three simulated builds under the previous gate reached 78-83% overall with
the exploded plate placed and the table right, then spent 12-20 attempts
chasing 'contradicted' verdicts on a headline set in a substitute face and
on 50px chrome strips whose detail was paper grain. Text with structure
above the floor and its palette intact is drift; chrome and controls with
structure and palette held are drift. The adversarial set (swapped
columns, mirror, sepia, noise plate, tile shuffle) still fails.

isMain uses realpath on both sides so a skill mounted through a symlink
(Cursor, worktrees, staged evals) still runs its CLIs.

AI-assisted (Claude).

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Paul Bakaus
2026-08-28 06:13:59 +05:00
committed by Abdul Wahab
co-authored by Claude
parent d9a155be8c
commit 24773eeedf
3 changed files with 31 additions and 4 deletions
+7 -1
View File
@@ -37,6 +37,7 @@
*/
import fs from 'node:fs';
import path from 'node:path';
import { fileURLToPath } from 'node:url';
import { decodePng, encodePng } from './lib/png.mjs';
import { crop, resize, fillRect, strokeRect, drawLabel, drawText } from './lib/raster.mjs';
import { dominantColors, horizontalBands, detailGrid } from './lib/image-metrics.mjs';
@@ -320,5 +321,10 @@ async function main() {
console.log(printSpec(spec));
}
const isMain = process.argv[1] && path.resolve(process.argv[1]) === path.resolve(new URL(import.meta.url).pathname);
// realpath on both sides: a skill mounted through a symlink (Cursor, a
// worktree, an eval stage) must still run as a CLI.
const isMain = (() => {
try { return !!process.argv[1] && fs.realpathSync(process.argv[1]) === fs.realpathSync(fileURLToPath(import.meta.url)); }
catch { return !!process.argv[1] && path.resolve(process.argv[1]) === path.resolve(new URL(import.meta.url).pathname); }
})();
if (isMain) main();