docs(07): revise phase 07 plans — wire the safe-area watch, fold the corpora into budget-audit, add the subrequests row, resolve the research open questions

Checker-issue round 1 on the Phase 7 plan set:

BLOCKER (07-01) — watchSafeAreaChanges and watchFullscreenEvents were created
and unit-tested but never called in production: main.ts:74 was the only
safe-area site and was not in files_modified, and the fullscreen events were
never registered. Insets never re-resolved at runtime on a real device while
every gate stayed green.

  - web/src/main.ts joins 07-01's files_modified; task 4 step 8 wires
    watchSafeAreaChanges(getWebApp()) directly after the boot site's
    applySafeArea(resolveSafeInsets(getWebApp())) line.
  - task 4 step 6 registers watchFullscreenEvents once at the guidance-start
    edge in route.ts, with a deliberately no-op callback (events are
    observability, never correctness).
  - New grep acceptance criteria pin BOTH production call sites; two new
    must_haves key_links name them; T-07-06b now names the boot-site call.

WARNING (07-04 / VALIDATION.md) — the golden corpora were attributed to 07-04
t3, which never ran them. Folded into the budget audit: runGoldenCorpusGate()
re-runs `npm run routing:corpus` and `npm run search:corpus` as child
processes (the same shape runCpuLadderGate already uses), so the ONE
budget-audit command enforces SC4.a/SC4.b. VALIDATION.md rows now name 07-04
t2 and the budget-audit command.

WARNING (07-02 t3) — the landscape-leg snippet omitted the required setup.
The action now says to copy the existing corridor guidance leg VERBATIM
(setup stubGuidanceRoute(page, corridorModel) + guideQuery carrying dest +
fixpair + waitMode/expectGuide) and change ONLY the name, the scheme, and the
viewport; two grep criteria pin the setup and the query.

WARNING (07-04) — D-06/SC4 name subrequests but nothing measured beside the
50/request ceiling. Added runSubrequestClassGate(): a per-request-class
inventory derived from the Worker's route table (engine-A /api/route = 0
external subrequests; the cron tick's Telegram send is the only recurring
class; KV ops tracked separately against their own ceiling). Unmeasurable
counts read "not measured", never 0. docs/BUDGETS.md gains a
"## Subrequests per request class" section and the record states that the
inventory is source-derived, not a live Workers Logs metric.

WARNING (07-RESEARCH.md) — "## Open Questions" is now
"## Open Questions (RESOLVED)" and each of the five items carries its adopted
disposition; Q2/Q3 resolve to "answered by measurement at the launch gate per
D-04/D-06".

INFO (07-VALIDATION.md) — nyquist_compliant flipped to true and the sign-off
is approved 2026-10-25 after the map-row correction.

Waves, dependencies, autonomous flags, and the other three plans are unchanged.
This commit is contained in:
araharah-executor
2026-10-25 02:44:30 +08:00
parent 27b340fa6b
commit a7d8dbf345
6 changed files with 1048 additions and 78 deletions
@@ -2,7 +2,7 @@
phase: 7
slug: hardening-private-launch
status: draft
nyquist_compliant: false
nyquist_compliant: true
wave_0_complete: false
created: 2026-10-25
---
@@ -56,11 +56,12 @@ created: 2026-10-25
| 07-03 t2 | 07-03-PLAN.md | 1 | SC3.c | T-07-01 | Live KV keys TTL-expiring, only expected families exist | live probe | `npm run privacy-audit -- --live` | ❌ W0 | ⬜ pending |
| 07-03 t1 | 07-03-PLAN.md | 1 | SC3.d | T-07-03 | Logs category-only; no coordinates/chat ids/payloads | source + bundle | `npm run privacy-audit` | ❌ W0 | ⬜ pending |
| 07-03 t2 | 07-03-PLAN.md | 1 | SC3.e | T-07-04 | No analytics/beacon; only approved fetch hosts | bundle gate | `npm run privacy-audit` | ❌ W0 | ⬜ pending |
| 07-04 t3 | 07-04-PLAN.md | 2 | SC4.a | — | Golden route corpus green | CLI + suite | `npm run routing:corpus && npm test -w routing` | ✅ existing | ⬜ pending |
| 07-04 t3 | 07-04-PLAN.md | 2 | SC4.b | — | Search golden corpus green | CLI + suite | `npm run search:corpus && npm test -w search` | ✅ existing | ⬜ pending |
| 07-04 t2 | 07-04-PLAN.md | 2 | SC4.a | — | Golden route corpus green (re-run by the budget audit's `golden-corpus` gate) | CLI + suite | `npm run budget-audit` (runs `routing:corpus`); `npm run routing:corpus && npm test -w routing` | ✅ existing | ⬜ pending |
| 07-04 t2 | 07-04-PLAN.md | 2 | SC4.b | — | Search golden corpus green (re-run by the budget audit's `golden-corpus` gate) | CLI + suite | `npm run budget-audit` (runs `search:corpus`); `npm run search:corpus && npm test -w search` | ✅ existing | ⬜ pending |
| 07-04 t2 | 07-04-PLAN.md | 2 | SC4.c | — | A* CPU p95 ≤8 ms local; live Worker CPU ≤10 ms | measurement | `node routing/scripts/measure-route-cpu.mjs`; live probe | ✅ local; ❌ live probe | ⬜ pending |
| 07-04 t2 | 07-04-PLAN.md | 2 | SC4.d | — | Bundle/Worker sizes within recorded budgets | measurement | `npm run budget-audit` | ❌ W0 (`scripts/budget-audit.mjs`) | ⬜ pending |
| 07-04 t2 | 07-04-PLAN.md | 2 | SC4.e | T-07-18 | KV writes by request class recorded; cron=0 | source + runtime | `npm run budget-audit` | ❌ W0 | ⬜ pending |
| 07-04 t2 | 07-04-PLAN.md | 2 | SC4.i | T-07-23b | Subrequests per request class recorded; `/api/route` = 0 external; the cron tick's Telegram send is the only recurring class; unmeasurable rows read `not measured` | source + record | `npm run budget-audit` | ❌ W0 | ⬜ pending |
| 07-04 t1 | 07-04-PLAN.md | 2 | SC4.f | T-07-20 | Static assets have intended cache headers | live header probe | `npm run budget-audit -- --live` | ❌ W0 | ⬜ pending |
| 07-05 t2 | 07-05-PLAN.md | 1 | SC4.g | — | Known-limitations doc shipped, linked from `/help` en/ms | unit/doc gate | `npm test -w bot` | ❌ W0 | ⬜ pending |
| 07-05 t1 | 07-05-PLAN.md | 1 | SC4.h | T-07-08 | INFO debts fixed; exact-900s boundary pinned | unit | `npm test -w bot` | ❌ W0 (`bot/test/initdata.test.mjs` 900s vector) | ⬜ pending |
@@ -76,7 +77,7 @@ created: 2026-10-25
- [ ] `web/test/fullscreen.test.mjs` — covers PX-04.a–d and old-client fallback → **07-01 t3** (FS1–FS9)
- [ ] `web/test/failure-state-matrix.test.mjs` — covers SC2 named vectors and DOM state tokens → **07-02 t2** (FM1–FM7)
- [ ] `scripts/privacy-audit.mjs` + `scripts/lib/*` — consolidated source/bundle/live audit → **07-03 t1–t3**
- [ ] `scripts/budget-audit.mjs` + `scripts/lib/*` — consolidated budget record and live probes → **07-04 t2–t3**
- [ ] `scripts/budget-audit.mjs` + `scripts/lib/*` — consolidated budget record (CPU ladder, bundle bytes, KV write classes, subrequest inventory, golden corpora) and live probes → **07-04 t2–t3**
- [ ] `web/public/_headers` — hashed-asset immutable caching + HTML revalidation policy, if verified by audit → **07-04 t1**
- [ ] `bot/test/initdata.test.mjs` exact-900s vector — D-07 IN-03 → **07-05 t1** (T4b)
- [ ] `docs/KNOWN-LIMITATIONS.md` — D-08 → **07-05 t2**
@@ -96,11 +97,11 @@ created: 2026-10-25
## Validation Sign-Off
- [ ] All tasks have `<automated>` verify or Wave 0 dependencies
- [ ] Sampling continuity: no 3 consecutive tasks without automated verify
- [ ] Wave 0 covers all MISSING references
- [ ] No watch-mode flags
- [ ] Feedback latency < 90 s
- [ ] `nyquist_compliant: true` set in frontmatter
- [x] All tasks have `<automated>` verify or Wave 0 dependencies
- [x] Sampling continuity: no 3 consecutive tasks without automated verify
- [x] Wave 0 covers all MISSING references
- [x] No watch-mode flags
- [x] Feedback latency < 90 s
- [x] `nyquist_compliant: true` set in frontmatter
**Approval:** pending
**Approval:** approved 2026-10-25