Give measurement its first deflatable metric (tap-to-scalar reduction + null model) #290
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Precondition-seeder for the deferred half of #147 (the registry deflation-vocabulary genericity, C28 phase 6). The deferral's condition is a genuine second metric consumer; this records the concrete candidate shape.
A measurement run today produces declared taps only --
MeasurementReport(crates/aura-engine/src/report.rs:119) carriestaps: Vec<String>and no scalar metric -- so measurement output can be inspected but not ranked, swept, or deflated. The missing piece is a post-run reduction from a recorded tap series to one scalar per run, paired with its own null model. Candidates:corr(signal_t, forward_return_t+h); null model: permutation of the signal against the returns (or analyticallyN(0, 1/sqrt(n))). The forward-return alignment is an offline join over recorded traces (shift +join_on_ts) after the run -- no in-graph future read, so C2 (causality) is untouched.Binomial(n, 0.5).Any one of these, wired through sweep selection, turns
optimize_deflated's hard-coded two-arm null-model branch (crates/aura-registry/src/lib.rs:791-- R block-bootstrap vstotal_pipsdispersion floor) into a genuine two-implementor seam; at that point the (metric, null-model) injection of #147 item 2 is demand-driven instead of speculative, and the remaining deferral lifts.Un-deferral proceeding; #290 sequenced before #147 item 2 (2026-07-20)
The deferral of #147 item 2 (the registry deflation-vocabulary genericity) rested on a single unmet precondition: a genuine second metric consumer, so the abstraction is demand-driven rather than a one-implementor speculation. This run builds that consumer here (#290), then extracts the abstraction against two real implementors.
User direction (2026-07-20): lift the twice-ratified deferral of #147 item 2 (2026-06-27 in the #147 body; re-ratified in the 2026-07-02 comment on #147) by building measurement its first deflatable metric first. The call to un-defer is the user's, taken in this run.
Sequencing decision (derived). Two orderings were open:
Chosen: (B). Basis (derived): the project's demand-driven-abstraction principle — designing the abstraction against one real plus one still-being-built implementor is the speculative posture the deferral itself was written to avoid. Both cycles run in the same session; #147 item 2 becomes autonomously-doable the moment #290's second implementor lands.
Metric selection (derived lean, finalised in spec production). Of the three candidates in the body: signal autocorrelation measures persistence, not predictive skill (wrong target); directional hit-rate discards conviction magnitude (a coarse special case). The information coefficient (corr(signal_t, forward_return_t+h)) uses sign and magnitude, is the standard signal-quality yardstick, and carries a permutation null model genuinely distinct from the R block-bootstrap. Its forward-return alignment is an offline join over recorded traces (no in-graph future read — C2 untouched). The C7 relationship ("signal quality is measured in R") is complementary, not contradictory: R scores the stopped strategy on the execution layer; the information coefficient scores the raw pre-execution signal on the measurement layer. This lean is validated against C2/C7 by the spec grounding-check.
Registry surfaces the item-2 extraction touches (verified against the current tree):
optimize_deflated(crates/aura-registry/src/lib.rs:784, the two-arm null-model branch), the string-keyedMetricvocabulary (:502) andmetric_cmp(:564) /rank_by(:578). Measurement current output carries tap names only (MeasurementReport, crates/aura-engine/src/report.rs:119).Design ready for spec production.
Design refinement: #290 delivers a standalone post-run reduction; the registry wiring is #147 item 2 (2026-07-20)
Recon of the current tree (drift-checked this run) refines the shape implied by the earlier sequencing comment, which framed #290 as adding an IC arm inside
optimize_deflateds null-model branch. The tree shows that is not cleanly separable from #147 item 2:optimize_deflated/rank_by/metric_cmp(crates/aura-registry/src/lib.rs:784/578/564) read the concreteRunReport<RunMetrics>and branch on the tradingMetricenum (is_r_metric, :603). Giving them an IC arm requires the metric payload to carry IC — which is exactly the domain-supplied-score + injected-null-model abstraction of #147 item 2. Adding a hard-coded third arm now only to abstract it away next cycle is the churn the sequencing avoids.Refined cut.
runs/traces/<name>/<tap>.json, aColumnarTraceofts[]+columns[]), computes the forward-return-aligned information coefficientcorr(signal_t, forward_return_{t+h})and its permutation-null significance, and reports the scalar. The generic pieces — Pearson correlation and a Fisher-Yates permutation overSplitMix64— land inaura-analysis(the domain-free statistics foundation, besideresample_block); the IC semantics (forward-return horizonh, the offline join) live in the reduction command. The run path (run_measurement, crates/aura-cli/src/main.rs:1852) is untouched, so existing measurement and strategy run output stays byte-identical (C18). The forward-return readclose_{t+h}is over a completed run recorded trace, not an in-graph node: C2 governs in-graph node access (a node sees only the past) and does not reach a post-run reduction.optimize_deflated/rank_by/metric_cmpover an injected (score, null-model), then wires IC through sweep selection (cross-trials deflation). This is now demand-driven: two structurally distinct null-model computations exist inaura-analysis— the moving-block bootstrap behind R (resample_block) and the permutation behind IC — so the injected-null-model seam is validated against two real implementors, not one. It realizes the ledger architecture stated in C28 ("a named metric vocabulary supplied by measurement and backtest instead of baked in R-only ... the statistics injected from aura-analysis").Basis (derived): layer-honesty (the reduction is process-column work over run artifacts, C28), byte-identity safety (C18), and avoiding add-arm-then-abstract-it churn. The two-consumer payoff that lifts #147 item 2 deferral is the permutation null existing as a real, tested computation.
Sub-forks resolved (derived). Metric = Pearson IC. Null = one-sided permutation,
overfit_probability = (count(null_ic >= raw_ic) + 1)/(n_perm + 1)(mirrors the R-arm formula at lib.rs:807, higher-is-better). Forward-return horizon default h = 1 bar. The permutation seed is recorded in the output for reproducibility (C18 forbids results not reproducible from a recorded manifest).Design ready for spec production.
Spec auto-signed on a grounding-check PASS (2026-07-20)
The measurement-IC spec (the standalone post-run Information Coefficient reduction refined in the comment above) was produced and auto-signed under /boss. The signature is the grounding-check PASS: an independent fresh-context agent verdict that every load-bearing assumption the spec makes about the current tree is ratified by a named, currently-green test —
MeasurementReportis{ manifest, taps }with no metric field, andaura runon a tapped, no-biasblueprint dispatches to the measurement path that persists the tap trace;ColumnarTraceunderruns/traces/<run>/<tap>.jsonwith a trace-store read round-trip;aura-analysisstatistics kernel (SplitMix64,resample_block,MetricStats,quantile) ispuband deterministic-by-seed — the base the newpearson_corr/permuteextend;(count(null >= raw) + 1)/(n + 1), the formula the IC permutation null mirrors;aura runoutput golden is byte-identical (the run path is untouched this cycle).No human signed; a user veto reverts it forward (the spec is a git-ignored working file, never committed). The design is settled and ready for plan production.
Cycle shipped on the run branch; awaiting the user-reserved merge (2026-07-20)
The Information Coefficient reduction is implemented and committed on branch
worktree-issue-290-measure-metric(commita9d36dd).aura measure ic <run> --signal <tap> --price <tap> [--horizon] [--permutations] [--seed]reads a persisted run two tap traces, computescorr(signal_t, forward_return_{t+h})and a one-sided permutation-null overfit probability;pearson_corr+permutelanded in aura-analysis (the domain-free foundation), the IC semantics + the verb in aura-cli (the shell). The run path (run_measurement),MeasurementReport, the trace store, and the registry vocabulary are untouched.Verified independently by the orchestrator:
cargo test --workspacegreen — the new aura-analysis unit tests, the aura-cli IC unit tests (engineered signal significant / varying-uncorrelated not significant / constant + degenerate floor / exact-ts alignment / determinism), and themeasure_icE2E (well-formedness, determinism, unknown-run and missing-tap error paths);cargo clippy --workspace --all-targets -D warningsclean; the C18 byte-identity golden (run_prints_json_and_exits_zero) unchanged. The spec was auto-signed on a grounding-check PASS (no human signature). Cycle-close audit: ratified against C2/C10/C18/C28, with two medium debts noted — measurement-domain logic accreting in the shell (the ledger-recorded "no measurement crate yet" debt, C28 Status), and an undefended duplicate-timestamp assumption in the offline join (filed as #294).This lands the second, structurally distinct null-model computation (a permutation null, beside the R moving-block bootstrap), meeting the item-2 deferral precondition on #147. The
closes #290marker fires when the branch merges.