- Split DSH_COVERAGE_MAX_WORKERS between the two parallel gates
(instrumented gets ~2/3, exempt gets ~1/3, both at least 1) so the
lane never exceeds the budget the failover pool's 8 x 6-instance
bound assumes; a budget of 1 pairs with DSH_GATE_CONCURRENCY=1 on
the serial reference lanes, which already prevents gate overlap.
- Fail loud on a set-but-not-'1' DSH_COVERAGE_EXEMPT_HEAVY value in
vitest.config.ts instead of silently ignoring it.
- Add coverage-exempt.spec.ts: each roster entry's filter and exclude
must select the same non-empty spec set and entries must not
overlap, so a renamed suite breaks the gate instead of silently
returning to the instrumented run with a stale roster.
Agent Note (both languages, pairing recorded): what is exempted, the
per-entry reconciliation showing no threshold input changes, the
membership contract, and why the per-file 100% thresholds police the
roster automatically.
The coverage lane's wall clock was pinned by a few compiler- and
subprocess-bound suites whose v8 instrumentation tax is a multiple of
their runtime while contributing nothing the per-file thresholds need:
typert generator fixtures (whole-workspace compiler analysis; its src is
threshold-excluded) and three scripts/ child-process fixture suites
(scripts/ sources are never coverage-measured; in-process imports are
covered by their owning package tests).
Split ci-coverage into two parallel gates: the instrumented run sets
DSH_COVERAGE_EXEMPT_HEAVY=1 and vitest.config.ts drops the exempt suites
from both projects (CLI --exclude cannot reach per-project include
resolution); a second uninstrumented gate runs exactly those suites, so
the aggregate still executes every test. Membership contract and the
filter/exclude pairs live in scripts/coverage-exempt.ts.
Local 6-worker A/B: instrumented gate 900s -> 260s wall; exempt gate
262s wall runs beside it, so the lane converges near the slower of the
two (~4.4min vs ~7min single-gate). DSH_GATE_CONCURRENCY now has two
schedulable gates in this lane.
The row moves from web.cordis.yml to base.cordis.yml, so the TUI reports
too (its exit paths already drain: disposeRootAndExit on normal exit, root
dispose before the /resume execve). The TUI launcher applies the same
resolveTelemetryPatch opt-out, judged against the tree actually booting via
configHasTelemetryRow so a --config-replace tree without the row is not
failed by a switch with nothing to disable. The TUI keyless smoke disables
telemetry in its child env; README (en/zh) and the Agent Note pair updated
to the every-surface stance.
The pairing gate requires both sides of a bilingual pair to link the same
target; point the zh side's cross-references at the English canonical files
and re-record both i18n pairings.
- resolveTelemetryPatch: extracted pure switch resolution (unit-tested);
fails loud when DSH_TELEMETRY_DISABLED is set but the row is absent, and
documents that ANY non-empty value (including '0'/'false') disables.
- runHeadless: SIGINT/SIGTERM now dispose the tree before exit so the
telemetry tail and shutdown marker drain (Node's default signal exit
skips disposal).
- web.cordis.yml: explicit maxQueueSize beside maxExportBatchSize (the
single-batch drain invariant no longer leans on an SDK default), comment
covers exportTimeoutMillis's role and links the Agent Note.
- apps/web scaffold: disable telemetry-otel — fixture sessions must never
leave the process.
- apps/cli README (en/zh + pairing): document the default endpoint, both
env seams, and the no-redaction disclosure.
Pins the deployment rulings: default-on with the production endpoint,
DSH_TELEMETRY_OTLP_URL / DSH_TELEMETRY_DISABLED env seams, 10s cadence,
the ~1s exit-drain parameter set, CI isolation, and the explicit
follow-ups (redaction, identity resource, TUI adoption, metrics).