Files
initiative/specs/025-display-initiative/plan.md

3.6 KiB
Raw Blame History

Implementation Plan: Display Initiative

Branch: 025-display-initiative | Date: 2026-03-10 | Spec: spec.md Input: Feature specification from /specs/025-display-initiative/spec.md

Summary

Add initiative modifier and passive initiative display to the creature stat block panel. A pure domain function calculates initiative as DEX modifier + (proficiency multiplier × proficiency bonus) from bestiary data. The bestiary adapter parses the initiative.proficiency field from 5etools JSON. The stat block component displays the result as "Initiative +X (Y)" in the header area next to AC, matching the Monster Manual 2024 format.

Technical Context

Language/Version: TypeScript 5.8 (strict mode, verbatimModuleSyntax) Primary Dependencies: React 19, Vite 6, Tailwind CSS v4, Lucide React (icons) Storage: N/A (no storage changes — purely derived from existing bestiary data) Testing: Vitest Target Platform: Browser (single-page web app) Project Type: Web application (monorepo: domain → application → web adapter) Performance Goals: N/A (simple arithmetic calculation, no performance concerns) Constraints: Domain layer must remain pure — no I/O or framework imports Scale/Scope: ~500 creatures in bestiary dataset

Constitution Check

GATE: Must pass before Phase 0 research. Re-check after Phase 1 design.

Principle Status Notes
I. Deterministic Domain Core PASS Initiative calculation is a pure function: (dex, cr, profMultiplier) → modifier. No I/O, randomness, or clocks.
II. Layered Architecture PASS Domain: pure calculateInitiative function. Adapter: parse initiative.proficiency from raw JSON into Creature type. Web: display in StatBlock component. No layer violations.
III. Agent Boundary N/A No agent layer involvement.
IV. Clarification-First PASS Feature is fully specified — formula, display format, and positioning are all explicit.
V. Escalation Gates PASS Display-only scope is clearly bounded. FR-007 explicitly excludes initiative rolling.
VI. MVP Baseline Language PASS Spec uses "MVP baseline does not include automatic initiative rolling or encounter order integration."
VII. No Gameplay Rules PASS Initiative calculation formula is in the feature spec, not the constitution.

Gate result: PASS — no violations.

Project Structure

Documentation (this feature)

specs/025-display-initiative/
├── plan.md              # This file
├── research.md          # Phase 0 output
├── data-model.md        # Phase 1 output
├── quickstart.md        # Phase 1 output
└── tasks.md             # Phase 2 output (/speckit.tasks command)

Source Code (repository root)

packages/domain/src/
├── creature-types.ts        # MODIFY: add initiativeProficiency field to Creature
├── initiative.ts            # NEW: pure calculateInitiative function
├── index.ts                 # MODIFY: export new function and types
└── __tests__/
    └── initiative.test.ts   # NEW: tests for initiative calculation

apps/web/src/
├── adapters/
│   └── bestiary-adapter.ts  # MODIFY: parse initiative.proficiency from raw JSON
└── components/
    └── stat-block.tsx        # MODIFY: display initiative in header area

Structure Decision: Follows existing monorepo layout. New domain function in its own file (initiative.ts) matching the pattern of other domain functions (e.g., hp-status.ts). No new packages or layers needed.