Surfaced while reviewing #192, but this is a pre-existing gap in the unmigrated execution path, not that PR's defect.
keel/cli.py:1172 _interactive_confirm takes a raw dict and knows nothing about the port's Preview type. It therefore has nowhere to render Preview.synthetic.
Preview's own docstring is explicit about why that matters:
synthetic=True means these numbers are an estimate the adapter computed, not a quote the broker returned. Anything rendering a Preview must surface that distinction: approving an estimate must never look identical to approving a broker's own quote.
Today this is latent: the only venue on the live path is Coinbase, which has a native preview endpoint (supports_native_preview=True, synthetic=False), so nothing synthetic reaches a human. It becomes real for any venue that synthesizes previews — Robinhood is the first (synthesizes_preview=True, every Preview carries synthetic=True), and its estimates come from estimated_price with no venue-side quote behind them.
Compounding it: the Robinhood adapter currently returns Decimal("0") with errors=() when pricing fails, so an unpriceable order can present as a $0.00 order with no error attached (tracked in the review-findings issue). A confirm gate that can show neither the synthetic flag nor an error has nothing left to warn with.
Fix direction: migrate _interactive_confirm to accept the Preview domain type as part of the port migration, and render the synthetic/native distinction prominently rather than as a footnote.
Surfaced while reviewing #192, but this is a pre-existing gap in the unmigrated execution path, not that PR's defect.
keel/cli.py:1172 _interactive_confirmtakes a rawdictand knows nothing about the port'sPreviewtype. It therefore has nowhere to renderPreview.synthetic.Preview's own docstring is explicit about why that matters:Today this is latent: the only venue on the live path is Coinbase, which has a native preview endpoint (
supports_native_preview=True,synthetic=False), so nothing synthetic reaches a human. It becomes real for any venue that synthesizes previews — Robinhood is the first (synthesizes_preview=True, everyPreviewcarriessynthetic=True), and its estimates come fromestimated_pricewith no venue-side quote behind them.Compounding it: the Robinhood adapter currently returns
Decimal("0")witherrors=()when pricing fails, so an unpriceable order can present as a $0.00 order with no error attached (tracked in the review-findings issue). A confirm gate that can show neither the synthetic flag nor an error has nothing left to warn with.Fix direction: migrate
_interactive_confirmto accept thePreviewdomain type as part of the port migration, and render the synthetic/native distinction prominently rather than as a footnote.