9.6 KiB
phase, plan, subsystem, tags, requires, provides, affects, tech-stack, key-files, key-decisions, patterns-established, requirements-completed, duration, completed
| phase | plan | subsystem | tags | requires | provides | affects | tech-stack | key-files | key-decisions | patterns-established | requirements-completed | duration | completed | |||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 05-routing-route-display | 03 | bot |
|
|
|
|
|
|
|
|
5min | 2026-10-23 |
Phase 5 Plan 3: Guidance-Session Contract Freeze (Types-Only) Summary
The guidance_sessions envelope frozen as a types-only Phase 6 contract — 4-field envelope + inline 6-field route snapshot (D-07: one key, one TTL) + the 7200 s TTL constant + guidance:<id> key scheme, with zero runtime behavior and seven GE gates proving the boundary mechanically.
Performance
- Duration: 5 min
- Started: 2026-10-23T21:05:12Z
- Completed: 2026-10-23T21:09:35Z
- Tasks: 1/1 (TDD RED→GREEN)
- Files modified: 2 (both created; zero existing files touched)
Accomplishments
- The Phase 6 contract exists in code (D-06):
GuidanceSessionEnvelope(EXACTLYid,chat_id,route_snapshot,created_at— the SessionClaim field-freeze law) andGuidanceRouteSnapshot(EXACTLYdestinationId,destinationName,distanceM,durationS,geometry,startedAtSec), theguidance:<id>key scheme, andGUIDANCE_SESSION_TTL_SECONDS = 7200— pinned by GE1/GE2 so drift reddens the suite. - D-07 is mechanical, not aspirational:
route_snapshot: GuidanceRouteSnapshotis typed INLINE (GE3), the tokenssnapshotRef/snapshot_refare banned across all ofbot/src, and the TTL law means one key, one expiry — nothing outlives 2h, nothing is reconstructable after expiry. - The types-only boundary cannot leak this phase (T-05-08): GE4 comment-strips the module and bans every behavior token (KV binding type,
.put(,.get(,.delete(, function exports, imports); GE5 pins wrangler.jsonc to EXACTLY ONE kv namespace (chat_sessions); GE6 pinsEnvfree of any guidance field; GE7 bans anybot/srcimport of the module — no runtime shadow, no premature consumer. - Zero existing bot files modified:
wrangler.jsoncandconfig.tsare untouched; the full bot suite is green at 72/72 (65 pre-existing + 7 GE gates) andbot:typecheckexits 0 (the module sits inside the bot tsconfig'sinclude: ["src"]).
Task Commits
Each gate of the TDD cycle was committed atomically:
- task 1: the frozen envelope types + the types-only gate suite
0b8671etest(05-03): add failing guidance-envelope types-only gates (GE1-GE7) (RED)d5c2bc0feat(05-03): freeze guidance_sessions envelope as types-only contract (GREEN)
Plan metadata: committed separately (docs, force-added — .planning/ is gitignored)
TDD Gate Compliance
- RED gate:
0b8671e— GE1–GE4 fail on the absent module (ERR_MODULE_NOT_FOUND / ENOENT, verified as the exact failure modes); GE5–GE7 pass as documented green-by-construction boundary guards. - GREEN gate:
d5c2bc0— 72/72 pass, typecheck exit 0. - REFACTOR gate: not needed — 58 lines of pure types + one constant; nothing to clean.
Files Created/Modified
bot/src/kv/guidance-sessions.ts— the frozen contract: module header (types-only law, D-06/D-07 citations,guidance:<id>key scheme),GUIDANCE_SESSION_TTL_SECONDS = 7200,GuidanceRouteSnapshot(6 fields),GuidanceSessionEnvelope(4 fields). No imports, no functions, no class.bot/test/guidance-envelope.test.mjs— GE1–GE7: TTL constant value; interface-body field-freeze regex (^\s{2}\w+:betweeninterface X {and\n}); inline-snapshot type + repo-wide ref-token ban; comment-stripped behavior-token ban (the routing C4stripCommentspattern); comment-stripped JSON.parse of wrangler.jsonc; config.ts token ban; import-statement ban across the recursivebot/srctree.
Decisions Made
- Header wording: "No KV binding" instead of the KVNamespace type name — the plan's
<interfaces>header template contains that literal token, but the plan's own acceptance criterion requiresgrep -rc 'KvNamespace'to return 0 with "the word never appears" (comments included). The mechanical gate wins; the law stated is identical. - GE5–GE7 declared green-by-construction in the RED commit — they are negative-space guards over files that must NOT change, so they cannot fail while the boundary holds (their RED state is vacuous). Mirrors 05-01's C4/C5/C6 zero-laws precedent; documented in both the suite header and the RED commit message.
Deviations from Plan
None — plan executed exactly as written. The two items above are judgment calls inside the plan's own acceptance gates, documented for the verifier.
Known Stubs
None — the module ships types + one constant by design (D-06); nothing flows to UI, nothing consumes it at runtime (GE7 pins that). Phase 6 builds the service on this frozen shape.
Threat Surface Scan
No new surface beyond the plan's <threat_model>: no endpoints, no auth paths, no file access, no schema at a trust boundary — the module has zero runtime behavior. All three register entries have implemented, gate-covered mitigations: T-05-08 (premature persistence → GE4/GE5/GE6/GE7), T-05-08b (retention → GE1 + GE3 inline snapshot), T-05-08c (contract drift → GE2 exact field sets). No threat flags.
Issues Encountered
- Pre-existing uncommitted working-tree changes to
bot/test/cari.test.mjsandbot/test/commands.test.mjs(a prior session's register-commands scope-shadow fix pins) were present at start. Baseline verified green WITH them (65/65) before any of my commits; they were left untouched and excluded from every commit. Out of scope per the plan-boundary rule. - Node lives under nvm in this environment — verification commands sourced
~/.nvm/nvm.shfirst (the 05-01 precedent). No project impact.
User Setup Required
None — no external service configuration required. The module ships no behavior; nothing deploys.
Next Phase Readiness
- Phase 6 (backgrounded turn-card service): consumes
GuidanceSessionEnvelope/GuidanceRouteSnapshot/GUIDANCE_SESSION_TTL_SECONDS/ theguidance:<id>key scheme verbatim — the shape cannot have drifted (GE1/GE2 pin it). Phase 6's plan owns: the KV namespace binding + Env field (relaxing GE5/GE6), the consumer import (relaxing GE7), and extending the PG1 same-line-expirationTtlgrep gate toguidance:writes. - Phase 5 remaining plans: none depend on this module (depends_on: [], wave: 1); 05-04/05-05 web-side work is unaffected.
Phase: 05-routing-route-display Completed: 2026-10-23
Self-Check: PASSED
- All 2 created files verified present on disk (guidance-sessions.ts, guidance-envelope.test.mjs).
- Both plan commits verified in git log (
0b8671eRED,d5c2bc0GREEN). npm test -w bot: 72 passed, 0 failed (PASS GE1…GE7 + all 65 pre-existing cases).npm run bot:typecheck: exit 0.- All seven acceptance greps pass on the module (envelope iface, snapshot iface, TTL const, key scheme, KvNamespace count = 0, inline snapshot).
- Zero existing files modified by this plan; STATE.md and ROADMAP.md untouched (orchestrator-owned writes).