Files
initiative/specs/018-combatant-concentration/plan.md

3.6 KiB

Implementation Plan: Combatant Concentration

Branch: 018-combatant-concentration | Date: 2026-03-06 | Spec: spec.md Input: Feature specification from /specs/018-combatant-concentration/spec.md

Summary

Add concentration as a separate per-combatant boolean state (not a condition). A Brain icon toggle appears on hover (or stays visible when active), a colored left border accent marks concentrating combatants, and a pulse animation fires when a concentrating combatant takes damage. Implementation follows the existing toggle-condition pattern across all three layers (domain, application, web adapter).

Technical Context

Language/Version: TypeScript 5.8 (strict mode, verbatimModuleSyntax) Primary Dependencies: React 19, Vite 6, Tailwind CSS v4, Lucide React (icons) Storage: Browser localStorage (existing adapter, transparent JSON serialization) Testing: Vitest Target Platform: Modern browsers (local-first, single-user) Project Type: Web application (monorepo: domain / application / web) Performance Goals: Instant UI response on toggle; pulse animation ~600-800ms Constraints: No migration needed for localStorage; new optional boolean field is backward-compatible Scale/Scope: Single-user encounter tracker; ~10-20 combatants per encounter

Constitution Check

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

Principle Status Notes
I. Deterministic Domain Core PASS toggleConcentration is a pure function: same input encounter + combatant ID yields same output. No I/O, randomness, or clocks.
II. Layered Architecture PASS Domain defines the toggle function; Application orchestrates via EncounterStore port; Web adapter implements UI + persistence. No layer violations.
III. Agent Boundary N/A No agent/AI features in this feature.
IV. Clarification-First PASS Spec is fully specified; no NEEDS CLARIFICATION markers.
V. Escalation Gates PASS All work is within spec scope.
VI. MVP Baseline Language PASS No permanent bans introduced.
VII. No Gameplay Rules PASS Concentration is state tracking only; no automatic save mechanics or rule enforcement.

All gates pass. No violations to track.

Project Structure

Documentation (this feature)

specs/018-combatant-concentration/
├── plan.md
├── research.md
├── data-model.md
├── quickstart.md
└── tasks.md

Source Code (repository root)

packages/domain/src/
├── types.ts                          # Add isConcentrating to Combatant
├── events.ts                         # Add ConcentrationStarted/ConcentrationEnded
├── toggle-concentration.ts           # New pure domain function
├── index.ts                          # Re-export new function + events
└── __tests__/
    └── toggle-concentration.test.ts  # New test file

packages/application/src/
├── toggle-concentration-use-case.ts  # New use case
└── index.ts                          # Re-export

apps/web/src/
├── hooks/use-encounter.ts            # Add toggleConcentration callback
├── components/combatant-row.tsx      # Add Brain icon toggle + left border accent + pulse
├── persistence/encounter-storage.ts  # Add isConcentrating to rehydration
└── App.tsx                           # Wire toggleConcentration prop

Structure Decision: Follows existing monorepo layout with domain/application/web layers. Each new file mirrors the established pattern (e.g., toggle-concentration.ts mirrors toggle-condition.ts).