From 5f4fd8b297d2c55b7f2bc2cb8d4806d6b401de92 Mon Sep 17 00:00:00 2001 From: araharah-executor Date: Sun, 25 Oct 2026 05:33:45 +0800 Subject: [PATCH] =?UTF-8?q?docs(07-06):=20complete=20the=20launch-gate=20p?= =?UTF-8?q?rep=20=E2=80=94=20SUMMARY?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - unsigned protocol file, audit-green restoration, /cari root-cause fix, deploy dd55a073 + full canary verification documented - task 2 (the physical walk + battery run) BLOCKING for the human; task 3 (STATE.md record) orchestrator-owned --- .../07-06-SUMMARY.md | 166 ++++++++++++++++++ 1 file changed, 166 insertions(+) create mode 100644 .planning/phases/07-hardening-private-launch/07-06-SUMMARY.md diff --git a/.planning/phases/07-hardening-private-launch/07-06-SUMMARY.md b/.planning/phases/07-hardening-private-launch/07-06-SUMMARY.md new file mode 100644 index 0000000..b2a70c8 --- /dev/null +++ b/.planning/phases/07-hardening-private-launch/07-06-SUMMARY.md @@ -0,0 +1,166 @@ +--- +phase: 07-hardening-private-launch +plan: 06 +subsystem: qa-gates +tags: [launch-gate, device-matrix, battery-record, privacy-audit, budget-audit, canary, setmycommands, deferred-debt] + +# Dependency graph +requires: + - phase: 07-03 + provides: scripts/privacy-audit.mjs + scripts/lib/source-gates.mjs — the runtime-hosts gate the /help pointer adjudication extends, and the --live probe contract + - phase: 07-04 + provides: scripts/budget-audit.mjs + docs/BUDGETS.md — the KV-list over-ceiling finding and the signature block this gate signs + - phase: 07-05 + provides: docs/KNOWN-LIMITATIONS.md + the /help pointer line (en + ms) — the shipped doc the checklist verifies + - phase: 06-DEVICE-GATE.md + provides: the never-fake device-gate protocol and the file structure this gate copies +provides: + - ".planning/phases/07-hardening-private-launch/07-LAUNCH-GATE.md — the UNSIGNED launch protocol: Part A (4 clients × 7 interactions, PASS/FAIL/NOT RUN), Part B (11-field Android battery record), Part C (the 12 automated-half commands), Part D (the six D-09 checklist items), executor notes, unsigned FINAL VERDICT" + - "Audit-green tree restored: npm run privacy-audit exits 0 again (the 07-05 /help pointer adjudicated as a documented doc-pointer static-text class, SA6-pinned)" + - "The /cari menu defect ROOT-CAUSED and FIXED: register-commands.mjs sent the scope under the wrong Bot API field name (bot_command_scope; the field is scope) — Telegram silently ignored it, every call hit the default scope, the clear calls wiped the default set; all private-chat scopes now read back help, privacy, cari" + - "Fresh deploy dd55a073 with canaries verified: webhook armed (secret-token channel, no fresh errors), menu button web_app, all six command scopes armed + read-back proven, _headers policy observed live (immutable assets / revalidating HTML)" +affects: [the human launch gate (Parts A–D are walked and signed), STATE.md milestone completion record (written by the orchestrator AFTER signing), forks (the gate file as onboarding evidence)] + +# Tech tracking +tech-stack: + added: [] + patterns: + - "Scope adjudications stay NARROW and pinned: a static-text host class consults ONLY bare URL literals — a fetch( target naming the same host still fails (SA6)" + - "A quoted string is always a fetch TARGET — a URL colon must not masquerade as a TS annotation colon" + - "canary read-back with the CORRECT API parameter names: setMyCommands ok:true proved nothing about scope until getMyCommands read back per scope" + - "canary staleness protocol: getWebhookInfo.last_error cannot clear until the next real update — record last_error_date, compare against the deploy timeline" + +key-files: + created: + - .planning/phases/07-hardening-private-launch/07-LAUNCH-GATE.md + modified: + - scripts/lib/source-gates.mjs + - scripts/test/privacy-audit.test.mjs + - docs/PRIVACY-AUDIT.md + - docs/KNOWN-LIMITATIONS.md + - bot/scripts/register-commands.mjs + - bot/README.md + - bot/src/bot/commands/start.ts + - web/src/shell.css + - README.md, AGENTS.md, 4 mockup screens (logo residue) + +key-decisions: + - "The /help pointer host (gitmirah) is adjudicated as a SOURCE-side doc-pointer static-text class following the audit's own laws — the URL stays the repo's actual published remote (07-05's decision); the class is narrow (URL literals only) and SA6-pinned; forks replace it with their own origin" + - "The KV-list over-ceiling (1,440/day vs 1,000/day) is NOT auto-fixed: it is a designed product-timing decision (the due-card math couples tick and cadence) carried to the human gate with the documented options — a 90 s tick is NOT expressible in cron (minimum granularity 60 s)" + - "The kv-expiry --live leg stays NOT RUN: it needs CLOUDFLARE_API_TOKEN + CLOUDFLARE_ACCOUNT_ID which the executor's environment does not carry — an auth gate surfaced to the maintainer, never faked; a manual wrangler corroboration (namespace lists []) IS recorded" + +requirements-completed: [] # PX-04 completes at the SIGNED gate (task 2); the orchestrator marks requirements + +# Metrics +duration: 47min +completed: 2026-10-25 +--- + +# Phase 7 Plan 06: Launch Gate (automated prep) Summary + +**The unsigned launch-gate protocol written (4×7 device matrix, 11-field battery record, 12-command automated half, the six D-09 checklist items), the audit-green state restored (the 07-05 `/help` pointer adjudicated lawfully), the `/cari` menu defect root-caused to a wrong Bot API field name and FIXED, and the fresh deploy verified by the full canary protocol.** + +## Performance + +- **Duration:** 47 min (21:15Z → 22:02Z) +- **Started:** 2026-10-24T21:15:21Z +- **Automated prep completed:** 2026-10-24T22:02Z +- **Tasks:** 1/3 executed (task 2 = THE BLOCKING HUMAN GATE; task 3 = orchestrator-owned, deferred per the spawn objective) +- **Files modified:** 15 (1 created, 14 modified/landed) + +## Accomplishments + +- **07-LAUNCH-GATE.md** exists as a complete, unsigned protocol: Part A — the ONE consolidated walk (D-05): Android + iOS + Telegram Desktop + plain browser × (boot · search→route · guidance · minimize/resume · trip-end · theme flip · landscape/fullscreen), ⬜ cells, the PASS/FAIL/NOT RUN vocabulary defined in the file's own voice, and per-interaction observable pass conditions; Part B — the 11-field Android battery record with the no-extrapolation rule; Part C — the 12 exact automated-half commands with ⬜ result cells and the "a NOT-RUN --live probe is NOT a pass" note; Part D — the six D-09 checklist items, each naming its evidence; executor notes carrying every known-open item; an unsigned dated FINAL VERDICT block +- **Audit-green restored:** the deferred-items #1 RED (07-05's `http://gitmirah:3000` /help pointer, 2 runtime-hosts violations) fixed per the gates' OWN laws — a documented `DOC_POINTER_STATIC_TEXT_HOSTS` class on the source-side runtime-hosts gate, NARROW (URL literals only) and pinned by the new SA6 vector; `npm run privacy-audit` → **PRIVACY AUDIT CLEAN — 5 gate(s) passed, 0 violations**, suite 13/13 +- **Rule 1 bonus (found by SA6's RED):** the fetch( call-site handler's declaration heuristic misclassified any quoted absolute URL as a TS method declaration — quoted fetch targets now reach the host check +- **The /cari menu defect's true root cause found and FIXED at the canary:** the Bot API parameter is `scope` (verified against core.telegram.org/bots/api); the script's `bot_command_scope` was silently ignored so every call hit the default scope and the two "clear" calls wiped the default set entirely. Registration re-run; `getMyCommands` read back per scope with the correct param: default (agnostic/en/ms) + all_private_chats (agnostic/ms) all list `help, privacy, cari`; group scopes verified cleared. The limitations doc's wrong attribution corrected; residual client menu-caching caveat + workaround kept +- **Fresh deploy `dd55a073` + full canary protocol verified:** webhook armed with the secret-token channel (`last_error` stale from the phase-3 era, `last_error_date` 2026-10-22T11:18Z recorded, pending 0), menu button `web_app` → deployed origin, all command scopes armed, secrets in gitignored `.dev.vars` only; the live asset-headers leg **PASS** (immutable `/assets/*`, revalidating HTML — 07-04's `_headers` policy observed on the shipped origin) +- **Part C green at prep time:** bot 126/126, web 165/165, routing 65/65, search 57/57, both corpora PASS, ladder p95 74.055 ms (documented c3 band), privacy-audit CLEAN, budget-audit CLEAN, captures 22/22 + +## task Commits + +Each unit committed atomically: + +1. **fold 07-03 residue (status-first header probe, XHTML namespace, evidence-reason contract)** — `7a1206d` (fix) +2. **RED — SA6 doc-pointer vector** — `b06c64d` (test) +3. **GREEN — the doc-pointer static-text class + PRIVACY-AUDIT.md adjudication + dated addendum** — `2489cca` (fix) +4. **logo-asset replacement residue (quick task 261024-001, commit recorded TBD in STATE)** — `b7576c1` (chore) +5. **landscape cockpit geometry refinement (07-02 device-walk feedback) + re-run captures** — `71fff10` (fix) +6. **/cari root-cause fix + limitations-doc correction + README row** — `141d6d2` (fix) +7. **the launch gate protocol file** — `53930eb` (docs) + +## Files Created/Modified + +- `.planning/phases/07-hardening-private-launch/07-LAUNCH-GATE.md` — NEW: the unsigned protocol +- `scripts/lib/source-gates.mjs` — DOC_POINTER_STATIC_TEXT_HOSTS + the fetch-handler fix +- `scripts/test/privacy-audit.test.mjs` — the SA6 vector (plus the folded CP2/AU1 contract updates) +- `docs/PRIVACY-AUDIT.md` — the adjudication + dated gate-prep re-run addendum +- `docs/KNOWN-LIMITATIONS.md` — the /cari section corrected to the real root cause +- `bot/scripts/register-commands.mjs` — `scope` field name + the fix documented at the site +- `bot/README.md`, `README.md`, `AGENTS.md`, 4 mockup screens, `bot/src/bot/commands/start.ts`, `web/src/shell.css`, 6 captures — residue landed + +## Decisions Made + +- **Adjudicate, don't weaken:** the pointer URL keeps its host (07-05's documented decision — the repo's actual remote); the AUDIT gains a documented, narrow static-text class. A protocol-relative or host-neutral rewrite would have gamed the scanner while leaving drivers a dead link. +- **The KV-list cadence stays a user decision:** 07-04 classified the retiming as Rule 4 (the due-card math couples `SCAN_TICK_S` into `projectTurnCards`' due rule); this prep carries the three documented options into the gate file and the checkpoint, plus the correction that a 90 s tick is not cron-expressible. +- **The kv-expiry live leg is an auth gate, not a skip-failure:** absent CF credentials degrade to exit 2 by design; the manual wrangler listing (`[]`) corroborates the namespace's live state and is recorded in the gate file. + +## Deviations from Plan + +### Auto-fixed Issues + +**1. [Rule 1 - Bug] The fetch( call-site handler misclassified quoted absolute URLs as TS declarations** +- **Found during:** SA6's RED phase +- **Issue:** `argText.includes(":")` treats any quoted URL's colon as a TS annotation colon, skipping quoted absolute fetch targets entirely — the doc-pointer class could not be narrow +- **Fix:** quoted strings are targets; only unquoted colon-carrying args are declarations +- **Files modified:** scripts/lib/source-gates.mjs +- **Commit:** 2489cca + +**2. [Rule 1 - Bug] register-commands.mjs sent the wrong Bot API field name (the /cari menu defect's true root cause)** +- **Found during:** the deploy canary (default-scope read-back was empty, all_private_chats lacked cari) +- **Issue:** `bot_command_scope` is not a Bot API field; Telegram silently ignores it — all four registration calls hit the default scope and the two clear calls cleared the default set +- **Fix:** field renamed to `scope` in all six calls; registration re-run; per-scope read-back proven with `getMyCommands` + the correct param; docs corrected +- **Files modified:** bot/scripts/register-commands.mjs, docs/KNOWN-LIMITATIONS.md, bot/README.md +- **Commit:** 141d6d2 + +**3. [Rule 3 - Blocking residue] Pre-existing uncommitted work landed (07-04's residue caution + the logo quick task's TBD commit)** +- **Found during:** tree prep before deploy +- **Issue:** the 07-03 follow-up fixes were described in 07-03-SUMMARY but absent from its commits; the logo replacement was complete but uncommitted (and web/public assets were untracked while start.ts referenced them) +- **Fix:** landed as three commits (`7a1206d`, `b7576c1`, `71fff10`) after re-verifying the baselines (bot 126/126, web 165/165, captures 22/22) +- **Files modified:** scripts/lib/cloudflare-probes.mjs + source-gates.mjs + test; logo residue set; shell.css + captures + +--- + +**Total deviations:** 3 auto-fixed (2 bugs, 1 residue landing) +**Impact on plan:** the audit-green state is restored and the launch canaries are genuinely armed; no plan surface was dropped. Task 2 (the physical walk + battery run) and task 3 (STATE.md record) remain. + +## Issues Encountered + +- No Cloudflare API token in the executor's environment (`bot/.dev.vars` carries only BOT_TOKEN/WEBHOOK_SECRET/WEBHOOK_URL) — the kv-expiry live leg stays NOT RUN (exit 2, honest class); exact token-creation steps surfaced at the checkpoint +- The stale phase-2/3-era Telegram command sets (all_chat_administrators: `start`; all_private_chats: `help, privacy` without cari) are now genuinely cleared/overwritten by the fixed registration +- `npm run capture` needs a >120 s window (Playwright legs) — completed with an extended timeout + +## Known Stubs + +None — the gate file is a protocol by design (every verdict cell starts ⬜ per T-07-27); no product code carries placeholder data. + +## User Setup Required + +**One auth gate (kv-expiry live leg):** create a Cloudflare API token (Account scope: Workers KV Storage → Read) and export `CLOUDFLARE_API_TOKEN` + `CLOUDFLARE_ACCOUNT_ID`, then re-run `npm run privacy-audit -- --live` and `npm run budget-audit -- --live` at gate time. + +## Next Phase Readiness + +- **The gate file is ready to walk:** Part 0 (the automated half — every command exits 0 at prep time, re-run at gate time), Part A (the physical walk — the user's legs), Part B (the battery run — the user's legs), Part D (the signature) +- **Two decisions ride with the signature:** the KV-list cadence (options in the gate file) and the kv-expiry credential provision +- Baselines: bot 126/126, web 165/165, routing 65/65, search 57/57, privacy suite 13/13, budget suite 19/19, captures 22/22; deploy `dd55a073` + +--- +*Phase: 07-hardening-private-launch* +*Completed: 2026-10-25* + +## Self-Check: PASSED + +- `07-LAUNCH-GATE.md` on disk with all six section headings; 32 ⬜ lines; no APPROVED string. +- All 7 commits verified in git log (`7a1206d`, `b06c64d`, `2489cca`, `b7576c1`, `71fff10`, `141d6d2`, `53930eb`). +- Final suite: bot 126/126, web 165/165, routing 65/65, search 57/57; privacy-audit CLEAN; budget-audit CLEAN. +- STATE.md and ROADMAP.md untouched (orchestrator-owned, per the spawn objective).