Files
gstack/test/helpers/fake-impeccable.ts
Garry TanandClaude Fable 5.1 b2e67d0097 fix(design-detect): an engine is a file named impeccable outside the project; DOM dumps scan without inline ignores
Second review cycle, security + checklist:

- IMPECCABLE_BIN=/bin/sh (or node) was READY, and `detect` with cwd=repoRoot
  made the interpreter run the repository's own `detect` file. Every engine
  candidate (env override, PATH entry, cache, sibling) is now judged by the
  realpath of the FILE and must be named impeccable[.exe]; PATH and cache
  candidates that resolve into the repository are skipped like the others.
  "Inside the project" means the repository, or cwd when cwd is a project
  directory: HOME and its ancestors are exempt, so a URL-mode review launched
  from HOME still finds the HOME-rooted installs.
- A base for --changed that starts with `-` was spliced into git argv
  (`--output=<file>` made git write a file and report no changes); an option-
  like or missing base is DETECT_REFUSED (not a ref name), exit 1, and the
  parser no longer defaults a missing value to main.
- DOM dumps are the audited page's bytes, so an in-file `impeccable-disable`
  comment there is page-controlled: batches under the designs root run with
  --no-inline-ignores, repository batches keep the project's own ignores.
- neutralizeSentinels covers the shapes it missed (bare sentinels such as
  DETECT_TOP total= and IMPECCABLE_DISABLED, the DETECT_EXIT_CODE= echo, the
  `[rule-id] impact=` group header) in one precompiled alternation instead of
  37 replaceAll passes per field; only kept findings are normalized, and the
  summary's total stays the engine's count.
- The minimal engine environment compares keys case-insensitively on Windows
  (process.env enumerates Path, SystemRoot there) and passes PATHEXT, COMSPEC,
  HOMEDRIVE, HOMEPATH, PROGRAMDATA.
- Bare 64s move into DETECT_LIMITS; the unused SentinelName type is gone; the
  header states the directory-target contract (the engine's own walk).

Tests: an interpreter as IMPECCABLE_BIN never runs the repo's detect file; a
PATH symlink into the repository is never READY; option-like and empty bases
are refused with no file written; the designs-root batch carries
--no-inline-ignores and the repo batch does not; the identity label is
deterministic per binary; the bare-sentinel and header shapes are neutralized;
the installed fake engine works without IMPECCABLE_FAKE_OUTPUT (the helper
copies the sample beside it); two tests clean up in finally.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-08 18:05:21 +00:00

21 lines
988 B
TypeScript

/**
* Install test/fixtures/fake-impeccable.ts as an executable `impeccable` in a
* fresh temp dir OUTSIDE any repo (the wrapper refuses an in-repo IMPECCABLE_BIN
* by design). Shared by the unit and E2E suites so the shim is set up one way.
*/
import * as fs from 'fs';
import * as os from 'os';
import * as path from 'path';
export const IMPECCABLE_FAKE_SRC = path.join(import.meta.dir, '..', 'fixtures', 'fake-impeccable.ts');
export const DETECT_SAMPLE = path.join(import.meta.dir, '..', 'fixtures', 'impeccable-detect-sample.json');
export function installFakeImpeccable(prefix = 'gstack-fake-impeccable-'): { dir: string; bin: string } {
const dir = fs.mkdtempSync(path.join(os.tmpdir(), prefix));
const bin = path.join(dir, 'impeccable');
fs.copyFileSync(IMPECCABLE_FAKE_SRC, bin);
fs.chmodSync(bin, 0o755);
fs.copyFileSync(DETECT_SAMPLE, path.join(dir, 'impeccable-detect-sample.json')); // the shim's documented default output, beside it
return { dir, bin };
}