refactor(stage1-r): name the conviction column conviction_at_entry

Rename the dense PositionManagement record's column 9 from `bias_at_entry_abs`
to `conviction_at_entry` (FIELD_NAMES, the `r_col`/test index constants, the
cross-crate layout guard, and the doc comments).

Why: the column holds |bias| at entry, which C10 defines AS conviction (bias =
direction + conviction magnitude; ledger INDEX.md ~458). The record already names
the other half of that decomposition by its domain concept (`direction` = sign,
not `bias_sign`), so naming the magnitude half mechanically (`bias_at_entry_abs`)
was an inconsistency; `conviction_at_entry` speaks the ledger's ubiquitous
language and parallels `direction`, while `_at_entry` preserves the
frozen-snapshot precision.

Considered and rejected: collapsing `(direction, bias_at_entry_abs)` into one
signed `bias_at_entry` and dropping `direction` as redundant — it is not
redundant. On a reversal row col 4 (`direction`) tracks the reopened leg while
col 9 tracks the closed trade's entry conviction, so the two describe different
trades and cannot be losslessly merged; they are also distinct semantic axes
(current-position direction vs per-trade entry conviction).

Scope: domain name at the data boundary, mechanical name internally — the
internal `bias.abs()` variables (`Open.bias_abs`, the fold's `Trade.bias_abs`)
keep their computation-faithful names, exactly the raw-internal / domain-external
split the record uses elsewhere.

Behaviour-preserving: cargo build --workspace clean; cargo test --workspace 500
passed, 0 failed (unchanged); clippy --all-targets -D warnings clean. The layout
guard (`r_col_indices_match_producer_field_layout`) confirms the renamed string.

refs #117
This commit is contained in:
2026-06-24 10:25:18 +02:00
parent b4e84335c4
commit 92591e5dc0
3 changed files with 12 additions and 12 deletions
+4 -4
View File
@@ -38,7 +38,7 @@ const OPEN: usize = 11;
const UNREALIZED_R: usize = 12;
const ENTRY_PRICE: usize = 6;
const STOP_PRICE: usize = 7;
const BIAS_AT_ENTRY_ABS: usize = 9;
const CONVICTION_AT_ENTRY: usize = 9;
const SIZE: usize = 10;
/// Property: the real producer->consumer seam composes. Driving `FixedStop` ->
@@ -264,14 +264,14 @@ fn r_col_indices_match_producer_field_layout() {
assert_eq!(PM_RECORD_KINDS[REALIZED_R], ScalarKind::F64);
assert_eq!(PM_RECORD_KINDS[UNREALIZED_R], ScalarKind::F64);
// iter-2 reads: entry_price (6), stop_price (7), bias_at_entry_abs (9) — the geometry
// iter-2 reads: entry_price (6), stop_price (7), conviction_at_entry (9) — the geometry
// summarize_r recovers latched_dist (net-of-cost) and conviction (terciles) from.
assert_eq!(PM_FIELD_NAMES[ENTRY_PRICE], "entry_price");
assert_eq!(PM_FIELD_NAMES[STOP_PRICE], "stop_price");
assert_eq!(PM_FIELD_NAMES[BIAS_AT_ENTRY_ABS], "bias_at_entry_abs");
assert_eq!(PM_FIELD_NAMES[CONVICTION_AT_ENTRY], "conviction_at_entry");
assert_eq!(PM_RECORD_KINDS[ENTRY_PRICE], ScalarKind::F64);
assert_eq!(PM_RECORD_KINDS[STOP_PRICE], ScalarKind::F64);
assert_eq!(PM_RECORD_KINDS[BIAS_AT_ENTRY_ABS], ScalarKind::F64);
assert_eq!(PM_RECORD_KINDS[CONVICTION_AT_ENTRY], ScalarKind::F64);
// iter-2 size column (10): the Sizer's `size` flows here, and the sibling
// `risk_executor.rs` fixture asserts its R-invariance by reading this index — so the