Getting it into your agent
One page per mod, every tool's command on it. A separate URL per tool would split the same page into five that compete with each other.
npx agentmods add instructions/phase-rs/phase/claude-mdgit clone --depth 1 https://github.com/phase-rs/phaseWhat it costs to keep this loaded
Counted locally with the o200k_base tokenizer, which is exact for GPT models; Claude uses its own tokenizer and its counts differ. Treat this as one consistent yardstick across the catalogue rather than a bill. Prices are per million input tokens.
| Model | Per session | Once invoked |
|---|---|---|
| Fable 5 | $0.07632 | $0.07632 |
| Opus 5 | $0.03816 | $0.03816 |
| Sonnet 5 | $0.01526 | $0.01526 |
| Haiku 4.5 | $0.00763 | $0.00763 |
Grade A, and why
phase CLAUDE.md scanned grade A with 0 findings against 26 rules in 11 categories — prompt injection, anti-refusal, data exfiltration, privilege escalation, supply chain, agent snooping, system-prompt leakage, SSRF and excessive agency — measured 2d ago.
A static scan of the body, not an audit. Every finding is printed with the line that produced it so you can judge whether it matters here. A mod is markdown that instructs an agent; that is exactly why what it instructs is worth reading.
Nothing flagged
None of the 26 patterns this scan looks for appear in this file: no shell pipes, no recursive deletes, no credential paths, no hidden text, no instruction-override or anti-refusal phrasing, no agent-config snooping. That is not a guarantee, it is the absence of the things that are checkable.
How it starts
The opening of the file, as written. The whole thing — 185 lines — stays where its author put it; the contents beside it link to each section on GitHub.
CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Project Overview
phase.rs is a Magic: The Gathering game engine written in Rust (compiling to native + WASM) with a React/TypeScript frontend. It implements MTG game rules using functional architecture (discriminated unions, pure reducers, immutable state) with an Arena-quality browser UI. Card data is sourced from MTGJSON (MIT-licensed) with custom typed JSON ability definitions.
Design Principles — READ THIS FIRST
Above all else, this project prioritizes three co-equal pillars: idiomatic Rust, composable building-block architecture, and strict fidelity to the MTG Comprehensive Rules. These are non-negotiable and override convenience, speed-of-delivery, or "getting it working." Every code change must pass through all three lenses before anything else.
- Idiomatic Rust, always. Use Rust's type system, ownership model, and idioms to their fullest. Prefer
enumover stringly-typed data. Prefer exhaustivematchover fallback defaults. Prefer trait-based polymorphism over dynamic dispatch when the type set is known. If the idiomatic path is harder, take it anyway — shortcuts compound into debt. - Rules-correct over convenient — the #1 hard rule. This is an MTG rules engine — correctness to the Comprehensive Rules is a hard requirement, not a nice-to-have. Every implementation pattern MUST be verified against the relevant CR section before it is considered complete. When a rules-correct implementation is more complex than a shortcut, take the complex path. A simpler implementation that gets the rules wrong is not simpler — it is wrong. If you are unsure whether a behavior is rules-correct, look up the CR section, annotate the code, and implement what the rules say, not what seems reasonable. "It works for most cases" is not acceptable when the CR specifies exact behavior. No game logic ships without CR validation.
- Build for the class, not the card. Every new enum variant, parser pattern, effect handler, or filter must handle a category of cards, not a single card. Before writing any logic, ask: "How many cards does this cover?" If the answer is one, you're building a special case — find the general pattern and build that instead. A one-off that works for one card but breaks for the next card with the same pattern is not a building block; it is technical debt.
- The engine owns all logic. All game rules, validation, derived state, and computed values live in the
enginecrate. Transport layers (WASM bridge, Tauri IPC, WebSocket server) are thin serialization boundaries — zero game logic allowed. If multiple consumers need the same behavior, it belongs in the engine. Never duplicate logic across adapters. When in doubt, put it in the engine. - The frontend is a display layer, not a logic layer. The React client renders engine-provided state and dispatches user actions — nothing more. It must never compute, derive, transform, or re-interpret game data. If the frontend needs a value, the engine must provide it. Formatting for display (e.g., string interpolation of engine-provided fields) is acceptable; calculating, filtering, or inferring game state is not. Any "smart" frontend code is a bug — move it to the engine.
- Compose from building blocks. Every new capability should be decomposed into reusable primitives that unlock future features. Before writing specific logic, ask: "What is the general pattern here?" and build that instead. This applies equally to data modeling: when a new field or parameter needs to distinguish cases, use an existing typed enum (e.g.,
ControllerRef,Comparator,Option<T>) — never a rawbool. A boolean isn't composable; an existing type is self-documenting, extensible, and expresses the full design space. Examples:contains_possessive/contains_object_pronounfor Oracle text matching,ChangeZone+Shufflecomposition for compound shuffles,Option<ControllerRef>for "whose turn is required" instead ofrequires_your_turn: bool. - Parameterize, don't proliferate. Before adding a sibling variant to an enum, ask: is the new variant a leaf-level parameterization of an existing variant's structural axis (scope, target, aggregate function, condition shape)? If yes, refactor the existing variants into a parameterized form (e.g.,
LifeTotal { player: PlayerScope }instead ofLifeTotal+OpponentLifeTotal+TargetLifeTotal;UnlessQuantity { comparator, filter, count }instead ofUnlessControlsCountMatching+UnlessControlsMatching+UnlessControlsOtherLeq). Adding a sibling to an enum that should be parameterized compounds debt exponentially: one sibling is cheap, ten siblings make the eventual refactor multi-week as call sites multiply across parser, converter, resolver, and tests. Sibling-cluster smell: when an enum has three or more variants that share a name root (X / OpponentX / TargetX / AllX), differ only in a context label, or only differ in a comparator/aggregator/scope axis, that's a parameterization that didn't happen — refactor before extending. The strict-failure tag is the right place to leave coverage waiting while the architecture wins. Categorical boundary rule: the parameterization axis must lie within a single CR rule section. Life is CR 119 (player-only). Power/toughness are CR 208/209 (creature/planeswalker). Don't unify these under oneLife { target: {Self,Opponent,Creature}, type: {Total,Remaining} }— that conflates rule sections the engine treats as separately resolvable. Cross-section unification belongs atTargetFilteror at the effect handler (Effect::DealDamageper CR 120 unifies all damage subjects), never at the leaf-reference layer. Discoverability: before any engine variant proposal, grepdata/engine-inventory.json(auto-generated bycargo engine-inventory; gitignored — runcargo engine-inventoryto (re)generate it locally first) for existence verification and sibling-cluster smells. The inventory is the canonical source of engine surface — replaces hand-maintained CLAUDE.md lists that drift. Run the workspaceadd-engine-variantskill checklist as the runnable gate; CLAUDE.md is the principle, the skill is the gate. - Nom combinators on the first pass — no exceptions. All new parser code MUST use nom combinators (
tag(),alt(),value(),terminated(),pair(), etc.) from the very first line written. Never writefind(),split_once(),contains(), orstarts_with()for parsing dispatch and then "plan to convert to combinators later." There is no later — write it correctly the first time. Usenom_on_lowerbridge for mixed-case text,tag().parse()for already-lowercase text. Use existing building blocks (parse_single_cost,parse_target,parse_for_each_clause, etc.) for composed operations. If you catch yourself writing string matching for parsing, stop and rewrite with combinators before proceeding. This has been a recurring issue and is non-negotiable. - Extend, don't hack. New features should slot cleanly into existing patterns (effect handlers, game modules, ability definitions). If a feature requires working around the architecture, the architecture should be extended first.
- Trace before you build. Before implementing a new pattern, trace how an existing analogous feature works end-to-end (e.g., trace
enter_tappedbefore buildingenter_with_counters; traceChangelingbefore building a new CDA). This prevents reinventing existing infrastructure and ensures consistency. - Verify the card, not just the rule. Before planning or implementing a fix for a specific card, confirm that card's actual Oracle text against an authoritative source (Scryfall API, MTGJSON) — never from memory or from a task description's paraphrase. This is a distinct check from CR-annotation verification: CR verification confirms the rule you cite is real; this confirms the card ability you're building a fix for is real. A fabricated clause can survive multiple rounds of architecture and implementation review, because those reviews verify that a design is executed correctly against its stated premise — they do not fact-check the premise itself. If a clause has no analogous card anywhere in the engine, or a CR citation doesn't cleanly fit any rule, treat that as a signal to re-verify the premise before re-deriving the design.
- Production quality, always. Write code as if a professional team will audit every line. No "good enough for now." No tech debt IOUs. Every function should be clear, every abstraction should earn its keep, and every pattern should be consistent across the codebase.
- Single authority for ability costs. When an ability has costs (tap, sacrifice, pay life, discard, etc.), all cost resolution must go through one authoritative resolver function. Callers dispatch activation — they never inspect or handle individual cost components. This prevents scattered responsibility where every call site must remember to sacrifice Treasures, pay life, or handle future cost types. If you find yourself checking an ability's cost structure at a call site, you're in the wrong layer — push it into the resolver.
What this file has done since we first saw it
Hashed on every crawl. A supply-chain change to an agent config is a question of when, not whether, so the history is kept rather than the latest state alone.
- 2d ago First seen · 185 lines · 7,632 tokens per session scan A 4dad356f2fea
phase CLAUDE.md is an instructions file published in the GitHub repository phase-rs/phase (259 stars, last pushed 2d ago), licensed Apache-2.0. It adds 7,632 tokens to every session, about $0.0382 per session on Opus 5. A static security scan graded it A with 0 findings. No closer match exists in the catalogue, so it is treated as the original; first seen 2026-08-30.
Other instructions, from other repositories
argentum-engine AGENTS.md
AGENTS.md instructions for wingedsheep/argentum-engine, covering agents.md, hard rules, module layout, load-bearing rules and card / effect authoring.
argentum-engine CLAUDE.md
Claude Code instructions for wingedsheep/argentum-engine, a project described as: Magic: The Gathering rules engine + online play platform, in Kotlin.
anarlog AGENTS.md
AGENTS.md instructions for fastrepl/anarlog, covering commands, pre-commit verification, guidelines, code style and cli tui command architecture.
Claw3D AGENTS.md
Instructions for iamlukethedev/Claw3D, covering agent instructions, cursor cloud specific instructions, service overview, running the app and lint, typecheck, and tests.
Pake copilot-instructions.md
Copilot instructions for tw93/Pake, a project described as: 🤱🏻 Turn any webpage into a desktop app with one command.
Pake CLAUDE.md
Claude Code instructions for tw93/Pake, a project described as: 🤱🏻 Turn any webpage into a desktop app with one command.