128 lines
8.4 KiB
Markdown
128 lines
8.4 KiB
Markdown
---
|
||
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*
|