docs(03-04): complete one-deployable architecture plan — SUMMARY (checkpoint armed)

This commit is contained in:
araharah-executor
2026-10-23 00:46:44 +08:00
parent 5c155e393d
commit fc183216c3
@@ -0,0 +1,134 @@
---
phase: 03-mini-app-shell-geolocation
plan: 04
subsystems: [worker-assets, build-tooling, capture-harness, device-matrix]
tags: [cloudflare-workers, static-assets, vite, playwright, privacy, d13, d14, d15]
requires: [03-01 (web workspace, chain), 03-03 (shell, map, capture signals)]
provides:
- D-13 one-deployable Worker: assets binding serving web/dist + run_worker_first on /api/* and /telegram/*
- D-14 build-artifact gate (BA1–BA6): zero CDN refs, self-hosted fonts, bundled MapLibre worker, inlined style, harness-free production bundle
- D-15 one-command deploy (npm run deploy = theme → web → wrangler deploy) and one-command dev (npm run dev, port 8787, local KV)
- Dual-build contract: web/dist (production) vs web/dist-harness (capture-only), isolated by __ARAHARAH_HARNESS__ define
- web/scripts/capture.mjs: 7 Playwright captures + GEO-03 runtime storage probe
- 03-DEVICE-MATRIX.md: the six-leg exit-gate checklist (BLOCKING, awaiting user)
affects: [phase-4 verification, phase-7 hardening]
tech-stack:
added: [wrangler static-assets binding, vite --mode harness dual build]
patterns: [build-time dead-code elimination via define, console-signal READY race]
key-files:
created:
- web/test/build-artifact.test.mjs
- web/scripts/capture.mjs
- web/src/vite-env.d.ts
- .planning/phases/03-mini-app-shell-geolocation/03-DEVICE-MATRIX.md
modified:
- bot/wrangler.jsonc
- bot/package.json
- package.json
- web/package.json
- .gitignore
- web/vite.config.ts
- web/index.html
- web/src/main.ts
decisions:
- Dual-build isolation: harness bundle is a separate outDir gated by a build-time constant, never deployed (T-03-21)
- runner-page profile block wrapped wholly in if (__ARAHARAH_HARNESS__) with HTML-inclusive BA5 scan
- Local-dev topology = wrangler dev --port 8787 --local (D-12); localhost is a secure context so geolocation works
metrics:
duration: resumed run (tasks 1–2 pre-committed; deploy + matrix + checkpoint this run)
completed: 2026-10-23
---
# Phase 03 Plan 04: One-Deployable Architecture + Device-Matrix Exit Gate — Summary
**One deploy ships the Mini App, API, and webhook: `npm run deploy` builds theme → web → wrangler deploy with `web/dist` as static assets; six automated gates prove the bundle is fully self-contained and harness-free, and a 7-capture Playwright harness plus a real boot-to-live storage probe mechanically verify the shell — with the six-leg real-device matrix now armed and awaiting the user.**
## Completed Tasks
| # | Task | Commit | Key files |
|---|------|--------|-----------|
| 1 | Worker `[assets]` binding + one-command deploy + D-14 gate | 8b39a7a (kept from prior run: `8b39ea7`) | bot/wrangler.jsonc, package.json, bot/package.json, web/vite.config.ts, web/test/build-artifact.test.mjs, .gitignore, web/package.json |
| 2 | Mock-Telegram runner page + Playwright capture harness | 5c155e3 | web/index.html, web/scripts/capture.mjs, web/src/vite-env.d.ts, web/src/main.ts |
| 3 | Device-matrix exit gate | **BLOCKED — checkpoint reached** | 03-DEVICE-MATRIX.md written; real-device legs must be walked by the user |
## What Was Built
**D-13 — one Worker, everything attached.** `bot/wrangler.jsonc` now carries the `assets`
binding (`../web/dist`, `not_found_handling: "none"`) plus the `run_worker_first` glob array
for `/api/*` and `/telegram/*`. Verified live at https://araharah-bot.araharah-bot.workers.dev/:
`GET /` → 200 text/html from the asset tree; `POST /api/session` on unsigned bodies → 401
(the HMAC gate answers, so the Worker still owns the API routes).
**D-14 — self-contained bundle, proven.** `web/test/build-artifact.test.mjs` runs BA1–BA6
over `web/dist` (HTML-inclusive for BA5/BA6): no third-party CDN references, ≥1 self-hosted
woff2, hashed MapLibre worker chunk, inlined Rams style JSON (`"liberty-rams"` markers in
the bundle), and — critically — no `installMockWebApp`, `__ARAHARAH_MOCK__`,
`/api/session`, or `/api/location-fallback` in ANY emitted production file. 33/33 web tests
pass, 48/48 bot tests pass.
**D-15 / D-12 — one command each way.** Root `deploy` (build theme → build web →
`wrangler deploy && set-webhook.mjs`) and root `dev` (build theme → build web →
`wrangler dev --port 8787 --local`, KV in local simulation) chain the gitignored
`theme/dist/` build so a fresh clone works.
**T-03-21 in both directions.** `web/vite.config.ts` injects `__ARAHARAH_HARNESS__` (true
only in `--mode harness`, outDir `dist-harness`); `web/index.html` wraps the ENTIRE
Mock-Telegram profile (marker, `/api/session` + `/api/location` + `/api/location-fallback`
fetch stubs, installer) in that guard, with `import("/src/main.ts")` outside it.
`grep -rl 'installMockWebApp\|__ARAHARAH_MOCK__' web/dist/` → empty while `dist-harness`
greps ≥1. `capture.mjs` asserts both directions before racing and aborts with a named
diagnostic otherwise.
**D-11 / DSGN-02 / GEO-03 — the capture harness.** `web/scripts/capture.mjs` extends the
Phase-1 screenshot toolchain (MIN_BYTES 10240, docroot-guarded server, console-signal
READY race) to serve `web/dist-harness` and race `RAMS-BASEMAP-READY` then
`ARAHARAH-LIVE`. Seven non-blank captures under `web/screenshots/`: boot stage 1 + 2,
live light, live dark, the Desktop denied card (via its dedicated 90s race against
LINK 3's 60 s pre-denial chat-pin poll), the `?pin=1` chat-pin relay to LIVE, and the
DSGN-02 side-by-side vs `navigate_map_overview/screen.png`. The GEO-03 probe then asserts
localStorage, sessionStorage, cookies, and IndexedDB all empty after a real boot-to-live
cycle — none were.
## Deploy Verification (real canaries)
- `npm run deploy` → araharah-bot@2c1336e3-58f9-4b0b-86a8-b25de66e327c, webhook re-set ok.
- `getWebhookInfo`: URL ends `/telegram/webhook`, no `last_error`, secret armed (values not echoed).
- `getChatMenuButton`: type `commands`.
- Origin serves the app (200) and the API 401s unsigned traffic.
## Deviations from Plan
1. **[Rule 3 - Blocking] `run_worker_first` unrecognized by wrangler 4.151.3.** The
`npm run deploy` emitted `Unexpected fields found in top-level field: "run_worker_first"`.
The plan claimed a deploy `--dry-run` would prove the key was accepted; it warns, not
fails. Deploy succeeded, and request-by-request probes showed the routing D-13 requires
holds regardless (assets serve only non-API paths in the default assets-first model; the
Worker 404s misses itself, so `/api/*`/`/telegram/*` are never intercepted). Left as-is
with the observed behavior documented in 03-DEVICE-MATRIX.md; a wrangler upgrade to
≥4.152.0 is suggested when convenient but was not forced mid-plan.
2. **[Continuation] Tasks 1 and 2 were found already executed and committed** (8b39ea7,
5c155e3) when this run started; this run verified their gates, performed the deploy +
canaries, and armed task 3.
## Authentication Gates
None.
## Known Stubs
None. Every capture, gate, and probe is wired to real behavior; the harness stubs are by
design confined to the never-deployed `web/dist-harness` build.
## Checkpoint: Device-Matrix Exit Gate (task 3) — BLOCKING, awaits user
`.planning/phases/03-mini-app-shell-geolocation/03-DEVICE-MATRIX.md` is written with the
deployed URL, the Bot API 10.2 BotFather-origin prerequisite, and all six legs as
unchecked checkboxes: Android boot + permission persistence, Android stale-fix (A1
retire-or-confirm), iOS, Desktop Telegram denied→ASK VIA CHAT→keyboard→pin→LIVE, plain
browser denied card, and the mid-session light↔dark theme flip (PX-02 manual-only).
Real hardware is unavailable to the executor — per plan and T-03-25, no leg was faked;
Success Criterion 5 remains open until the user reports results.
**Resume signal:** "device matrix passed", a per-leg failure report, or a
no-device-available report (→ Success Criterion 5 = UNVERIFIED; recommend Phase-7
deferral with GEO-01/GEO-02 noted unverified on hardware).