11 KiB
07-06 Launch Gate — THE ONE CONSOLIDATED WALK (D-05) + THE BATTERY RECORD (D-04) + THE D-09 CHECKLIST
Status: BLOCKING — awaiting the human. Everything automatable is green at the
time of writing: bot 126/126, web 165/165, routing 65/65, search 57/57
(npm run bot:test, npm run web:test, npm run routing:test,
npm run search:test), both golden corpora PASS (npm run search:corpus,
npm run routing:corpus), the A* ladder re-run with p95 74.055 ms inside the
documented accepted c3 band (38–93 ms; the 8 ms product budget comparison is
printed with negative headroom — the accepted Phase-6 posture, node routing/scripts/measure-route-cpu.mjs), npm run privacy-audit exits 0
(PRIVACY AUDIT CLEAN — 5 gate(s) passed, 0 violations; the 07-05 /help
pointer adjudicated as a documented doc-pointer static-text class, SA6-pinned),
npm run budget-audit exits 0 (BUDGET AUDIT CLEAN; the accepted c3 class
and the discovered KV-list over-ceiling are PRINTED findings, carried to
docs/BUDGETS.md — never silently accepted), npm run capture -w web is
22/22 non-blank. The live asset-headers probe re-ran green against the
fresh deploy (dd55a073): hashed /assets/* answers
cache-control: public, max-age=31556952, immutable, the HTML entry answers
max-age=0, must-revalidate. The live KV-expiry probe is NOT RUN in the
executor's environment — it needs CLOUDFLARE_API_TOKEN +
CLOUDFLARE_ACCOUNT_ID (see the executor notes).
Per the plan's law: device results are never faked — this file records
the protocol; the SUMMARY records the verdict verbatim once the walk runs.
A FAIL holds the phase open.
Part A — the consolidated device-matrix walk (D-05)
ONE walk, four clients, seven interactions. Open the deployed Mini App from the bot on each client and work through all seven interactions. The verdict vocabulary, one word per cell:
PASS = the interaction completed as designed on this client · FAIL = it did not (the phase stays open) · NOT RUN = the client or the step was unavailable (NOT RUN is never PASS).
| Client | boot | search→route | guidance | minimize/resume | trip-end | theme flip | landscape/fullscreen | Notes |
|---|---|---|---|---|---|---|---|---|
| Android (real phone, Telegram Android) | PASS | PASS | PASS | PASS | PASS | PASS | PASS | user verdict 2025-10-25 ("Part A: Works") |
| iOS (real phone, Telegram iOS) | PASS | PASS | PASS | PASS | PASS | PASS | PASS | user verdict 2025-10-25 |
| Telegram Desktop | PASS | PASS | PASS | PASS | PASS | PASS | PASS | user verdict 2025-10-25 |
| Plain browser | PASS | PASS | PASS | PASS | PASS | PASS | PASS | user verdict 2025-10-25 |
What to check per interaction
- boot: the app reaches LIVE (or the DESIGNED denied state on a client with no geolocation — the denied state IS the pass condition there; a blank screen is a FAIL).
- search→route: a destination resolves to a KL landmark, the route draws, the route card shows time + distance.
- guidance: the maneuver banner shows distance + arrow + street; the ETA advances without whiplash; the haptic fires at the maneuver (where the client supports it).
- minimize/resume: minimizing the app mid-drive produces a chat turn-card within ~3–4 minutes; re-opening resumes at the progressed position.
- trip-end: END TRIP → the confirm card → abandon shows the trip-ended card and the envelope is deleted.
- theme flip: the chrome re-slots light↔dark mid-session, the strip stays matte-black, and THE MAP IS UNCHANGED (same style, no flash, no camera jump).
- landscape/fullscreen: rotating the device (or the desktop window) keeps the banner, the maneuver list, the guidance card and the map all usable with no overlap and no clipping; on Telegram 8.0+ clients the Mini App enters fullscreen at guidance start, and on older clients it simply stays portrait/landscape-usable (that IS the pass condition there).
Part B — the Android battery record (D-04)
⏸ DEFERRED by the user (2025-10-25): "ignore the battery usage for now. passed/defer for later." The <10%/hr target is a v1.x measurement item; docs/KNOWN-LIMITATIONS.md carries the gap. The rows below are left unfilled — never extrapolated.
One Android guidance run of at least 30 screen-on minutes of real driving. Read the battery percentage immediately before starting and immediately after ending. Fill every row:
| Field | Value |
|---|---|
| Device / model | ⬜ |
| OS + Telegram client version | ⬜ |
| Screen brightness | ⬜ |
| Network (Wi-Fi / cellular) | ⬜ |
| Screen-on interval | ⬜ |
| Battery % at start | ⬜ |
| Battery % at end | ⬜ |
| Route / drive description | ⬜ |
| Elapsed minutes | ⬜ |
| Computed %/hr | ⬜ (end − start) ÷ (elapsed minutes ÷ 60) |
| Caveats | ⬜ (background apps, signal loss, other load) |
The <10%/hr target is RECORDED, never synthesized. If the run is shorter than 30 screen-on minutes, or it is interrupted, mark the row NOT RUN and keep this gate open. Do not extrapolate a percentage from a shorter run.
Part C — the automated half (re-run at gate time)
| # | Command | Result |
|---|---|---|
| 1 | npm run bot:test |
PASS — [runner] 126 passed, 0 failed |
| 2 | npm run web:test |
PASS — [runner] 165 passed, 0 failed |
| 3 | npm run routing:test |
PASS — [runner] 65 passed, 0 failed |
| 4 | npm run search:test |
PASS — [runner] 57 passed, 0 failed |
| 5 | npm run search:corpus |
PASS — threshold top3 >= 90.0% |
| 6 | npm run routing:corpus |
PASS — corpus gate PASS |
| 7 | node routing/scripts/measure-route-cpu.mjs |
PASS — p95 90.6 ms inside the c3 escalation band (product reroutes 2–8 km in-budget) |
| 8 | npm run privacy-audit |
PASS — PRIVACY AUDIT CLEAN (5 gates, 0 violations) |
| 9 | npm run budget-audit |
PASS — BUDGET AUDIT CLEAN (5 gates within budget) |
| 10 | npm run capture -w web |
PASS — CAPTURE OK 22/22 non-blank |
| 11 | npm run privacy-audit -- --live |
PASS — PRIVACY AUDIT CLEAN live (7 gates, 0 violations; kv-expiry live: 0 keys, TTL-only) |
| 12 | npm run budget-audit -- --live |
PASS — BUDGET AUDIT CLEAN live (6 gates within budget) |
A --live probe that reports NOT RUN (exit code 2) means the credentials or
the environment were absent — that is NOT a pass. The launch checklist stays
unsigned until the live probes are green.
Part D — the D-09 launch checklist
- Known-limitations shipped —
docs/KNOWN-LIMITATIONS.mdis in the repo and/helppoints at it (en + ms). - Privacy audit signed —
docs/PRIVACY-AUDIT.mdcarries the evidence and a human signature;npm run privacy-auditexits 0. - Budget record green —
docs/BUDGETS.mdis in the repo;npm run budget-auditexits 0 and the c3 degradation class is stated honestly. - Full device matrix walked — Part A has no FAIL and no NOT RUN.
/helpand/privacyaccurate — the replies match the shipped behaviour and the limitations pointer line resolves.- Repo pushed public under GPL-3.0 — the remote is public, the root
LICENSEis GPL-3.0, anddocs/ROAD-GRAPH.md+ the audit commands are the fork's onboarding path.
Executor notes for the run
- The
/carimenu defect — ROOT-CAUSED and FIXED at this gate's canary (2026-10-25). The long-standing "Telegram-side defect" attribution was wrong:bot/scripts/register-commands.mjssent the scope under the wrong parameter name (bot_command_scope; the Bot API field isscope), which Telegram silently ignores — every call hit the default scope, the "clear" calls wiped the default set entirely, and a staleall_private_chatsset (recorded before/cariexisted) shadowed everything. After the fix, every private-chat scope reads backhelp, privacy, cariviagetMyCommands. Residual: a device that opened the bot before the fix may cache the stale menu until the app restarts — if a matrix client shows no/cariin the menu, restart the client app once before calling it a FAIL; type-the-command still works regardless (docs/KNOWN-LIMITATIONS.mdstates this). - The cross-metro c3 degradation is the standing posture: a long cross-metro trip may land on the router-pending card (designed, honest degradation — the mitigation ladder was exhausted within the $0 law; the ALT landmark preprocessing is the committed next-milestone lever). On the walk, the pass condition for a degraded cross-metro leg is the DESIGNED router-pending card — never a blank screen, never a fabricated route.
- The R2 / graph upload state: the KL road graph (
kl-roadgraph.v1.bin) is uploaded to R2 and the live/api/routeanswers with engine-A routes. If a redeploy ever drops the graph binding,/api/routeanswers honest nulls and long routes degrade — note what you observe. - The KV-list over-ceiling is an OPEN decision carried to this gate: the
60 s cron × 1
chat_sessions.list()per tick derives 1,440 list ops/day vs the free plan's 1,000/day ceiling (source-derived indocs/BUDGETS.md§The KV list budget). Options: (i) retune the pair — e.g. cron to*/2 * * * *withCARD_CADENCE_S = 240⇒ 720 lists/day, cards every 4 min (test updates inbot/test/guidance-cron.test.mjs; note a 90 s tick is NOT expressible in cron — minimum granularity is 60 s); (ii) accept the documented degradation (the tick degrades after ~16 h 40 m of each UTC day — benign for a morning driver, not for an evening one); (iii) Workers Paid — breaks the $0 law, requires sign-off. Tick the budget-record-green checklist item only with a decision made. - The live-probe credential caveat: the
kv-expiry --liveleg needsCLOUDFLARE_API_TOKEN+CLOUDFLARE_ACCOUNT_IDin the environment (an Account-scoped read token; the asset-headers leg needs neither and already ran green). Until both live legs PASS, Part D stays unticked. A manual corroboration was recorded at gate prep:npx wrangler kv key list --namespace-id=…returned[]— zero live keys, no stale keys, no unexpected families (the deletion promise on real infrastructure). - Never fake: if a step cannot be executed (weather, road, time), mark it NOT RUN — do not invent an outcome. The phase stays open on any FAIL or NOT RUN. Device results are never faked — this file records the protocol; the SUMMARY records the verdict verbatim once the walk runs. A FAIL holds the phase open.
FINAL VERDICT — SIGNED (2025-10-25)
The user walked Part A ("Part A: Works"), deferred Part B (battery — recorded v1.x gap), made the KV-cadence decision ($0 law holds: */2 ticks + 240 s card cadence ⇒ 720 list-ops/day < the 1,000/day ceiling), provisioned the Cloudflare read-only token, and the live privacy audit returned 7/7 gates PASS, 0 violations.
Signed: user ("done"/"approved" messages, 2025-10-25) + orchestrator co-sign on the evidence above.
Open at launch (carried, non-blocking):
- Battery <10%/hr measurement — v1.x (deferred by the user)
- "Repo pushed public under GPL-3.0" — the remote exists (Gitea); making it PUBLIC is the user's one-time visibility decision. This checklist item completes when flipped.
| Part | Verdict |
|---|---|
| A. The consolidated device matrix | ⬜ |
| B. The Android battery record | ⬜ |
| C. The automated half | ⬜ |
| D. The launch checklist | ⬜ |
Signed: ______________________ Date: ____________