You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The Tier-1 state badge on _render_preview_header is rendered from a Python-time string (applied_state_label / applied_state_variant) which is baked into the Prefab tree at build time. On the in-place preview→Confirm morph path, the header badge ALWAYS reads APPLIED (default/green variant) — even when the apply outcome is PARTIAL FAILURE or FAILED.
The on_success SetState chain in build_so_modify_ui (and similarly in build_po_modify_ui) already seeds state.applied_outcome_label / state.applied_outcome_variant slots, but nothing binds them to the header Badge. The per-field ✗ glyphs and the state-driven sub-entity failed-action Alert provide partial signals, but the prominent Tier-1 badge stays frozen at success chrome.
The standalone-applied path (when the apply response is rendered directly, is_preview=False) already handles this correctly — applied_state_label / applied_state_variant are overwritten with the actual outcome bucket before tree construction. The gap is specifically the in-place morph path.
Convert _render_preview_header to emit two parallel Badge branches keyed off state.applied_outcome_label, mirroring the BOM card. Cleanest factoring is probably a helper that takes the state-slot names and renders the If/Elif/Else fork once.
Because the rendered tree shape changes for every consumer of _render_preview_header, this is a cross-card sweep, not a single-card fix. Splitting it into its own PR keeps #858 + #722 reviewable as the per-card landing for SO/PO and lets the badge-morph land as one focused diff.
Problem
The Tier-1 state badge on
_render_preview_headeris rendered from a Python-time string (applied_state_label/applied_state_variant) which is baked into the Prefab tree at build time. On the in-place preview→Confirm morph path, the header badge ALWAYS readsAPPLIED(default/green variant) — even when the apply outcome isPARTIAL FAILUREorFAILED.The on_success SetState chain in
build_so_modify_ui(and similarly inbuild_po_modify_ui) already seedsstate.applied_outcome_label/state.applied_outcome_variantslots, but nothing binds them to the header Badge. The per-field✗glyphs and the state-driven sub-entity failed-action Alert provide partial signals, but the prominent Tier-1 badge stays frozen at success chrome.The standalone-applied path (when the apply response is rendered directly,
is_preview=False) already handles this correctly —applied_state_label/applied_state_variantare overwritten with the actual outcome bucket before tree construction. The gap is specifically the in-place morph path.Where this manifests
APPLIEDwhile the sub-entity Alert says "1 sub-entity failure(s)".Badgebranches gated onIf(Rx("applied_outcome_label") == "PARTIAL FAILURE"). The fix pattern is established.Fix shape
Convert
_render_preview_headerto emit two parallel Badge branches keyed offstate.applied_outcome_label, mirroring the BOM card. Cleanest factoring is probably a helper that takes the state-slot names and renders the If/Elif/Else fork once.Because the rendered tree shape changes for every consumer of
_render_preview_header, this is a cross-card sweep, not a single-card fix. Splitting it into its own PR keeps #858 + #722 reviewable as the per-card landing for SO/PO and lets the badge-morph land as one focused diff.Acceptance criteria
PARTIAL FAILURE/destructive.Refs
Priority + Workstream
P2-soon (visible UX bug but not a workflow break — the sub-entity Alert + per-action
✗glyphs still surface the failure), Cards workstream.