Files
initiative/specs/005-set-initiative/plan.md

3.7 KiB

Implementation Plan: Set Initiative

Branch: 005-set-initiative | Date: 2026-03-04 | Spec: spec.md Input: Feature specification from /specs/005-set-initiative/spec.md

Summary

Add an optional integer initiative property to combatants and a setInitiative domain function that sets/changes/clears the value and automatically reorders combatants descending by initiative (unset last, stable sort for ties). The active combatant's turn is preserved through reorders by tracking identity rather than position.

Technical Context

Language/Version: TypeScript 5.x (strict mode, verbatimModuleSyntax) Primary Dependencies: React 19, Vite Storage: In-memory React state (local-first, single-user MVP) Testing: Vitest Target Platform: Web browser (localhost:5173 dev) Project Type: Web application (monorepo: domain → application → web adapter) Performance Goals: N/A (local in-memory, trivial data sizes) Constraints: Pure domain functions, no I/O in domain layer Scale/Scope: Single-user, single encounter

Constitution Check

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

Principle Status Notes
I. Deterministic Domain Core PASS setInitiative is a pure function: same encounter + id + value → same result. No I/O, randomness, or clocks.
II. Layered Architecture PASS Domain function in packages/domain, use case in packages/application, UI in apps/web. Dependency direction preserved.
III. Agent Boundary N/A No agent layer involvement in this feature.
IV. Clarification-First PASS Spec has no NEEDS CLARIFICATION markers. All design decisions are spec-driven.
V. Escalation Gates PASS Feature scope matches spec exactly. No out-of-scope additions.
VI. MVP Baseline Language PASS Spec uses "MVP baseline does not include" for secondary tiebreakers.
VII. No Gameplay Rules PASS Constitution contains no gameplay mechanics; initiative logic is in the spec.

All gates pass. No violations to justify.

Post-Design Re-check: All gates still pass. The setInitiative domain function is pure, layering is preserved, and no out-of-scope additions were introduced during design.

Project Structure

Documentation (this feature)

specs/005-set-initiative/
├── spec.md
├── plan.md              # This file
├── research.md          # Phase 0 output
├── data-model.md        # Phase 1 output
├── quickstart.md        # Phase 1 output
├── contracts/           # Phase 1 output
│   └── domain-api.md
├── checklists/
│   └── requirements.md
└── tasks.md             # Phase 2 output (via /speckit.tasks)

Source Code (repository root)

packages/domain/src/
├── types.ts                    # Modified: add initiative to Combatant
├── events.ts                   # Modified: add InitiativeSet event
├── set-initiative.ts           # New: setInitiative domain function
├── index.ts                    # Modified: export setInitiative
└── __tests__/
    └── set-initiative.test.ts  # New: tests for setInitiative

packages/application/src/
├── set-initiative-use-case.ts  # New: setInitiativeUseCase
└── index.ts                    # Modified: export use case

apps/web/src/
├── hooks/
│   └── use-encounter.ts        # Modified: add setInitiative callback
└── App.tsx                     # Modified: add initiative input field

Structure Decision: Follows existing monorepo layered structure. Each new domain operation gets its own file per established convention.

Complexity Tracking

No constitution violations. Table not needed.