fix(06): revise plans per checker feedback — D-12 street-bearing cards by default, split 06-05 task 2, dep/wording/doc fixes
This commit is contained in:
@@ -167,12 +167,11 @@ Output: glyphs + 5 builders + 2 guard modules + webapp contract members + string
|
||||
</task>
|
||||
|
||||
<task type="auto" tdd="true">
|
||||
<name>task 2: Banner + list + guidance/confirm/trip-end card builders + shell.css</name>
|
||||
<files>web/src/guidance/banner.ts, web/src/shell.css, web/test/guidance-surface.test.mjs</files>
|
||||
<name>task 2: Banner + maneuver-list builders + gantry blink</name>
|
||||
<files>web/src/guidance/banner.ts, web/test/guidance-surface.test.mjs</files>
|
||||
<read_first>
|
||||
- web/src/route/route-card.ts (THE builder law: actions interface first, createElement+textContent only, aria on interactive groups, instrument formats composed in code)
|
||||
- web/src/ui/strip.ts + the strip section of web/src/shell.css (what [data-guidance="active"] compacts — layout only, strip.ts logic untouched)
|
||||
- .planning/phases/06-turn-by-turn-guidance-live-driving/06-UI-SPEC.md sections: Shell Layout, Maneuver Banner, Maneuver List, Guidance Card, Abandon-Route Confirm Card, Trip-Ended Card, State Coexistence
|
||||
- .planning/phases/06-turn-by-turn-guidance-live-driving/06-UI-SPEC.md sections: Maneuver Banner, Maneuver List, State Coexistence (the banner's four registers + calm-state slot swaps)
|
||||
- web/test/route-surface.test.mjs RS5/RS9 (the structural-gate style guidance-surface mirrors)
|
||||
</read_first>
|
||||
<behavior>
|
||||
@@ -180,6 +179,36 @@ Output: glyphs + 5 builders + 2 guard modules + webapp contract members + string
|
||||
- the banner root is a <button> (full-width, the list toggle) with aria-controls → the list panel's id
|
||||
- buildManeuverList: card panel (max-width 320px, role="region", aria-label=ariaManeuverList) + transparent tap-out layer; rows in trip order with glyph 24×24 + street + right-aligned distance; NEXT row = orange glyph + 8×8 orange lamp; FUTURE = matte-black glyph; PAST = outline ink glyph + outline text; rows are real text, glyphs aria-hidden
|
||||
- startGantryBlink(el)/stopGantryBlink(el): JS-timed two-state toggle ~500 ms (the boot-card precedent — an indicator duty cycle, never CSS animation)
|
||||
- structural: zero inline copy in the built surface (RS9-analog scan); the svgHost innerHTML whitelist is the ONLY sanctioned site
|
||||
</behavior>
|
||||
<action>
|
||||
1. `web/src/guidance/banner.ts` — create the module with the banner-surface exports, each `(locale, view, actions) => HTMLElement` with a view interface per the behavior list (copy route-card.ts's actions-interface-first structure):
|
||||
- `buildGuidanceBanner(locale, view: { state: GuidanceState; glyph: GlyphKind; distanceM: number | null; street: string | null; listOpen: boolean }, actions: { onToggle(): void })`
|
||||
- `buildManeuverList(locale, rows: Array<{ kind: GlyphKind; street: string; distanceM: number; rowState: "next" | "future" | "past" }>, actions: { onDismiss(): void })` (the tap-out layer dismisses)
|
||||
- `startGantryBlink(el: HTMLElement): void` / `stopGantryBlink(el: HTMLElement): void` (setInterval 500 ms toggling a data attribute; one interval per element, stop clears)
|
||||
All copy via `strings[locale]`; registers composed in code (`\`${strings[locale].guideRegister} // NEXT\`` style instrument constants); formats via a local `fillTemplate`-style composer (route-card precedent).
|
||||
2. RED→GREEN `web/test/guidance-surface.test.mjs` (the RS style: Node-24 dynamic .ts imports, minimal document fake — reuse the route-surface DOM-stub approach): behavioral tests per the behavior list (five-slot-every-state banner, list row states, gantry blink start/stop, banner/list aria) + structural gates — innerHTML ban with the svgHost whitelist (exactly one sanctioned site), inline-copy ban (RS9-analog grep of banner.ts for English/Malay literals outside strings imports — allowed: the instrument register words NEXT/REROUTING/RESUMING/NO REROUTE/CONFIRM/END and unit formats).
|
||||
</action>
|
||||
<verify>
|
||||
<automated>npm test -w web</automated>
|
||||
</verify>
|
||||
<acceptance_criteria>
|
||||
- guidance-surface.test.mjs green with: five-slot-every-state banner test, list row-states test, gantry blink start/stop test, aria assertions (banner button aria-expanded/controls, list region label)
|
||||
- structural: banner.ts innerHTML appears ONLY in svgHost against GLYPHS[kind]
|
||||
- typecheck clean
|
||||
</acceptance_criteria>
|
||||
<done>The banner and list render: five-slot discipline with the calm REROUTING/RESUMING/NO REROUTE states and the honest collapsible list — Node-tested DOM with the single sanctioned innerHTML site</done>
|
||||
</task>
|
||||
|
||||
<task type="auto" tdd="true">
|
||||
<name>task 3: Guidance/confirm/trip-end card builders + shell.css guidance block</name>
|
||||
<files>web/src/guidance/banner.ts, web/src/shell.css, web/test/guidance-surface.test.mjs</files>
|
||||
<read_first>
|
||||
- web/src/guidance/banner.ts (task 2's module — the card builders APPEND to it; banner/list builders untouched)
|
||||
- web/src/ui/strip.ts + the strip section of web/src/shell.css (what [data-guidance="active"] compacts — layout only, strip.ts logic untouched)
|
||||
- .planning/phases/06-turn-by-turn-guidance-live-driving/06-UI-SPEC.md sections: Shell Layout, Guidance Card, Abandon-Route Confirm Card, Trip-Ended Card
|
||||
</read_first>
|
||||
<behavior>
|
||||
- buildGuidanceCard: GUIDE register, destination headline, telemetry row (minutes telemetry-num + MIN + {km} KM + ETA HH:MM), 4px progress bar (role="progressbar", aria-valuemin 0 / max 100 / now pct, aria-label ariaTripProgress), state line ONLY in no_reroute (guideNoRerouteBody), actions = ONE .btn-secondary END TRIP — no .btn-primary anywhere in guidance chrome except the confirm card
|
||||
- buildConfirmCard: GUIDE // CONFIRM + exact en/ms headline/body + .btn-primary "YES, ABANDON" + .btn-secondary "CONTINUE"; bottom register placement class
|
||||
- buildTripEndCard: GUIDE // END + exact headline/body, no actions
|
||||
@@ -187,30 +216,28 @@ Output: glyphs + 5 builders + 2 guard modules + webapp contract members + string
|
||||
- structural: zero "transition"/"animation" CSS in the new shell.css block; zero hex literals (token vars only); zero border-radius; zero box-shadow
|
||||
</behavior>
|
||||
<action>
|
||||
1. `web/src/guidance/banner.ts` — five exported builders, each `(locale, view, actions) => HTMLElement` with a view interface per the behavior list (copy route-card.ts's actions-interface-first structure):
|
||||
- `buildGuidanceBanner(locale, view: { state: GuidanceState; glyph: GlyphKind; distanceM: number | null; street: string | null; listOpen: boolean }, actions: { onToggle(): void })`
|
||||
- `buildManeuverList(locale, rows: Array<{ kind: GlyphKind; street: string; distanceM: number; rowState: "next" | "future" | "past" }>, actions: { onDismiss(): void })` (the tap-out layer dismisses)
|
||||
- `startGantryBlink(el: HTMLElement): void` / `stopGantryBlink(el: HTMLElement): void` (setInterval 500 ms toggling a data attribute; one interval per element, stop clears)
|
||||
1. `web/src/guidance/banner.ts` — APPEND the three card builders (signatures per the behavior list; route-card.ts actions-interface-first law):
|
||||
- `buildGuidanceCard(locale, view: { destinationName: string; minutesRemaining: number; kmRemaining: number; etaClock: string; progressPct: number; showNoReroute: boolean }, actions: { onEndTrip(): void })`
|
||||
- `buildConfirmCard(locale, actions: { onAbandon(): void; onContinue(): void })` and `buildTripEndCard(locale): HTMLElement`
|
||||
All copy via `strings[locale]`; registers composed in code (`\`${strings[locale].guideRegister} // NEXT\`` style instrument constants); formats via a local `fillTemplate`-style composer (route-card precedent).
|
||||
All copy via `strings[locale]`; registers composed in code; instrument formats via the fillTemplate-style composer from task 2.
|
||||
2. `web/src/shell.css` — append the guidance block, token vars ONLY: banner band (matte-black chassis, min-height 96px, padding space-sm space-md, full-bleed, below safe-top + space-sm), 1px chassis-subtle banner→strip separator, `[data-guidance="active"]` strip compaction (min-height 24px, padding-block space-xs, telemetry cluster display:none — layout only), list panel + row anatomy + separators + lamp, guidance-card telemetry row + 4px progress bar (chassis-subtle track, 1px matte-black border, signal-orange fill, width set by inline style from the pct), ink colors per the hierarchy (register chassis-subtle, street soft-beige, distance pure-white). NO transition/animation/box-shadow/border-radius/hex anywhere in the block.
|
||||
3. RED→GREEN `web/test/guidance-surface.test.mjs` (the RS style: Node-24 dynamic .ts imports, minimal document fake — reuse the route-surface DOM-stub approach): behavioral tests per the behavior list + structural gates — innerHTML ban with the svgHost whitelist (exactly one sanctioned site), inline-copy ban (RS9-analog grep of banner.ts for English/Malay literals outside strings imports — allowed: the instrument register words NEXT/REROUTING/RESUMING/NO REROUTE/CONFIRM/END and unit formats), CSS block scan (no transition|animation|box-shadow|border-radius|#[0-9a-f]{3,6} in the appended guidance section), aria assertions (banner button aria-expanded/controls, list region label, progressbar valueattrs).
|
||||
3. RED→GREEN: extend `web/test/guidance-surface.test.mjs` with the card tests (confirm/trip-end copy asserting the exact strings-module keys, END TRIP is btn-secondary and the only card action, progressbar aria) + the CSS block scan (no transition|animation|box-shadow|border-radius|#[0-9a-f]{3,6} in the appended guidance section) + the strip.ts-untouched structural check.
|
||||
</action>
|
||||
<verify>
|
||||
<automated>npm test -w web</automated>
|
||||
</verify>
|
||||
<acceptance_criteria>
|
||||
- guidance-surface.test.mjs green with: five-slot-every-state banner test, list row-states test, gantry blink start/stop test, confirm/trip-end copy tests asserting the exact strings-module keys, END TRIP is btn-secondary and the only card action, progressbar aria assertions
|
||||
- structural: banner.ts innerHTML appears ONLY in svgHost against GLYPHS[kind]; grep "btn-primary" in banner.ts matches ONLY the confirm card builder
|
||||
- guidance-surface.test.mjs green with: confirm/trip-end copy tests asserting the exact strings-module keys, END TRIP is btn-secondary and the only card action, progressbar aria valueattrs
|
||||
- structural: grep "btn-primary" in banner.ts matches ONLY the confirm card builder
|
||||
- shell.css guidance block: grep `transition|animation|box-shadow|border-radius` → 0 matches in the appended section; grep `#[0-9a-fA-F]{3,6}` → 0 matches (token vars only)
|
||||
- strip.ts untouched (grep confirms no changes; compaction is pure CSS under [data-guidance="active"])
|
||||
- typecheck clean
|
||||
</acceptance_criteria>
|
||||
<done>The cockpit renders: banner five-slot discipline with calm states, honest collapsible list, evolved guidance card with progress instrument, guarded confirm surface, and trip-end card — all token-pure and Node-tested</done>
|
||||
<done>The cockpit's instruments complete: evolved guidance card with progress bar, guarded confirm surface, trip-end card, and the token-pure shell.css block that dresses the whole cockpit</done>
|
||||
</task>
|
||||
|
||||
<task type="auto" tdd="true">
|
||||
<name>task 3: Capability guards — haptics + close protection + webapp members + gate bumps</name>
|
||||
<name>task 4: Capability guards — haptics + close protection + webapp members + gate bumps</name>
|
||||
<files>web/src/guidance/haptics.ts, web/src/guidance/close-protection.ts, web/src/telegram/webapp.ts, web/test/guidance-surface.test.mjs, web/test/route-surface.test.mjs, web/test/build-artifact.test.mjs</files>
|
||||
<read_first>
|
||||
- web/src/telegram/webapp.ts lines 31–65 (the contract: optional members only — grow it, never break existing fakes)
|
||||
|
||||
Reference in New Issue
Block a user