fix: pre-landing review fixes for the v2 port wave

Review army (checklist + 5 specialists) + coverage/plan audits on the
assembled branch. Genuine correctness/security/hygiene fixes:

- test-paid-shards: strictTestExitCode now receives expectedFiles on the
  real bun path, so a shard that runs fewer files than planned (harness
  crash, nothing loaded) with exit 0 is no longer recorded 'passed' — the
  invisible-non-execution class the runner exists to kill. Pinned by the
  new test/strict-output.test.ts (also covers the chunk-boundary classifier).
- test-paid-shards: EVALS_TIER env is validated (gate|periodic) like the
  --tier flag, so a typo can't self-skip every test and exit 0 green.
- package.json: test:periodic:sharded sets EVALS_ALL=1, restoring the
  full-tier semantics the pre-shard script had (CI already set it; local
  eval:bg:periodic silently under-measured without it).
- brain-sync.test: run() pins HOME to the temp home so gstack-artifacts-init
  stops writing/clobbering the operator's real ~/.gstack-artifacts-remote.txt
  every free-suite run; afterEach now also scrubs the current filename.
- egress-receipt: cap each receipt field at 512B so a serialized line always
  fits the 4KB tail-read window — a longer line would make the next append
  hash a truncated prior line and verifyLedger report a permanent false
  TAMPER. warnLedgerSize short-circuits before statSync once fired (append
  hot path).
- gstack-egress: import.meta.dir (Windows-safe) instead of new URL().pathname
  so grants doesn't silently report defaults on Windows; strip control chars
  from ledger-derived fields on render so a crafted receipt can't spoof the
  auditor's view.
- extension/background.js + CLAUDE.md: renumber the identity-pin migration
  refs v1.62 -> v1.63 (main claimed 1.62.0.0; this wave queue-advances).
- egress-receipt-wiring: pin lib/context-bill.ts unconditionally (both land
  together now); drop the dead RunShardsOptions.tier field.

All fix-affected test files green; gate failures triaged as external-env
(codex/gemini CLI drift) or pre-existing (hermetic-canary fails identically
on base). Deferred polish tracked in the PR body + decision store.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Garry Tan
2026-08-12 16:02:11 -07:00
co-authored by Claude Fable 5
parent ea7ba921ce
commit ccb91c3afb
9 changed files with 156 additions and 27 deletions
+17 -1
View File
@@ -121,8 +121,20 @@ function receiptError(message: string, cause?: unknown): Error & { code: string
return error;
}
// A serialized receipt line must stay under TAIL_READ_BYTES so the O(1)
// tail-read always captures the FULL previous line before hashing it into the
// chain. A caller-controlled field (sink/host/payloadClass/consent — e.g.
// context-bill builds payloadClass dynamically) long enough to push the line
// past the tail window would make the next append hash a truncated prior line,
// and verifyLedger would then report a permanent false TAMPER. Cap each field
// well under the window so the invariant holds by construction.
const MAX_FIELD_BYTES = 512;
function requireString(value: unknown, name: string): string {
if (typeof value !== 'string' || !value) throw receiptError(`Egress receipt requires a non-empty ${name}`);
if (Buffer.byteLength(value) > MAX_FIELD_BYTES) {
throw receiptError(`Egress receipt ${name} exceeds ${MAX_FIELD_BYTES} bytes (${Buffer.byteLength(value)})`);
}
return value;
}
@@ -199,13 +211,17 @@ export function resetLedgerSizeWarningForTests(): void {
}
function warnLedgerSizeOnce(ledger: string): void {
// Short-circuit BEFORE the stat: the warning fires at most once per process,
// so after it has fired there is no reason to stat the ledger on every
// subsequent writeReceipt (this runs on the append hot path).
if (warnedLedgerSize) return;
let size: number;
try {
size = fs.statSync(ledger).size;
} catch {
return; // no file yet — nothing to warn about
}
if (size <= LEDGER_WARN_BYTES || warnedLedgerSize) return;
if (size <= LEDGER_WARN_BYTES) return;
warnedLedgerSize = true;
process.stderr.write(ledgerSizeWarning(ledger, size) + '\n');
}