From 1f15ad202b873e3349b61c38ccbfdb3988eefe6f Mon Sep 17 00:00:00 2001 From: araharah-executor Date: Thu, 22 Oct 2026 11:39:09 +0800 Subject: [PATCH] docs(02-01): complete bot scaffold + RED initdata suite plan --- .../02-01-SUMMARY.md | 127 ++++++++++++++++++ 1 file changed, 127 insertions(+) create mode 100644 .planning/phases/02-bot-skeleton-initdata-security/02-01-SUMMARY.md diff --git a/.planning/phases/02-bot-skeleton-initdata-security/02-01-SUMMARY.md b/.planning/phases/02-bot-skeleton-initdata-security/02-01-SUMMARY.md new file mode 100644 index 0000000..8448e9c --- /dev/null +++ b/.planning/phases/02-bot-skeleton-initdata-security/02-01-SUMMARY.md @@ -0,0 +1,127 @@ +--- +phase: 02-bot-skeleton-initdata-security +plan: 01 +subsystem: infra +tags: [telegram, grammy, cloudflare-workers, wrangler, npm-workspaces, typescript, hmac, tdd] + +# Dependency graph +requires: + - phase: 01-design-tokens-rams-foundation + provides: npm workspace pattern (root delegate scripts + per-workspace package.json) and hand-rolled zero-dep test runner shape (theme/scripts/audit.test.mjs, D-12 precedent) +provides: + - `bot/` npm workspace (`@araharah/bot`) with grammy ^1.46.0 + wrangler ^4.151.3 + TypeScript ^5.9.3, registry-verified + - `bot/src/config.ts` Env contract (BOT_TOKEN, WEBHOOK_SECRET, chat_sessions KVNamespace) consumed by plans 02/03 + - `bot/wrangler.jsonc` Worker config with main src/webhook.ts + chat_sessions KV binding (id placeholder → plan 03) + - `bot/test/harness.mjs` + `runner.mjs` — D-12 zero-dependency runner, suite-load failures become FAIL cases + - `bot/test/initdata.test.mjs` — RED vector suite T1–T7 (contract for plan 02 GREEN) + - Secret hygiene baseline: `.gitignore` (.dev.vars, .wrangler/) + `.dev.vars.example` shipped in first commit +affects: [02-02 security core (GREEN against this suite), 02-03 commands+KV+deploy, phase 3 mini app shell, phase 5 session envelope] + +# Tech tracking +tech-stack: + added: [grammy ^1.46.0, wrangler ^4.151.3, typescript ^5.9.3, @cloudflare/workers-types ^5.20261022.1, @types/node ^26.6.5] + patterns: [npm workspace sibling to theme/ with root delegate scripts, hand-rolled registry/runner test harness (D-12), erasable-only TypeScript under type-stripping, RED-first TDD for security gates, secrets as wrangler secrets + gitignored .dev.vars mirror] + +key-files: + created: + - bot/package.json + - bot/tsconfig.json + - bot/wrangler.jsonc + - bot/.gitignore + - bot/.dev.vars.example + - bot/src/config.ts + - bot/test/harness.mjs + - bot/test/runner.mjs + - bot/test/initdata.test.mjs + modified: + - package.json (workspaces + bot:* delegate scripts) + - package-lock.json (bot workspace deps) + +key-decisions: + - "Lazy per-case dynamic import of ../src/security/initdata.ts in the RED suite: each vector reports its own FAIL (8 named FAILs at RED) instead of losing the whole suite to one load error; the suite-load-failure path survives as the runner's crash guard" + - "Test-side HMAC signing helper uses node:crypto (two-step Telegram derivation) so the RED suite is provably independent of the SubtleCrypto implementation path plan 02 writes; T7 pins the primitive against the RFC-4231 case-1 vector" + +patterns-established: + - "D-12 harness: import { test } from './harness.mjs' in any bot/test/*.test.mjs; runner auto-discovers, prints PASS/FAIL per case + '[runner] N passed, M failed', exit 0 only when all green" + - "Root delegate scripts: bot:test / bot:typecheck / bot:dev / bot:deploy / bot:commands (mirrors Phase 1 build:* pattern)" + - "Erasable-only TS in bot/src (no enums/parameter properties/namespaces); tsconfig: strict + noEmit + allowImportingTsExtensions + workers-types" + +requirements-completed: [ONBD-01, PRIV-01, PRIV-02] # substrate only — D-15/D-17 secret-hygiene + D-12 verification substrate for these reqs; full req delivery lands in plans 02/03 + +# Metrics +duration: 4min +completed: 2026-10-22 +--- + +# Phase 2 Plan 1: Bot Workspace Scaffold + RED initdata Vector Suite Summary + +**`bot/` npm workspace stood up with grammy/wrangler/TS and the D-12 zero-dep test harness, shipping a RED-demonstrated initdata HMAC vector suite (T1–T7, 8 FAILs / exit 1) that plan 02 goes GREEN against** + +## Performance + +- **Duration:** 4 min +- **Started:** 2026-10-22T03:35:10Z +- **Completed:** 2026-10-22T03:38:23Z +- **Tasks:** 2 +- **Files modified:** 11 (9 created, 2 modified) + +## Accomplishments +- `bot/` workspace installs and typechecks clean: grammy@1.46.0 + wrangler@4.151.3 + typescript@5.9.3 landed exactly in ranges pinned by RESEARCH.md (lockfile-verified) +- `Env` interface contract (`BOT_TOKEN`, `WEBHOOK_SECRET`, `chat_sessions: KVNamespace`) committed as the type anchor plans 02/03 implement against +- Secret hygiene from the first commit: `.gitignore` (.dev.vars, .wrangler/) ships in the same commit as `.dev.vars.example`; `git check-ignore bot/.dev.vars` verified +- Hand-rolled runner (D-12) replicates Phase 1's pattern in a second workspace: zero deps, suite-load failures become FAIL cases (never crashes), `[runner] N passed, M failed` summary, exit 1 on any failure +- RED vector suite final-contract: T1 known-good, T2 tampered, T3 stale (3600 s), T4 boundary (899 ok / 901 stale), T5 order-independence, T6a–c malformed, T7 RFC-4231 node:crypto independence pin — demonstrated RED with 8 named FAILs against missing `src/security/initdata.ts` + +## task Commits + +Each task was committed atomically: + +1. **task 1: bot workspace scaffold with Env contract (D-09/D-10/D-11/D-15)** — `c9b6ba4` (feat) +2. **task 2: Wave 0 harness + RED initdata vector suite (D-12, TDD RED)** — `fc5001a` (test) + +_Note: task 2 is TDD RED by plan design; the GREEN commit belongs to plan 02 task 1 (wave 2), which will flip this suite from 8 FAILs to all-pass._ + +## Files Created/Modified +- `package.json` — workspaces `["theme","bot"]` + `bot:*` delegate scripts (theme scripts untouched) +- `bot/package.json` — `@araharah/bot` workspace: test/typecheck/dev/deploy/commands scripts, grammy + wrangler/TS deps +- `bot/tsconfig.json` — strict ES2023, noEmit, moduleResolution bundler, workers-types, allowImportingTsExtensions +- `bot/wrangler.jsonc` — name araharah-bot, `main: src/webhook.ts`, chat_sessions KV binding (id = KV_ID_PLACEHOLDER until plan 03's `wrangler kv namespace create`) +- `bot/.gitignore` — exactly `.dev.vars` + `.wrangler/` (D-15/D-17) +- `bot/.dev.vars.example` — shape only (BOT_TOKEN=, WEBHOOK_SECRET=, WEBHOOK_URL=), no values +- `bot/src/config.ts` — `export interface Env` + KVNamespace member (contract only, no implementation) +- `bot/test/harness.mjs` — zero-dep registry: `test(name, fn)` / `registry` +- `bot/test/runner.mjs` — D-12 runner: sorted `*.test.mjs` discovery, suite-load error → stored FAIL case, PASS/FAIL + summary + exit codes +- `bot/test/initdata.test.mjs` — vector suite T1–T7; signing helper in-file via node:crypto; fixtures in-process +- `package-lock.json` — bot workspace dep tree (grammy 1.46.0, wrangler 4.151.3 pinned) + +## Decisions Made +- **Lazy per-case validator import in the RED suite:** the plan allowed either "suite load failed" or per-case FAILs; per-case chosen so RED shows each vector's own failure (and plan 02's GREEN progress will be visible per-vector) +- **Test-side signing via node:crypto (not SubtleCrypto):** keeps the RED suite's expected-hash path independent of the implementation path under test; T7's RFC-4231 pin makes that independence a guarded invariant + +## Deviations from Plan + +None - plan executed exactly as written. (T6 was split into T6a/T6b/T6c named cases within the plan's single T6 bullet — this stays within the documented contract and yields ≥7 independent FAILs at RED.) + +## Issues Encountered +- Verified at execution start that Node 24.18.0 dynamic-imports `.ts` modules from `.mjs` natively (probe in /tmp/opencode/) — no `--experimental-strip-types` flag needed, confirming the runner + type-test design works without tooling changes +- npm emitted allow-scripts warnings for esbuild/workerd/@parcel/watcher install scripts (self-hosted toolchain hygiene; unrelated to this plan — dev-only tooling, noted for awareness, no action taken per scope boundary) + +## User Setup Required + +None for this plan. (Real secrets — BOT_TOKEN / WEBHOOK_SECRET / Cloudflare account — are only needed at plan 03's deploy checkpoint, per D-15/D-16.) + +## Next Phase Readiness +- Plans 02/03 can implement against `bot/src/config.ts` Env + `bot/wrangler.jsonc` entry points; `npm test -w bot` and `npm run bot:typecheck` are the wave verification commands +- Plan 02 task 1 must make `bot/test/initdata.test.mjs` GREEN (implement `src/security/initdata.ts` per the T1–T7 contract) +- Plan 03 task 1 fills the real KV namespace id into `bot/wrangler.jsonc` (replace `KV_ID_PLACEHOLDER`) + +## Self-Check: PASSED + +- All 9 created files verified present on disk (bot/ tree + test files) +- Commits verified in history: `c9b6ba4` (feat task 1), `fc5001a` (test task 2 RED) +- `git check-ignore bot/.dev.vars` → ignored (secret hygiene confirmed) +- STATE.md / ROADMAP.md untouched by this agent (ROADMAP.md's pre-existing modification belongs to the orchestrator) + +--- +*Phase: 02-bot-skeleton-initdata-security* +*Completed: 2026-10-22*