28 KiB
phase, plan, type, wave, depends_on, files_modified, autonomous, requirements, must_haves
| phase | plan | type | wave | depends_on | files_modified | autonomous | requirements | must_haves | ||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 07-hardening-private-launch | 06 | execute | 3 |
|
|
false |
|
|
Purpose: D-05 — the QA pass is ONE walk (four clients × seven interactions),
not four separate sessions. D-04 — the battery target is a RECORDED real
measurement, never synthesized. D-09 — the private launch IS the checklist
being signed; the launch act itself is the user's. This plan produces the
gate FILE (the protocol + the record) and then blocks for the human.
Output: .planning/phases/07-hardening-private-launch/07-LAUNCH-GATE.md (new
— the protocol, the empty result tables, and the signature block) and, after
the human signs, the .planning/STATE.md milestone completion record.
<execution_context> @$HOME/.config/opencode/get-shit-done/workflows/execute-plan.md @$HOME/.config/opencode/get-shit-done/templates/summary.md </execution_context>
@.planning/PROJECT.md @.planning/ROADMAP.md @.planning/STATE.md @.planning/phases/07-hardening-private-launch/07-CONTEXT.md @.planning/phases/07-hardening-private-launch/07-RESEARCH.md @.planning/phases/07-hardening-private-launch/07-PATTERNS.md The gate-file structure to copy — `.planning/phases/06-turn-by-turn-guidance-live-driving/06-DEVICE-GATE.md` (its blocking header at lines 3–8, its part tables at lines 32–43, its executor notes at lines 59–68, and its FINAL VERDICT section at lines 72–82):**Status: BLOCKING — awaiting the human.** Everything automatable is green: …
Per the plan's law: **device results are never faked** — this file records the
protocol; the SUMMARY records the verdict verbatim once the drive runs.
A FAIL holds the phase open.
| # | Step | Verify |
|---|------|--------|
## Executor notes for the run
- **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.
## FINAL VERDICT
| Part | Verdict |
|------|---------|
The battery record fields (from 07-RESEARCH.md §Pitfall 11 and D-04):
| Field | Requirement |
|---|---|
| Device / model | required |
| OS + Telegram client version | required |
| Screen brightness | required |
| Network (Wi-Fi / cellular) | required |
| Screen-on interval | ≥ 30 minutes |
| Battery % at start | required |
| Battery % at end | required |
| Route / drive description | required |
| Elapsed minutes | required |
| Computed %/hr | (end − start) / (elapsed minutes / 60) |
| Caveats | required (background apps, signal loss, other load) |
The seven interactions (D-05) — each leg is tested against every client:
- boot
- search → route
- guidance
- minimize / resume
- trip-end
- theme flip
- landscape / fullscreen
The D-09 launch checklist (six items):
- known-limitations shipped
- privacy audit signed
- budget record green
- full device matrix walked
/help+/privacyaccurate- repo pushed public under GPL-3.0
1. A blocking status header. Name what is already green at the time of
writing — the suite counts and the exact commands (npm run bot:test,
npm run web:test, npm run routing:test, npm run search:test,
npm run privacy-audit, npm run budget-audit, npm run capture -w web) —
and include the never-fake law VERBATIM in the file's own voice:
"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."
2. ## Part A — the consolidated device-matrix walk (D-05). A FOUR-CLIENT
× SEVEN-INTERACTION table. The four clients are: Android (real phone,
Telegram Android), iOS (real phone, Telegram iOS), Telegram Desktop, and a
plain browser. The seven interactions are: boot · search→route · guidance ·
minimize/resume · trip-end · theme flip · landscape/fullscreen. The table
shape is one row per CLIENT with a per-interaction verdict column set:
| Client | boot | search→route | guidance | minimize/resume | trip-end | theme flip | landscape/fullscreen | Notes |
| --- | --- | --- | --- | --- | --- | --- | --- | --- |
| Android (real phone, Telegram Android) | ⬜ | ⬜ | ⬜ | ⬜ | ⬜ | ⬜ | ⬜ | |
| iOS (real phone, Telegram iOS) | ⬜ | ⬜ | ⬜ | ⬜ | ⬜ | ⬜ | ⬜ | |
| Telegram Desktop | ⬜ | ⬜ | ⬜ | ⬜ | ⬜ | ⬜ | ⬜ | |
| Plain browser | ⬜ | ⬜ | ⬜ | ⬜ | ⬜ | ⬜ | ⬜ | |
The verdict vocabulary is PASS / FAIL / NOT RUN — one word per cell,
plus the free-text Notes column. Define the vocabulary right above the table:
"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)."
Add a ### What to check per interaction list — one short line per
interaction, stating the observable pass condition:
- 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).
3. ## Part B — the Android battery record (D-04). A table with the
field list from the interfaces section above, all values left as ⬜ EXCEPT
the rows that name a REQUIREMENT (device, OS, client version, brightness,
network, screen-on interval ≥ 30 min, start %, end %, route, elapsed minutes,
computed %/hr, caveats). Below the table, the honest rule, in the file's
voice: "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."
4. ## Part C — the automated half (re-run at gate time). A table of the
exact commands with a ⬜ result column, so the human can re-run them at
gate time and see the counts:
npm run bot:test · npm run web:test · npm run routing:test ·
npm run search:test · npm run search:corpus · npm run routing:corpus ·
node routing/scripts/measure-route-cpu.mjs · npm run privacy-audit ·
npm run budget-audit · npm run capture -w web ·
npm run privacy-audit -- --live · npm run budget-audit -- --live.
Note under the table: "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."
5. ## Part D — the D-09 launch checklist. Six checkbox rows, each with
the evidence that satisfies it:
- 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.
6. ## Executor notes for the run. The known-open items: the /cari
menu defect (type the command — the doc says so); the cross-metro c3
degradation (a long cross-metro trip may land on the router-pending card);
the R2 / graph upload state (if the graph is absent, /api/route answers
honest nulls and long routes degrade); the live-probe credential caveat; and
the never-fake rule.
7. ## FINAL VERDICT. A part-by-part table (| Part | Verdict | with
rows A, B, C, D), left EMPTY for the human to fill, followed by a dated
signature block:
---
## FINAL VERDICT — ⬜ NOT YET SIGNED
| Part | Verdict |
| --- | --- |
| A. The consolidated device matrix | ⬜ |
| B. The Android battery record | ⬜ |
| C. The automated half | ⬜ |
| D. The launch checklist | ⬜ |
**Signed:** ______________________ **Date:** ____________
Do NOT fill any verdict in this task — the file records the PROTOCOL. The
human fills the verdicts.
<acceptance_criteria>
- .planning/phases/07-hardening-private-launch/07-LAUNCH-GATE.md exists and contains the section headings ## Part A — the consolidated device-matrix walk (D-05), ## Part B — the Android battery record (D-04), ## Part C — the automated half (re-run at gate time), ## Part D — the D-09 launch checklist, ## Executor notes for the run, ## FINAL VERDICT
- grep -c "device results are never faked" .planning/phases/07-hardening-private-launch/07-LAUNCH-GATE.md returns ≥ 1
- grep -c "NOT RUN" .planning/phases/07-hardening-private-launch/07-LAUNCH-GATE.md returns ≥ 3 (the verdict vocabulary, the battery rule, and the executor note)
- grep -c "⬜" .planning/phases/07-hardening-private-launch/07-LAUNCH-GATE.md returns ≥ 20 (the empty result cells — nothing is pre-filled)
- grep -c "Known-limitations shipped" .planning/phases/07-hardening-private-launch/07-LAUNCH-GATE.md returns 1 and grep -c "Repo pushed public under GPL-3.0" .planning/phases/07-hardening-private-launch/07-LAUNCH-GATE.md returns 1 (the six D-09 checklist items)
- grep -c "SIGNED" .planning/phases/07-hardening-private-launch/07-LAUNCH-GATE.md returns ≥ 1 and the file contains NO filled verdict (no APPROVED string)
</acceptance_criteria>
export PATH="$HOME/.nvm/versions/node/v24.18.0/bin:$PATH"; cd /home/C-Fu/araharah && test -f .planning/phases/07-hardening-private-launch/07-LAUNCH-GATE.md && grep -c "⬜" .planning/phases/07-hardening-private-launch/07-LAUNCH-GATE.md && ! grep -q "APPROVED" .planning/phases/07-hardening-private-launch/07-LAUNCH-GATE.md && echo "gate file is an empty protocol"
The launch gate file exists with the full protocol — the 4×7 device
matrix, the battery record fields, the automated-half commands, the six
D-09 checklist items, and an unsigned FINAL VERDICT block.
What is left is exactly what no tool can produce: the physical walk and
the measured battery number.
```
npm run bot:test && npm run web:test && npm run routing:test && npm run search:test
npm run search:corpus && npm run routing:corpus
node routing/scripts/measure-route-cpu.mjs
npm run privacy-audit
npm run budget-audit
npm run capture -w web
npm run privacy-audit -- --live
npm run budget-audit -- --live
```
Every command must exit 0. A `--live` probe that prints `NOT RUN` and
exits 2 is NOT a pass — the credentials must be present.
**Part A — the ONE consolidated walk (D-05).** Open the deployed Mini App
from the bot on each of the four clients, and work through all seven
interactions on EACH client: boot · search→route · guidance ·
minimize/resume · trip-end · theme flip · landscape/fullscreen. Fill one
verdict word per cell in Part A of
`.planning/phases/07-hardening-private-launch/07-LAUNCH-GATE.md` — PASS,
FAIL, or NOT RUN — plus a note in the Notes column. The pass conditions
are listed in the file under "What to check per interaction"; read them
before starting. A NOT RUN cell (a device that was not available) keeps
the checklist unsigned — it is not a PASS.
**Part B — the battery run (D-04).** On the Android phone, start a
guidance run and keep the screen on for AT LEAST 30 MINUTES of real
driving (a real route, not a stationary app). Read the battery
percentage immediately before starting and immediately after ending, and
fill every field of Part B: device, OS, Telegram client version,
brightness, network, the screen-on interval, start %, end %, the route,
the elapsed minutes, the computed %/hr, and the caveats. If the run was
shorter than 30 minutes or was interrupted, mark it NOT RUN and leave the
gate open — do not extrapolate.
**Part C — the automated half table.** Fill the result column for each
command.
**Part D — the checklist.** Tick each of the six items only when its
evidence actually exists: the limitations doc is in the repo and `/help`
points at it; `docs/PRIVACY-AUDIT.md` is signed; `docs/BUDGETS.md` is
green and states the c3 class; Part A has no FAIL and no NOT RUN; `/help`
and `/privacy` read accurately against the shipped behaviour; and the
remote repository is public with the root `LICENSE` at GPL-3.0.
**The verdict.** Fill the FINAL VERDICT table (Parts A–D) and the
signature line with your name and the date.
**The launch itself is yours.** Once the checklist is signed, the
milestone completes — the workflow does NOT distribute the bot link. Give
it to your first KL drivers yourself.
In .planning/STATE.md:
- Update the frontmatter
status:tocompleteandstopped_at:to a sentence naming the signed launch gate (e.g.Phase 7 complete — the launch gate is signed (private beta checklist)). Updatelast_updated:andlast_activity:to today's date. - Update the
## Current Positionblock:Phase: 7→Phase: 7 (complete),Plan: Not started→Plan: Complete,Status: Ready to plan→Status: Launch gate signed. - Set the
Progress:bar to[░░░░░░░░░░] 100%. - In
## Accumulated Context→### Decisions, ADD a bullet recording the Phase-7 decisions that bind future work:- The private launch is a checklist-signed private beta; the launch act is the maintainer's.
- v1 carries ZERO telemetry — the audit proves an absence; opt-in telemetry is a post-validation milestone.
- The cross-metro CPU class (c3) is the standing degradation: cross-metro routes land on the router-pending card; the ALT landmark preprocessing is the committed next-milestone lever.
- In
### Blockers/Concerns, move the resolved entries into a short "RESOLVED 2026-10-25" note and REMOVE the stale open ones — in particular the/carimenu entry stays listed as a KNOWN Telegram-side defect (with the workaround), and the Phase-4 "legs UNVERIFIED" entry is replaced by the Phase-7 walk's recorded verdicts. - In
### Deferred Items, ADD the rows that Phase 7 committed to the v1.x milestone: ALT landmark preprocessing (c2), the WASM-router track, engine B (the fully client-side webview router), and opt-in telemetry — each with "Deferred to v1.x milestone" and "Deferred At: Phase 7 (2026-10-25)". - Update
## Session Continuity—Last session:andStopped at:andResume file:(point at the gate file, since it holds the signed record).
In .planning/ROADMAP.md:
- Mark the Phase 7 entry
- [ ]→- [x]and add(completed 2026-10-25). - Replace
**Plans:** TBDunder Phase 7 with**Plans:** 6 plans. - Fill the Phase 7 plan list with the six plan files and their one-line
objectives, marking them
[x]. - Update the
## Progresstable's Phase 7 row to6/6 | Complete | 2026-10-25. - Leave every other phase's rows untouched.
Do NOT rewrite the roadmap's success criteria, the goal, or any earlier
phase's text.
<acceptance_criteria>
- .planning/STATE.md frontmatter contains status: complete
- .planning/STATE.md contains the literal ZERO telemetry in the Decisions list
- .planning/STATE.md contains the literal ALT landmark preprocessing in the Deferred Items table
- .planning/ROADMAP.md contains **Plans:** 6 plans under Phase 7 and the phase line contains - [x] **Phase 7:
- .planning/ROADMAP.md's Phase 7 progress row contains 6/6
</acceptance_criteria>
export PATH="$HOME/.nvm/versions/node/v24.18.0/bin:$PATH"; cd /home/C-Fu/araharah && grep -c "status: complete" .planning/STATE.md && grep -c "**Plans:** 6 plans" .planning/ROADMAP.md && grep -c "6/6" .planning/ROADMAP.md
STATE.md records the completed milestone with the binding decisions and the
v1.x deferrals, and ROADMAP.md shows Phase 7 complete with its six plans.
<threat_model>
Trust Boundaries
| Boundary | Description |
|---|---|
| The human report → the milestone record | The launch gate's verdicts are human-supplied observations; they are the only evidence source for the physical properties. |
| The signed checklist → the public launch | Signing asserts the artifact set is honest and complete; a false signature is the worst failure mode in the phase. |
STRIDE Threat Register
| Threat ID | Category | Component | Disposition | Mitigation Plan |
|---|---|---|---|---|
| T-07-27 | Repudiation | 07-LAUNCH-GATE.md — a synthesized device verdict or battery number |
mitigate | Every cell starts as ⬜; the vocabulary is PASS/FAIL/NOT RUN with NOT RUN explicitly never counting as PASS; the never-fake law is stated verbatim in the file; the battery rule forbids extrapolating a shorter run; the task's own acceptance criteria assert the file contains NO pre-filled verdict (APPROVED absent). A synthesized result is structurally impossible to write by accident. |
| T-07-28 | Tampering | the checklist — signing before the evidence exists | mitigate | The six D-09 items each name their own evidence (the shipped doc, the signed audit record, the budget record, a matrix with no FAIL/NOT RUN, the accurate /help and /privacy replies, the public GPL-3.0 remote). The --live probes reporting NOT RUN (exit 2) explicitly keep the checklist unsigned. |
| T-07-29 | Information Disclosure | 07-LAUNCH-GATE.md — a device/OS/battery record leaking into a public repo |
accept | The gate file records a device model, an OS version, a battery percentage and a route description — no identity, no account, no coordinate, no credential. The repo is published public under GPL-3.0 by design (D-09), and this data class is intentionally disclosed for the battery method's reproducibility. |
| T-07-30 | Elevation of Privilege | the milestone completion — the workflow acting as the launch act | mitigate | Task 3 runs only after the checkpoint returns "signed"; the gate file states that the launch act itself is the maintainer's — the workflow produces the evidence and the checklist, never the distribution. STATE.md records the SIGNED checklist, not a distribution. |
| </threat_model> |
export PATH="$HOME/.nvm/versions/node/v24.18.0/bin:$PATH"
cd /home/C-Fu/araharah
npm run bot:test && npm run web:test && npm run routing:test && npm run search:test
npm run privacy-audit && npm run budget-audit
All must exit 0. The gate file's FINAL VERDICT must be filled and signed, and
.planning/STATE.md must read status: complete.
<success_criteria>
07-LAUNCH-GATE.mdexists as a complete, unsigned protocol: a 4×7 device matrix, the battery record fields, the automated-half command list, the six D-09 checklist items, the executor notes, and an empty FINAL VERDICT.- The blocking checkpoint was walked by the human; every matrix cell carries a PASS/FAIL/NOT RUN verdict and the battery run is a recorded ≥30-minute real measurement.
- The six checklist items are each backed by their named evidence, and the FINAL VERDICT is signed with a name and a date.
STATE.mdrecords the milestone completion with the binding decisions and the v1.x deferrals;ROADMAP.mdshows Phase 7 complete with six plans. </success_criteria>