Replace prop drilling with React context providers. App.tsx shrinks from 427 lines to ~80 lines of pure layout. Components consume shared state directly via 7 context providers instead of threading 50+ props. Key changes: - 7 context providers wrapping existing hooks (encounter, bestiary, player characters, side panel, theme, bulk import, initiative rolls) - 2 coordinating hooks extracted from App.tsx (useInitiativeRolls, useAutoStatBlock) - All 9 affected components refactored from prop-based to context-based - 6 test files updated to use providers or context mocks - Prop count enforcement script (max 8 per component interface) - Constitution principle II-A added (context-based state flow) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
160 lines
6.7 KiB
Markdown
160 lines
6.7 KiB
Markdown
<!--
|
|
Sync Impact Report
|
|
───────────────────
|
|
Version change: 3.0.0 → 3.1.0 (MINOR — new principle II-A: context-based state flow)
|
|
Modified sections:
|
|
- Core Principles: added II-A. Context-Based State Flow (max 8 props, context over prop drilling)
|
|
Templates requiring updates: none
|
|
-->
|
|
# Encounter Console Constitution
|
|
|
|
## Core Principles
|
|
|
|
### I. Deterministic Domain Core
|
|
|
|
All domain logic MUST be implemented as pure state transitions.
|
|
Given the same input state and action, the output state MUST be
|
|
identical across runs. Side effects (I/O, randomness, clocks) MUST
|
|
be injected at the boundary, never sourced inside the domain layer.
|
|
|
|
- State transitions MUST be expressed as pure functions.
|
|
- Random values (e.g., dice rolls) MUST be passed in as resolved
|
|
inputs, not generated within the domain.
|
|
- Domain functions MUST NOT depend on wall-clock time, network, or
|
|
filesystem.
|
|
|
|
### II. Layered Architecture
|
|
|
|
The codebase MUST be organized into three layers with strict
|
|
dependency direction:
|
|
|
|
1. **Domain** — pure types, state transitions, validation rules.
|
|
No imports from other layers.
|
|
2. **Application** — orchestrates domain operations, manages
|
|
workflows, coordinates use cases. Application defines port
|
|
interfaces that Adapters implement. May import Domain only.
|
|
3. **Adapters** — I/O, persistence, UI rendering, external APIs.
|
|
May import Application and Domain.
|
|
|
|
A module in an inner layer MUST NOT import from an outer layer.
|
|
|
|
### II-A. Context-Based State Flow
|
|
|
|
UI components MUST consume shared application state via React context
|
|
providers, not prop drilling. Props are reserved for per-instance
|
|
configuration (e.g., a specific data item, a layout variant, a ref).
|
|
|
|
- Components MUST NOT declare more than 8 explicit props in their
|
|
own interface. This is enforced by `scripts/check-component-props.mjs`
|
|
at pre-commit.
|
|
- Generic UI primitives (`components/ui/`) that extend HTML element
|
|
attributes are exempt — only explicitly declared props count, not
|
|
inherited HTML attributes.
|
|
- Coordinating hooks that consume multiple contexts (e.g.,
|
|
`useInitiativeRolls`) are preferred over wiring callbacks through
|
|
a parent component.
|
|
|
|
### III. Clarification-First
|
|
|
|
Before making any non-trivial assumption during specification,
|
|
planning, or implementation, Claude Code MUST surface a clarification
|
|
question to the user. "Non-trivial" means any decision that would
|
|
alter observable behavior, data model shape, or public API surface.
|
|
Claude Code MUST also ask when multiple valid interpretations exist,
|
|
when a choice would affect architectural layering, or when scope
|
|
would expand beyond the current spec. Claude Code MUST NOT silently
|
|
choose among valid alternatives.
|
|
|
|
### IV. Escalation Gates
|
|
|
|
Any feature, requirement, or scope change not present in the current
|
|
spec MUST be rejected at implementation time until the spec is
|
|
explicitly updated. The workflow is:
|
|
|
|
1. Identify the out-of-scope item.
|
|
2. Document it as a proposal.
|
|
3. Update the spec via `/speckit.specify` or `/speckit.clarify`.
|
|
4. Only then proceed with implementation.
|
|
|
|
### V. MVP Baseline Language
|
|
|
|
Constraints in this constitution and in specs MUST use MVP baseline
|
|
language ("MVP baseline does not include X") rather than permanent
|
|
architectural bans ("X is forbidden"). This preserves the option to
|
|
add capabilities in future iterations without constitutional
|
|
amendment. The current MVP baseline is local-first and single-user;
|
|
this is a starting scope, not a permanent restriction.
|
|
|
|
### VI. No Gameplay Rules in Constitution
|
|
|
|
This constitution MUST NOT contain concrete gameplay mechanics,
|
|
rule-system specifics, or encounter resolution logic. Such details
|
|
belong in feature specs. The constitution governs process,
|
|
architecture, and quality — not product behavior.
|
|
|
|
## Scope Constraints
|
|
|
|
- The Encounter Console's primary focus is initiative tracking and
|
|
encounter state management. Adjacent capabilities (e.g., bestiary
|
|
integration, richer game-engine features) may be added via spec
|
|
updates.
|
|
- Technology choices, UI framework, and storage mechanism are
|
|
spec-level decisions, not constitutional mandates.
|
|
- Testing strategy (unit, integration, contract) is determined per
|
|
feature spec; the constitution requires only that domain logic
|
|
remains testable via pure-function assertions.
|
|
|
|
## Development Workflow
|
|
|
|
- No change may be merged unless all automated checks (tests and
|
|
static analysis as defined by the project) pass.
|
|
- Specs describe **features**, not individual changes. Each spec is
|
|
a living document. New features begin with `/speckit.specify`
|
|
(which creates a feature branch for the full speckit pipeline);
|
|
changes to existing features update the existing spec via
|
|
`/integrate-issue`.
|
|
- The full pipeline (spec → plan → tasks → implement) applies to new
|
|
features and significant additions. Bug fixes, tooling changes,
|
|
and trivial UI adjustments do not require specs.
|
|
- Domain logic MUST be testable without mocks for external systems.
|
|
- Long-running or multi-step state transitions SHOULD be verifiable
|
|
through reproducible event logs or snapshot-style tests.
|
|
- Commits SHOULD be atomic and map to individual tasks where
|
|
practical.
|
|
- Layer boundary compliance MUST be verified by automated import
|
|
rules or architectural tests.
|
|
- All automated quality gates MUST run at the earliest feasible
|
|
enforcement point (currently pre-commit via Lefthook). No gate
|
|
may exist only as a CI step or manual process.
|
|
- When a feature adds, removes, or changes user-facing capabilities
|
|
described in README.md, the README MUST be updated in the same
|
|
change. Features that materially alter what the product does or
|
|
how it is set up SHOULD also be reflected in the README.
|
|
- When a feature changes the tech stack, project structure, or
|
|
architectural patterns documented in CLAUDE.md, the CLAUDE.md
|
|
MUST be updated in the same change.
|
|
|
|
## Governance
|
|
|
|
This constitution is the highest-authority document for the
|
|
Encounter Console project. All specs, plans, and implementations
|
|
MUST comply with its principles.
|
|
|
|
**Amendment procedure**:
|
|
1. Propose change with rationale.
|
|
2. Update constitution via `/speckit.constitution`.
|
|
3. Verify downstream template compatibility (Sync Impact Report).
|
|
4. A human maintainer MUST review and commit the update before
|
|
ratification takes effect.
|
|
5. Commit with version bump.
|
|
|
|
**Versioning policy**: MAJOR.MINOR.PATCH per semantic versioning.
|
|
- MAJOR: principle removal or backward-incompatible redefinition.
|
|
- MINOR: new principle or materially expanded guidance.
|
|
- PATCH: clarification, typo, or non-semantic refinement.
|
|
|
|
**Compliance review**: Every spec and plan MUST include a
|
|
Constitution Check section validating adherence to all principles.
|
|
|
|
**Version**: 3.1.0 | **Ratified**: 2026-03-03 | **Last Amended**: 2026-03-19
|