]> Piment Noir Git Repositories - freqai-strategies.git/commitdiff
docs: reconcile strategy guides and invariant ownership
authorJérôme Benoit <jerome.benoit@piment-noir.org>
Wed, 23 Sep 2026 18:02:25 +0000 (20:02 +0200)
committerJérôme Benoit <jerome.benoit@piment-noir.org>
Wed, 23 Sep 2026 18:02:25 +0000 (20:02 +0200)
README.md
ReforceXY/reward_space_analysis/README.md
ReforceXY/reward_space_analysis/tests/README.md

index 77fb5da4b53a5196411aa1c478d6d4989d897c51..e301b963b6956f1d3d09e98f00e7babca00e1d91 100644 (file)
--- a/README.md
+++ b/README.md
@@ -5,11 +5,17 @@
 - [QuickAdapter](#quickadapter)
   - [Quick start](#quick-start)
   - [Configuration tunables](#configuration-tunables)
+  - [Continual learning](#continual-learning)
+  - [Live inference](#live-inference)
   - [Backtest evaluation protocol](#backtest-evaluation-protocol)
 - [ReforceXY](#reforcexy)
   - [Quick start](#quick-start-1)
   - [Supported models](#supported-models)
   - [Configuration tunables](#configuration-tunables-1)
+  - [Continual learning](#continual-learning-1)
+  - [Live inference](#live-inference-1)
+  - [Training and HPO](#training-and-hpo)
+  - [Reward and portfolio accounting](#reward-and-portfolio-accounting)
 - [Development](#development)
 - [Common workflows](#common-workflows)
 - [Note](#note)
@@ -161,12 +167,6 @@ below.
 | freqai.optuna_hyperopt.reset_label_study_on_schema_mismatch    | true                     | bool                                                                                                                                                                                                         | Reset a persisted `label` study when its selection schema is missing, invalid, or incompatible. `true` performs a destructive reset, deleting the study before recreating it; `false` preserves its trials and stored metadata, permits caller-managed reuse in memory, and does not persist selected params until the schema is reconciled. Both fail closed: an inspection error, or (under `true`) a deletion error, aborts study creation. Has no effect when `continuous=true` or outside live/dry-run modes, where studies are always reset.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
 | freqai.optuna_hyperopt.vary_model_seed_by_trial                | true                     | bool                                                                                                                                                                                                         | Add `trial.number` to each regressor's configured model seed (or its default seed of `1`) during HPO. `true` samples model randomness across trials; `false` evaluates every trial and the final fit with the same model seed. This does not change `freqai.optuna_hyperopt.seed`.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
 
-In backtests, continual training uses only a saved model whose training cutoff
-precedes the current window's end and its last available candle boundary. A
-later model left under the same identifier is not reused when a backtest is
-extended into the past. Live and dry-run restarts still restore compatible
-deployed models.
-
 The `label_weighting`, `label_smoothing`, `label_pipeline` and
 `label_prediction` sections accept either the flat paths listed above or a
 per-label format using `default` and `columns.<glob>`. Do not mix both formats in
@@ -175,6 +175,16 @@ ignored with a warning. Matching column patterns are applied from least to most
 specific; equally specific patterns follow declaration order, so the later one
 wins.
 
+### Continual learning
+
+In backtests, continual training uses only a saved model whose training cutoff
+precedes the current window's end and its last available candle boundary. A
+later model left under the same identifier is not reused when a backtest is
+extended into the past. Live and dry-run restarts still restore compatible
+deployed models.
+
+### Live inference
+
 In live and dry-run modes, each pair requires
 `freqai.fit_live_predictions_candles` real model predictions before adaptive
 thresholds become available. The Nth observation first affects the next
index dc96fedc2c872f0ff8abf289f9dd9ec9da81afb4..c5381a9efc3cb49a89d31027e0d3d5efe86eb254 100644 (file)
@@ -57,7 +57,7 @@ Full test documentation: [tests/README.md](./tests/README.md).
   - [Transform Functions](#transform-functions)
   - [Skipping Feature Analysis](#skipping-feature-analysis)
   - [Reproducibility](#reproducibility)
-  - [Overrides vs --params](#overrides-vs--params)
+  - [Overrides vs --params](#overrides-vs---params)
 - [Examples](#examples)
 - [Outputs](#outputs)
   - [Main Report (`statistical_analysis.md`)](#main-report-statistical_analysismd)
@@ -257,15 +257,16 @@ The exit factor is computed as:
 **Formula:**
 
 Let `pnl_target = profit_aim · risk_reward_ratio` and
-`pnl_ratio = pnl / pnl_target`. On the loss branch,
-`loss_threshold = pnl_target / risk_reward_ratio` and
-`loss_ratio = |pnl| / loss_threshold = |pnl_ratio| · risk_reward_ratio`.
+`pnl_ratio = pnl / pnl_target` when `pnl_target > 0`. For losses, let
+`effective_rr = risk_reward_ratio` if positive, or `2.0` otherwise (the runtime
+fallback). Then `loss_threshold = pnl_target / effective_rr` and
+`loss_ratio = |pnl| / loss_threshold = |pnl_ratio| · effective_rr`.
 
 - If `pnl_target ≤ 0`: `pnl_target_coefficient = 1.0`
 - If `pnl_ratio > 1.0`:
   `pnl_target_coefficient = 1.0 + win_reward_factor · tanh(pnl_amplification_sensitivity · (pnl_ratio - 1.0))`
 - If `pnl < -loss_threshold`:
-  `pnl_target_coefficient = 1.0 + (win_reward_factor · risk_reward_ratio) · tanh(pnl_amplification_sensitivity · (loss_ratio - 1.0))`
+  `pnl_target_coefficient = 1.0 + (win_reward_factor · effective_rr) · tanh(pnl_amplification_sensitivity · (loss_ratio - 1.0))`
 - Else: `pnl_target_coefficient = 1.0`
 
 ##### Efficiency
@@ -569,8 +570,8 @@ Within the same analyzer revision, identical `params_hash` values mean the resol
 | `*_ks_statistic`  | KS two-sample statistic               | [0,1]; higher ⇒ divergence                                                    |
 | `*_ks_pvalue`     | KS test p-value                       | API-only with `independent_observations=True`; omitted by the descriptive CLI |
 
-Implementation: 50-bin histograms with ε=1e-10; constants have zero divergence.
-Inferential KS p-values are available only under the programmatic independence contract.
+Implementation: up to 50 evenly spaced histogram edges (normally 49 bins) with
+ε=1e-10; constants have zero divergence.
 
 ---
 
@@ -609,8 +610,8 @@ uv run python reward_space_analysis.py \
   --out_dir real_vs_synthetic
 ```
 
-Shift metrics: lower divergence preferred (except p-value: higher ⇒ cannot
-reject equality).
+For the CLI's descriptive shift metrics, lower values indicate closer
+synthetic and real distributions.
 
 ### Batch Analysis
 
index 82733cf846618d331ebdf399ca8da634ee8f83bb..457742f45dc31cfba5e09dc35d0cc91a7aa7914f 100644 (file)
@@ -35,8 +35,9 @@ Markers are declared in `pyproject.toml` and enforced with `--strict-markers`.
 
 ## Test Framework
 
-The test suite uses **pytest as the runner** with **unittest.TestCase as the
-base class** (via `RewardSpaceTestBase`).
+The suite runs under **pytest**. Most class-based tests inherit from
+`RewardSpaceTestBase` (a `unittest.TestCase` subclass); others are standalone
+pytest functions.
 
 ### Hybrid Approach Rationale
 
@@ -51,7 +52,7 @@ This design provides:
 
 ### Base Class
 
-All test classes inherit from `RewardSpaceTestBase` (defined in `test_base.py`):
+Class-based tests normally inherit from `RewardSpaceTestBase` (in `test_base.py`):
 
 ```python
 from ..test_base import RewardSpaceTestBase
@@ -172,68 +173,69 @@ uv run --locked --extra dev pytest -m "statistics and slow" -q
 
 Columns:
 
-- ID: Stable identifier (`<category>-<shortname>-NNN`).
+- ID: Stable identifier (`<category>-<shortname>-NNN`; optional letter for
+  split invariants).
 - Category: Taxonomy directory marker.
 - Description: Concise invariant statement.
-- Owning File: Path:line of primary declaration (prefer comment line
-  `# Owns invariant:` when present; otherwise docstring line).
-- Notes: Clarifications (sub-modes, extensions, non-owning references elsewhere,
-  line clusters for multi-path coverage).
-
-| ID                                            | Category    | Description                                                                         | Owning File                               | Notes                                                                                                                                                                          |
-| --------------------------------------------- | ----------- | ----------------------------------------------------------------------------------- | ----------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
-| report-additives-deterministic-092            | components  | Additives deterministic report section                                              | components/test_additives.py:4            | Integration/PBRS may reference outcome non-owning                                                                                                                              |
-| robustness-decomposition-integrity-101        | robustness  | Single active core component equals total reward under mutually exclusive scenarios | robustness/test_robustness.py:43          | Scenarios: idle, hold, exit, invalid; non-owning refs integration/test_reward_calculation.py                                                                                   |
-| robustness-exit-mode-fallback-102             | robustness  | Unknown exit_attenuation_mode falls back to linear w/ warning                       | robustness/test_robustness.py:654         | Comment line (function at :655)                                                                                                                                                |
-| robustness-negative-grace-clamp-103           | robustness  | Negative exit_plateau_grace clamps to 0.0 w/ warning                                | robustness/test_robustness.py:696         |                                                                                                                                                                                |
-| robustness-invalid-power-tau-104              | robustness  | Invalid power tau falls back alpha=1.0 w/ warning                                   | robustness/test_robustness.py:747         |                                                                                                                                                                                |
-| robustness-near-zero-half-life-105            | robustness  | Near-zero half life yields no attenuation (factor≈base)                             | robustness/test_robustness.py:792         |                                                                                                                                                                                |
-| pbrs-canonical-exit-semantic-106              | pbrs        | Canonical exit uses shaping=-prev_potential and next_potential=0.0                  | pbrs/test_pbrs.py:374                     | Uses stored potential across steps; no drift correction applied                                                                                                                |
-| statistics-partial-deps-skip-107              | statistics  | skip_partial_dependence => empty PD structures                                      | statistics/test_statistics.py:42          | Docstring line                                                                                                                                                                 |
-| helpers-transitions-preserve-multiplicity-108 | helpers     | Repeated transitions retain their empirical multiplicity                            | helpers/test_utilities.py:26              |                                                                                                                                                                                |
-| helpers-missing-cols-fill-109                 | helpers     | Missing required columns filled with NaN + single warning                           | helpers/test_utilities.py:51              | Docstring line                                                                                                                                                                 |
-| statistics-binned-stats-min-edges-110         | statistics  | <2 bin edges raises ValueError                                                      | statistics/test_statistics.py:60          | Docstring line                                                                                                                                                                 |
-| statistics-constant-cols-exclusion-111        | statistics  | Constant columns excluded & listed                                                  | statistics/test_statistics.py:71          | Docstring line                                                                                                                                                                 |
-| statistics-degenerate-distribution-shift-112  | statistics  | Constants: zero distances; KS p only with declared independent observations         | statistics/test_statistics.py:87          | Docstring line                                                                                                                                                                 |
-| statistics-constant-dist-exact-ci-113a        | statistics  | Both modes retain exact constant CI bounds                                          | statistics/test_statistics.py:606         |                                                                                                                                                                                |
-| statistics-percentile-outside-mean-113b       | statistics  | Percentile bounds need not contain the sample mean                                  | statistics/test_statistics.py:620         |                                                                                                                                                                                |
-| statistics-constant-diagnostics-115           | statistics  | Constants have N/A higher moments, normality tests and Q-Q fits in both modes       | statistics/test_statistics.py:194         |                                                                                                                                                                                |
-| pbrs-canonical-near-zero-report-116           | pbrs        | Canonical trajectories with valid evidence are classified as verified               | pbrs/test_pbrs.py:1509                    | Requires local identity, continuity, discounted terminal boundary, and zero observed additives; the non-owning boundary test also covers a complete singleton terminal episode |
-| robustness-exit-pnl-only-117                  | robustness  | Only exit actions have non-zero PnL                                                 | robustness/test_robustness.py:127         | Comment line                                                                                                                                                                   |
-| pbrs-absence-shift-placeholder-118            | pbrs        | Placeholder shift line present when shaping shift is absent                         | pbrs/test_pbrs.py:1877                    |                                                                                                                                                                                |
-| components-pbrs-breakdown-fields-119          | components  | PBRS breakdown fields finite and mathematically aligned                             | components/test_reward_components.py:830  | Tests base_reward, pbrs_delta and invariance_correction alignment                                                                                                              |
-| integration-pbrs-metrics-section-120          | integration | PBRS Metrics section present in report with tracing metrics                         | integration/test_report_formatting.py:137 |                                                                                                                                                                                |
-| cli-pbrs-csv-columns-121                      | cli         | PBRS columns in reward_samples.csv when shaping enabled                             | cli/test_cli_params_and_csv.py:347        | Verifies finite reward_base, reward_pbrs_delta and reward_invariance_correction values                                                                                         |
-| statistics-bh-finite-family-122               | statistics  | Undefined tests excluded from finite-only BH family; marked non-applicable          | statistics/test_statistics.py:499         |                                                                                                                                                                                |
-| statistics-independence-contract-123          | statistics  | Inferential helpers require independent_observations=True                           | statistics/test_statistics.py:636         | Covers hypothesis tests and bootstrap intervals                                                                                                                                |
-| report-independent-sections-124               | integration | CI, diagnostics and shift sections do not depend on hypothesis-test output          | integration/test_report_formatting.py:28  | Also verifies the reported bootstrap resample count                                                                                                                            |
-| pbrs-discounted-evidence-125                  | pbrs        | Verification requires local identity, continuity and discounted terminal boundary   | pbrs/test_pbrs.py:1699                    | Discontinuous potentials are not verified                                                                                                                                      |
-| statistics-proportional-histograms-126        | statistics  | Proportional histograms ignore sample count; moved mass yields positive KL/JS       | statistics/test_statistics.py:119         | KL and JS remain finite and non-negative                                                                                                                                       |
-| pbrs-near-bound-clamp-127                     | pbrs        | Relaxed near-bound clamps apply exact endpoints and retain all reasons              | pbrs/test_pbrs.py:1276                    | Includes numeric-string coercion                                                                                                                                               |
-| pbrs-exit-mode-validation-128                 | pbrs        | Exit-potential choices are strict or canonicalized; direct calls fail safe          | pbrs/test_pbrs.py:1296                    | Direct calculation and simulation boundaries warn before fallback; PBRS calls suppress additives                                                                               |
-| cli-invalid-exit-mode-129                     | cli         | Invalid `--params exit_potential_mode` fails before artifacts                       | cli/test_cli_params_and_csv.py:322        | Strict CLI validation                                                                                                                                                          |
-| cli-warning-header-recognition-130            | cli         | Warning counts accept only anchored Python warning header formats                   | cli/test_cli_params_and_csv.py:49         | Covers POSIX, relative, synthetic and Windows source locations                                                                                                                 |
-| pbrs-invalid-mode-provenance-131              | pbrs        | Invalid imported exit-mode metadata cannot certify canonical invariance             | pbrs/test_pbrs.py:475                     | Preserves the invalid raw value and reports effective additive settings as unknown                                                                                             |
+- Owning test: Relative source path and function name (`path.py::test_name`),
+  stable across unrelated line insertions.
+- Notes: Sub-modes, non-owning references and multi-path coverage.
+
+| ID                                            | Category    | Description                                                                         | Owning test                                                                                        | Notes                                                                                                                                                                          |
+| --------------------------------------------- | ----------- | ----------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
+| report-additives-deterministic-092            | components  | Additives deterministic report section                                              | components/test_additives.py::test_additive_activation_deterministic_contribution                  | Integration/PBRS may reference outcome non-owning                                                                                                                              |
+| robustness-decomposition-integrity-101        | robustness  | Single active core component equals total reward under mutually exclusive scenarios | robustness/test_robustness.py::test_decomposition_integrity                                        | Scenarios: idle, hold, exit, invalid; non-owning refs integration/test_reward_calculation.py                                                                                   |
+| robustness-exit-mode-fallback-102             | robustness  | Unknown exit_attenuation_mode falls back to linear w/ warning                       | robustness/test_robustness.py::test_robustness_102_unknown_exit_mode_fallback_linear               |                                                                                                                                                                                |
+| robustness-negative-grace-clamp-103           | robustness  | Negative exit_plateau_grace clamps to 0.0 w/ warning                                | robustness/test_robustness.py::test_robustness_103_negative_plateau_grace_clamped                  |                                                                                                                                                                                |
+| robustness-invalid-power-tau-104              | robustness  | Invalid power tau falls back alpha=1.0 w/ warning                                   | robustness/test_robustness.py::test_robustness_104_invalid_power_tau_fallback_alpha_one            |                                                                                                                                                                                |
+| robustness-near-zero-half-life-105            | robustness  | Near-zero half life yields no attenuation (factor≈base)                             | robustness/test_robustness.py::test_robustness_105_half_life_near_zero_fallback                    |                                                                                                                                                                                |
+| pbrs-canonical-exit-semantic-106              | pbrs        | Canonical exit uses shaping=-prev_potential and next_potential=0.0                  | pbrs/test_pbrs.py::test_exit_step_shaping_matches_exit_step_rules                                  | Uses stored potential across steps; no drift correction applied                                                                                                                |
+| statistics-partial-deps-skip-107              | statistics  | skip_partial_dependence => empty PD structures                                      | statistics/test_statistics.py::test_statistics_feature_analysis_skip_partial_dependence            |                                                                                                                                                                                |
+| helpers-transitions-preserve-multiplicity-108 | helpers     | Repeated transitions retain their empirical multiplicity                            | helpers/test_utilities.py::test_repeated_transitions_preserve_multiplicity                         |                                                                                                                                                                                |
+| helpers-missing-cols-fill-109                 | helpers     | Missing required columns filled with NaN + single warning                           | helpers/test_utilities.py::test_missing_multiple_required_columns_single_warning                   |                                                                                                                                                                                |
+| statistics-binned-stats-min-edges-110         | statistics  | <2 bin edges raises ValueError                                                      | statistics/test_statistics.py::test_statistics_binned_stats_invalid_bins_raises                    | Docstring line                                                                                                                                                                 |
+| statistics-constant-cols-exclusion-111        | statistics  | Constant columns excluded & listed                                                  | statistics/test_statistics.py::test_statistics_correlation_dropped_constant_columns                | Docstring line                                                                                                                                                                 |
+| statistics-degenerate-distribution-shift-112  | statistics  | Constants: zero distances; KS p only with declared independent observations         | statistics/test_statistics.py::test_statistics_distribution_shift_metrics_degenerate_zero          | Docstring line                                                                                                                                                                 |
+| statistics-constant-dist-exact-ci-113a        | statistics  | Both modes retain exact constant CI bounds                                          | statistics/test_statistics.py::test_stats_bootstrap_constant_distribution_exact_bounds             |                                                                                                                                                                                |
+| statistics-percentile-outside-mean-113b       | statistics  | Percentile bounds need not contain the sample mean                                  | statistics/test_statistics.py::test_stats_bootstrap_percentiles_need_not_contain_mean              |                                                                                                                                                                                |
+| statistics-constant-diagnostics-115           | statistics  | Constants have N/A higher moments, normality tests and Q-Q fits in both modes       | statistics/test_statistics.py::test_statistics_distribution_constant_diagnostics                   |                                                                                                                                                                                |
+| pbrs-canonical-near-zero-report-116           | pbrs        | Canonical trajectories with valid evidence are classified as verified               | pbrs/test_pbrs.py::test_pbrs_canonical_near_zero_report                                            | Requires local identity, continuity, discounted terminal boundary, and zero observed additives; the non-owning boundary test also covers a complete singleton terminal episode |
+| robustness-exit-pnl-only-117                  | robustness  | Only exit actions have non-zero PnL                                                 | robustness/test_robustness.py::test_pnl_invariant_exit_only                                        |                                                                                                                                                                                |
+| pbrs-absence-shift-placeholder-118            | pbrs        | Placeholder shift line present when shaping shift is absent                         | pbrs/test_pbrs.py::test_pbrs_absence_and_distribution_shift_placeholder                            |                                                                                                                                                                                |
+| components-pbrs-breakdown-fields-119          | components  | PBRS breakdown fields finite and mathematically aligned                             | components/test_reward_components.py::test_pbrs_breakdown_fields_finite_and_aligned                | Tests base_reward, pbrs_delta and invariance_correction alignment                                                                                                              |
+| integration-pbrs-metrics-section-120          | integration | PBRS Metrics section present in report with tracing metrics                         | integration/test_report_formatting.py::test_report_includes_pbrs_metrics_section                   |                                                                                                                                                                                |
+| cli-pbrs-csv-columns-121                      | cli         | PBRS columns in reward_samples.csv when shaping enabled                             | cli/test_cli_params_and_csv.py::test_csv_contains_pbrs_columns_when_shaping_present                | Verifies finite reward_base, reward_pbrs_delta and reward_invariance_correction values                                                                                         |
+| statistics-bh-finite-family-122               | statistics  | Undefined tests excluded from finite-only BH family; marked non-applicable          | statistics/test_statistics.py::test_bh_excludes_undefined_tests_from_finite_family                 |                                                                                                                                                                                |
+| statistics-independence-contract-123          | statistics  | Inferential helpers require independent_observations=True                           | statistics/test_statistics.py::test_inference_helpers_require_independent_observations             | Covers hypothesis tests and bootstrap intervals                                                                                                                                |
+| report-independent-sections-124               | integration | CI, diagnostics and shift sections do not depend on hypothesis-test output          | integration/test_report_formatting.py::test_statistical_sections_do_not_depend_on_hypothesis_tests | Also verifies the reported bootstrap resample count                                                                                                                            |
+| pbrs-discounted-evidence-125                  | pbrs        | Verification requires local identity, continuity and discounted terminal boundary   | pbrs/test_pbrs.py::test_pbrs_canonical_discontinuous_potentials_report                             | Discontinuous potentials are not verified                                                                                                                                      |
+| statistics-proportional-histograms-126        | statistics  | Proportional histograms ignore sample count; moved mass yields positive KL/JS       | statistics/test_statistics.py::test_distribution_shift_proportional_histograms_ignore_sample_count | KL and JS remain finite and non-negative                                                                                                                                       |
+| pbrs-near-bound-clamp-127                     | pbrs        | Relaxed near-bound clamps apply exact endpoints and retain all reasons              | pbrs/test_pbrs.py::test_validate_reward_parameters_records_near_bound_clamps_exactly               | Includes numeric-string coercion                                                                                                                                               |
+| pbrs-exit-mode-validation-128                 | pbrs        | Exit-potential choices are strict or canonicalized; direct calls fail safe          | pbrs/test_pbrs.py::test_invalid_exit_mode_warns_at_direct_and_simulation_boundaries                | Direct calculation and simulation boundaries warn before fallback; PBRS calls suppress additives                                                                               |
+| cli-invalid-exit-mode-129                     | cli         | Invalid `--params exit_potential_mode` fails before artifacts                       | cli/test_cli_params_and_csv.py::test_invalid_exit_potential_mode_params_fails_before_artifacts     | Strict CLI validation                                                                                                                                                          |
+| cli-warning-header-recognition-130            | cli         | Warning counts accept only anchored Python warning header formats                   | cli/test_cli_params_and_csv.py::test_warning_header_positive_and_negative_formats                  | Covers POSIX, relative, synthetic and Windows source locations                                                                                                                 |
+| pbrs-invalid-mode-provenance-131              | pbrs        | Invalid imported exit-mode metadata cannot certify canonical invariance             | pbrs/test_pbrs.py::test_report_rejects_invalid_exit_mode_provenance                                | Preserves the invalid raw value and reports effective additive settings as unknown                                                                                             |
+| pbrs-synthetic-fee-floor-132                  | pbrs        | High-fee entry loss remains in long/short synthetic PnL and exit rewards            | pbrs/test_pbrs.py::test_synthetic_fee_loss_extrema_match_retained_pnl                              | Direct and transformed trajectories                                                                                                                                            |
 
 ### Non-Owning Smoke / Reference Checks
 
-Files that reference invariant outcomes (formatting, aggregation) without owning
-the invariant must include a leading comment:
+Tests that check an invariant owned elsewhere identify its owner in a comment
+or docstring, for example:
 
 ```python
 # Non-owning smoke; ownership: <owning file>
 ```
 
-Table tracks approximate line ranges and source ownership:
+The following tests also check outcomes owned elsewhere:
 
-| File                                   | Lines (approx) | References                                           | Ownership Source                                                    |
-| -------------------------------------- | -------------- | ---------------------------------------------------- | ------------------------------------------------------------------- |
-| integration/test_reward_calculation.py | 44             | Decomposition identity (sum components)              | robustness/test_robustness.py:43                                    |
-| components/test_reward_components.py   | 551            | Exit factor finiteness & plateau behavior            | robustness/test_robustness.py:43+                                   |
-| pbrs/test_pbrs.py                      | 1053           | Canonical vs non-canonical classification formatting | robustness/test_robustness.py:43, robustness/test_robustness.py:127 |
-| pbrs/test_pbrs.py                      | 1415           | Non-canonical full report reason aggregation         | robustness/test_robustness.py:43                                    |
-| pbrs/test_pbrs.py                      | 1469           | Non-canonical mode-only reason (additives disabled)  | robustness/test_robustness.py:43                                    |
-| statistics/test_statistics.py          | 292            | Mean decomposition consistency                       | robustness/test_robustness.py:43                                    |
+| Non-owning test                                                                | Reference check                             | Owning test                                                                                              |
+| ------------------------------------------------------------------------------ | ------------------------------------------- | -------------------------------------------------------------------------------------------------------- |
+| integration/test_reward_calculation.py::test_reward_component_activation_smoke | Core component activation and decomposition | robustness/test_robustness.py::test_decomposition_integrity                                              |
+| components/test_reward_components.py::test_exit_factor_calculation             | Exit factor modes and plateau behavior      | robustness/test_robustness.py::test_exit_factor_comprehensive; test_plateau_continuity_at_grace_boundary |
+| pbrs/test_pbrs.py::test_pbrs_canonical_near_zero_report                        | Canonical classification and decomposition  | robustness/test_robustness.py::test_decomposition_integrity                                              |
+| pbrs/test_pbrs.py::test_pbrs_non_canonical_full_report_reason_aggregation      | Non-canonical report reasons                | robustness/test_robustness.py::test_decomposition_integrity                                              |
+| pbrs/test_pbrs.py::test_pbrs_non_canonical_mode_only_reason                    | Non-canonical exit mode without additives   | robustness/test_robustness.py::test_decomposition_integrity                                              |
+| statistics/test_statistics.py::test_stats_mean_decomposition_consistency       | Mean decomposition consistency              | robustness/test_robustness.py::test_decomposition_integrity                                              |
 
 ### Deprecated / Reserved IDs