# WP-210 — capture tests in one package

> Engineering log · [Phase 19 — Codebase audit remediation](https://borda.github.io/lucid-YOLO/engineering/phase-19-codebase-audit/)
>
> 🔗 Depends on [WP-208](https://borda.github.io/lucid-YOLO/work_packages/wp-208/) · Needed by [WP-211](https://borda.github.io/lucid-YOLO/work_packages/wp-211/)
>
> ⬅️ [WP-209](https://borda.github.io/lucid-YOLO/work_packages/wp-209/) · [Roadmap](https://borda.github.io/lucid-YOLO/ROADMAP/) · [WP-211](https://borda.github.io/lucid-YOLO/work_packages/wp-211/) ➡️


<a id="wp-210"></a>

## WP-210 — capture tests in one package with shared scaffolds and private-state access

**Finding.** Audit T6 found nine CUDA replay test files mixed into `tests/ptl/`, repeated CPU routing scaffolds, scattered reads of private replay-holder state and inline recorder patches beside an inherited recording spy.

**Move.** The nine files retain their names under `tests/ptl/capture/`, without an `__init__.py`. The parent `tests/ptl/conftest.py` stays unchanged and its fixtures remain inherited. Live references follow the move; historical work-package prose retains its recorded paths.

**Shared scaffolds and helpers.** `tests/fixtures/capture_access.py` owns the identical CUDA-flagged tensor implementation, its image construction, the precision-query refusal, the ordered CUDA stream fence and the private-state accessors, imported by bare module name like the neighbouring fixture helpers. Five suites apply the inherited `deterministic_kernels` fixture through module-level `pytestmark`; the segmentation-network suite applies its distinct `deterministic_kernels_pinning_cudnn_benchmark` fixture the same way. No capture conftest or re-wrapped autouse fixture remains. Local image helper entry points retain their original doctests, delegating construction to the shared implementation so no collected case disappears. Constructors, byte comparisons and nested state comparisons with differing bodies stay local. Accessors centralize reads of the loss objective, network holder, pose child holders and head topology; deliberate private-state writes remain visible in the setup that needs them. Every behavioural byte and gradient equality assertion is retained.

**Recorder patches.** Four absence-only patches in `test_loss_capture.py` become call-count observations through the inherited `graph_recordings` fixture. Three distinct substitutions stay local: `_host_recorder` replaces CUDA with CPU autograd, the recording-failure test injects an exception, and the GC-policy test samples collection state inside the recording call. A wrapping call spy alone cannot provide those substitutions or the GC observation.

**Baseline CPU durations.** Before edits, the nine files passed 429 tests with 206 skipped in 25.28 s. The requested `--durations=25` output's final 40 lines contain the skip summary, so a second unchanged run retained the complete timing output: 429 passed, 206 skipped, 26 warnings in 24.81 s. These are CPU timings with CUDA cases skipped, not accelerator performance measurements. Suite names below refer to the original `tests/ptl/test_<suite>.py` paths.

| Seconds | Phase | Suite | Test |
| -- | -- | -- | -- |
| 1.48 | call | `network_capture_guards` | `TestPrecisionPolicy::test_new_api_policy_reads_and_distinguishes_values` |
| 1.05 | call | `pose_network_capture` | `tests.ptl.test_pose_network_capture._assert_same_gradients_and_state` |
| 0.99 | call | `segment_head_capture` | `test_old_checkpoint_loads_with_native_default` |
| 0.57 | call | `segment_head_capture` | `test_inactive_request_matches_native_train_forward_and_gradients[True]` |
| 0.43 | call | `segment_head_capture` | `test_inactive_request_matches_native_train_forward_and_gradients[False]` |
| 0.40 | call | `network_capture_guards` | `TestStageModuleBreach::test_names_cause[compiled]` |
| 0.38 | call | `network_capture` | `tests.ptl.test_network_capture._fit_and_discard` |
| 0.25 | call | `segment_head_capture` | `test_cpu_fit_wires_lifecycle_and_warns_once_without_replay` |
| 0.19 | call | `segment_network_capture` | `test_segment_host_routing_and_native_fallback[inactive]` |
| 0.17 | call | `segment_network_capture` | `test_frozen_segment_features_retire_before_cuda_submission` |
| 0.17 | call | `loss_capture` | `test_images_without_targets_match_native[cpu-first-image]` |
| 0.17 | call | `loss_capture` | `test_images_without_targets_match_native[cpu-every-image]` |
| 0.17 | call | `pose_network_capture` | `test_pose_routing_falls_back_when_features_are_absent` |
| 0.17 | call | `segment_network_capture` | `test_segment_head_hook_retires_feature_replay_and_stays_observable` |
| 0.17 | call | `segment_network_capture` | `test_segmentation_cli_keeps_feature_and_prediction_options_independent[True]` |
| 0.16 | call | `loss_capture` | `test_images_without_targets_match_native[cpu-second-image]` |
| 0.15 | call | `segment_network_capture` | `test_segment_host_routing_and_native_fallback[record]` |
| 0.15 | call | `oriented_network_capture` | `test_oriented_routing_leaves_cpu_images_native` |
| 0.14 | call | `oriented_network_capture` | `test_oriented_routing_retires_then_runs_native[objective-override]` |
| 0.14 | call | `pose_network_capture` | `test_pose_head_certificate_survives_copy_and_rejects_dispatch_overrides[forward-branch]` |
| 0.13 | call | `network_capture` | `test_cli_accepts_network_capture_option[False-True]` |
| 0.13 | call | `pose_network_capture` | `test_altered_pose_head_dispatch_fails_certificate[child-swap]` |
| 0.13 | call | `pose_network_capture` | `test_pose_routing_dispatches_shared_features_to_native_head` |
| 0.12 | call | `oriented_network_capture` | `test_oriented_default_and_cpu_fallback[validate]` |
| 0.11 | setup | `segment_head_capture_guards` | `TestRunnerCertificate::test_nontraining_calls_keep_native_without_retiring[no_grad]` |

**Verification.**

- **Collection.** Before: 4014 tests. After: 4022, the eight added being the doctests of the new `tests/fixtures/capture_access.py` helpers; no test is removed or renamed.
- **CPU.** `make gate` green on this commit's tree.
- **Assertions.** An AST comparison against the parent commit retains all 572 original assertions, every test function name, parametrization, capability marker and class decorator; four recorder call-count assertions are added.
- **CUDA.** `make gate-gpu` green on an A100 (py3.11, torch 2.9.1+cu129) at the stack's tip `72b5505`, the tree [WP-218](https://borda.github.io/lucid-YOLO/work_packages/wp-218/) left: 359 passed and 2 skipped (a `grad_dtype` case that needs a newer torch, and a replay test that needs two CUDA devices), every notebook in full, `demo_obb` on DOTA-v1.0 among them, and 55/55 accelerator goldens. `tests/ptl -m "gpu or data"` also passed on Colab's py3.13 / torch 2.11 (242 passed). The same selection on this package's own commit, `a1c72f4`, passed in that session too (242 passed). The moved suites run in both.

