test: red executable-spec for #265 — introspect --unwired states knob units
The four silently-misreadable cost/risk knobs (cost_per_trade, slip_vol_mult, vol.length, vol.k) must carry one-line unit/semantics annotations in campaign introspect --unwired — blocking the price-vs-R and length-as-timescale misreadings that produce no error today. refs #265
This commit is contained in:
@@ -667,6 +667,58 @@ fn campaign_introspect_unwired_lists_the_risk_slot_when_explicitly_empty() {
|
||||
);
|
||||
}
|
||||
|
||||
/// #265: the cost and risk slots name their knobs but not their UNITS or
|
||||
/// SEMANTICS, and the two natural misreadings are silent (wrong by orders of
|
||||
/// magnitude / change an experiment's meaning, with no error). Property: when
|
||||
/// `campaign introspect --unwired` lists the open cost and risk slots, each of
|
||||
/// the four silently-misreadable knobs carries a one-line unit/semantics note
|
||||
/// that blocks its misreading — `constant.cost_per_trade` is in PRICE units
|
||||
/// (charged per close as cost/|entry−stop| in R), `vol_slippage.slip_vol_mult`
|
||||
/// is a MULTIPLIER on the per-cycle vol estimate (charged in R likewise),
|
||||
/// `vol.length` SMOOTHS the estimator and does NOT set the stop's timescale,
|
||||
/// and `vol.k` SCALES the stop distance. Autonomous: a bare `{}` envelope
|
||||
/// (both slots open) written inline, no project, hostless. Wording stays free
|
||||
/// (matched case-insensitively on load-bearing fragments, not whole lines); it
|
||||
/// fails today because the annotations are absent, not on scaffolding.
|
||||
#[test]
|
||||
fn campaign_introspect_unwired_annotates_cost_and_risk_knob_units() {
|
||||
let dir = temp_cwd("campaign-introspect-unwired-knob-units");
|
||||
write_doc(&dir, "bare.json", "{}");
|
||||
let (out, code) = run_code_in(&dir, &["campaign", "introspect", "--unwired", "bare.json"]);
|
||||
assert_eq!(code, Some(0), "stdout/stderr: {out}");
|
||||
let low = out.to_lowercase();
|
||||
|
||||
// constant.cost_per_trade — price units, not R (the order-of-magnitude trap).
|
||||
assert!(low.contains("cost_per_trade"), "the cost knob must still be named: {out}");
|
||||
assert!(
|
||||
low.contains("price units"),
|
||||
"cost_per_trade must be annotated as a PRICE-unit numerator (its misreading is a cost in R): {out}"
|
||||
);
|
||||
|
||||
// vol_slippage.slip_vol_mult — a multiplier on the per-cycle vol estimate.
|
||||
assert!(low.contains("slip_vol_mult"), "the vol-slippage knob must still be named: {out}");
|
||||
assert!(
|
||||
low.contains("multiplier on the per-cycle vol"),
|
||||
"slip_vol_mult must be annotated as a MULTIPLIER on the per-cycle vol estimate: {out}"
|
||||
);
|
||||
|
||||
// vol.length — smooths the estimator; it does NOT set the stop's timescale.
|
||||
assert!(
|
||||
low.contains("smooths"),
|
||||
"vol.length must be annotated as SMOOTHING the per-cycle vol estimator: {out}"
|
||||
);
|
||||
assert!(
|
||||
low.contains("does not set the stop's timescale"),
|
||||
"vol.length must state it does NOT set the stop's timescale (its exact misreading): {out}"
|
||||
);
|
||||
|
||||
// vol.k — scales the stop distance (the risk-unit lever).
|
||||
assert!(
|
||||
low.contains("scales the stop distance"),
|
||||
"vol.k must be annotated as SCALING the stop distance (the risk-unit lever): {out}"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn campaign_introspect_unwired_reports_the_spec_example_slots() {
|
||||
let dir = temp_cwd("campaign-introspect-unwired");
|
||||
|
||||
Reference in New Issue
Block a user