Add a benchmark lane (`vitest.bench.config.ts`, `pnpm run test:bench`,
gate mode `ci-bench`) and a required `node 24 / benchmarks` CI job that
runs it alone. Benchmarks synthesize their input in-process from fixed
parameters and fail on documented budgets:
- `open-generation.bench.ts`: a 200-turn released-v0 log with 500 text
and 125 reasoning deltas per reply (127,400 events, ~2.8 MB) encoded
through the frozen v0 codec; the migrating first `open()` must finish
within 2,000 ms in a child process capped at 128 MB of old space, and a
fresh process must open the published current generation within 500 ms.
- `conversation-fold.bench.client.ts`: 200 replies whose compact streams
hold 2,000 text + 500 reasoning deltas each, folded through every Chat
Definition by the real assembler; the fold must finish within 150 ms
and stay within 3x the fold of the same window with 100 deltas per
reply.
On this commit both gates fail: the migration exhausts the 128 MB heap
(4.8 s and 696 MB peak RSS without the cap; the pre-stack decode of the
same bytes took 34 ms and 168 MB) and the fold scales 11x with the delta
count. The stacked fixes bring both paths to O(records).
A replay must not depend on the runner's network policy, the same reason it
pins its home and sessions root. The harness now honors the proxy environment,
so a runner exporting one sent the web-fetch scenario's fixture request to a
proxy that could not resolve the fixture host and recorded that proxy's error
page. Clear the proxy names in both test-support spawners, from the one list
dsh-http-proxy owns.
The Windows coverage lane grants DSH_COVERAGE_TEST_TIMEOUT_MS=90000, but two
paths declined it.
scripts/install-lefthook.spec.ts took a describe-level 30_000, restated as a
per-case constant on five cases. Every case drives spawned Git and Node
subprocesses; the slowest costs 7.5 s on an idle host, so the ceiling carried
roughly fourfold headroom and fired on branches that did not touch the file.
The suite takes 90_000 and the redundant constant is removed.
coverageTestTimeoutArgs raised --testTimeout and --expect.poll.timeout but left
--hookTimeout at Vitest's separate 10 s default, which removeFixtureSafely's
documented 10-second Windows retry window meets exactly. Raising only the test
budget would move a contended suite's failure into its teardown.
- The base-mounted projection cache's write-behind forces session-log
flushes at cache-chosen times, splitting packed chunk rows and collapsing
the persistence window the keyless acp transcripts pin. ACP exposes no
session-listing surface, so the automation profile disables the base row,
restoring the pre-base behavior the fixtures were recorded against.
- The windows coverage lane runs suites that read built lib/ output (the
webworker-packer image tests) and raced the build gate's tsdown writes
against a partial tree; every coverage gate now waits for the build gate.
Add verify-application-entrypoints to the top-level gate graph. It inventories executable sources and package bins across apps, packages, and examples; rejects unclassified launchers including root-level js/mjs/cjs/ts files; and permits only the dsh CLI plus the explicitly private Python runtime carrier exception.
Update repository, architecture, CLI, and naming records to state the same rule: Node consumers select a dsh profile instead of invoking application-package bins, and no compatibility aliases remain. Fixtures prove both allowed classifications and representative escape attempts, making the architectural rule mechanically enforceable.