docs: adopt unified-3.0 Claude rule set + trim duplications
Adopts the four-file rule set the player added to the working tree:
- CLAUDE.md grows from a 114-line pointer doc to the 571-line
`unified-3.0` rulebook: hard global constraints (§2), engine
rules (§3), asset rules (§4), code standards (§5), build +
verification (§6), git workflow (§7), the change-control
ASK BEFORE list (§8), and the Context Injection System (§14).
- CLAUDE_SPEC.md — formal architecture spec: crate dependency
graph with forbidden_deps, data ownership map, state-machine
invariants ("52 cards always exist", "no duplicate IDs",
"all cards belong to exactly one pile"), sync merge contract,
server contract, validation checklist.
- CLAUDE_WORKFLOW.md — two-agent Builder/Guardian pipeline with
hard-fail patterns that auto-reject (core uses IO/Bevy/network,
GameState mutated outside GameLogicSystem, blocking async on
main thread, duplicate logic, merge altered incorrectly).
- CLAUDE_PROMPT_PACK.md — task-type templates.
Three duplicate rule passages removed:
- CLAUDE_SPEC.md §0 dropped no_panics_in_core / core_is_pure /
event_driven_engine — already canonical in CLAUDE.md §2.1, §2.3,
§3.1. Kept single_source_of_truth and sync_is_additive (those
describe data flow, not in CLAUDE.md).
- CLAUDE_SPEC.md §11 Prohibited Patterns now references CLAUDE.md
§11 instead of restating the same five forbidden items.
- ARCHITECTURE.md Design Principles dropped the pure-core /
no-panics / UI-first bullets — those are enforcement constraints
living in CLAUDE.md §2.1, §2.3, §3.3; this file describes the
design that motivates them. Kept the offline-first, one-language,
and plugin-based-Bevy bullets (those are descriptive, not
enforcement).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
+2
-3
@@ -47,11 +47,10 @@ Solitaire Quest is a cross-platform Klondike Solitaire game written in Rust, tar
|
|||||||
### Design Principles
|
### Design Principles
|
||||||
|
|
||||||
- **Offline first.** The local file is always the source of truth. Sync is additive, never destructive.
|
- **Offline first.** The local file is always the source of truth. Sync is additive, never destructive.
|
||||||
- **Pure core.** All game logic lives in a dependency-free Rust crate with no Bevy, no network, and no I/O. This keeps it fully unit-testable and portable.
|
|
||||||
- **No panics in game logic.** Every state transition returns `Result<_, MoveError>`. Panics are only acceptable in startup/configuration code.
|
|
||||||
- **One language, one repo.** The game client, sync client, shared types, and sync server are all Rust crates in a single Cargo workspace.
|
- **One language, one repo.** The game client, sync client, shared types, and sync server are all Rust crates in a single Cargo workspace.
|
||||||
- **Plugin-based Bevy architecture.** Each major feature is a Bevy `Plugin`. Systems are small and single-purpose. Cross-system communication uses Bevy `Event`s.
|
- **Plugin-based Bevy architecture.** Each major feature is a Bevy `Plugin`. Systems are small and single-purpose. Cross-system communication uses Bevy `Event`s.
|
||||||
- **UI-first interaction.** Every player-triggered action — new game, undo, draw, pause, open stats / settings / help / profile / leaderboard, etc. — must be reachable from a visible UI control. Keyboard shortcuts exist only as optional accelerators for power users; they are never the sole entry point. A player using only mouse or touch must be able to perform every action. New gameplay features ship with the UI control alongside the system that backs it.
|
|
||||||
|
Pure-core, no-panics-in-game-logic, and UI-first-interaction constraints are enforced by CLAUDE.md §2.1, §2.3, and §3.3 respectively — those are the canonical statements; this file describes the design that motivates them.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
@@ -1,114 +1,571 @@
|
|||||||
# Solitaire Quest — Claude Code Instructions
|
# CLAUDE.md
|
||||||
|
|
||||||
See @ARCHITECTURE.md for full project design, crate responsibilities, data models, and API reference.
|
version: unified-3.0
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Project Layout
|
# 0. Role of This File
|
||||||
|
|
||||||
```text
|
This document defines:
|
||||||
solitaire_core/ # Pure Rust game logic — NO Bevy, NO network, NO I/O
|
|
||||||
solitaire_sync/ # Shared API types — NO Bevy, serde/uuid/chrono only
|
* **Execution rules (what Claude must do)**
|
||||||
solitaire_data/ # Persistence + SyncProvider trait + server client
|
* **System constraints (what Claude must never violate)**
|
||||||
solitaire_engine/ # Bevy ECS systems, components, plugins
|
* **Operational architecture (how code is structured)**
|
||||||
solitaire_server/ # Axum sync server binary
|
|
||||||
solitaire_app/ # Thin binary entry point
|
For full system design details:
|
||||||
assets/ # Source assets — embedded at compile time via include_bytes!()
|
→ `ARCHITECTURE.md` (authoritative source of truth)
|
||||||
|
|
||||||
|
This file overrides all conversational assumptions.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# 1. System Architecture (Authoritative Mapping)
|
||||||
|
|
||||||
|
## 1.1 Crates
|
||||||
|
|
||||||
|
```text id="crate_map"
|
||||||
|
solitaire_core/ # PURE logic (no IO, no Bevy, deterministic)
|
||||||
|
solitaire_sync/ # Shared API + merge logic
|
||||||
|
solitaire_data/ # Persistence + sync client
|
||||||
|
solitaire_engine/ # Bevy ECS + UI + gameplay orchestration
|
||||||
|
solitaire_server/ # Axum backend (optional sync layer)
|
||||||
|
solitaire_app/ # Entry binary
|
||||||
|
assets/ # Runtime assets (except audio)
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Build & Test Commands
|
## 1.2 Architecture Source of Truth
|
||||||
|
|
||||||
```bash
|
* Full system design: `ARCHITECTURE.md`
|
||||||
# Dev run (fast compile via dynamic linking)
|
* This file NEVER redefines system design
|
||||||
cargo run -p solitaire_app --features bevy/dynamic_linking
|
* This file ONLY enforces behavior
|
||||||
|
|
||||||
# Release build
|
---
|
||||||
cargo build --workspace --release
|
|
||||||
|
|
||||||
# All tests — MUST pass before any commit
|
# 2. Hard Global Constraints (NON-NEGOTIABLE)
|
||||||
|
|
||||||
|
These override all other instructions.
|
||||||
|
|
||||||
|
## 2.1 Core Determinism
|
||||||
|
|
||||||
|
* `solitaire_core` MUST:
|
||||||
|
|
||||||
|
* be deterministic
|
||||||
|
* be side-effect free
|
||||||
|
* never depend on Bevy / IO / async
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2.2 Sync Isolation
|
||||||
|
|
||||||
|
* `solitaire_sync`:
|
||||||
|
|
||||||
|
* no Bevy
|
||||||
|
* no IO
|
||||||
|
* no engine dependencies
|
||||||
|
* merge logic must be pure functions only
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2.3 Error Policy
|
||||||
|
|
||||||
|
* NO `unwrap()`
|
||||||
|
* NO `panic!()` in runtime/game logic
|
||||||
|
* All state transitions:
|
||||||
|
|
||||||
|
```rust id="err_model"
|
||||||
|
Result<T, MoveError>
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2.4 Threading Rules
|
||||||
|
|
||||||
|
* Sync must run on `AsyncComputeTaskPool`
|
||||||
|
* NEVER block Bevy main thread
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2.5 Persistence Rules
|
||||||
|
|
||||||
|
* atomic writes only:
|
||||||
|
|
||||||
|
* write `.tmp`
|
||||||
|
* rename atomically
|
||||||
|
* no partial state writes allowed
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2.6 Security Rules
|
||||||
|
|
||||||
|
* credentials ONLY via `keyring`
|
||||||
|
* NEVER store secrets in:
|
||||||
|
|
||||||
|
* files
|
||||||
|
* logs
|
||||||
|
* source code
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2.7 Sync System Rules
|
||||||
|
|
||||||
|
* All sync backends implement:
|
||||||
|
|
||||||
|
```rust id="sync_trait"
|
||||||
|
trait SyncProvider
|
||||||
|
```
|
||||||
|
|
||||||
|
* `SyncPlugin` MUST be backend-agnostic
|
||||||
|
* NEVER match on backend inside ECS systems
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# 3. Engine Rules (Bevy Layer)
|
||||||
|
|
||||||
|
## 3.1 ECS Design
|
||||||
|
|
||||||
|
* systems = single responsibility
|
||||||
|
* communication = Events only
|
||||||
|
* shared state = Resources only
|
||||||
|
* per-entity state = Components only
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 3.2 Game State Authority
|
||||||
|
|
||||||
|
* ONLY `GameStateResource` can mutate game state
|
||||||
|
* UI systems MUST NOT directly modify core logic
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 3.3 UI-First Constraint (CRITICAL)
|
||||||
|
|
||||||
|
Every player action MUST:
|
||||||
|
|
||||||
|
* have a visible UI control
|
||||||
|
* NOT rely solely on keyboard shortcuts
|
||||||
|
|
||||||
|
Keyboard shortcuts are:
|
||||||
|
→ optional accelerators only
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 3.4 Layout System
|
||||||
|
|
||||||
|
* recompute on `WindowResized`
|
||||||
|
* no fixed resolution assumptions
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# 4. Asset System Rules
|
||||||
|
|
||||||
|
## 4.1 Runtime Assets (AssetServer)
|
||||||
|
|
||||||
|
Loaded via:
|
||||||
|
|
||||||
|
* `CardImageSet`
|
||||||
|
* `BackgroundImageSet`
|
||||||
|
* `FontResource`
|
||||||
|
|
||||||
|
Includes:
|
||||||
|
|
||||||
|
* cards
|
||||||
|
* backgrounds
|
||||||
|
* fonts
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 4.2 Embedded Assets
|
||||||
|
|
||||||
|
Only audio:
|
||||||
|
|
||||||
|
```text id="audio_rule"
|
||||||
|
include_bytes!()
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 4.3 Test Compatibility Rule
|
||||||
|
|
||||||
|
All asset loaders MUST accept:
|
||||||
|
|
||||||
|
```rust id="asset_fallback"
|
||||||
|
Option<Res<AssetServer>>
|
||||||
|
```
|
||||||
|
|
||||||
|
Must degrade gracefully under `MinimalPlugins`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# 5. Code Standards
|
||||||
|
|
||||||
|
## 5.1 Error Handling
|
||||||
|
|
||||||
|
* use `thiserror`
|
||||||
|
* no `Box<dyn Error>` in libraries
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 5.2 Public API Rules
|
||||||
|
|
||||||
|
* prefer `Into<T>` over concrete types
|
||||||
|
* all public items require doc comments
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 5.3 Derive Order
|
||||||
|
|
||||||
|
```rust id="derive_order"
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 5.4 Performance Rules
|
||||||
|
|
||||||
|
* NO `clone()` in hot paths
|
||||||
|
* profile before optimizing
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 5.5 SQL Rules
|
||||||
|
|
||||||
|
* ONLY `sqlx::query!`
|
||||||
|
* NO raw SQL strings
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# 6. Build & Verification Rules
|
||||||
|
|
||||||
|
These are mandatory before ANY commit.
|
||||||
|
|
||||||
|
```bash id="build_rules"
|
||||||
cargo test --workspace
|
cargo test --workspace
|
||||||
|
|
||||||
# Lint — MUST pass clean (zero warnings)
|
|
||||||
cargo clippy --workspace -- -D warnings
|
cargo clippy --workspace -- -D warnings
|
||||||
|
|
||||||
# Run sync server locally
|
|
||||||
cargo run -p solitaire_server
|
|
||||||
|
|
||||||
# Check a single crate
|
|
||||||
cargo test -p solitaire_core
|
|
||||||
cargo clippy -p solitaire_core -- -D warnings
|
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Hard Rules
|
# 7. Git Workflow Rules
|
||||||
|
|
||||||
- `solitaire_core` and `solitaire_sync` must never gain Bevy or network dependencies.
|
## Commit format
|
||||||
- No `unwrap()` or `panic!()` in game logic. All state transitions return `Result<_, MoveError>`.
|
|
||||||
- Audio assets are embedded at compile time using `include_bytes!()` in `audio_plugin.rs`.
|
```text id="commit_fmt"
|
||||||
- Card faces (52 PNGs in `assets/cards/faces/`), card backs (`assets/cards/backs/back_N.png`), board backgrounds (`assets/backgrounds/bg_N.png`), and the UI font (`assets/fonts/main.ttf`) are loaded at runtime via `AssetServer::load()` and stored as `Handle<Image>`/`Handle<Font>` in the `CardImageSet`, `BackgroundImageSet`, and `FontResource` resources. The `assets/` directory must ship alongside the binary.
|
type(scope): description
|
||||||
- Asset-loading systems take `Option<Res<AssetServer>>` so they degrade cleanly under `MinimalPlugins` (tests). When `CardImageSet` is absent, `card_plugin` falls back to a `Text2d` rank+suit overlay; when `BackgroundImageSet` is absent, the board falls back to a solid colour.
|
```
|
||||||
- Atomic file writes only: write to `filename.json.tmp`, then `rename()`.
|
|
||||||
- Passwords and tokens are stored in the OS keychain via the `keyring` crate — never in plaintext files or logs.
|
Examples:
|
||||||
- Sync runs on `AsyncComputeTaskPool` — never block the Bevy main thread.
|
|
||||||
- All sync backends implement the `SyncProvider` trait. The `SyncPlugin` is backend-agnostic — never `match` on `SyncBackend` inside a Bevy system.
|
* feat(core): add draw-three rules
|
||||||
- `cargo clippy --workspace -- -D warnings` must pass clean after every change.
|
* fix(engine): correct drag z-order
|
||||||
- `cargo test --workspace` must pass after every change.
|
* test(core): undo boundary cases
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Code Style
|
## Commit conditions
|
||||||
|
|
||||||
- Use `thiserror` for error types. Never `Box<dyn Error>` in library crates.
|
* tests must pass
|
||||||
- Prefer `Into<T>` over concrete types in public API function parameters.
|
* clippy must be clean
|
||||||
- All public items must have doc comments (`///`). Private items: comment only when non-obvious.
|
|
||||||
- Derive order convention: `#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]`
|
NEVER commit otherwise
|
||||||
- Bevy systems: one responsibility per system. Use `Events` for cross-system communication, never shared mutable state.
|
|
||||||
- SQL queries: use `sqlx::query!` macros (compile-time checked), not raw string queries.
|
|
||||||
- No `clone()` calls in hot paths (game loop systems). Profile before optimising elsewhere.
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Bevy Conventions
|
# 8. Change Control (ASK BEFORE DOING)
|
||||||
|
|
||||||
- One `Plugin` per major feature: `CardPlugin`, `AudioPlugin`, `AchievementPlugin`, `UIPlugin`, `SyncPlugin`.
|
Claude must request confirmation before:
|
||||||
- Resources own shared state. Events communicate between systems. Components own per-entity data.
|
|
||||||
- All UI screens are built with Bevy UI (`bevy::ui`). Never mix UI layout and game logic in the same system.
|
* adding dependencies
|
||||||
- Layout is recomputed on `WindowResized` — never assume a fixed window size.
|
* modifying `solitaire_sync`
|
||||||
- **UI-first.** Every player-triggered action (new game, undo, draw, pause, open stats / settings / help / profile / leaderboard, switch mode, etc.) must be reachable from a visible UI control. Keyboard shortcuts are optional accelerators — never the sole entry point. New gameplay features ship with the UI control alongside the system that backs it; do not merge a feature that is keyboard-only.
|
* changing DB schema
|
||||||
|
* introducing `unsafe`
|
||||||
|
* changing merge strategy
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Git Workflow
|
# 9. System Mental Model (IMPORTANT)
|
||||||
|
|
||||||
- Commit after each passing phase, not after every file change.
|
```text id="mental_model"
|
||||||
- Commit message format: `type(scope): description`
|
Core (rules + deterministic logic)
|
||||||
- `feat(core): add draw-three mode validation`
|
↓
|
||||||
- `fix(engine): card z-order during drag`
|
Engine (Bevy orchestration)
|
||||||
- `test(core): undo stack boundary conditions`
|
↓
|
||||||
- `chore(server): add sqlx migration 002`
|
Data layer (persistence + sync)
|
||||||
- Never commit with failing tests or clippy warnings.
|
↓
|
||||||
- Never commit secrets, `.env` files, or `*.db` files.
|
Server (optional external system)
|
||||||
|
```
|
||||||
|
|
||||||
|
Core is always the source of truth.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Ask Before Doing
|
# 10. Known Platform Pitfalls
|
||||||
|
|
||||||
- Adding a new crate dependency (discuss alternatives first).
|
Must always be handled explicitly:
|
||||||
- Changing a type in `solitaire_sync` (breaking change on both client and server).
|
|
||||||
- Altering the database schema (requires a new sqlx migration).
|
* Bevy `Time` uses `f32`
|
||||||
- Introducing `unsafe` code anywhere.
|
* `sqlx::migrate!()` path is crate-relative
|
||||||
- Changing the merge strategy in `solitaire_sync::merge()`.
|
* `dirs::data_dir()` may return `None`
|
||||||
|
* Linux may lack keyring backend
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Lessons Learned
|
# 11. Forbidden Patterns
|
||||||
|
|
||||||
> Add entries here when Claude makes a mistake so it isn't repeated.
|
* game logic inside Bevy systems
|
||||||
|
* duplication across crates
|
||||||
|
* blocking async calls in ECS
|
||||||
|
* insecure credential storage
|
||||||
|
* bypassing core logic layer
|
||||||
|
|
||||||
- Bevy's `Time` resource uses `f32` seconds; convert to `u64` only when writing to `StatsSnapshot`.
|
---
|
||||||
- `sqlx::migrate!()` macro path is relative to the crate root, not the workspace root.
|
|
||||||
- `keyring` on Linux requires a running secret service (e.g. GNOME Keyring or KWallet) — handle `Error::NoStorageAccess` gracefully and fall back to prompting the user.
|
# 12. Execution Rules for Claude
|
||||||
- `dirs::data_dir()` returns `None` on some minimal Linux environments — always handle the `None` case explicitly, do not unwrap.
|
|
||||||
|
When generating code:
|
||||||
|
|
||||||
|
1. respect crate boundaries
|
||||||
|
2. minimize diff size
|
||||||
|
3. do not expand scope
|
||||||
|
4. follow existing patterns
|
||||||
|
5. preserve invariants
|
||||||
|
|
||||||
|
If unclear:
|
||||||
|
→ ask before acting
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# 13. Relationship to ARCHITECTURE.md
|
||||||
|
|
||||||
|
| File | Role |
|
||||||
|
| --------------- | ------------------------- |
|
||||||
|
| CLAUDE.md | execution + constraints |
|
||||||
|
| ARCHITECTURE.md | system design truth |
|
||||||
|
| Both combined | full system understanding |
|
||||||
|
|
||||||
|
---
|
||||||
|
# 14. Context Injection System (AUTOMATIC SCOPE FILTER)
|
||||||
|
|
||||||
|
## 14.1 Purpose
|
||||||
|
|
||||||
|
Before generating any response, Claude MUST construct a **minimal relevant context set**.
|
||||||
|
|
||||||
|
This prevents:
|
||||||
|
|
||||||
|
* architectural drift
|
||||||
|
* irrelevant spec loading
|
||||||
|
* over-engineering
|
||||||
|
* cross-crate confusion
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 14.2 Input Classification Step (MANDATORY)
|
||||||
|
|
||||||
|
Every request MUST be classified into exactly one task type:
|
||||||
|
|
||||||
|
```text id="task_types"
|
||||||
|
feature
|
||||||
|
bugfix
|
||||||
|
refactor
|
||||||
|
system_design
|
||||||
|
bevy_system
|
||||||
|
core_logic
|
||||||
|
sync
|
||||||
|
optimization
|
||||||
|
test
|
||||||
|
debug
|
||||||
|
```
|
||||||
|
|
||||||
|
If uncertain → ask clarification.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 14.3 Context Selection Engine
|
||||||
|
|
||||||
|
After classification, Claude MUST include ONLY the relevant sections below.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 14.4 Context Map (CORE RULESET)
|
||||||
|
|
||||||
|
### feature
|
||||||
|
|
||||||
|
Include:
|
||||||
|
|
||||||
|
* §2 Hard Global Constraints
|
||||||
|
* §3 Engine Rules
|
||||||
|
* ARCHITECTURE.md (crate of target feature only)
|
||||||
|
* relevant data models (GameState, SyncPayload if needed)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### bugfix
|
||||||
|
|
||||||
|
Include:
|
||||||
|
|
||||||
|
* §2 Hard Global Constraints
|
||||||
|
* §5 Code Standards
|
||||||
|
* affected crate boundaries
|
||||||
|
* relevant system (engine/core/sync only)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### refactor
|
||||||
|
|
||||||
|
Include:
|
||||||
|
|
||||||
|
* §3 Engine Rules
|
||||||
|
* §5 Code Standards
|
||||||
|
* §11 Forbidden Patterns
|
||||||
|
* target crate boundaries
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### system_design
|
||||||
|
|
||||||
|
Include:
|
||||||
|
|
||||||
|
* ARCHITECTURE.md (FULL)
|
||||||
|
* §9 Mental Model
|
||||||
|
* §1 System Architecture Mapping
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### core_logic
|
||||||
|
|
||||||
|
Include:
|
||||||
|
|
||||||
|
* solitaire_core rules only
|
||||||
|
* GameState model
|
||||||
|
* MoveError model
|
||||||
|
* §2.1–2.3 constraints
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### bevy_system
|
||||||
|
|
||||||
|
Include:
|
||||||
|
|
||||||
|
* §3 Engine Rules
|
||||||
|
* ECS rules (Events/Resources/Components)
|
||||||
|
* UI-first constraint
|
||||||
|
* relevant plugin system only
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### sync
|
||||||
|
|
||||||
|
Include:
|
||||||
|
|
||||||
|
* SyncProvider trait
|
||||||
|
* merge strategy rules
|
||||||
|
* solitaire_sync models
|
||||||
|
* §2.6 Sync Rules
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### optimization
|
||||||
|
|
||||||
|
Include:
|
||||||
|
|
||||||
|
* target crate only
|
||||||
|
* §5.4 Performance Rules
|
||||||
|
* hot path constraints
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### test
|
||||||
|
|
||||||
|
Include:
|
||||||
|
|
||||||
|
* §6 Build Rules
|
||||||
|
* relevant module
|
||||||
|
* expected invariants
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### debug
|
||||||
|
|
||||||
|
Include:
|
||||||
|
|
||||||
|
* target file/module only
|
||||||
|
* §2.3 Error Policy
|
||||||
|
* runtime assumptions relevant to failure
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 14.5 Context Compression Rules
|
||||||
|
|
||||||
|
Claude MUST obey:
|
||||||
|
|
||||||
|
* never include full ARCHITECTURE.md unless system_design
|
||||||
|
* max 2 crates per response unless explicitly required
|
||||||
|
* prefer function-level context over file-level context
|
||||||
|
* exclude unrelated plugins/systems
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 14.6 Context Priority Order
|
||||||
|
|
||||||
|
When space is limited:
|
||||||
|
|
||||||
|
1. Hard Constraints (§2)
|
||||||
|
2. Target crate rules
|
||||||
|
3. Data models
|
||||||
|
4. Only then: architecture snippets
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 14.7 “No Context Pollution” Rule
|
||||||
|
|
||||||
|
Claude must NOT include:
|
||||||
|
|
||||||
|
* unrelated crates
|
||||||
|
* unrelated plugins
|
||||||
|
* unused data models
|
||||||
|
* full architecture dumps
|
||||||
|
* speculative systems
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 14.8 Self-Check Before Execution
|
||||||
|
|
||||||
|
Before writing code, Claude MUST verify:
|
||||||
|
|
||||||
|
* [ ] Is only relevant context included?
|
||||||
|
* [ ] Is at least one hard constraint present?
|
||||||
|
* [ ] Am I touching more than one crate unnecessarily?
|
||||||
|
* [ ] Am I duplicating ARCHITECTURE.md content?
|
||||||
|
|
||||||
|
If any fail → revise context selection.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 14.9 Injection Output Format (Internal Model)
|
||||||
|
|
||||||
|
Claude should behave as if it constructed:
|
||||||
|
|
||||||
|
```text id="ctx_format"
|
||||||
|
[SELECTED TASK TYPE]
|
||||||
|
|
||||||
|
[MINIMAL REQUIRED RULES]
|
||||||
|
|
||||||
|
[MINIMAL ARCHITECTURE SLICES]
|
||||||
|
|
||||||
|
[RELEVANT MODELS]
|
||||||
|
|
||||||
|
[REQUEST]
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 14.10 Relationship to ARCHITECTURE.md
|
||||||
|
|
||||||
|
* ARCHITECTURE.md = source of truth
|
||||||
|
* CLAUDE.md = execution constraints
|
||||||
|
* THIS SECTION = filtering layer between them
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# END CONTEXT INJECTION SYSTEM
|
||||||
|
|||||||
@@ -0,0 +1,497 @@
|
|||||||
|
# CLAUDE_PROMPT_PACK.md
|
||||||
|
|
||||||
|
version: 1.0
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# 0. GLOBAL INSTRUCTION (prepend to every prompt)
|
||||||
|
|
||||||
|
```
|
||||||
|
You must follow CLAUDE_SPEC.md strictly.
|
||||||
|
|
||||||
|
Rules:
|
||||||
|
- Do not expand scope beyond what is defined
|
||||||
|
- Do not refactor unrelated code
|
||||||
|
- Do not introduce new dependencies
|
||||||
|
- Prefer minimal, surgical changes
|
||||||
|
- Use existing patterns in the codebase
|
||||||
|
- Return minimal diffs or changed functions only
|
||||||
|
|
||||||
|
Before writing code:
|
||||||
|
1. List relevant constraints from CLAUDE_SPEC.md
|
||||||
|
2. Identify risks
|
||||||
|
3. Then implement
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# 1. FEATURE IMPLEMENTATION
|
||||||
|
|
||||||
|
```
|
||||||
|
# TASK: Feature Implementation
|
||||||
|
|
||||||
|
feature: "<name>"
|
||||||
|
|
||||||
|
goal:
|
||||||
|
"<clear outcome>"
|
||||||
|
|
||||||
|
scope:
|
||||||
|
crates: []
|
||||||
|
systems: []
|
||||||
|
files: []
|
||||||
|
|
||||||
|
non_goals:
|
||||||
|
- ""
|
||||||
|
|
||||||
|
constraints:
|
||||||
|
- must follow CLAUDE_SPEC.md
|
||||||
|
- event-driven architecture required
|
||||||
|
- no blocking operations
|
||||||
|
- no cross-crate leakage
|
||||||
|
|
||||||
|
acceptance_criteria:
|
||||||
|
- ""
|
||||||
|
- ""
|
||||||
|
|
||||||
|
edge_cases:
|
||||||
|
- ""
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Required Patterns
|
||||||
|
|
||||||
|
Use this pattern for systems:
|
||||||
|
<PASTE EXISTING SYSTEM SNIPPET HERE>
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Output Format
|
||||||
|
|
||||||
|
intent:
|
||||||
|
plan:
|
||||||
|
constraints_used:
|
||||||
|
risks:
|
||||||
|
|
||||||
|
code_changes:
|
||||||
|
(minimal diffs only)
|
||||||
|
|
||||||
|
notes:
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# 2. BUGFIX
|
||||||
|
|
||||||
|
```
|
||||||
|
# TASK: Bug Fix
|
||||||
|
|
||||||
|
bug_description:
|
||||||
|
"<what is broken>"
|
||||||
|
|
||||||
|
expected_behavior:
|
||||||
|
"<correct behavior>"
|
||||||
|
|
||||||
|
root_cause_hint (optional):
|
||||||
|
""
|
||||||
|
|
||||||
|
scope:
|
||||||
|
crates: []
|
||||||
|
files: []
|
||||||
|
|
||||||
|
constraints:
|
||||||
|
- minimal fix only
|
||||||
|
- no refactors unless required
|
||||||
|
- must add regression protection if applicable
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
|
||||||
|
1. Identify root cause
|
||||||
|
2. Fix it minimally
|
||||||
|
3. Preserve all invariants
|
||||||
|
4. Do not change unrelated logic
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Output Format
|
||||||
|
|
||||||
|
analysis:
|
||||||
|
root_cause:
|
||||||
|
fix_strategy:
|
||||||
|
|
||||||
|
code_changes:
|
||||||
|
(minimal diff)
|
||||||
|
|
||||||
|
regression_test (only if high-value):
|
||||||
|
|
||||||
|
notes:
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# 3. REFACTOR
|
||||||
|
|
||||||
|
```
|
||||||
|
# TASK: Refactor
|
||||||
|
|
||||||
|
target:
|
||||||
|
"<what is being improved>"
|
||||||
|
|
||||||
|
goal:
|
||||||
|
"<what improves>"
|
||||||
|
|
||||||
|
scope:
|
||||||
|
crates: []
|
||||||
|
files: []
|
||||||
|
|
||||||
|
non_goals:
|
||||||
|
- no behavior changes
|
||||||
|
- no new features
|
||||||
|
|
||||||
|
constraints:
|
||||||
|
- must preserve behavior exactly
|
||||||
|
- must respect crate boundaries
|
||||||
|
- must not duplicate logic
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Refactor Type
|
||||||
|
|
||||||
|
- [ ] simplify logic
|
||||||
|
- [ ] reduce duplication
|
||||||
|
- [ ] improve readability
|
||||||
|
- [ ] performance (non-invasive)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Output Format
|
||||||
|
|
||||||
|
analysis:
|
||||||
|
issues_found:
|
||||||
|
|
||||||
|
refactor_plan:
|
||||||
|
|
||||||
|
code_changes:
|
||||||
|
(diff only)
|
||||||
|
|
||||||
|
verification:
|
||||||
|
- behavior unchanged: yes/no
|
||||||
|
- invariants preserved: yes/no
|
||||||
|
|
||||||
|
notes:
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# 4. SYSTEM DESIGN (NEW FEATURE)
|
||||||
|
|
||||||
|
```
|
||||||
|
# TASK: System Design
|
||||||
|
|
||||||
|
feature:
|
||||||
|
"<name>"
|
||||||
|
|
||||||
|
goal:
|
||||||
|
"<what problem it solves>"
|
||||||
|
|
||||||
|
constraints:
|
||||||
|
- must fit existing architecture
|
||||||
|
- must follow plugin + event model
|
||||||
|
- must not violate crate boundaries
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Required Output
|
||||||
|
|
||||||
|
design:
|
||||||
|
|
||||||
|
components:
|
||||||
|
- plugins:
|
||||||
|
- systems:
|
||||||
|
- events:
|
||||||
|
- resources:
|
||||||
|
|
||||||
|
data_flow:
|
||||||
|
(step-by-step)
|
||||||
|
|
||||||
|
integration_points:
|
||||||
|
- where it connects to existing systems
|
||||||
|
|
||||||
|
risks:
|
||||||
|
- ""
|
||||||
|
|
||||||
|
tradeoffs:
|
||||||
|
- ""
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## DO NOT
|
||||||
|
|
||||||
|
- write full implementation
|
||||||
|
- modify unrelated systems
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# 5. NEW BEVY SYSTEM
|
||||||
|
|
||||||
|
```
|
||||||
|
# TASK: Add Bevy System
|
||||||
|
|
||||||
|
system_name:
|
||||||
|
""
|
||||||
|
|
||||||
|
trigger:
|
||||||
|
(event or condition)
|
||||||
|
|
||||||
|
reads:
|
||||||
|
[Resources]
|
||||||
|
|
||||||
|
writes:
|
||||||
|
[Resources]
|
||||||
|
|
||||||
|
emits:
|
||||||
|
[Events]
|
||||||
|
|
||||||
|
constraints:
|
||||||
|
- must be event-driven
|
||||||
|
- must not directly mutate unrelated state
|
||||||
|
- must be single responsibility
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Output Format
|
||||||
|
|
||||||
|
system_signature:
|
||||||
|
|
||||||
|
implementation:
|
||||||
|
(code only)
|
||||||
|
|
||||||
|
notes:
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# 6. CORE LOGIC FUNCTION (solitaire_core)
|
||||||
|
|
||||||
|
```
|
||||||
|
# TASK: Core Logic Implementation
|
||||||
|
|
||||||
|
function:
|
||||||
|
"<name>"
|
||||||
|
|
||||||
|
goal:
|
||||||
|
"<what it does>"
|
||||||
|
|
||||||
|
rules:
|
||||||
|
- no IO
|
||||||
|
- no async
|
||||||
|
- no Bevy
|
||||||
|
- deterministic
|
||||||
|
|
||||||
|
invariants:
|
||||||
|
- ""
|
||||||
|
- ""
|
||||||
|
|
||||||
|
errors:
|
||||||
|
- ""
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Output Format
|
||||||
|
|
||||||
|
constraints_checked:
|
||||||
|
|
||||||
|
implementation:
|
||||||
|
(code only)
|
||||||
|
|
||||||
|
edge_case_handling:
|
||||||
|
|
||||||
|
notes:
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# 7. SYNC / MERGE LOGIC
|
||||||
|
|
||||||
|
```
|
||||||
|
# TASK: Sync Logic
|
||||||
|
|
||||||
|
goal:
|
||||||
|
"<what is being merged or synced>"
|
||||||
|
|
||||||
|
constraints:
|
||||||
|
- must be deterministic
|
||||||
|
- must be idempotent
|
||||||
|
- must be lossless
|
||||||
|
- must not delete data
|
||||||
|
|
||||||
|
rules:
|
||||||
|
- counters → max
|
||||||
|
- times → min
|
||||||
|
- collections → union
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Output Format
|
||||||
|
|
||||||
|
analysis:
|
||||||
|
|
||||||
|
merge_logic:
|
||||||
|
|
||||||
|
code_changes:
|
||||||
|
|
||||||
|
invariants_verified:
|
||||||
|
- deterministic
|
||||||
|
- idempotent
|
||||||
|
- lossless
|
||||||
|
|
||||||
|
notes:
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# 8. PERFORMANCE OPTIMIZATION
|
||||||
|
|
||||||
|
```
|
||||||
|
# TASK: Optimization
|
||||||
|
|
||||||
|
target:
|
||||||
|
"<what is slow>"
|
||||||
|
|
||||||
|
constraints:CLAUDE_WORKFLOW.md
|
||||||
|
- no behavior change
|
||||||
|
- no architecture change
|
||||||
|
- minimal code changes
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Output Format
|
||||||
|
|
||||||
|
analysis:
|
||||||
|
bottleneck:
|
||||||
|
|
||||||
|
optimization_strategy:
|
||||||
|
|
||||||
|
code_changes:
|
||||||
|
|
||||||
|
impact_estimate:
|
||||||
|
|
||||||
|
notes:
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# 9. TEST GENERATION (STRICT MODE)
|
||||||
|
|
||||||
|
```
|
||||||
|
# TASK: Test Generation
|
||||||
|
|
||||||
|
target:
|
||||||
|
"<function/system>"
|
||||||
|
|
||||||
|
reason:
|
||||||
|
- bugfix | complex logic | invariant protection
|
||||||
|
|
||||||
|
constraints:
|
||||||
|
- no redundant tests
|
||||||
|
- must test real behavior
|
||||||
|
- must fail if logic breaks
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Output Format
|
||||||
|
|
||||||
|
test_cases:
|
||||||
|
- ""
|
||||||
|
|
||||||
|
test_code:
|
||||||
|
|
||||||
|
notes:
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# 10. DEBUGGING / INVESTIGATION
|
||||||
|
|
||||||
|
```
|
||||||
|
# TASK: Debug
|
||||||
|
|
||||||
|
problem:
|
||||||
|
"<symptom>"
|
||||||
|
|
||||||
|
context:
|
||||||
|
"<relevant code or system>"
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Required Steps
|
||||||
|
|
||||||
|
1. List possible causes
|
||||||
|
2. Narrow down most likely
|
||||||
|
3. Suggest verification steps
|
||||||
|
4. Provide minimal fix
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Output Format
|
||||||
|
|
||||||
|
hypotheses:
|
||||||
|
|
||||||
|
most_likely:
|
||||||
|
|
||||||
|
verification_steps:
|
||||||
|
|
||||||
|
fix:
|
||||||
|
|
||||||
|
notes:
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# 11. HARD CONSTRAINT OVERRIDE (RARE)
|
||||||
|
|
||||||
|
```
|
||||||
|
# TASK: Exception Handling
|
||||||
|
|
||||||
|
reason:
|
||||||
|
"<why constraints must be bent>"
|
||||||
|
|
||||||
|
requested_exception:
|
||||||
|
"<rule being broken>"
|
||||||
|
|
||||||
|
justification:
|
||||||
|
"<why unavoidable>"
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Output Format
|
||||||
|
|
||||||
|
analysis:
|
||||||
|
|
||||||
|
alternatives_considered:
|
||||||
|
|
||||||
|
final_decision:
|
||||||
|
|
||||||
|
risk:
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# 12. STOP CONDITIONS (always append)
|
||||||
|
|
||||||
|
```
|
||||||
|
Stop when:
|
||||||
|
- acceptance criteria are met
|
||||||
|
- code is minimal and correct
|
||||||
|
|
||||||
|
Do NOT:
|
||||||
|
- expand scope
|
||||||
|
- refactor unrelated code
|
||||||
|
- optimize prematurely
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# END
|
||||||
+292
@@ -0,0 +1,292 @@
|
|||||||
|
# CLAUDE_SPEC.md
|
||||||
|
|
||||||
|
version: 1.0
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 0. Global Rules
|
||||||
|
|
||||||
|
(Core determinism, panic policy, and event-driven engine constraints live in CLAUDE.md §2.1, §2.3, §3.1. Listed here only when they add information CLAUDE.md doesn't carry.)
|
||||||
|
|
||||||
|
rules:
|
||||||
|
|
||||||
|
* id: single_source_of_truth
|
||||||
|
description: "GameStateResource is the only mutable game state in runtime"
|
||||||
|
|
||||||
|
* id: sync_is_additive
|
||||||
|
description: "Remote data must never destructively overwrite local data"
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 1. Crate Graph
|
||||||
|
|
||||||
|
crates:
|
||||||
|
solitaire_core:
|
||||||
|
depends_on: [rand, serde, chrono]
|
||||||
|
forbidden_deps: [bevy, reqwest, tokio, std::fs]
|
||||||
|
|
||||||
|
solitaire_sync:
|
||||||
|
depends_on: [serde, serde_json, uuid, chrono]
|
||||||
|
role: "shared_types"
|
||||||
|
|
||||||
|
solitaire_data:
|
||||||
|
depends_on: [solitaire_core, solitaire_sync, reqwest, tokio, keyring]
|
||||||
|
role: "persistence_and_sync"
|
||||||
|
|
||||||
|
solitaire_engine:
|
||||||
|
depends_on: [bevy, kira, solitaire_core, solitaire_data]
|
||||||
|
role: "runtime_engine"
|
||||||
|
|
||||||
|
solitaire_server:
|
||||||
|
depends_on: [solitaire_sync, axum, sqlx, jsonwebtoken]
|
||||||
|
role: "backend"
|
||||||
|
|
||||||
|
solitaire_app:
|
||||||
|
depends_on: [solitaire_engine]
|
||||||
|
role: "entrypoint"
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2. Data Ownership
|
||||||
|
|
||||||
|
ownership:
|
||||||
|
GameState:
|
||||||
|
owner: solitaire_core
|
||||||
|
mutable_in: solitaire_engine
|
||||||
|
access_pattern: "via GameStateResource only"
|
||||||
|
|
||||||
|
StatsSnapshot:
|
||||||
|
owner: solitaire_data
|
||||||
|
|
||||||
|
PlayerProgress:
|
||||||
|
owner: solitaire_data
|
||||||
|
|
||||||
|
AchievementRecord:
|
||||||
|
owner: solitaire_data
|
||||||
|
|
||||||
|
SyncPayload:
|
||||||
|
owner: solitaire_sync
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 3. State Transitions
|
||||||
|
|
||||||
|
state_machine:
|
||||||
|
GameState:
|
||||||
|
transitions:
|
||||||
|
- action: move_cards
|
||||||
|
returns: Result<GameState, MoveError>
|
||||||
|
|
||||||
|
```
|
||||||
|
- action: draw
|
||||||
|
returns: Result<GameState, MoveError>
|
||||||
|
|
||||||
|
- action: undo
|
||||||
|
returns: Result<GameState, MoveError>
|
||||||
|
|
||||||
|
invariants:
|
||||||
|
- "52 cards always exist"
|
||||||
|
- "no duplicate card IDs"
|
||||||
|
- "all cards belong to exactly one pile"
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 4. Event System
|
||||||
|
|
||||||
|
events:
|
||||||
|
|
||||||
|
input:
|
||||||
|
- MoveRequestEvent
|
||||||
|
- DrawRequestEvent
|
||||||
|
- UndoRequestEvent
|
||||||
|
- NewGameRequestEvent
|
||||||
|
|
||||||
|
state:
|
||||||
|
- StateChangedEvent
|
||||||
|
- GameWonEvent
|
||||||
|
|
||||||
|
meta:
|
||||||
|
- AchievementUnlockedEvent
|
||||||
|
- SyncCompleteEvent
|
||||||
|
|
||||||
|
rules:
|
||||||
|
|
||||||
|
* "Input events trigger core logic"
|
||||||
|
* "Core logic emits state events"
|
||||||
|
* "UI reacts to state events only"
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 5. Sync Contract
|
||||||
|
|
||||||
|
sync:
|
||||||
|
|
||||||
|
provider_trait:
|
||||||
|
methods:
|
||||||
|
- pull() -> SyncPayload
|
||||||
|
- push(payload) -> SyncResponse
|
||||||
|
|
||||||
|
guarantees:
|
||||||
|
- "non-blocking during gameplay"
|
||||||
|
- "blocking allowed on exit only"
|
||||||
|
|
||||||
|
merge:
|
||||||
|
rules:
|
||||||
|
counters: "max"
|
||||||
|
best_times: "min"
|
||||||
|
collections: "union"
|
||||||
|
achievements: "never removed"
|
||||||
|
|
||||||
|
```
|
||||||
|
properties:
|
||||||
|
- deterministic
|
||||||
|
- idempotent
|
||||||
|
- lossless
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 6. Persistence
|
||||||
|
|
||||||
|
storage:
|
||||||
|
|
||||||
|
format: json
|
||||||
|
|
||||||
|
files:
|
||||||
|
- stats.json
|
||||||
|
- progress.json
|
||||||
|
- achievements.json
|
||||||
|
- settings.json
|
||||||
|
- game_state.json
|
||||||
|
|
||||||
|
guarantees:
|
||||||
|
- atomic_write: true
|
||||||
|
- crash_safe: true
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 7. Engine Rules
|
||||||
|
|
||||||
|
engine:
|
||||||
|
|
||||||
|
mutation_rules:
|
||||||
|
- "Only GameLogicSystem mutates GameState"
|
||||||
|
- "UI systems are read-only"
|
||||||
|
|
||||||
|
threading:
|
||||||
|
- "sync runs on AsyncComputeTaskPool"
|
||||||
|
- "main thread must never block"
|
||||||
|
|
||||||
|
plugins:
|
||||||
|
pattern: "feature_isolation"
|
||||||
|
communication: "events"
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 8. Server Contract
|
||||||
|
|
||||||
|
server:
|
||||||
|
|
||||||
|
auth:
|
||||||
|
method: jwt
|
||||||
|
access_expiry: 24h
|
||||||
|
refresh_expiry: 30d
|
||||||
|
|
||||||
|
endpoints:
|
||||||
|
- POST /api/auth/register
|
||||||
|
- POST /api/auth/login
|
||||||
|
- GET /api/sync/pull
|
||||||
|
- POST /api/sync/push
|
||||||
|
|
||||||
|
limits:
|
||||||
|
payload_max: 1MB
|
||||||
|
rate_limit: "10 req/min auth routes"
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 9. Achievement System
|
||||||
|
|
||||||
|
achievements:
|
||||||
|
|
||||||
|
definition_location: solitaire_core
|
||||||
|
state_location: solitaire_data
|
||||||
|
|
||||||
|
types:
|
||||||
|
- condition_based
|
||||||
|
- event_driven
|
||||||
|
|
||||||
|
rule:
|
||||||
|
- "achievements cannot be revoked"
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 10. Testing Rules
|
||||||
|
|
||||||
|
testing:
|
||||||
|
|
||||||
|
philosophy:
|
||||||
|
- "test real failures"
|
||||||
|
- "avoid redundant tests"
|
||||||
|
|
||||||
|
required_coverage:
|
||||||
|
solitaire_core:
|
||||||
|
- move_validation
|
||||||
|
- undo_integrity
|
||||||
|
- win_detection
|
||||||
|
|
||||||
|
```
|
||||||
|
solitaire_sync:
|
||||||
|
- merge_correctness
|
||||||
|
- idempotency
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 11. Prohibited Patterns
|
||||||
|
|
||||||
|
(See CLAUDE.md §11 for the canonical forbidden-patterns list.)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 12. Extension Points
|
||||||
|
|
||||||
|
extensibility:
|
||||||
|
|
||||||
|
sync_backends:
|
||||||
|
pattern: "implement SyncProvider"
|
||||||
|
|
||||||
|
game_modes:
|
||||||
|
location: solitaire_core::GameMode
|
||||||
|
|
||||||
|
plugins:
|
||||||
|
rule: "new feature = new plugin"
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 13. Validation Checklist (for Claude)
|
||||||
|
|
||||||
|
validation:
|
||||||
|
|
||||||
|
* check: "crate dependency rules respected"
|
||||||
|
* check: "no panics in core"
|
||||||
|
* check: "events used for cross-system communication"
|
||||||
|
* check: "GameState mutations centralized"
|
||||||
|
* check: "merge function properties preserved"
|
||||||
|
* check: "no blocking operations in main loop"
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 14. Mental Model
|
||||||
|
|
||||||
|
model:
|
||||||
|
|
||||||
|
layers:
|
||||||
|
- core
|
||||||
|
- engine
|
||||||
|
- data
|
||||||
|
- server
|
||||||
|
|
||||||
|
flow:
|
||||||
|
- input -> engine -> core -> engine -> ui
|
||||||
|
- data <-> sync <-> server
|
||||||
@@ -0,0 +1,335 @@
|
|||||||
|
# CLAUDE_WORKFLOW.md
|
||||||
|
|
||||||
|
version: 1.0
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 0. Overview
|
||||||
|
|
||||||
|
This workflow defines a **two-agent system**:
|
||||||
|
|
||||||
|
* **Builder Agent** → writes and modifies code
|
||||||
|
* **Guardian Agent** → enforces architecture + rejects invalid changes
|
||||||
|
|
||||||
|
No code is considered valid unless it passes Guardian validation.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 1. Agent Roles
|
||||||
|
|
||||||
|
### 1.1 Builder Agent
|
||||||
|
|
||||||
|
role: "code_generation"
|
||||||
|
|
||||||
|
responsibilities:
|
||||||
|
|
||||||
|
* implement features
|
||||||
|
* refactor code
|
||||||
|
* generate tests (only when justified)
|
||||||
|
* follow CLAUDE_SPEC.md
|
||||||
|
|
||||||
|
constraints:
|
||||||
|
|
||||||
|
* cannot bypass validation
|
||||||
|
* must declare intent before writing code
|
||||||
|
|
||||||
|
output_contract:
|
||||||
|
must_produce:
|
||||||
|
- change_summary
|
||||||
|
- files_modified
|
||||||
|
- reasoning (short)
|
||||||
|
- code_diff
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 1.2 Guardian Agent
|
||||||
|
|
||||||
|
role: "architecture_enforcement"
|
||||||
|
|
||||||
|
responsibilities:
|
||||||
|
|
||||||
|
* validate against CLAUDE_SPEC.md
|
||||||
|
* detect violations
|
||||||
|
* reject or approve changes
|
||||||
|
* suggest minimal fixes (not full rewrites)
|
||||||
|
|
||||||
|
constraints:
|
||||||
|
|
||||||
|
* no feature implementation
|
||||||
|
* no large rewrites
|
||||||
|
* must be deterministic
|
||||||
|
|
||||||
|
output_contract:
|
||||||
|
must_produce:
|
||||||
|
- status: APPROVED | REJECTED
|
||||||
|
- violations[]
|
||||||
|
- required_fixes[]
|
||||||
|
- optional_improvements[]
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2. Workflow Pipeline
|
||||||
|
|
||||||
|
```text
|
||||||
|
User Request
|
||||||
|
↓
|
||||||
|
Builder Agent (proposal + code)
|
||||||
|
↓
|
||||||
|
Guardian Agent (validation)
|
||||||
|
↓
|
||||||
|
IF approved → commit
|
||||||
|
IF rejected → feedback → Builder retry
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 3. Builder Protocol
|
||||||
|
|
||||||
|
### Step 1 — Intent Declaration
|
||||||
|
|
||||||
|
Builder MUST start with:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
intent:
|
||||||
|
feature: "<name>"
|
||||||
|
crates_touched: []
|
||||||
|
systems_affected: []
|
||||||
|
risk_level: low|medium|high
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Step 2 — Plan
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
plan:
|
||||||
|
- step: "..."
|
||||||
|
- step: "..."
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Step 3 — Implementation
|
||||||
|
|
||||||
|
* Only modify declared crates
|
||||||
|
* Follow ownership rules
|
||||||
|
* Use events for cross-system communication
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Step 4 — Output
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
change_summary: "..."
|
||||||
|
|
||||||
|
files_modified:
|
||||||
|
- path: ...
|
||||||
|
change: "..."
|
||||||
|
|
||||||
|
violations_self_check:
|
||||||
|
- none | list
|
||||||
|
|
||||||
|
notes: "short reasoning"
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 4. Guardian Protocol
|
||||||
|
|
||||||
|
### Step 1 — Spec Validation
|
||||||
|
|
||||||
|
Check against:
|
||||||
|
|
||||||
|
* crate boundaries
|
||||||
|
* mutation rules
|
||||||
|
* event system usage
|
||||||
|
* sync guarantees
|
||||||
|
* forbidden patterns
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Step 2 — Invariant Validation
|
||||||
|
|
||||||
|
Must verify:
|
||||||
|
|
||||||
|
* GameState invariants preserved
|
||||||
|
* no new panic paths
|
||||||
|
* no blocking calls in engine
|
||||||
|
* merge properties unchanged
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Step 3 — Output Decision
|
||||||
|
|
||||||
|
#### APPROVED
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
status: APPROVED
|
||||||
|
|
||||||
|
notes:
|
||||||
|
- "no violations"
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
#### REJECTED
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
status: REJECTED
|
||||||
|
|
||||||
|
violations:
|
||||||
|
- id: core_purity_violation
|
||||||
|
file: "solitaire_core/src/..."
|
||||||
|
reason: "uses std::fs"
|
||||||
|
|
||||||
|
required_fixes:
|
||||||
|
- "move IO to solitaire_data"
|
||||||
|
|
||||||
|
optional_improvements:
|
||||||
|
- "simplify event naming"
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 5. Enforcement Rules
|
||||||
|
|
||||||
|
### Hard Fail (automatic rejection)
|
||||||
|
|
||||||
|
* core crate uses IO / Bevy / network
|
||||||
|
* GameState mutated outside GameLogicSystem
|
||||||
|
* blocking async on main thread
|
||||||
|
* duplicate logic across crates
|
||||||
|
* merge function altered incorrectly
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Soft Fail (allowed but flagged)
|
||||||
|
|
||||||
|
* unnecessary complexity
|
||||||
|
* redundant tests
|
||||||
|
* minor architectural drift
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 6. Iteration Loop
|
||||||
|
|
||||||
|
Max attempts per task: **3**
|
||||||
|
|
||||||
|
```text
|
||||||
|
Attempt 1 → Reject → Fix
|
||||||
|
Attempt 2 → Reject → Fix
|
||||||
|
Attempt 3 → Final decision
|
||||||
|
```
|
||||||
|
|
||||||
|
If still failing:
|
||||||
|
→ escalate to user
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 7. Diff Strategy
|
||||||
|
|
||||||
|
Builder MUST produce:
|
||||||
|
|
||||||
|
* minimal diffs
|
||||||
|
* no unrelated refactors
|
||||||
|
* no formatting-only changes
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 8. Test Strategy Integration
|
||||||
|
|
||||||
|
Builder rules:
|
||||||
|
|
||||||
|
* only add tests if:
|
||||||
|
|
||||||
|
* fixing a bug
|
||||||
|
* protecting complex logic
|
||||||
|
* validating invariants
|
||||||
|
|
||||||
|
Guardian rejects:
|
||||||
|
|
||||||
|
* redundant tests
|
||||||
|
* no-op tests
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 9. Optional Extensions
|
||||||
|
|
||||||
|
### 9.1 Third Agent (Optimizer)
|
||||||
|
|
||||||
|
role: performance + cleanup
|
||||||
|
|
||||||
|
runs AFTER approval:
|
||||||
|
|
||||||
|
* reduce allocations
|
||||||
|
* simplify logic
|
||||||
|
* improve ECS scheduling
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 9.2 CI Integration
|
||||||
|
|
||||||
|
Pipeline:
|
||||||
|
|
||||||
|
```text
|
||||||
|
Builder → Guardian → cargo check → clippy → tests
|
||||||
|
```
|
||||||
|
|
||||||
|
Guardian runs BEFORE compilation to catch structural issues early.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 10. Example Interaction
|
||||||
|
|
||||||
|
### Builder
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
intent:
|
||||||
|
feature: "undo stack limit fix"
|
||||||
|
crates_touched: [solitaire_core]
|
||||||
|
risk_level: low
|
||||||
|
```
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
change_summary: "limit undo stack to 64 entries"
|
||||||
|
|
||||||
|
files_modified:
|
||||||
|
- solitaire_core/src/game_state.rs
|
||||||
|
|
||||||
|
notes: "prevents unbounded memory growth"
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Guardian
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
status: APPROVED
|
||||||
|
|
||||||
|
notes:
|
||||||
|
- "respects core constraints"
|
||||||
|
- "no invariant violations"
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 11. Mental Model
|
||||||
|
|
||||||
|
* Builder = **creative**
|
||||||
|
* Guardian = **strict**
|
||||||
|
|
||||||
|
Builder explores
|
||||||
|
Guardian enforces
|
||||||
|
|
||||||
|
Neither replaces the other.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 12. Success Criteria
|
||||||
|
|
||||||
|
System is working if:
|
||||||
|
|
||||||
|
* architectural violations go to ~0
|
||||||
|
* code stays consistent across features
|
||||||
|
* refactors become safe
|
||||||
|
* complexity grows sub-linearly
|
||||||
Reference in New Issue
Block a user