Full lane wall-time: 6:35 → 2:25 (2.7× speedup). No behavioral
changes; same 1933 passed, 2 skipped.
Three wins, biggest first:
1. pytest-xdist as a project dependency.
``pyproject.toml`` gains ``pytest-xdist>=3.6``. ``cmd_test``
injects ``-n auto`` for ``--suite full`` when xdist is importable;
curated suites stay single-process because worker-spawn overhead
is net-negative on the smaller suites. Operator can override
via passing ``-n <N>`` or ``--dist`` explicitly.
Verified: ``core test --suite full -q`` prints ``bringing up
nodes...`` and parallelises across the runner's CPUs.
2. Module-scoped fixture for run_demo() in test_learning_loop_demo.py.
The 7 demo tests each previously called ``run_demo(emit_json=True)``
from scratch — and ``run_demo`` itself runs the cognition lane
twice via the replay-equivalence gate. ~15s/file → ~3s/file.
Module scope (not session) is intentional: pytest-xdist
distributes by test, so a session-scoped fixture would still be
re-evaluated per worker that picks up a test from this file.
Module scope keeps the cost paid once per worker per file, which
is the actual lower bound.
3. Module-scoped fixture for the teaching-loop bench.
``test_teaching_loop_bench.py``'s 5 tests previously each ran
``run_teaching_loop_determinism(runs=2 or 3)`` — 12 pipeline
invocations across the file. One ``runs=3`` invocation shared
across all 5 tests covers every assertion: ~25s → ~7s.
For local iteration, ``core test --suite cognition -q`` etc. remain
fast (no xdist overhead). The full-lane speedup is most visible
under CI / pre-merge runs.
`core bench --suite teaching-loop [--runs N]` runs the full reviewed-
corpus extension pipeline (propose → real replay-equivalence gate →
operator accept) N times against an identical input and asserts
byte-identical artifacts every run:
- proposal_id (SHA-256 of canonical-JSON payload)
- replay_baseline (cognition lane metrics on active corpus)
- replay_candidate (cognition lane metrics on transient corpus)
- regressed_metrics (sorted tuple)
- chain_id_written
Also reports per-iteration latency (mean / p50 / p95) and total wall.
100-run result against today's main:
unique(proposal_id)=1 unique(baseline)=1 unique(candidate)=1
unique(chain_id)=1 active_corpus_byte_eq=True
mean=1.849s p50=1.838s p95=1.851s
The full learning loop is replayable bit-identically across N
independent invocations. Pairs naturally with ADR-0045's 100% exact-
NIAH recall numbers — same epistemic class of guarantee, applied to
the *learning loop* itself rather than only to retrieval. No LLM
provider can publish equivalent numbers on a learning path.
- benchmarks/teaching_loop.py — `run_teaching_loop_determinism(runs)`
returns a typed `TeachingLoopBenchReport` with uniqueness counts,
determinism flag, byte-identical-active-corpus flag, and latency
distribution (mean / p50 / p95 / total). Pure-stdlib percentile —
no numpy dep on this path.
- benchmarks/run_benchmarks.py — `bench_teaching_loop_determinism`
shim + `_SUITES["teaching-loop"]` registration + runs= passthrough.
- core/cli.py — `--suite teaching-loop` choice added to bench parser.
- tests/test_teaching_loop_bench.py — 5 tests pin determinism at
small N, proposal_id SHA-256 shape, canonical chain_id layout,
latency stats well-formedness, JSON serialisation.
Trust boundary: every write is confined to a tempdir created inside
the bench loop; the active corpus is read once at start, once at end,
and any byte difference would fail the bench.