Files
Arah2/.planning/phases/02-bot-skeleton-initdata-security/02-01-SUMMARY.md
T

8.4 KiB
Raw Blame History


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