Status
Defect. Found while reviewing PR #644 (#546), reproduced on main@ad4289e. Same falsehood as #546, moved from first-time users to returning ones — which is why it only became visible once #546 routed returning users into that branch deliberately.
The observation
card_renderer._next_block's no-commitment branch resolves the rule text once, from this period's prescription, and uses it in both the pending and the standing wrapper:
standing = (localized_rule(state.get("rule_dim"), language,
cap=state.get("max_position_pct"))
if state.get("rule_dim") else None)
...
standing_key = "rule_standing" if prior_commitment.get("rule") else "rule_pending"
text = missing[standing_key].format(rule=standing)
rule_dim is actionable[0].get("dim") (trade_recap.py:2018) — the top scored problem this period. It has no input from prior_commitment. The two are independent by construction, so they diverge whenever the book's leading problem changes, which is the ordinary case across weeks.
Reproduced
Rendered directly, en, same prescription (position_sizing) in both, only the persisted commitment differing:
prior_commitment.rule = "Hold any new position at least 30 days before selling"
rendered = "No rule change this period; the standing rule remains:
\"Cap any single position at 20%. Trim if it goes over, and do not add.\""
The user committed to a holding-period rule. The card tells them their standing rule "remains" — and then names a concentration rule they never chose.
Why it matters
Both halves of the sentence are wrong at once, and they reinforce each other: "no rule change this period" says continuity, and the quoted rule is the evidence offered for it. A user reconciling against what they committed to last time reads a rule they did not write and has no way to tell whether the product forgot their answer or silently replaced it. This is the same class as #546 and the same class as #429's dead question — a sentence whose truth nobody checked because the surrounding block was about something else.
It is worse than #546 in one respect: a first-time user has no memory to contradict, so the false claim is merely confusing. A returning user has an actual commitment they can compare against, so the product visibly disagrees with its own record.
Not in #546's scope, deliberately
#546's acceptance says "Returning-user preview with a real prior commitment may use the standing-rule continuity copy", and its stop condition forbids widening. PR #644 is correct as merged; this is the next cut.
Decision needed before implementing — two readings, and they are different products
- The continuity line quotes the prior commitment.
standing comes from prior_commitment["rule"] when one exists. Truthful and simple, but the sentence then says "no rule change this period" while the engine may in fact be prescribing a different dimension — the card would stop surfacing that divergence at all.
- The line only fires when they agree, and a divergence gets its own honest wording (the engine now points somewhere else than your standing rule). More work, and it needs new copy in three locales, but it is the only reading where the block keeps saying something true and useful.
The prior_commitment payload carries rule, metric_key and metric_value (read at card_renderer.py:2325 for #292) — whether it carries a dim comparable to state["rule_dim"] needs checking before option 2 is costed.
Scope
- Whichever reading is chosen, the quoted rule and the continuity claim must agree with the record.
- Preview and finalized card both, and Markdown and HTML through the shared
_card_structure path.
en / zh-TW / zh-CN synchronized; replace sentences rather than adding, per the standing no-explanatory-Note ruling.
docs/output-contract.md's Block-4 row moves with it (mirrored surface).
Acceptance
Privacy
Fresh isolated roots and committed fictional personas only.
Related
#546 (the first-time-user half, merged as PR #644), #292 (the prior-commitment reconciliation path that already reads the correct predicate), #356 (an earlier defect in this same branch), #429 (a sentence nobody reads is a defect, not neutral).
Status
Defect. Found while reviewing PR #644 (#546), reproduced on
main@ad4289e. Same falsehood as #546, moved from first-time users to returning ones — which is why it only became visible once #546 routed returning users into that branch deliberately.The observation
card_renderer._next_block's no-commitment branch resolves the rule text once, from this period's prescription, and uses it in both the pending and the standing wrapper:rule_dimisactionable[0].get("dim")(trade_recap.py:2018) — the top scored problem this period. It has no input fromprior_commitment. The two are independent by construction, so they diverge whenever the book's leading problem changes, which is the ordinary case across weeks.Reproduced
Rendered directly,
en, same prescription (position_sizing) in both, only the persisted commitment differing:The user committed to a holding-period rule. The card tells them their standing rule "remains" — and then names a concentration rule they never chose.
Why it matters
Both halves of the sentence are wrong at once, and they reinforce each other: "no rule change this period" says continuity, and the quoted rule is the evidence offered for it. A user reconciling against what they committed to last time reads a rule they did not write and has no way to tell whether the product forgot their answer or silently replaced it. This is the same class as #546 and the same class as #429's dead question — a sentence whose truth nobody checked because the surrounding block was about something else.
It is worse than #546 in one respect: a first-time user has no memory to contradict, so the false claim is merely confusing. A returning user has an actual commitment they can compare against, so the product visibly disagrees with its own record.
Not in #546's scope, deliberately
#546's acceptance says "Returning-user preview with a real prior commitment may use the standing-rule continuity copy", and its stop condition forbids widening. PR #644 is correct as merged; this is the next cut.
Decision needed before implementing — two readings, and they are different products
standingcomes fromprior_commitment["rule"]when one exists. Truthful and simple, but the sentence then says "no rule change this period" while the engine may in fact be prescribing a different dimension — the card would stop surfacing that divergence at all.The
prior_commitmentpayload carriesrule,metric_keyandmetric_value(read atcard_renderer.py:2325for #292) — whether it carries adimcomparable tostate["rule_dim"]needs checking before option 2 is costed.Scope
_card_structurepath.en/zh-TW/zh-CNsynchronized; replace sentences rather than adding, per the standing no-explanatory-Note ruling.docs/output-contract.md's Block-4 row moves with it (mirrored surface).Acceptance
rule_pendingpath stays exactly as merged.python3 tests/run_all.pypasses.Privacy
Fresh isolated roots and committed fictional personas only.
Related
#546 (the first-time-user half, merged as PR #644), #292 (the prior-commitment reconciliation path that already reads the correct predicate), #356 (an earlier defect in this same branch), #429 (a sentence nobody reads is a defect, not neutral).