Deliver net-R on the family/campaign path — the cost graph lost its last production caller in #221 #234

Closed
opened 2026-07-10 17:15:22 +02:00 by Brummel · 3 comments
Owner

Invariant 7's research loop is "flat-1R, gross R → net R via the composable cost-model graph (C10)". Since the #221 cut (commit b5ad53d, 2026-07-09) removed wrap_r's cost-graph branch — its last production caller, per the code comment at crates/aura-cli/src/main.rs:62-65 — net-R is unreachable from every CLI path:

  • no cost consumer exists in crates/aura-campaign/src or crates/aura-cli/src/verb_sugar.rs (grep over both: zero hits);
  • persist_taps accepts net_r_equity but skips it at run time ("net_r_equity has no channel here", crates/aura-cli/src/campaign_run.rs:582);
  • a test pins the absence: tap_channel("net_r_equity") == None, "unproducible on the current path" (campaign_run.rs:1004-1010).

The #221 rationale — cost "routes through the sweep/campaign reduce path" — described the intended home, not a shipped one. The cost machinery itself is complete and tested (cost-model-graph milestone, closed 2026-06-29: CostNode/CostRunner/CostSum, ConstantCost/VolSlippageCost/CarryCost, the cost_graph composite, the summarize_r net fold); it is unwired, not missing.

Consequence for a research project: every sweep/walkforward/mc/generalize/campaign result is gross-of-costs, and nothing on the surface says so.

Delivery home is the campaign path (per-member cost graph → net_r_equity tap → net summarize). #152 (intern cost port names as cost[k].<port> instead of a per-build leak) is the naming prerequisite for cost on the per-member sweep path. A cost-model reference also belongs in the harness-binding vocabulary of #231 once that lands.

  • a campaign/family run can produce net_r_equity again
  • gross-only results are labelled as such (or net becomes the default via an explicit zero-cost model)
Invariant 7's research loop is "flat-1R, gross R → net R via the composable cost-model graph (C10)". Since the #221 cut (commit b5ad53d, 2026-07-09) removed `wrap_r`'s cost-graph branch — its last production caller, per the code comment at crates/aura-cli/src/main.rs:62-65 — net-R is unreachable from every CLI path: - no cost consumer exists in crates/aura-campaign/src or crates/aura-cli/src/verb_sugar.rs (grep over both: zero hits); - `persist_taps` accepts `net_r_equity` but skips it at run time ("`net_r_equity` has no channel here", crates/aura-cli/src/campaign_run.rs:582); - a test pins the absence: `tap_channel("net_r_equity") == None`, "unproducible on the current path" (campaign_run.rs:1004-1010). The #221 rationale — cost "routes through the sweep/campaign reduce path" — described the intended home, not a shipped one. The cost machinery itself is complete and tested (cost-model-graph milestone, closed 2026-06-29: CostNode/CostRunner/CostSum, ConstantCost/VolSlippageCost/CarryCost, the `cost_graph` composite, the `summarize_r` net fold); it is unwired, not missing. Consequence for a research project: every sweep/walkforward/mc/generalize/campaign result is gross-of-costs, and nothing on the surface says so. Delivery home is the campaign path (per-member cost graph → `net_r_equity` tap → net summarize). #152 (intern cost port names as `cost[k].<port>` instead of a per-build leak) is the naming prerequisite for cost on the per-member sweep path. A cost-model reference also belongs in the harness-binding vocabulary of #231 once that lands. - [ ] a campaign/family run can produce `net_r_equity` again - [ ] gross-only results are labelled as such (or net becomes the default via an explicit zero-cost model)
Brummel added this to the Real-project readiness — role-complete research loop (no freeze) milestone 2026-07-10 17:15:22 +02:00
Brummel added the feature label 2026-07-10 17:15:22 +02:00
Author
Owner

Design reconciliation (specify)

Spec: net-r-campaign-cost. The delivery-shape forks the issue leaves open are resolved as follows.

  • Fork: authorable cost form -> an additive cost: Vec<CostSpec> block on the campaign document, mirroring the risk-regime precedent exactly (externally tagged additive enum over the three shipped cost nodes — constant / vol_slippage / carry; serde default + skip-if-empty so cost-less documents keep their content ids; a std::cost construct-vocabulary block and validation like std::risk). Basis: derived — the risk block is the proven shape for a closed, Blockly-clean structural campaign axis; the cost machinery's own arity (cost_graph takes a Vec, summed by CostSum) matches a Vec block; content-id stability follows the documented risk/description precedent.
  • Fork: gross labelling vs net default (acceptance box 2) -> net-by-default via zero cost. An absent/empty cost block means zero costs, and summarize_r already computes the net metric family unconditionally (an empty cost slice yields net == gross), so every result IS net and no labelling machinery or second result kind exists. Basis: derived — invariant 7's research loop is "gross R -> net R via the cost graph"; the zero-cost default satisfies it structurally with zero golden churn.
  • Fork: metrics-only vs also the in-graph tap -> both. The cost rows join summarize_r per member (member metrics genuinely net), AND the #221-deleted in-graph leg returns as an optional cost leg in the harness scaffolding (cost_graph + the LinComb(4) net_r_equity curve + its recorder), routed as a producible tap channel — acceptance box 1 names net_r_equity, which is the tap, not a metric. The absence pin (tap_channel("net_r_equity") == None) flips to routed. Basis: derived — the box's own wording plus the tap/metric vocabularies already carrying both names.
  • Fork: #152 sequencing -> folded in as this cycle's first task, per that issue's recorded plan (comment of 2026-07-09: "folding this in as that cycle's first task remains the plan of record"): a process-global interned name helper for cost[k]./cost[k]. in the cost module, consumed by CostSum, cost_graph, and the CLI feed — replacing the per-build .leak()s before cost is rebuilt per member across a sweep.
  • Fork: verb-sugar surface -> no --cost flag now; the sugar passes an empty cost block (zero-cost default) and authored campaign documents carry cost models — the same lean-flag decision the #231 bindings block took (issues/231#issuecomment note of 2026-07-10). A flag can come later as pure sugar.
## Design reconciliation (specify) Spec: net-r-campaign-cost. The delivery-shape forks the issue leaves open are resolved as follows. - **Fork: authorable cost form** -> an additive `cost: Vec<CostSpec>` block on the campaign document, mirroring the risk-regime precedent exactly (externally tagged additive enum over the three shipped cost nodes — constant / vol_slippage / carry; serde default + skip-if-empty so cost-less documents keep their content ids; a `std::cost` construct-vocabulary block and validation like `std::risk`). Basis: derived — the risk block is the proven shape for a closed, Blockly-clean structural campaign axis; the cost machinery's own arity (cost_graph takes a Vec, summed by CostSum) matches a Vec block; content-id stability follows the documented `risk`/`description` precedent. - **Fork: gross labelling vs net default (acceptance box 2)** -> net-by-default via zero cost. An absent/empty cost block means zero costs, and summarize_r already computes the net metric family unconditionally (an empty cost slice yields net == gross), so every result IS net and no labelling machinery or second result kind exists. Basis: derived — invariant 7's research loop is "gross R -> net R via the cost graph"; the zero-cost default satisfies it structurally with zero golden churn. - **Fork: metrics-only vs also the in-graph tap** -> both. The cost rows join summarize_r per member (member metrics genuinely net), AND the #221-deleted in-graph leg returns as an optional cost leg in the harness scaffolding (cost_graph + the LinComb(4) net_r_equity curve + its recorder), routed as a producible tap channel — acceptance box 1 names net_r_equity, which is the tap, not a metric. The absence pin (tap_channel("net_r_equity") == None) flips to routed. Basis: derived — the box's own wording plus the tap/metric vocabularies already carrying both names. - **Fork: #152 sequencing** -> folded in as this cycle's first task, per that issue's recorded plan (comment of 2026-07-09: "folding this in as that cycle's first task remains the plan of record"): a process-global interned name helper for cost[k].<port>/cost[k].<field> in the cost module, consumed by CostSum, cost_graph, and the CLI feed — replacing the per-build .leak()s before cost is rebuilt per member across a sweep. - **Fork: verb-sugar surface** -> no --cost flag now; the sugar passes an empty cost block (zero-cost default) and authored campaign documents carry cost models — the same lean-flag decision the #231 bindings block took (issues/231#issuecomment note of 2026-07-10). A flag can come later as pure sugar.
Author
Owner

Spec auto-signed (2026-07-11): the net-R delivery spec (docs/specs/net-r-campaign-cost.md, a git-ignored working file) was signed autonomously — the signature is an independent fresh-context grounding-check PASS (8 load-bearing assumptions about current behaviour, each ratified against a named currently-green test; one informational imprecision noted — the leak twins live in cost_graph only, cost_sum builds owned strings — which changes no requirement). No human signed. The design decisions are the five forks in the reconciliation comment of 2026-07-11 above. Planning proceeds from this spec.

Spec auto-signed (2026-07-11): the net-R delivery spec (docs/specs/net-r-campaign-cost.md, a git-ignored working file) was signed autonomously — the signature is an independent fresh-context grounding-check PASS (8 load-bearing assumptions about current behaviour, each ratified against a named currently-green test; one informational imprecision noted — the leak twins live in cost_graph only, cost_sum builds owned strings — which changes no requirement). No human signed. The design decisions are the five forks in the reconciliation comment of 2026-07-11 above. Planning proceeds from this spec.
Author
Owner

Shipped on the branch, seven commits: 249aafd (#152: interned cost[k].* names, both cost_graph leaks gone), bdcf045 (CostSpec campaign vocabulary — additive cost block mirroring risk, two-tier-validated, content-id-stable), a1afc2f (wrap_r's optional cost leg — the #221 wiring rebuilt behaviour-preservingly, suite green unchanged as the gate), bb1f6c8 (doc -> member -> both re-run sides: genuinely net member metrics, manifest stamping, reproduce + persist re-derivation — the #233 pattern), da7d547 (TapChannel::Net — the net_r_equity tap routes and persists; remedy-naming skip for cost-less docs), c32c01a (closing archive-gated e2e: costed GER40 campaign nets every member, gross parity without the block, curve persisted, family reproduces bit-identically), aaca18c (audit close: C10 ledger reconciled with superseded/discharged annotations + the cycle-net-r realization; one-knob invariant unit-pinned).

Both acceptance boxes are met: a campaign/family run produces net_r_equity again (box 1), and net is the default via the explicit zero-cost model — an absent cost block hashes and behaves byte-identically to today while summarize_r's net family equals gross under it (box 2, second arm). The spec was auto-signed on a grounding-check PASS; the five design forks are in the reconciliation comment of 2026-07-11 above. #152 closed with the first commit. Closes via commit on merge.

Shipped on the branch, seven commits: 249aafd (#152: interned cost[k].* names, both cost_graph leaks gone), bdcf045 (CostSpec campaign vocabulary — additive cost block mirroring risk, two-tier-validated, content-id-stable), a1afc2f (wrap_r's optional cost leg — the #221 wiring rebuilt behaviour-preservingly, suite green unchanged as the gate), bb1f6c8 (doc -> member -> both re-run sides: genuinely net member metrics, manifest stamping, reproduce + persist re-derivation — the #233 pattern), da7d547 (TapChannel::Net — the net_r_equity tap routes and persists; remedy-naming skip for cost-less docs), c32c01a (closing archive-gated e2e: costed GER40 campaign nets every member, gross parity without the block, curve persisted, family reproduces bit-identically), aaca18c (audit close: C10 ledger reconciled with superseded/discharged annotations + the cycle-net-r realization; one-knob invariant unit-pinned). Both acceptance boxes are met: a campaign/family run produces net_r_equity again (box 1), and net is the default via the explicit zero-cost model — an absent cost block hashes and behaves byte-identically to today while summarize_r's net family equals gross under it (box 2, second arm). The spec was auto-signed on a grounding-check PASS; the five design forks are in the reconciliation comment of 2026-07-11 above. #152 closed with the first commit. Closes via commit on merge.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: Brummel/Aura#234