Summary
PR #745 (enforcement-liveness-fix U2, merged + marked DONE via #751) ships variant A as compile-at-install — but tsc is unavailable to a real consumer, so the compiled rule barrel is silently broken. CI is green (our repo has tsc), the consumer's enforcement is dead → "green lies", the exact failure this umbrella exists to prevent.
Evidence (current staging, code-deduced — 3 greps = 0)
setup.d/40-configs.sh searches for tsc only under PKG_ROOT/.../node_modules/.bin + /app/node_modules — never the consumer's own PROJECT_ROOT/node_modules/.bin/tsc:
git show origin/staging:setup.d/40-configs.sh | grep -c 'PROJECT_ROOT/node_modules/.bin/tsc' → 0
typescript (the package that provides tsc) is not in the consumer dev-deps list:
git show origin/staging:setup.d/70-deps.sh | grep -c 'typescript@' → 0 (tsx is present; bare typescript is not)
- No pre-compiled
.mjs committed in the rule source dirs (so it must compile at install):
git ls-tree -r origin/staging | grep -cE 'eslint-rules/.*\.mjs$' → 0
Net: a consumer install runs 40-configs.sh Step A → tsc not found → it still generates eslint-rules-local/index.mjs importing sibling *.mjs that were never produced → ERR_MODULE_NOT_FOUND on barrel load → all custom-rule enforcement silently off. (Locally reproduced via f17 Arm without tsc: Cannot find module '.../no-direct-time-randomness.mjs'.)
Additional: #745's S5 "Node 20+22 proof" runs f17 which uses the tsx Linter-API path (always green on every Node) — it does not exercise the raw npx eslint / pre-commit channel that is the actual consumer exposure (per S1 finding #744).
Fix (in progress — Option A, operator-chosen)
Ship pre-compiled .mjs + .d.ts at framework build time (commit them next to the .ts sources); 40-configs.sh copies them — consumer needs no tsc. Add a drift-gate (recompile + diff) and a premise-aware raw-channel arm to f17 (raw node import, no tsx) under the Node 20+22 matrix.
Scope note
This reopens the enforcement-liveness-fix umbrella: #745's done.md (#751) is premature — the fix does not hold for consumers. Follow-up PR will correct closure with consumer-valid evidence.
Summary
PR #745 (enforcement-liveness-fix U2, merged + marked DONE via #751) ships variant A as compile-at-install — but
tscis unavailable to a real consumer, so the compiled rule barrel is silently broken. CI is green (our repo hastsc), the consumer's enforcement is dead → "green lies", the exact failure this umbrella exists to prevent.Evidence (current staging, code-deduced — 3 greps = 0)
setup.d/40-configs.shsearches fortsconly underPKG_ROOT/.../node_modules/.bin+/app/node_modules— never the consumer's ownPROJECT_ROOT/node_modules/.bin/tsc:git show origin/staging:setup.d/40-configs.sh | grep -c 'PROJECT_ROOT/node_modules/.bin/tsc'→ 0typescript(the package that providestsc) is not in the consumer dev-deps list:git show origin/staging:setup.d/70-deps.sh | grep -c 'typescript@'→ 0 (tsxis present; baretypescriptis not).mjscommitted in the rule source dirs (so it must compile at install):git ls-tree -r origin/staging | grep -cE 'eslint-rules/.*\.mjs$'→ 0Net: a consumer install runs
40-configs.shStep A →tscnot found → it still generateseslint-rules-local/index.mjsimporting sibling*.mjsthat were never produced →ERR_MODULE_NOT_FOUNDon barrel load → all custom-rule enforcement silently off. (Locally reproduced via f17 Arm without tsc:Cannot find module '.../no-direct-time-randomness.mjs'.)Additional: #745's S5 "Node 20+22 proof" runs
f17which uses the tsx Linter-API path (always green on every Node) — it does not exercise the rawnpx eslint/ pre-commit channel that is the actual consumer exposure (per S1 finding #744).Fix (in progress — Option A, operator-chosen)
Ship pre-compiled
.mjs+.d.tsat framework build time (commit them next to the.tssources);40-configs.shcopies them — consumer needs notsc. Add a drift-gate (recompile + diff) and a premise-aware raw-channel arm tof17(rawnodeimport, no tsx) under the Node 20+22 matrix.Scope note
This reopens the enforcement-liveness-fix umbrella: #745's
done.md(#751) is premature — the fix does not hold for consumers. Follow-up PR will correct closure with consumer-valid evidence.