* fix(tests): pass Windows base system env to isolated pytest child
The live-test policy regression tests spawn a pytest child with a minimal,
from-scratch env. On Windows that env lacks SystemRoot/TEMP/USERPROFILE, so
the child dies during import asyncio (WinError 10106, winsock provider init)
and tempfile cannot resolve a directory, making the tests fail for
environment reasons instead of testing the opt-in policy.
Extract the env assembly into _child_pytest_env() and pass through a small
allowlist of Windows base system variables (SystemRoot, windir, COMSPEC,
PATHEXT, TEMP, TMP, USERPROFILE) when present. These carry no credentials,
so the isolation contract (no API keys, no real .env) is unchanged, and
POSIX behavior is byte-identical. A new unit test pins the contract: only
the allowlisted base vars may pass through, and SystemRoot must be present
on Windows.
* test(live-policy): seed Windows base env vars in the bootability contract
The contract test asserted TEMP/TMP pass-through without seeding them, so
on Windows hosts that do not export those optional variables (CPython then
falls back to %USERPROFILE%\AppData\Local\Temp) it failed on host
configuration rather than on the helper's contract.
Seed the representative base variables with monkeypatch and assert the
forwarded set exactly, so the isolation contract is deterministic on every
host. Red/green evidence: with TEMP/TMP stripped from the environment the
old assertion fails (extra = {COMSPEC, PATHEXT, SystemRoot, USERPROFILE,
windir}) while the seeded assertion passes.
Addresses the P3 finding in the review of PR #6439.
* ci(tests): cover Windows live-test policy
---------
Co-authored-by: Willem Jiang <willem.jiang@gmail.com>
* feat(ci): split backend unit tests into parallel CI shards
Split the single offline backend `make test` job into four GitHub Actions
matrix shards (SPLITS=4, GROUP=1..4) via pytest-split, so the ~12k-test suite
runs in parallel instead of in one 15-minute job. Each shard runs on its own
runner with its own Postgres/Redis services; fail-fast: false lets a failing
shard report its owned tests without cancelling its peers.
`make test` stays the canonical full-suite entry point; CI now calls the new
`make test-shard SPLITS=4 GROUP=N`. tests/blocking_io remains owned solely by
the dedicated blocking-I/O workflow (excluded via --ignore), extending #5105.
Fixes#5088
* test(ci): make backend test shards duration-aware and pin the contract
Make `make test-shard` an explicit least_duration split that READS
backend/.test_durations (read-only for shards, so concurrent CI jobs never
race writes on it), and add `make test-shard-durations` to regenerate that
file from the full offline suite. Update the CI unit-test workflow contract to
call `make test-shard SPLITS=4 GROUP=<n>` and assert the shard command carries
--splits 4, --group 2, -m "not live", --ignore=tests/blocking_io and
--splitting-algorithm least_duration. Verified on the real 13,140-test normal
suite that the four shards are pairwise disjoint and their union equals the
unsplit suite.
Refs #5088
* test(ci): fail fast when the duration baseline is missing
`make test-shard` now requires backend/.test_durations and exits with a clear
error instead of letting pytest-split silently degrade to an even (count-based)
split. Harden the CI contract test to pin `--durations-path=.test_durations` and
to assert the repo ships the committed duration baseline.
Refs #5088
* docs: trim backend/AGENTS.md within guidance budget
* test(ci): add backend test duration baseline
Add the duration baseline generated by a full offline backend run on a
GitHub-hosted ubuntu-latest runner (the same runner type the shards use), so
`make test-shard` balances the four matrix shards by real wall-clock cost.
Refs #5088
* test(ci): make the duration writer honor DURATIONS_FILE
`test-shard-durations` now writes `--durations-path=$(DURATIONS_FILE)` instead of a
hard-coded .test_durations, so the reader and writer stay consistent when the
path is overridden.
Refs #5088
* test(ci): address sharding review feedback
* test: isolate subagent execution capacity state
---------
Co-authored-by: Willem Jiang <willem.jiang@gmail.com>
* fix(test): exclude blocking I/O suite from make test
Keep make test-blocking-io as the dedicated suite owner.
Add regression coverage for the Makefile contract.
Refs #5088
* test: pin blocking I/O workflow ownership
Document both targets required for full offline validation.
Keep the dedicated workflow and Makefile target under contract coverage.
Refs #5088
* docs(test): align blocking-I/O test guidance