fix(06-08): the D-09 confirm card survives a live fix — renderCockpit guards the card rebuild
- a fix arriving while the abandon confirm is open rebuilt the guidance card over it (the ONE PX-03 exit guard evaporating mid-decision); the pump now re-renders banner/list only and the confirm surface survives until CONTINUE or YES, ABANDON - G7b pins it: confirm mounts -> live fix -> confirm still shown, guidancePhase=confirm holds, YES ABANDON still tears down - found while building 06-08's scripted END TRIP capture leg; the real drive's step 6 (END TRIP on a live road) would have hit this within one watch fix
This commit is contained in:
@@ -372,6 +372,11 @@ export function createRouteController(deps: RouteControllerDeps): {
|
||||
}
|
||||
}
|
||||
const eta = g.eta ?? updateEta(null, 0, g.snap.remainingM);
|
||||
// G7b: while the D-09 confirm card owns the bottom register, the pump's
|
||||
// per-fix re-render must never rebuild the guidance card over it — the
|
||||
// confirm is the ONE exit guard (PX-03); a live fix re-renders the
|
||||
// banner/list but the confirm surface survives until CONTINUE/abandon.
|
||||
if (!g.confirmOpen) {
|
||||
deps.showRouteCard(
|
||||
buildGuidanceCard(
|
||||
deps.locale,
|
||||
@@ -386,6 +391,7 @@ export function createRouteController(deps: RouteControllerDeps): {
|
||||
"bottom",
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function toggleList(): void {
|
||||
const g = guidance;
|
||||
|
||||
@@ -1307,6 +1307,29 @@ test("G7 END TRIP → confirm → YES ABANDON teardown; CONTINUE dismisses with
|
||||
});
|
||||
});
|
||||
|
||||
test("G7b the confirm card survives a live fix — the D-09 surface never evicts mid-decision", async () => {
|
||||
await withDocumentAsync(async () => {
|
||||
const deps = steppedDeps();
|
||||
const controller = createRouteController(deps);
|
||||
await driveTo(deps, controller);
|
||||
findByClass(deps.__recorded.shown.at(-1).card, "btn-secondary").click(); // END TRIP
|
||||
assert.ok(findByClass(deps.__recorded.shown.at(-1).card, "guide-confirm") !== null, "the confirm surface mounts");
|
||||
// a live fix arrives while the driver is deciding — the confirm card is
|
||||
// the ONE exit guard; a pump re-render must never replace it
|
||||
feed(1200, { deps, advanceMs: 2500 });
|
||||
await drain();
|
||||
const shown = deps.__recorded.shown.at(-1);
|
||||
assert.ok(
|
||||
findByClass(shown.card, "guide-confirm") !== null,
|
||||
`the confirm card must survive the fix (register=${shown.register}, got ${findByClass(shown.card, "guide-confirm") === null ? "the guidance card back" : "the confirm card"})`,
|
||||
);
|
||||
assert.equal(controller.guidancePhase, "confirm", "the confirm phase holds across the fix");
|
||||
findByClass(shown.card, "btn-primary").click(); // YES, ABANDON — still reachable
|
||||
assert.equal(deps.__guide.watchStopped, 1, "the teardown still runs from the surviving card");
|
||||
assert.equal(controller.guidancePhase, "ended", "the trip ended through the guarded surface");
|
||||
});
|
||||
});
|
||||
|
||||
test("G8 arrival — the machine's arrival effect runs the same teardown", async () => {
|
||||
await withDocumentAsync(async () => {
|
||||
const deps = steppedDeps();
|
||||
|
||||
Reference in New Issue
Block a user