Files
arah2/.planning/phases/07-hardening-private-launch/07-06-PLAN.md

28 KiB
Raw Permalink Blame History

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
07-01
07-02
07-03
07-04
07-05
.planning/phases/07-hardening-private-launch/07-LAUNCH-GATE.md
.planning/STATE.md
false
PX-04
truths artifacts key_links
One consolidated walk covers Android, iOS, Telegram Desktop and a plain browser across seven interactions, and every leg carries a recorded PASS/FAIL/NOT RUN verdict — never a synthesized one.
The battery result is a RECORDED real measurement from one Android guidance run of at least 30 screen-on minutes — never extrapolated, never synthesized.
The launch checklist is signed only when every automated gate is green, the known-limitations doc is shipped, the privacy audit is signed, and the budget record is green.
The launch act itself is the user's — the workflow produces the evidence and the checklist, never the distribution.
path provides contains
.planning/phases/07-hardening-private-launch/07-LAUNCH-GATE.md The signed launch gate — the device matrix, the battery record, and the D-09 checklist FINAL VERDICT
path provides contains
.planning/STATE.md The milestone completion record (D-09 — the milestone completes when the checklist is signed) milestone
from to via pattern
.planning/phases/07-hardening-private-launch/07-LAUNCH-GATE.md .planning/phases/07-hardening-private-launch/07-03-PLAN.md the checklist's privacy-audit line references the signed record in docs/PRIVACY-AUDIT.md PRIVACY-AUDIT
from to via pattern
.planning/phases/07-hardening-private-launch/07-LAUNCH-GATE.md docs/KNOWN-LIMITATIONS.md the checklist's known-limitations line names the shipped doc KNOWN-LIMITATIONS
Close the phase honestly: one consolidated device-matrix walk, one recorded Android battery run, the D-09 launch checklist — and the milestone's completion record.

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:

  1. boot
  2. search → route
  3. guidance
  4. minimize / resume
  5. trip-end
  6. theme flip
  7. landscape / fullscreen

The D-09 launch checklist (six items):

  • known-limitations shipped
  • privacy audit signed
  • budget record green
  • full device matrix walked
  • /help + /privacy accurate
  • repo pushed public under GPL-3.0
task 1: write the launch gate file (the protocol, the empty result tables, the checklist, the signature block) .planning/phases/07-hardening-private-launch/07-LAUNCH-GATE.md - .planning/phases/06-turn-by-turn-guidance-live-driving/06-DEVICE-GATE.md (the WHOLE file is the structural template) - .planning/phases/03-mini-app-shell-geolocation/03-DEVICE-MATRIX.md (the six-leg table + the FINAL VERDICT table shape) - .planning/phases/07-hardening-private-launch/07-CONTEXT.md (D-04, D-05, D-09 verbatim) - .planning/phases/07-hardening-private-launch/07-RESEARCH.md §Pitfalls 11 and 12 Create `.planning/phases/07-hardening-private-launch/07-LAUNCH-GATE.md` (NEW — the whole file is new), copying `06-DEVICE-GATE.md`'s structure exactly. It MUST contain, in this order:

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.md is in the repo and /help points at it (en + ms).
  • Privacy audit signed — docs/PRIVACY-AUDIT.md carries the evidence and a human signature; npm run privacy-audit exits 0.
  • Budget record green — docs/BUDGETS.md is in the repo; npm run budget-audit exits 0 and the c3 degradation class is stated honestly.
  • Full device matrix walked — Part A has no FAIL and no NOT RUN.
  • /help and /privacy accurate — 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 LICENSE is GPL-3.0, and docs/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.

task 2: THE CONSOLIDATED WALK + THE BATTERY RUN (the blocking human gate) .planning/phases/07-hardening-private-launch/07-LAUNCH-GATE.md - .planning/phases/07-hardening-private-launch/07-LAUNCH-GATE.md (the protocol written in task 1 — the verdict vocabulary, the per-interaction pass conditions, the battery field list, and the six checklist items) - .planning/phases/06-turn-by-turn-guidance-live-driving/06-DEVICE-GATE.md (the never-fake protocol precedent) The human walks the four clients, runs the battery measurement, and fills the verdict tables IN PLACE in `07-LAUNCH-GATE.md`. No automated step replaces any of it. - `grep -c "⬜" .planning/phases/07-hardening-private-launch/07-LAUNCH-GATE.md` returns 0 (every verdict cell is filled — no cell is left blank) - `grep -c "NOT YET SIGNED" .planning/phases/07-hardening-private-launch/07-LAUNCH-GATE.md` returns 0 (the FINAL VERDICT header was updated to the signed verdict) - `grep -c "Signed:" .planning/phases/07-hardening-private-launch/07-LAUNCH-GATE.md` returns 1 and the signature line is NOT blank (a name is written) - `grep -c "Date:" .planning/phases/07-hardening-private-launch/07-LAUNCH-GATE.md` returns ≥ 1 and the date line is NOT blank - `grep -c "FAIL" .planning/phases/07-hardening-private-launch/07-LAUNCH-GATE.md` returns 0 in the FINAL VERDICT table OR the gate is reported as NOT SIGNED (a FAIL keeps the phase open — the file must not claim a signed state with a failing part) - the Part B table contains a start %, an end %, and an elapsed-minutes value (the battery record is measured, not blank) Everything automatable in Phase 7: the fullscreen capability layer and its 8.0 fallback (07-01), the landscape cockpit geometry and the failure-state matrix (07-02), the consolidated privacy audit and its signed record (07-03), the consolidated budget record and the static-asset cache policy (07-04), and the paid debts plus the known-limitations document (07-05). The launch gate file (07-06 task 1) holds the empty protocol: a 4×7 device matrix, the battery record fields, the automated-half command list, and the six D-09 checklist items.
What is left is exactly what no tool can produce: the physical walk and
the measured battery number.
**Part 0 — the automated half (re-run at gate time, ~2 minutes).** From the repo root:
```
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.
Type "signed" with the FINAL VERDICT filled (and paste the Part A matrix and the Part B battery numbers), or describe what failed / which legs were NOT RUN. On "signed", the executor writes the milestone completion record into `.planning/STATE.md`. On a FAIL or a NOT RUN, the phase stays open — open a `/gsd-debug` for the failing symptom and record the NOT RUN legs honestly. export PATH="$HOME/.nvm/versions/node/v24.18.0/bin:$PATH"; cd /home/C-Fu/araharah && grep -c "SIGNED" .planning/phases/07-hardening-private-launch/07-LAUNCH-GATE.md && ! grep -q "⬜ NOT YET SIGNED" .planning/phases/07-hardening-private-launch/07-LAUNCH-GATE.md && echo "the gate file is signed (the NOT YET SIGNED marker is gone)" Every Part A cell carries a PASS/FAIL/NOT RUN verdict with a note; Part B carries a real ≥30-minute Android battery measurement (or an explicit NOT RUN); Part C's command table is filled; Part D's six checklist items are each backed by their named evidence; and the FINAL VERDICT table is signed with a name and a date. task 3: record the milestone completion in STATE.md (after the checklist is signed) .planning/STATE.md - .planning/STATE.md (the whole file — the frontmatter fields, the "Current Position" block, the "Accumulated Context" sections, and the "Progress" table) - .planning/phases/07-hardening-private-launch/07-LAUNCH-GATE.md (the signed FINAL VERDICT — the source of this record) - .planning/ROADMAP.md (the Phase 7 entry — update its "Plans" count and its plan list) ONLY run this task after the checkpoint returned "signed" and the gate file's FINAL VERDICT table is filled.

In .planning/STATE.md:

  1. Update the frontmatter status: to complete and stopped_at: to a sentence naming the signed launch gate (e.g. Phase 7 complete — the launch gate is signed (private beta checklist)). Update last_updated: and last_activity: to today's date.
  2. Update the ## Current Position block: Phase: 7 → Phase: 7 (complete), Plan: Not started → Plan: Complete, Status: Ready to plan → Status: Launch gate signed.
  3. Set the Progress: bar to [░░░░░░░░░░] 100%.
  4. 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.
  5. In ### Blockers/Concerns, move the resolved entries into a short "RESOLVED 2026-10-25" note and REMOVE the stale open ones — in particular the /cari menu 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.
  6. 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)".
  7. Update ## Session Continuity — Last session: and Stopped at: and Resume file: (point at the gate file, since it holds the signed record).

In .planning/ROADMAP.md:

  1. Mark the Phase 7 entry - [ ] → - [x] and add (completed 2026-10-25).
  2. The Phase 7 entry already carries **Plans**: 6 plans — LEAVE that count line as it is; do NOT replace it and do NOT introduce a TBD placeholder.
  3. The six Phase 7 plan entries and their one-line objectives already exist in the ROADMAP's plan list — mark each of the six [x] (they are done once this task runs). Do NOT add a seventh entry and do NOT reword the six objectives.
  4. Update the ## Progress table's Phase 7 row to 6/6 | Complete | 2026-10-25.
  5. 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>
Run after all tasks:
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.md exists 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.md records the milestone completion with the binding decisions and the v1.x deferrals; ROADMAP.md shows Phase 7 complete with six plans. </success_criteria>
After completion, create `.planning/phases/07-hardening-private-launch/07-06-SUMMARY.md`