Agent Skills › levy-street/world-of-claudecraft

levy-street/world-of-claudecraft

GitHub

用于审查 Codex 架构的合规性、安全性及文档一致性。通过只读审计 AGENTS.md、技能配置等,识别风险与冗余,评估模型中立性与 CI 集成,输出分级修复建议。

16 skills 1,770

Install All Skills

npx skills add levy-street/world-of-claudecraft --all -g -y
More Options

List skills in collection

npx skills add levy-street/world-of-claudecraft --list

Skills in Collection (16)

用于审查 Codex 架构的合规性、安全性及文档一致性。通过只读审计 AGENTS.md、技能配置等,识别风险与冗余,评估模型中立性与 CI 集成,输出分级修复建议。
审查或现代化 AGENTS.md 和 .codex 文件 检查仓库 AI 架构是否符合当前规范 评估 Codex 工作流、脚本及文档漂移
.agents/skills/woc-codex-audit/SKILL.md
npx skills add levy-street/world-of-claudecraft --skill woc-codex-audit -g -y
SKILL.md
Frontmatter
{
    "name": "woc-codex-audit",
    "description": "Audit World of ClaudeCraft Codex support for current conventions, model neutrality, instruction quality, agent safety, skill design, hooks, CI integration, and documentation drift. Use when reviewing or modernizing AGENTS.md, .codex, .agents, Codex workflows, Codex-facing scripts, or the repository AI architecture."
}

Codex Architecture Audit

Evaluate whether Codex receives concise, safe, current, and scalable operating context without altering the Claude Code architecture. An audit request is read-only. Apply fixes only when the user explicitly requests implementation.

Preserve boundaries

  1. Read the root CLAUDE.md, AGENTS.md, and relevant local CLAUDE.md files.
  2. Run git status --short and preserve unrelated work.
  3. Treat root and local CLAUDE.md files as canonical repository truth.
  4. Do not edit CLAUDE.md or .claude/** as part of Codex support work.

Codex files should point to canonical instructions and add only Codex runtime guidance.

Research current behavior

Use current official OpenAI documentation for Codex configuration, skills, agents, hooks, permissions, model selection, and CI. Clearly separate documented facts from inference. Keep repository guidance model-neutral unless a task has an evidence-backed capability requirement, and prefer inheritance over project model pins.

Use the woc_docs_researcher custom agent for a bounded official-documentation pass when it is available. Verify consequential recommendations against the cited primary source.

Inventory

Inspect AGENTS.md, .codex/**, .agents/skills/**, custom agents, hooks, Codex GitHub workflows, AI-facing scripts and tests, documentation, ignore rules, and malware scanner coverage. Identify duplicated, abandoned, shadowed, untracked, or conflicting settings.

Assess

Verify that:

  • canonical instructions are referenced instead of copied;
  • guidance encodes decisions that a simple search cannot recover;
  • skill triggers and implicit-invocation policy match risk;
  • external writes require explicit authorization;
  • review-only workflows remain read-only;
  • the coordinator owns command execution and reviewers are scoped;
  • models, effort, permissions, and providers are not unnecessarily pinned;
  • hooks are fast, deterministic, local, and secret-safe;
  • CI isolates untrusted input, uses least privilege, and protects credentials;
  • worktree, dirty-tree, branch, and commit rules protect concurrent sessions;
  • shared and personal Codex state have deliberate tracking rules;
  • tests and scanners cover instruction-bearing Codex files;
  • documentation matches effective configuration.

Classify findings as P0 immediate credential or destructive risk, P1 architecture or reliability defect, or P2 drift and maintainability. Include evidence, impact, and the smallest change. Also report active surfaces, intentional Claude-only items, redundancy, missing verification, implementation order, and one verdict: CURRENT, NEEDS MAINTENANCE, or NEEDS REDESIGN.

用于在ClaudeCraft项目中实施新功能、修复缺陷或重构代码。遵循模块优先和行为驱动测试原则,确保最小化边界和回归覆盖,支持从大文件提取逻辑或沿架构接缝移动代码。
添加新功能行为 修复软件缺陷 从大文件中提取逻辑 沿现有架构接缝移动代码 执行聚焦的重构
.agents/skills/woc-extract-and-test/SKILL.md
npx skills add levy-street/world-of-claudecraft --skill woc-extract-and-test -g -y
SKILL.md
Frontmatter
{
    "name": "woc-extract-and-test",
    "description": "Implement World of ClaudeCraft features, bug fixes, and focused refactors using module-first design and behavior-driven tests. Use when adding behavior, fixing a defect, extracting logic from a large file, or moving code behind an existing architectural seam."
}

Extract and Test

Implement the requested behavior with the smallest clean module boundary and direct regression coverage.

Load context

  1. Read the root CLAUDE.md in full.
  2. Read the relevant local CLAUDE.md before opening or editing that area.
  3. Run git status --short and preserve unrelated work.
  4. Inspect the production path, its callers, and nearby tests before choosing a seam.

Apply canonical architecture rules to the concrete change without copying them here.

Before implementing database-backed behavior, invoke woc_database_performance for a read-only checkpoint when the change can affect SQL or query call sites, schema or indexes, query frequency or cardinality, pool configuration, lock scope, timeout policy, or stored-data growth, including database driver/dependency upgrades and PostgreSQL engine/resource/configuration/topology changes. Carry its concrete bounds and evidence requirements into the test-first contract.

Choose the workflow

For a bug fix:

  1. Reproduce the defect through the real production path.
  2. Add a focused test that fails for the intended reason.
  3. Confirm the test is red before changing production code.
  4. Make the smallest coherent fix.
  5. Add nearby edge cases only when they protect the same contract.

For a feature or refactor:

  1. Identify the existing module, coordinator, state owner, or extension seam.
  2. Place behavior in a pure sibling module, current state owner, or thin adapter.
  3. Separate pure decisions from I/O, rendering, global state, and transport.
  4. Give the extracted unit direct tests and keep consumers thin.
  5. When relocating behavior, preserve semantics before redesigning anything.

Do not grow a monolith when a tested sibling is appropriate, introduce a framework for one call site, bypass existing seams to reach private state, or build parallel versions of the same rule. Preserve determinism, parity, localization, and persistence contracts. Do not commit unless explicitly asked.

Validate

Run focused tests while iterating, then:

npm run ci:changed
npx tsc --noEmit

Run domain guards for architecture, localization, persistence, parity, or security when applicable. Re-run woc_database_performance on the finished diff when its database triggers match. Before declaring the implementation ready, run npm run gate.

Report the selected seam, behavior covered, commands run, and remaining manual checks.

用于将大型功能规划为架构对齐的垂直切片,明确决策、验证和交接状态。适用于用户请求分阶段实施计划、规划包或会话分解时,确保跨会话安全执行。
用户请求分阶段实施计划 用户请求规划包 用户请求会话分解 用户在实施前请求可扩展方法
.agents/skills/woc-feature-plan/SKILL.md
npx skills add levy-street/world-of-claudecraft --skill woc-feature-plan -g -y
SKILL.md
Frontmatter
{
    "name": "woc-feature-plan",
    "description": "Plan a large or multi-session World of ClaudeCraft feature as architecture-aligned vertical slices with explicit decisions, verification, and handoff state. Use when the user requests a phased implementation plan, planning packet, session breakdown, or scalable approach before implementation."
}

Feature Plan

Create the smallest planning artifact that makes a large feature safe to execute across sessions.

Research before planning

  1. Read the root and relevant local CLAUDE.md files.
  2. Run git status --short and preserve unrelated work.
  3. Inspect production paths, tests, module seams, and relevant project documentation.
  4. Use bounded parallel exploration for independent subsystems.
  5. Fetch current official documentation for version-sensitive external interfaces.
  6. When work adds or changes SQL, a database call site, stored-data growth, scheduled database work, pool sizing or admission, transaction or lock scope, or timeout policy; a database driver/dependency version, or PostgreSQL engine/resource/configuration/topology, use woc_database_performance for a read-only scaling pass.

Do not create planning files until the goal, scope, and important constraints are understood. Ask the user when a choice would materially change architecture or product behavior.

Define the change

Record current behavior and ownership, desired behavior and acceptance criteria, affected systems and platforms, constraining invariants, decisions already made, truly blocking open decisions, and compatibility, migration, localization, privacy, security, database performance, and testing implications. For database-backed work, record expected query frequency and cardinality, the index/cache/pagination strategy, pool and lock impact, version-sensitive timeout/planner assumptions, and the measured evidence the implementation must produce. Reference canonical instructions instead of copying them.

Build vertical phases

Prefer phases that deliver a testable behavior slice. Each phase states:

  1. Outcome and explicit scope.
  2. Expected modules or seams.
  3. Tests to add or update.
  4. Validation commands and manual verification.
  5. Exit criteria.
  6. State needed by the next phase.

Keep a phase small enough for one focused session when practical. Do not isolate documentation that belongs beside its implementation.

Persist only useful state

If the user requests planning files, use a minimal packet:

  • implementation-plan.md for architecture, decisions, phases, and completion criteria.
  • progress.md for verified phase status.
  • state.md for the exact resume point, blocker, and next action.

Add per-phase files only when a phase needs substantial independent detail. Starter prompts must be model-neutral and include the goal, relevant files, canonical constraints, authorized actions, checks, and handoff. Do not pin a model or effort.

Planning does not authorize implementation, commits, pushes, issues, or pull requests. Do not modify CLAUDE.md or .claude/** as Codex support work.

Return the phases, unresolved decisions, risk areas, and recommended first executable step.

根据用户明确指令,在World of ClaudeCraft项目中创建GitHub Issue。需先确认授权,通过研究代码和现有问题避免重复,按规范撰写包含复现步骤、预期行为等内容的Issue,仅在有明确创建请求时执行实际操作。
用户明确要求创建或提交GitHub Issue 用户要求打开新的项目问题
.agents/skills/woc-file-issue/SKILL.md
npx skills add levy-street/world-of-claudecraft --skill woc-file-issue -g -y
SKILL.md
Frontmatter
{
    "name": "woc-file-issue",
    "description": "Draft and create a focused GitHub issue for World of ClaudeCraft using the project issue format. Use only when the user explicitly asks to file, create, or open an issue. A request for a draft does not authorize creating the issue."
}

File GitHub Issue

Create a clear, bounded issue in levy-street/world-of-claudecraft.

Confirm authorization

Write to GitHub only when the user explicitly asks to file, create, or open the issue. For draft, rewrite, or proposal requests, return text only. Do not add labels, milestones, projects, or assignees unless requested or unambiguously specified.

Research

  1. Read the root and relevant local CLAUDE.md files.
  2. Inspect enough current code or documentation to avoid stale assumptions.
  3. Search open issues when duplicate risk is meaningful.
  4. Ask one blocking question only when expected behavior or scope cannot be inferred.

Do not invent reproduction results, environment details, ownership, severity, or implementation decisions.

Write

Use a concise title with the affected area. Structure the body around the problem or opportunity, current and expected behavior, scope, acceptance criteria, relevant implementation context, and verification expectations.

For a bug, include reproduction steps, actual and expected results, and environment only when known. Use unchecked tasks only for independently verifiable acceptance criteria. Put unknown details in HTML comments instead of presenting guesses as facts.

Create with gh issue create only after the authorization condition is satisfied. Return the final title, issue URL if created, assumptions, and confirmation that no extra metadata changed unless requested.

为World of ClaudeCraft项目提供端到端贡献质量保障,涵盖准备度检查、范围回归测试及条件专家审查。用于验证分支、检查工作就绪状态或评估贡献完整性,协调构建测试并分派专业审查员。
QA changes make work ready verify a branch or worktree assess whether a contribution is complete
.agents/skills/woc-qa/SKILL.md
npx skills add levy-street/world-of-claudecraft --skill woc-qa -g -y
SKILL.md
Frontmatter
{
    "name": "woc-qa",
    "description": "Run end-of-contribution QA for World of ClaudeCraft, including readiness checks, scoped regression testing, and conditional specialist review. Use when asked to QA changes, make work ready, verify a branch or worktree, or assess whether a contribution is complete."
}

World of ClaudeCraft QA

Coordinate one evidence-backed QA pass for the requested change.

Establish authority and scope

  1. Read the root CLAUDE.md in full.
  2. Read each relevant local CLAUDE.md before inspecting or editing that area.
  3. Run git status --short and preserve unrelated work.
  4. Establish the diff once. Prefer the working tree when changes are uncommitted; otherwise use the user-provided base or active release base. Never assume main.
  5. Treat review, check, and audit as read-only. Treat fix findings, make ready, or implementation requests as permission for scoped remediation.
  6. Do not commit, push, post comments, or create pull requests unless explicitly asked.

CLAUDE.md owns repository architecture and invariants. Reference it instead of restating or replacing it.

Run coordinator-owned checks

The coordinating agent owns build, test, lint, generation, and scanner commands. Specialist agents inspect code and shared command output without rerunning the full gate.

During iteration, run the smallest relevant set:

  1. Targeted Vitest files for changed behavior.
  2. Architecture or localization guard tests for touched domains.
  3. npm run i18n:gen before tests that require generated localization artifacts.
  4. npm run ci:changed.
  5. npx tsc --noEmit.

Before declaring implementation work ready, run:

npm run gate

If a command cannot run, report the exact blocker and continue with every safe check that remains.

Dispatch conditional reviewers

Give each reviewer the established diff, relevant files, applicable canonical instructions, and command results. Require read-only evidence with file and line references. Use only the agents relevant to the diff:

  • woc_sim_architecture for simulation behavior, determinism, or module boundaries.
  • woc_cross_platform for world, network, wire, RL, matcher, or client parity.
  • woc_persistence for DDL, stored JSONB, save paths, or compatibility.
  • woc_database_performance for SQL, indexes, query call sites, pool or lock behavior, timeout policy, background database work, driver/dependency upgrades, PostgreSQL engine/resource/configuration/topology changes, or features that increase stored-data cardinality.
  • woc_security for server, admin, auth, deployment, secrets, or trust boundaries.
  • woc_test_coverage for changed behavior, acceptance criteria, and regression tests.
  • woc_frontend for UI, render, CSS, i18n, accessibility, responsive, or fairness work.
  • woc_release_malware for releases, dependencies, install behavior, AI instructions, or suspicious executable content.

Run independent reviewers in parallel when capacity permits. Verify consequential findings against the actual diff and surrounding code. Reject speculative, inherited, duplicate, or out-of-scope findings. In review-only mode, do not edit files.

Report

Return the scope and base, commands and results, reviewers used, confirmed findings, authorized fixes, remaining risks, and one verdict: READY, READY WITH NOTES, or NOT READY.

用于发布前的恶意软件审计,通过确定性扫描和上下文排查检测释放树中的恶意行为。适用于发布前、依赖变更或安全审查场景,确保发布安全。
发布前检查 依赖或安装变更后的审计 明确要求进行恶意软件安全审查
.agents/skills/woc-release-malware-audit/SKILL.md
npx skills add levy-street/world-of-claudecraft --skill woc-release-malware-audit -g -y
SKILL.md
Frontmatter
{
    "name": "woc-release-malware-audit",
    "description": "Perform a whole-tree World of ClaudeCraft release malware audit using the deterministic scanner plus contextual triage. Use before a release, for a release tag or branch, after suspicious dependency or install changes, or when explicitly asked for a malware-focused security review."
}

Release Malware Audit

Determine whether the release tree contains deliberate malicious behavior or unresolved indicators that make release unsafe. This is read-only: do not modify files, dependencies, Git history, or remote state.

Establish scope

  1. Read the root CLAUDE.md and instructions for relevant release, script, server, deployment, and security paths.
  2. Run git status --short.
  3. Record the exact commit, branch, tag, or working tree.
  4. Audit the whole release tree, not only the latest diff.

Do not expose secrets or inspect unrelated private data.

Scan once

The coordinating agent runs:

node scripts/malware_scan.mjs --json --quiet

Exit 0 means no findings, 1 means findings need triage, and 2 means the scan failed. Capture structured output under a temporary path only when needed and preserve evidence.

Triage

Group findings by category and file. Dispatch independent read-only triage in parallel when useful. Specialists inspect files and shared output without rerunning the scanner.

Review credential or wallet theft, exfiltration, covert telemetry, backdoors, auth bypasses, command execution, obfuscated or fetched payloads, dependency and lifecycle abuse, cryptomining, resource hijacking, and instruction injection. Include sensitive behavior hidden in tests, fixtures, generated assets, documentation, and release tools.

For each flag, inspect context, reachability, intent, data flow, and whether it ships or executes. Accidental defects belong in a normal security review, but unresolved ambiguity in executable or release-critical content still blocks release.

Return PASS only when every finding and manual concern has a supported benign explanation. Return BLOCK for malicious, reachable suspicious, or unresolved behavior. Report the revision, tree state, scanner count, confirmed and unresolved indicators, dismissed flags with evidence, manual coverage, limitations, and verdict.

审查合并到长期分支的发布版本,检测语义冲突、遗留漂移、遗漏更新及失效假设。适用于合并后或恢复功能开发前的代码审计。
合并发布分支后 审查发布合并提交时 上游集成后恢复功能工作前
.agents/skills/woc-release-merge-audit/SKILL.md
npx skills add levy-street/world-of-claudecraft --skill woc-release-merge-audit -g -y
SKILL.md
Frontmatter
{
    "name": "woc-release-merge-audit",
    "description": "Audit a release merge into a long-lived World of ClaudeCraft branch for semantic conflict damage, legacy drift, missed inventory updates, and invalidated planning assumptions. Use after merging a release branch, when reviewing a release merge commit, or before resuming feature work after upstream integration."
}

Release Merge Audit

Inspect the merge result for semantic damage that a clean textual merge can hide. This workflow is read-only unless the user explicitly asks to fix confirmed findings.

Establish the merge

  1. Read the root and relevant local CLAUDE.md files.
  2. Run git status --short and preserve unrelated work.
  3. Identify the merge or integration range, both merge parents, and intended release base.
  4. Separate release-side changes, pre-existing branch changes, and files or behavior both sides touched.

Do not assume branch names or main.

Audit overlap

Compare meaningful overlaps with both parents and inspect the production path. Look for:

  • branch behavior replaced by an older upstream form;
  • release fixes omitted from branch-owned rewrites;
  • migrated modules and legacy twins that now diverge;
  • commands, routes, events, entities, or actions missing from registries and dispatch;
  • injected helpers rebound to stale defaults or bypassed through direct imports;
  • generated localization output resolved without canonical regeneration;
  • persistence mocks, migrations, fixtures, or schema assumptions that no longer match;
  • feature plans whose files, seam, or acceptance premise became stale;
  • tests passing because the merged path no longer exercises intended behavior.

Use history to understand intent, but judge the final tree.

Run targeted checks only as needed. For authorized remediation, add or update focused regression tests before changing the merge result, then run relevant changed-file checks and npm run gate. Never edit, commit, push, or rewrite history in audit-only mode.

Report parent roles, overlap inventory, verified regressions, stale plans, checks, recommended fixes in dependency order, and one verdict: CLEAN, CLEAN WITH FOLLOW-UP, or ACTION REQUIRED.

用于对 World of ClaudeCraft 的 Pull Request 进行只读、基于证据的代码审查。涵盖架构合规性、安全性及性能等维度,生成详细反馈。默认仅读取和起草,未经明确授权不得向 GitHub 提交评论或批准。
审查代码变更 评估 Pull Request 风险 检查数据库性能影响 准备代码反馈草稿
.agents/skills/woc-review-pr/SKILL.md
npx skills add levy-street/world-of-claudecraft --skill woc-review-pr -g -y
SKILL.md
Frontmatter
{
    "name": "woc-review-pr",
    "description": "Review a World of ClaudeCraft pull request against its actual diff, canonical architecture, tests, and domain risks. Use when asked to inspect, review, assess, or prepare feedback for a pull request. Reading and drafting are allowed by default, but posting GitHub feedback requires explicit authorization."
}

Review Pull Request

Perform a read-only, evidence-backed review of the requested pull request.

Hold the authorization boundary

A request to review, inspect, check, or assess authorizes reading and drafting only. Do not run gh pr review, post a comment, approve, request changes, push, edit the branch, or otherwise write to GitHub unless the user explicitly asks to submit the review.

Establish scope

  1. Read the root CLAUDE.md in full.
  2. Identify the pull request, repository, head, base, and merge base.
  3. Read local CLAUDE.md files for touched directories.
  4. Inspect the actual diff, surrounding production code, and linked acceptance criteria.
  5. Run git status --short and avoid disturbing unrelated work.

Use read-only Git and GitHub inspection as needed. Do not rely on the PR description.

Review and verify

Check correctness, edge cases, canonical architecture, determinism, parity, persistence, security, authorization, localization, generated artifacts, decisive tests, and updated operator documentation wherever those domains apply.

The coordinating agent runs targeted commands once. Specialist reviewers inspect the diff and shared results without duplicating the full test or build run.

Invoke woc_database_performance when the diff changes SQL, a database call site, schema or indexes, query frequency/cardinality, pool or lock behavior, timeout policy, background database work, database driver/dependency versions, PostgreSQL engine/resource/configuration/topology, or stored-data growth. Pair it with persistence or security review when those concerns also apply.

For every candidate finding:

  1. Trace the execution path.
  2. Confirm the PR introduces or exposes it.
  3. Check existing tests and guards.
  4. Identify concrete impact.
  5. Cite the narrowest useful file and line.
  6. Remove speculative, duplicate, inherited, and style-only noise.

Classify findings as blocking, should fix, or suggestion. Deliver confirmed findings first, followed by test gaps and residual risk.

If posting was explicitly authorized, show the final review text before the write when practical and submit only the requested action. Otherwise return the draft and state that nothing was posted.

将大型功能拆解为多阶段实施计划,适配 Opus 4.8。通过子代理和并行工作流节省上下文,确保各阶段独立运行并保留状态。需扫描记忆库并遵循项目架构及 i18n 规范,适用于跨会话的复杂开发任务。
用户请求分解大型功能 输入包含 /feature-plan 指令
.claude/skills/feature-plan/SKILL.md
npx skills add levy-street/world-of-claudecraft --skill feature-plan -g -y
SKILL.md
Frontmatter
{
    "name": "feature-plan",
    "description": "Break a big feature into a phased implementation plan with starter prompts, progress tracking, and cross-session state. Opus 4.8 native - each phase runs as its own session with context-saving subagents, agent teams, and (for batch-heavy work) deterministic Workflows, plus a web-research pass for any third-party surface. Use when a feature is too large for one session.",
    "user-invocable": true,
    "disable-model-invocation": true
}

Feature Plan: Multi-Phase Implementation Planning (Opus 4.8)

Break a large feature into a phased implementation plan designed for multiple Claude Code sessions. Every phase runs as its own fresh session and uses Opus 4.8 at xhigh effort (ultracode where the phase warrants deterministic multi-agent orchestration). The whole point is to save context per phase: the orchestrator delegates reading and fan-out to subagents and keeps only conclusions, so each session stays sharp.

The user will provide a feature description either inline (e.g., /feature-plan add a guild bank) or you will ask them to describe it.

Before doing anything else: scan memory. If you use Claude Code's memory feature, check your MEMORY.md index and project memory entries for prior decisions or feedback relevant to this feature's domain. Past incidents encoded there are cheaper than rediscovering them.


What this repo is (so the plan fits it)

Architecture and invariants live in the root CLAUDE.md (one sim three hosts, the IWorld seam, server authority, 20 Hz determinism via Rng, the i18n contract); the plan must respect all of them, so reference that file rather than restating it. Two planning-specific consequences:

  • A feature added to the offline Sim is not done until it is mirrored online (via ClientWorld) and, where relevant, exposed to the RL env. Extend IWorld first, then implement it in both worlds.
  • The contributor i18n policy is English-only. Every new player-visible string is a t() key added in ENGLISH to the matching src/ui/i18n.catalog/<domain>.ts module and rendered via t(). Never edit the src/ui/i18n.locales/<lang>.ts overlays: locale fills are release-time maintainer work (the one exception, M16: a wordy new English value also needs its five non-Latin fills in the same change, see src/ui/CLAUDE.md). Sim/server stay language-agnostic (no t(), no DOM) but their player text needs a matcher rule in src/ui/sim_i18n.ts / src/ui/server_i18n.ts in the SAME change; the S3 guard (tests/localization_fixes.test.ts) enforces it.

Orchestration Toolbox (Opus 4.8) - choose deliberately before running any phase

Opus 4.8 self-initiates fewer subagents than prior models, so you MUST request fan-out explicitly. Pick the lightest tool that fits; escalate only when the work demands it.

Tool What it is Use it when Context effect
Explore subagent (subagent_type: "Explore") Read-only search agent; reads excerpts, returns conclusions Mapping the codebase, locating files/patterns, "where is X used" Raw file reads stay in the subagent; only the summary returns. Default for all recon.
Parallel Agent fan-out (multiple Agent calls in one message) Several independent agents in one turn Independent vertical slices in a phase (sim + server + ui + tests); parallel reviews Each agent's work stays in its own context; you keep the results. Cap at ~5 manual agents.
Agent teams (name: + SendMessage) Addressable, longer-lived agents you can hand more work to with context intact Multi-round collaboration where an agent needs its prior context (iterative implement, fix, re-review) Reuses a warm agent instead of re-priming a fresh one. Never mode: "plan" on teammates (they stall).
Workflow (the Workflow tool) A JS script orchestrating dozens to hundreds of subagents deterministically (pipeline / parallel / loop-until-dry / adversarial-verify), with structured-output schemas A phase is batch-heavy or needs scale + verification: mass edits, content sweeps across many tables, exhaustive audits, adversarially-verified review. Requires explicit ultracode opt-in in the running prompt. Intermediate results live in script variables, not your context. Scales far past manual fan-out (16 concurrent / 1000 total).
ToolSearch / deferred tools On-demand tool-schema loading A phase needs an MCP/integration tool not loaded by default Keeps unused tool schemas out of context until needed.

Hard rules (Opus 4.8 + this repo):

  • Subagents inherit the parent model. No need to set model unless you deliberately want a cheaper tier; when unsure, omit.
  • Request fan-out explicitly - say "spawn N agents in parallel", name the split. 4.8 will not infer it.
  • Manual parallel fan-out caps at ~5 agents. Beyond that, coordination overhead wins - use a Workflow instead.
  • Workflow is opt-in. Only reach for it when the running phase prompt includes ultracode (or the user asked for a workflow). For batch-heavy phases, the starter prompt should TELL the runner to add ultracode and orchestrate via a Workflow.
  • Shared working tree. A concurrent session may share this exact checkout. Commit sequentially with EXPLICIT paths, never git add -A; often the right move is to commit nothing that is not yours. (See memory: shared-worktree-commit-care.)

Opus 4.8 Prompting Discipline (apply to EVERY prompt this skill emits)

  1. State scope literally and exhaustively. 4.8 follows instructions literally and will NOT generalize from one example. Write "all three hosts", "every new player string", "each of the nine classes" - never "the sections" or "the files".
  2. Reserve ALL-CAPS / NON-NEGOTIABLE for genuine determinism, server-authority, security, and data-integrity gates. If everything is emphasized, nothing is. Routine conventions read fine in plain voice.
  3. For review/QA agents, the finding stage is COVERAGE, not filtering. 4.8 honors "be conservative / don't nitpick" literally and reports fewer real issues. Always prompt: "report every issue including low-severity and uncertain ones; ranking happens in a later step."
  4. Review agents truncate mid-analysis. Budget 2-3 SendMessage rounds; resume with: "Stop reading more files. Output the full report now based on what you've already seen. No more tool calls. Format: BLOCKING / SHOULD-FIX / NICE-TO-HAVE / VERDICT."
  5. Demand structured handoffs. A phase ends by writing its state to progress.md / state.md and (for big packets) a per-phase resume file - that IS the cross-session memory. The next session reads the summary, not the transcript.

Context Discipline (how each phase stays cheap)

  • The orchestrator (main loop) does not read large docs or sprawl across source files. It spawns an Explore agent that returns a focused summary. (The coordinator monoliths src/ui/hud.ts, src/sim/sim.ts, and src/main.ts are huge, and the big i18n surface is src/ui/i18n.catalog/* plus the generated overlays; never read these whole in the main loop.)
  • Give each implementation agent ONLY the slice of context it needs (the Explore summary + its own files), never the raw planning docs.
  • Delegate web/doc lookups to a subagent (classic-era MMO formula references, a Three.js or GLB asset technique, the pg Postgres driver, Cloudflare Turnstile, any third-party surface); keep raw docs out of the main context.
  • For 12+ phase packets, use per-phase resume files so a fresh session resumes from a checkpoint, not from scratch.
  • Use ToolSearch to pull in deferred tool schemas only when a phase actually needs them.

Step 1: Understand the Feature

If the user did not provide a feature description inline, ask them to describe what they want to build. Get enough detail to understand scope, but do not over-interrogate.

Step 2: Explore the Codebase + Research the External Surface (parallel agents)

Spawn these in parallel in a single message. Do NOT read these files yourself - save your context window. Each returns a summary, not raw dumps.

Codebase Explore agents (subagent_type: "Explore")

Adapt the split to the feature (a content-only feature needs the sim/content explorer, not the net explorer; add a headless-explorer for RL-env work):

sim-explorer - src/sim/ core: tick loop, combat/abilities/threat, mob AI, parties/duels/arena/trade/market/dungeons, the RL observation surface, Rng usage, and overlapping content in src/sim/content/ (classes, abilities, zones, dungeons, items, talents). Note relevant test patterns in tests/.

server-explorer - server/: GameServer loop and command dispatch (server/game.ts), interest-scoped snapshots (wireEntity/selfWireJson), Postgres persistence and the inline SCHEMA (server/db.ts) + SOCIAL_SCHEMA (server/social_db.ts), auth (server/auth.ts), social/moderation, rate limiting.

client-explorer - src/render/ (Three.js renderer; reads world, never mutates), src/ui/ (HUD, windows, tooltips, map, FCT, i18n), and src/game/ (input, camera, keybinds, mobile/touch controls). Note which IWorld members the feature will read or call.

net-explorer - src/net/ (ClientWorld implements IWorld, REST auth, WS mirror) and the wire-protocol lockstep with server/game.ts (applySnapshot/applyWire, SimEvent handling). Use when the feature changes anything that crosses the network.

admin-explorer - src/admin/ (the separate admin dashboard SPA, its own admin.html entry and admin/api) and its dedicated i18n catalog src/admin/i18n.ts. Use when the feature has an admin, moderation, or operator surface. Operators are users, so admin strings localize too.

(Add headless-explorer for headless/ + python/ RL-env work. One focused agent per surface, up to the ~5-agent cap.)

Web-research agent (REQUIRED when the feature touches any third-party surface)

If the feature involves a third-party API, SDK, library, framework, cloud service, or a real classic-era MMO formula you need to get exactly right, spawn a web-research agent (general-purpose, or claude-code-guide for Claude tooling; both have WebSearch/WebFetch). Instruct it to pull current, primary-source data (prefer official docs over blogs), since APIs and references drift. Ask for: exact endpoints/auth/schemas (for an API), the canonical formula/constants (for balance math), version/migration notes, and licensing for any asset. It must return a tight brief with citations and mark anything unverifiable as OPEN rather than guessing. Fold OPEN items into the plan as blockers, never as assumptions. (Gameplay math must follow real classic-era formulas; do not invent balance numbers.)

For sweeping research (many sources cross-checked), the running session can use an ultracode Workflow (multi-modal sweep + adversarial-verify) instead of a single agent.

Step 3: Brainstorm with the User

Present findings from the Explore + research agents (summarized, not raw) and brainstorm:

  • What systems/content already exist vs what is new
  • What IWorld surface exists vs what needs adding
  • Creative ideas that leverage existing infrastructure (the sim already has parties, duels, arena, trade, market, dungeons, talents, pets)
  • What would make this feature stand out while staying classic-faithful
  • Any OPEN items from research that need a human/credential/design decision before phasing

Get user buy-in on the overall vision before planning phases.

Step 4: Create Planning Documents

Create docs/{feature-name}/ with these files:

  • README.md - packet entry point and index, links to every phase file plus the cross-cutting docs.
  • brainstorm.md - feature vision, approved ideas, current state summary, reusable systems/IWorld members, new work needed, research findings + OPEN items.
  • implementation-plan.md - TOC + canonical workflow + phase summary table.
  • progress.md - status table + per-phase deliverables/acceptance checklists.
  • state.md - cross-phase cheat sheet (locked decisions, validation matrix, file paths, new IWorld methods / SimEvents / wire fields / endpoints / tables / i18n keys).
  • qa-checklist.md - whole-feature integration QA matrix (three-host parity, determinism, i18n completeness, classic fidelity, persistence, performance, deploy verification).

For packets with 12+ phases (or when each phase is non-trivial), prefer per-phase resume files instead of inlining everything into implementation-plan.md:

  • phase-XX-{slug}.md - implementation prompt for phase XX (self-contained; a fresh-context Claude can paste it into a new session and execute without referring back to the TOC).
  • phase-XX-qa.md - QA prompt for phase XX.
  • implementation-plan.md then becomes a TOC + canonical workflow + summary table that references the per-phase files.

README.md

The packet entry point: a one-paragraph feature summary, an index linking every phase and QA file in order, and links to the cross-cutting docs (brainstorm.md, implementation-plan.md, progress.md, state.md, qa-checklist.md). A newcomer should be able to orient from here alone.

brainstorm.md

  • Feature vision and approved ideas
  • Current state summary
  • Existing systems / IWorld members / content tables that can be reused
  • New work needed (sim / server / net / render / ui / headless)
  • Web-research findings (with citations) and OPEN items
  • Open questions for design decisions

implementation-plan.md

Split the feature into phases. Each implementation phase is followed by a dedicated QA phase. Both are separate Claude Code sessions. The numbering is: Phase 1 (implement), Phase 1 QA (verify), Phase 2 (implement), Phase 2 QA (verify), etc.

Phase sizing (critical): Prefer many small phases over fewer large ones. A phase that tries to do too much burns context, produces sloppier output, and misses details. Each implementation phase should be completable in a single focused session without exhausting the context window. Rules of thumb:

  • One phase = one logical slice (e.g., "add the ability to the sim + content data + tests" or "wire the HUD window to the new IWorld members"). If you find yourself writing "and also..." in the phase description, split it.
  • 2-4 deliverables per phase is ideal. More than 5 is a sign the phase is too big.
  • When in doubt, split. Two small phases with QA passes will always produce better work than one large phase that rushes through.

Phase ordering principles:

  1. Phase 1 is always architecture/foundation: extend IWorld and the sim data model, establish the pattern all later phases follow.
  2. Phase 1 QA verifies Phase 1.
  3. Next phases implement sim behavior server-side and mirror it in ClientWorld (keep the offline and online worlds in lockstep as you go, not at the end).
  4. Then phases that add server persistence (extend the SCHEMA DDL, save/load round-trip, back-compat for existing JSONB saves).
  5. Then renderer/HUD/i18n surface, then polish/optimization last.
  6. Every implementation phase gets a QA phase immediately after it.
  7. The final QA phase closes the packet: once it passes, it offers Packet teardown (below), deleting docs/{feature-name}/ only on explicit user confirmation so the PR does not ship the planning scaffolding.

Team Workflow section (include at top of plan): Every phase runs on Opus 4.8 at xhigh effort (1m context variant where the file load demands it; ultracode for batch-heavy phases). Include this standard workflow:

  1. Step 0 - Pre-flight: Verify git status is clean (and that no concurrent session is mid-change in your files). Scan your Claude Code memory (the MEMORY.md index and any entries matching the phase domain), if you use it.
  2. Step 1 - Load Context: Spawn an Explore agent to read planning docs and relevant source files. The main agent does NOT read large docs directly. The Explore agent returns a focused summary.
  3. Step 2 - Choose Orchestration + Execute: Pick the lightest tool from the Orchestration Toolbox. Default: parallel Agent fan-out, one agent per vertical slice (give each ONLY the Explore summary, not raw planning docs). For batch-heavy/audit/content-sweep phases, run an ultracode Workflow (pipeline + adversarial-verify) instead. Use isolation: "worktree" only when agents mutate overlapping files in parallel.
  4. Step 3 - Validation + Multi-Agent Review Dispatch:
    • Run validation (see the matrix in state.md): npx tsc --noEmit; npx vitest run tests/<affected>.ts (or npm test for broad changes). If src/sim/ changed, run npx vitest run tests/architecture.test.ts (the sim-purity guard: no render/ui/game/net/three imports, no DOM globals, no nondeterminism). If any player-visible text was added or an emit changed, run npx vitest run tests/localization_fixes.test.ts (the S3 i18n drift guard). If the wire protocol / snapshots changed, run npx vitest run tests/snapshots.test.ts tests/env_protocol.test.ts tests/bandwidth.test.ts. If assets changed, npm run asset:budget. Before a big merge, run npm run gate (the CI-equivalent gate: i18n gen + freshness, malware scan, changed-files biome, sfx check, full tests with bounded workers, typecheck, all builds; release-tier automatically on a release/** branch). Never an ad-hoc && chain: piping npm test masks its exit code and an unbounded run flakes heavy suites.
    • Spawn review agents using the Review Dispatch Matrix below. Spawn ONLY the agents whose surface this change actually touches. Most phases trigger one or two, not all of them; a docs/test-only change triggers none. (Each agent also self-gates and exits cheaply if mis-dispatched, but spawning an out-of-scope agent still costs tokens, so gate at dispatch too.)
    • Prompt every review agent you DO spawn for COVERAGE not filtering ("report every issue including low-severity and uncertain ones"). Do not commit until each reports no BLOCKING issues. Resume any agent that truncates with: "Stop reading more files. Output the full report now based on what you've already seen. No more tool calls. Format: BLOCKING / SHOULD-FIX / NICE-TO-HAVE / VERDICT."

Review Dispatch Matrix (single source of truth: copy this table into the generated implementation-plan.md; starter prompts reference it, never inline a copy)

Match the change surface to the agent. Spawn an agent ONLY when its row matches the diff:

Agent Spawn ONLY when the diff touches Skip it for
privacy-security-review server/, src/admin/, src/net/, a deploy/secret file (Docker/compose/env/CI yml/DEPLOY.md), OR introduces SQL / auth / a secret / ALLOW_DEV_COMMANDS / a new Math.random|Date.now|performance.now in src/sim/ a pure src/ui / src/render / src/game / src/sim/content / docs / test change
migration-safety server/db.ts, server/social_db.ts, a server/*_db.ts, or a characters.state JSONB serialize/deserialize path any diff with no DDL and no persisted-state shape change
database-performance-reviewer SQL or a database call site, schema/indexes, query cadence or cardinality, pool/lock/timeout behavior, scheduled database work, a database driver or Postgres engine/config change, or stored-data growth any diff that cannot change database work or growth
cross-platform-sync src/world_api.ts or src/world_api/** (the IWorld facets), src/sim/ behavior/obs/SimEvent, src/net/online.ts, server/game.ts wire/dispatch, the matchers src/ui/sim_i18n.ts|src/ui/server_i18n.ts, or the RL surface (headless/, python/) a pure i18n catalog refactor (only src/ui/i18n.ts + locale data, t() keys unchanged) - tsc (: typeof en) + the resolved-equivalence test already cover it
architecture-reviewer a src/sim/ change: determinism, rng draw-order, tick-phase order, the SimContext seam, or a move-not-rewrite relocation a non-sim change, or a pure data/content/test change
frontend-seam-reviewer src/ui/, src/render/, src/game/, or src/styles/ (the view-core + PainterHost painter seams, graphics-settings fairness, mobile/touch surfaces) a diff with no frontend surface
qa-checklist a phase / deliverable set is COMPLETE (it self-scales via its per-category Skip rules) per-commit / mid-phase work, or a docs/test-only change

If NO row matches (e.g. a docs-only, test-only, or comment change), spawn NO review agent. Do not default to "run privacy-security-review anyway." 5. Step 4 - Update Docs + Memory: Update progress.md (mark phase complete; note deferrals) and state.md (new IWorld members, SimEvents, wire fields, endpoints, tables, i18n keys, locked decisions). If you use Claude Code memory, record any surprising rules learned or current-state notes there for the next session. Commit doc updates in the same logical commit as the implementation (EXPLICIT paths).

Agent Scaling Guidelines (include in Team Workflow): The starter prompts suggest a default split (sim + server + client + tests), but the orchestrator MUST assess the actual workload and scale accordingly:

  • Split large sim work across multiple agents when a single agent would handle 4+ independent concerns (e.g., a new ability system + threat changes + content tables + RL obs surface). Signs a split is needed: the deliverable list has 10+ items, the work spans 4+ modules, or the concerns are independent.
  • Merge small work into a single agent when one side has only 1-2 trivial changes (e.g., adding one IWorld getter, adding one i18n key). Do not spawn a dedicated agent for work that takes five minutes.
  • Split large client work when a phase adds 3+ HUD windows plus renderer changes plus input wiring. One agent for HUD/i18n, one for renderer, one for input/camera/mobile.
  • Use dedicated test agents when a phase has complex test requirements across multiple suites. A test agent can run in parallel after implementation agents commit their code.
  • Escalate to a Workflow past the manual cap. Hand-orchestrated parallel fan-out tops out at ~5 agents. When a phase has 10+ independent, uniform tasks (e.g., add a new field to every zone's mob table, register 30 new English i18n keys across the catalog domains, transform many content entries), do not hand-spawn - write an ultracode Workflow that pipelines them with structured outputs and verifies each.
  • Each agent should own complete vertical slices - do not split by file type (one for types, another for tests). Split by domain (one for the sim behavior + its tests, another for the HUD surface + its tests). Each agent writes its own tests for the code it creates.

Code Hygiene section (include in Team Workflow): Every phase must enforce:

  • Module-first: new self-contained behavior goes in its own focused module behind an existing seam (IWorld, a src/sim/content/ record, a src/render/<thing>.ts), not appended to a monolith (sim.ts, hud.ts, renderer.ts). Do not split a monolith for line count. Fix bugs test-first. See the extract-and-test skill and the root Modularity section.
  • New code gets tests: Every new ability, system, command, IWorld member, server endpoint, query, and behavior gets unit tests. Sim: combat math, abilities, AI, economy. Server: command dispatch, persistence, snapshots. Net: wire round-trip. UI: data transforms, frame logic. E2E (scripts/*.mjs): user flows where applicable. If you wrote it, test it.
  • Determinism tests: For sim changes, assert same-seed-same-result; never introduce Math.random / Date.now / performance.now into src/sim/.
  • Test maintenance: Update/remove tests when modifying existing code. When placeholder content is replaced with real content, update the tests. Never leave orphaned or broken tests.
  • Dead code removal: Delete fully replaced abilities, systems, components, helpers, and types. No commented-out code, unused imports, or deprecated functions.
  • Import cleanup: Zero unused imports. And uphold the import invariant: src/sim/ imports nothing from render/, ui/, game/, net/, and has no DOM/Three.js imports.
  • Type cleanup: Remove unreferenced interfaces/types. Consolidate evolved types, do not accumulate.
  • No generated-file hand-edits: Never hand-edit generated output (e.g. src/render/assets/manifest.generated.ts or the media manifest emitted by npm run build); regenerate via the build instead.

Every phase starter prompt must follow this structure:

### Starter Prompt
```
This is Phase N of the {Feature Name} feature: {Phase Title}.

Model: Opus 4.8, xhigh effort (reserve max for genuinely frontier problems), 1m context variant where the file load demands it.
Harness: Claude Code.
ULTRACODE: add the keyword `ultracode` to this prompt if this phase is batch-heavy
(content sweeps across many tables, bulk i18n catalog additions, exhaustive audit) so you
orchestrate via a Workflow (pipeline + adversarial-verify) instead of hand-spawning agents.

Goal: {one sentence}

STEP 0 - PRE-FLIGHT:
- Verify `git status` is clean before starting. If not, ask the user (a concurrent
  session may share this checkout).
- Memory scan (if you use Claude Code memory): check your `MEMORY.md` index and any
  entries relevant to this phase's domain (suggested topics: {phase-specific patterns}).

STEP 1 - LOAD CONTEXT (do NOT read planning docs directly, save your context):
Spawn an Explore agent to read and summarize:
- docs/{feature-name}/state.md (locked decisions, validation matrix, file paths)
- docs/{feature-name}/progress.md (Phase N status + deliverable checklist)
- docs/{feature-name}/phase-N-{slug}.md (this prompt) - verify the agent has the same understanding
- {relevant source files for this phase, listed individually}
- CLAUDE.md (root) + the relevant sub-CLAUDE.md files
  ({e.g. src/sim/CLAUDE.md, server/CLAUDE.md, src/ui/CLAUDE.md, src/net/CLAUDE.md})
The agent should return: {specific info this phase needs}.
{If this phase integrates a third-party API/SDK or needs an exact classic-era formula:
also spawn a web-research agent for current primary-source docs/constants; mark
unverifiable facts OPEN rather than guessing.}

STEP 2 - CHOOSE ORCHESTRATION + EXECUTE:
Pick the lightest tool that fits (Explore for recon, then parallel Agent fan-out for
independent slices, then Workflow for batch/scale). Request fan-out EXPLICITLY (Opus 4.8
will not self-initiate it). Give each agent ONLY the Explore summary, not raw planning
docs. Never `mode: "plan"` on teammates. Use `isolation: "worktree"` only if agents edit
overlapping files in parallel.

{Agent A} deliverables:
- {bullet}
- {bullet}

{Agent B} deliverables:
- {bullet}
- {bullet}

INVARIANTS THIS PHASE MUST KEEP (call out the ones in play):
- Determinism: all randomness via `Rng`; no `Math.random` / `Date.now` / `performance.now` in `src/sim/`.
- Seam: extend `IWorld` first, then implement in BOTH `Sim` and `ClientWorld`.
- Server authority: the client never decides combat/loot/quest/economy outcomes.
- i18n: every new player string is a `t()` key added in ENGLISH ONLY to the matching
  `src/ui/i18n.catalog/<domain>.ts` module (never edit the locale overlays; M16: a wordy
  new English value also needs its five non-Latin fills in the same change); sim/server
  player text gets a matcher rule in `src/ui/sim_i18n.ts` / `src/ui/server_i18n.ts` in
  the SAME change.
- Classic-era formulas only; do not invent balance numbers.

Out of scope (do NOT do in this phase):
- {explicit exclusions to prevent scope creep}

STEP 3 - VALIDATION + MULTI-AGENT REVIEW:
- Run: {phase-specific validation commands referencing the state.md matrix}
  (baseline: `npx tsc --noEmit` + `npx vitest run tests/<affected>.ts`; add
  `npx vitest run tests/localization_fixes.test.ts` if any player text changed; add the
  wire/snapshot suites if the protocol changed).
- Spawn review agents in parallel per the Review Dispatch Matrix in
  docs/{feature-name}/implementation-plan.md (the plan carries the one canonical copy).
  Check `git diff --name-only` against the phase-start commit and spawn ONLY the agents
  whose row matches; most phases trigger one or two, and if no row matches, spawn none.
- Prompt each agent you spawn for COVERAGE not filtering. Resume any that truncates with the
  "Stop reading. Output verdict now." message.
- Do not commit until each reports no BLOCKING issues.

STEP 4 - COMMIT CADENCE:
Aim for {2-5} commits with these headlines (Conventional Commits with a scope, e.g.
`feat(sim): ...`, `fix(net): ...`; EXPLICIT paths, never `git add -A`; no em dashes/emojis):
- {commit 1 headline}
- {commit 2 headline}
- ...

STEP 5 - ACCEPTANCE CRITERIA (verifiable checklist; do not mark complete until all check):
- [ ] {acceptance item}
- [ ] {acceptance item}
- ...

STEP 6 - DOC UPDATES + MEMORY:
- Update docs/{feature-name}/progress.md (mark Phase N status; note deferrals).
- Update docs/{feature-name}/state.md (new IWorld members, SimEvents, wire fields,
  endpoints, tables, i18n keys; locked decisions).
- If you use Claude Code memory, record any surprising rules or current-state notes for
  the next session.

STEP 7 - FINAL RESPONSE FORMAT:
End your turn with: phase status, files touched, validation results, review-agent verdicts,
any deferred items, and a one-line handoff for the QA session.

STOPPING RULES:
- {explicit stop conditions: "stop if determinism cannot be preserved", "stop and ask if
  Y changes the wire protocol in a backwards-incompatible way", etc.}
```

Every QA phase starter prompt must follow this structure:

### QA Starter Prompt
```
This is Phase N QA of the {Feature Name} feature: Verify {Phase Title}.

Model: Opus 4.8, xhigh effort (reserve max for genuinely frontier problems), 1m context variant where the file load demands it.
Harness: Claude Code.
ULTRACODE: for a large or high-risk phase, add `ultracode` so you can run an
adversarial-verify Workflow (each finding independently confirmed by a skeptic agent
before it counts).

Goal: Audit Phase N implementation for correctness, missing tests, dead code, determinism,
three-host parity, and i18n completeness.

STEP 0 - PRE-FLIGHT:
- Verify `git status` is clean (Phase N implementation should already be committed). If dirty, ask the user.
- Memory scan (if you use Claude Code memory): check entries from the Phase N domain.

STEP 1 - LOAD CONTEXT (do NOT read planning docs directly, save your context):
Spawn an Explore agent to read and summarize:
- docs/{feature-name}/state.md (new IWorld members, SimEvents, wire fields, endpoints, tables from Phase N)
- docs/{feature-name}/progress.md (Phase N deliverables checklist + acceptance criteria)
- docs/{feature-name}/phase-N-{slug}.md (the implementation prompt - what was promised)
- All files created or modified in Phase N (use `git diff` against the phase start commit)
- CLAUDE.md (root) and relevant sub-CLAUDE.md files
The agent should return: full list of Phase N deliverables, all new/modified files, and any known issues.

STEP 2 - QA AUDIT (spawn parallel review agents using the Explore summary; prompt each for COVERAGE not filtering):

Correctness agent:
- Verify every deliverable from Phase N was actually implemented
- Verify every acceptance criterion in the phase prompt is met
- Check for logic bugs, off-by-one errors, missing error handling
- Verify classic-era formulas match the cited references; no invented constants
- Verify the offline `Sim` path and the online `ClientWorld` path behave identically
- Test edge cases: empty states, error states, boundary values, concurrent access
- Run the affected tests and (where useful) an E2E script (`scripts/*.mjs`) and verify behavior matches intent

Test coverage agent:
- Identify new code paths without tests
- Add missing unit tests for new sim behavior, commands, IWorld members, endpoints, queries
- Add a determinism test (same seed, same result) for new sim logic
- Update existing tests broken by Phase N changes
- Remove orphaned tests for deleted/replaced code
- Verify test assertions are meaningful (not just "it runs")

Dead code & cleanup agent:
- Find unused imports, functions, types, components left behind
- Verify the import invariant holds (`src/sim/` imports nothing from render/ui/game/net; no DOM/Three)
- Remove commented-out code
- Consolidate duplicate or near-duplicate logic
- Verify no TODO/FIXME items were left unresolved
- Check for inconsistent naming or patterns vs the rest of the codebase

Multi-agent review dispatch: apply the Review Dispatch Matrix in
docs/{feature-name}/implementation-plan.md (the plan carries the one canonical copy).
Check `git diff --name-only` against the phase-start commit and spawn ONLY the agents
whose row matches, plus `qa-checklist` (this is the phase-completion QA gate).
Resume any review agent that truncates mid-analysis with: *"Stop reading more files. Output the full report now. No more tool calls. Format: BLOCKING / SHOULD-FIX / NICE-TO-HAVE / VERDICT."*

STEP 3 - FIX: Apply all BLOCKING and SHOULD-FIX items. Run the full validation matrix from state.md
(at minimum `npx tsc --noEmit` and the relevant vitest files; the S3 i18n guard if player text changed).
Commit fixes (separate commits from the QA verdicts themselves so the history is reviewable; EXPLICIT paths).

STEP 4 - UPDATE DOCS + MEMORY:
- Update docs/{feature-name}/progress.md (mark Phase N QA complete; note any items deferred to follow-up).
- Update docs/{feature-name}/state.md (any drift discovered during QA).
- If you use Claude Code memory, record any surprising rules learned during QA.

STEP 5 - PACKET TEARDOWN (final phase only; skip entirely otherwise):
If this is the LAST phase in the packet and everything is complete and green, ask the user
for explicit confirmation to delete the planning scaffolding before the PR, e.g.:
"All phases are complete and green. OK to delete docs/{feature-name}/ before the PR?"
- Surface any deferred follow-ups first so nothing tracked only in the packet is lost.
- On confirmation, delete ONLY that directory with an explicit path: `git rm -r
  docs/{feature-name}/` (if it was committed) then commit
  `docs: remove {feature-name} planning scaffolding`, or `rm -rf docs/{feature-name}/`
  (if it was never committed).
- If the user declines, leave it in place. Never delete anything outside that directory and
  never `git add -A`.

STEP 6 - FINAL RESPONSE FORMAT:
End your turn with: QA verdict (PASS / PASS-WITH-FOLLOWUPS / FAIL), counts of
BLOCKING/SHOULD-FIX/NICE-TO-HAVE found and fixed, deferred items, whether the planning
packet was removed, and a one-line handoff for the next implementation phase (or
"packet complete" if this was the final phase).

STOPPING RULES:
- Stop and surface to the user if any BLOCKING item cannot be fixed without changing the phase scope.
```

Every phase that changes server persistence MUST also:

  • Extend the DDL additively: edit server/db.ts SCHEMA (or server/social_db.ts SOCIAL_SCHEMA) using CREATE TABLE IF NOT EXISTS / ALTER TABLE ... ADD COLUMN IF NOT EXISTS so existing realms upgrade in place under the boot advisory lock. There is no migrations directory; the inline DDL is the schema.
  • Guarantee back-compat for existing JSONB character state: loading a character saved before this change must not throw or lose data (default any missing fields).
  • Add appropriate indexes for any new query predicate.
  • Add a persistence round-trip test under tests/ (save then load, assert equality).

Mobile in every client phase (the game ships touch controls):

  • Any HUD/input change must work with the touch controls in src/game/ and respect mobile safe areas.
  • Verify with the mobile screenshot scripts (e.g. node scripts/mobile_visual.mjs, the mobile_*_shot.mjs family) against a phone viewport with npm run dev running.
  • Keep tap targets comfortable; do not rely on hover for essential info.

Performance in every phase (the sim is a fixed 20 Hz budget):

  • Sim work per tick must stay within the 20 Hz frame budget; avoid per-tick allocations in hot paths.
  • Keep snapshots interest-scoped and delta-guarded; do not send unchanged heavy fields (see the interest radius and wireEntity / selfWireJson in server/game.ts).
  • The renderer reads the world and never mutates it; keep draw-call and texture budgets in check (npm run asset:budget, npm run perf:tour).
  • Keep the dependency set tiny; do not add packages without a clear need.

Deploy gates (any phase that ships server or client changes to production):

  • Production runs in Docker (see DEPLOY.md). Standalone update path: ssh to the host, cd /opt/eastbrook, sudo git pull, sudo docker compose up -d --build. Players are saved on shutdown and briefly disconnect.
  • Health check after deploy: curl -s localhost:8787/api/status returns {"ok":true,"players_online":N,...}.
  • Before any deploy, the CI-equivalent gate must be green locally: npm run gate (mirrors .github/workflows/ci.yml: i18n gen + freshness, malware scan, changed-files biome, sfx check, full tests, typecheck, all builds; release-tier on release/**).
  • Never set ALLOW_DEV_COMMANDS=1 in production (it enables level/teleport/item cheats).
  • Most phases do not deploy; deploys are manual and infrequent. Treat deploy as a deliberate, separate step, not part of every phase.

Packet teardown (final phase only): The planning packet in docs/{feature-name}/ is cross-session scaffolding, not a shipping artifact. The final QA phase, once every phase is complete and the build / CI-equivalent gate is green, MUST offer to remove it before a PR is opened:

  • Ask the user explicitly, in plain language, for example: "All phases are complete and green. OK to delete docs/{feature-name}/ (the planning scaffolding) before the PR?" Do not delete on assumption.
  • Surface any deferred follow-up items FIRST, so nothing tracked only inside the packet is lost when it goes.
  • Delete ONLY on explicit confirmation, and ONLY that one directory, with an explicit path:
    • If the docs were committed during the packet: git rm -r docs/{feature-name}/, then commit docs: remove {feature-name} planning scaffolding.
    • If they were never committed: rm -rf docs/{feature-name}/.
  • If the user declines or wants to keep them, leave the directory in place and say so; delete nothing.
  • Never delete anything outside docs/{feature-name}/, never fold the deletion into an unrelated commit, and never git add -A (a concurrent session may share this checkout).

progress.md

  • Overall status table (phase | status | date started | date completed) - includes both implementation and QA phases (e.g., "Phase 1", "Phase 1 QA", "Phase 2", "Phase 2 QA")
  • Per-phase checklist matching deliverables from implementation-plan.md
  • Per-QA-phase checklist (fixes applied, tests added, dead code removed)
  • Notes section per phase (filled in after completion)

state.md

Cross-phase cheat sheet. Contains ONLY what the next session needs:

  • Current phase number + status
  • Locked design decisions (record once, reference forever)
  • Non-negotiable constraints (determinism, server authority, IWorld-first, English-only i18n catalog keys, no generated-file edits, shared-worktree commit care)
  • Validation matrix by change type:
    • sim-only: npx tsc --noEmit + npx vitest run tests/sim.test.ts (and the relevant command suites); determinism check.
    • content-only: npx tsc --noEmit + npx vitest run tests/progression.test.ts tests/talents.test.ts (referential integrity); i18n if new names.
    • server-only: relevant server suites + npx tsc --noEmit + npm run build:server.
    • net/wire: npx vitest run tests/snapshots.test.ts tests/env_protocol.test.ts tests/bandwidth.test.ts + parity check.
    • ui/render: npx tsc --noEmit + npx vitest run tests/localization_fixes.test.ts (if text) + a mobile screenshot script.
    • headless/RL: npm run build:env + npx vitest run tests/env_protocol.test.ts + a short npm run bench.
    • full-stack / pre-merge: npm run gate (the CI-equivalent gate; release-tier on release/**).
    • any code change (Biome / CI ratchet): npm run ci:changed (Biome on the files you changed, what the .githooks/pre-push floor runs). Fix formatting with a SCOPED npx @biomejs/biome check --write <file>, never a whole-tree --write.
  • Key file paths (existing + created by this feature)
  • New files created per phase
  • New IWorld members added per phase
  • New SimEvents and wire/snapshot fields added per phase
  • API endpoints created per phase
  • Database tables/columns added per phase (in the inline SCHEMA)
  • New i18n keys + matcher rules added per phase
  • Architecture decisions (locked once made)
  • OPEN research items + known issues / gotchas

qa-checklist.md

Whole-feature integration matrix verified once at packet completion:

  • Three-host parity: the offline browser Sim, the online ClientWorld, and the headless env behave consistently for this feature.
  • Determinism: same seed gives the same world; no Math.random / Date.now / performance.now in src/sim/; determinism tests pass.
  • i18n completeness: every new player-visible string is a t() key in the English catalog (src/ui/i18n.catalog/), rendered via t(), with the locale overlays untouched (release-tier fills them; M16 wordy strings carry their five non-Latin fills); sim/server emits have matcher rules in sim_i18n.ts / server_i18n.ts; npx tsc --noEmit and npx vitest run tests/localization_fixes.test.ts (S3 guard) are green; numbers/money/dates go through formatNumber / formatMoney / formatDateTime.
  • Classic-era fidelity: formulas match the cited references; no invented balance numbers.
  • Server authority: no client-trusted outcomes; WS commands validated server-side.
  • Persistence: characters saved before this feature still load; save/load round-trip verified; DDL changes are additive and idempotent.
  • Performance / budgets: snapshot bandwidth sane; npm run asset:budget and npm run perf:tour within budget.
  • Copy review: no em dashes or emojis in player-facing text (raw emojis as in-game icons are also disallowed by the aesthetic rule).
  • Build gate: npm run gate is green (the CI-equivalent gate; release-tier on release/**).
  • Deploy verification (only if deployed): curl -s localhost:8787/api/status returns ok with the expected build.

Step 5: Commit

Stage and commit all planning docs (EXPLICIT paths, Conventional Commit, short message, no em dashes/emojis):

docs: add {feature-name} phased implementation plan

Present a summary to the user:

  • Number of phases (implementation + QA)
  • What each phase covers (one line each, showing the implement/QA pairs)
  • How to start Phase 1 (copy the starter prompt from phase-01-{slug}.md or the implementation-plan.md Phase 1 section)
  • Locked design decisions captured in state.md
  • OPEN research items still needing a human/credential/design answer
  • Cross-cutting workflow blocks the user can edit centrally (memory scan, orchestration choice, multi-agent dispatch, validation matrix, deploy gate)
  • That the final QA phase will offer packet teardown (delete docs/{feature-name}/) before the PR, on your explicit confirmation, so the planning scaffolding does not ship
将用户提供的粗略描述或截图转化为符合 World of ClaudeCraft 维护者风格的规范 GitHub Issue。自动分类 bug 或需求,生成包含问题、预期行为、范围及验收标准的专业报告,并处理 UI/UX 截图和环境信息。
创建 GitHub issue 提交 bug 报告 基于描述生成 issue
.claude/skills/file-issue/SKILL.md
npx skills add levy-street/world-of-claudecraft --skill file-issue -g -y
SKILL.md
Frontmatter
{
    "name": "file-issue",
    "description": "Create a GitHub issue for World of ClaudeCraft in the maintainer's house format. Use when asked to file, open, or create a GitHub issue or bug report from a description, a screenshot, or a rough placeholder. Rewrites the input into a clean, professional issue (Problem, Steps to reproduce, Expected, Actual, Scope, Acceptance criteria) and includes a Screenshot section only for UI\/UX issues. Posts to levy-street\/world-of-claudecraft via gh.",
    "user-invocable": true
}

File an issue (World of ClaudeCraft house style)

Turn a rough description, screenshot, or placeholder into a clean, professional GitHub issue that matches how the maintainer writes them, then create it on the canonical repo. Reference issues for the voice and shape: #1050 (feature/behavior) and #1051 (UI/UX bug with a screenshot section).

Voice and rules

  • Plain, professional, calm. No marketing, no preamble, no AI voice.
  • No em dashes, en dashes, or emojis anywhere in the title or body. Use commas, colons, parentheses, or "to" for ranges. (This repo bans them; do not introduce them.)
  • Be specific and factual. Rewrite vague placeholder copy into concrete, testable statements. If a detail is unknown, leave a clearly marked HTML comment rather than guessing a fact.
  • Title: short and descriptive, stating the problem (for example, "Unable to scroll the world market UI on mobile"). A severity prefix ("Critical: ...") is optional and only for genuinely high-severity issues, matching the maintainer's style in #1050.

Step 1: Gather and classify

From the user's input work out:

  • The core problem in one or two sentences.
  • Whether it is a bug (something is broken) or a request (new or changed behavior). Bugs get Steps to reproduce plus Actual behavior; requests usually do not.
  • Whether it is UI/UX related (visual, layout, HUD, mobile, input, rendering). Only UI/UX issues get the Screenshot section.
  • Whether it is platform or device specific (mobile, landscape, a browser). If so, include an Environment section.

If the core problem or the expected behavior is genuinely unclear, ask one short clarifying question before drafting. Do not stall on details you can reasonably infer from a screenshot or the description, note inferred specifics back to the user instead.

Step 2: Draft the body

Use this section set. Include the core sections always; include the situational ones only when they apply. Keep each section tight.

Core (always):

## Problem

<One to three short paragraphs: what is wrong or missing, and why it matters.>

## Expected behavior

- <Bulleted, concrete, observable statements of what should happen.>

## Scope

<What to investigate or change. A short bulleted list of the affected areas/tabs/flows.>

## Acceptance criteria

- <Checkable conditions that mean this is done. Mirror the Expected behavior, made testable.>
- <For UI/mobile bugs, include "the desktop experience is unchanged" or the equivalent.>

Situational (include only when they apply):

## Steps to reproduce        # bugs only

1. <step>
2. <step>
3. <observe the failure>

## Actual behavior           # bugs only

- <What actually happens today, the mirror of Expected behavior.>

## Environment               # platform/device-specific only

- Platform: <mobile web landscape / desktop / etc.>
- Surface: <in-game HUD window, guide page, admin, etc.>

## Notes                     # optional: likely root cause, non-goals, related work

Step 3: Screenshot section (UI/UX issues only)

If, and only if, the issue is UI/UX related, append a Screenshot section as a placeholder the user fills in later. If the user already provided an image, still leave the placeholder (issues are created from text via gh; the user attaches the image in the GitHub web UI afterward) and tell them where to drop it.

## Screenshot

<!-- Only add a screenshot if this issue is UI/UX related. Drag the image in here. -->

For a non-UI issue (logic, server, balance, content), omit the Screenshot section entirely.

Step 4: Create it

Write the body to a temp file and create the issue on the canonical repo. Always levy-street/world-of-claudecraft, never a fork.

gh issue create \
  --repo levy-street/world-of-claudecraft \
  --title "<title>" \
  --body-file <path-to-body.md>

Use --body-file (not --body) so headings, lists, and the HTML comment survive shell quoting. Add --label/--assignee only if the user asked for them.

Creating an issue is outward-facing, but invoking this skill IS the request to create it, so create directly. Then report back: the issue URL, the title, and a one-line note of any specifics you inferred (so the user can correct them) plus, for UI/UX issues, a reminder that the Screenshot section is waiting for their image.

用于为World of ClaudeCraft的PR捕获视觉变更的前后对比截图。支持桌面与移动端,自动识别变更区域并生成截图至docs/screenshots,附带Puppeteer陷阱规避指南。
涉及渲染、HUD、CSS等视觉变更的PR PR模板要求提供截图时 请求对游戏进行审查或对比截图时
.claude/skills/pr-screenshots/SKILL.md
npx skills add levy-street/world-of-claudecraft --skill pr-screenshots -g -y
SKILL.md
Frontmatter
{
    "name": "pr-screenshots",
    "description": "Capture before\/after screenshots for a World of ClaudeCraft PR (desktop and mobile), commit them under docs\/screenshots, and reference them from the PR body. Use when a change is visual (render, HUD, CSS, content models, windows), when the PR template's screenshot requirement applies, or when asked to screenshot the game for a review or comparison. Covers the change-aware capture tooling, the before\/after protocol, and the known puppeteer\/CDP traps.",
    "user-invocable": true
}

PR screenshots

The repo rule (root CLAUDE.md): a visual change ships with before/after screenshots, desktop and mobile where relevant, committed under docs/screenshots/ and referenced from the PR body. This skill is the capture recipe.

1. Use the change-aware tooling first

With npm run dev running (serves :5173):

git diff <base>...HEAD > /tmp/pr.diff
BROWSER_PATH=/path/to/chrome DIFF_FILE=/tmp/pr.diff SHOTS_DIR=pr-shots \
  node scripts/pr_screenshots.mjs

scripts/pr_screenshots.mjs drives the OFFLINE client through the shared entry flow (scripts/enter_offline_game.mjs, which handles the intro overlay that otherwise hides #ui) and decides WHAT to shoot from the diff: specific windows via the target table, the generic desktop/mobile HUD for broad visual changes, and nothing for non-visual diffs.

Adding coverage is one entry in scripts/pr_shot_targets.mjs, not a new script. Each target maps changed-path substrings to a bring-up recipe (driving window.__game) and a clip region. Only write a bespoke scripts/<thing>_shot.mjs when the flow genuinely cannot be a target entry (for example an online-only or multi-client scene).

2. Before/after protocol

  1. Capture AFTER on your branch.
  2. git stash or check out the base commit in a scratch worktree, capture BEFORE with the same script and targets, restore.
  3. The Vite dev client picks up source changes live, but npm run server bundles at START: after any branch flip, restart the server before online captures or you will shoot a stale bundle.
  4. Move the keepers to docs/screenshots/<slug>/before-*.png / after-*.png, commit them, and reference them from the PR body with repo-relative links.
  5. For screenshots in a REVIEW COMMENT on someone else's PR: GitHub user-attachments upload URLs only work from the web UI. Push the PNGs to a gist and embed the gist's raw URLs instead.

3. Traps that have burned sessions before

  • Viewport sizing: after page.setViewport, window.innerWidth can be stale. Use raw CDP Emulation.setDeviceMetricsOverride for exact metrics, and remember CDP Page.captureScreenshot shoots the WINDOW, not the viewport: clip explicitly.
  • page.evaluate under tsx: tsx's keepNames injects __name and breaks nested functions inside evaluate callbacks. Pass string-form bodies to evaluateOnNewDocument/evaluate when a script runs under tsx.
  • window.__game proves reachability only to the window boundary. For a claim about real behavior, drive the actual bound key or click, not the debug hook.
  • Mobile is landscape-only in-game on the web client: use landscape device metrics for mobile HUD shots (the shell/guide/admin pages allow portrait).
  • Dev commands: captures that teleport, level, or grant items need a server started with ALLOW_DEV_COMMANDS=1 (dev only, never production).
执行代码变更的端到端QA审查。通过范围界定、分发检查清单及领域审查代理,并行进行正确性与覆盖率分析,并运行确定性构建测试。最终修复阻塞问题,给出就绪状态及待验证项。
用户请求对当前代码变更进行质量审查 代码提交前或合并前的自动化质检流程触发
.claude/skills/qa/SKILL.md
npx skills add levy-street/world-of-claudecraft --skill qa -g -y
SKILL.md
Frontmatter
{
    "name": "qa",
    "description": "Run the full end-of-contribution QA review over the current change (the qa-checklist gate plus a coverage fan-out and the domain reviewers it names).",
    "user-invocable": true
}

You are running the project's end-of-contribution QA gate. Do this now, before the change is called done.

  1. Scope the review from the diff: git diff --name-only for uncommitted work. For committed work, merge-base against the branch's own base, never main (work is based off the latest release branch and main trails it, so a merge-base against main sweeps the whole release into scope). Fallback chain: the upstream, else the newest origin/release/* branch, else origin/main:

    base=$(git rev-parse --abbrev-ref '@{upstream}' 2>/dev/null) ||
      base=$(git for-each-ref --sort=-creatordate --format='%(refname:short)' \
        'refs/remotes/origin/release/*' | head -1)
    git diff --name-only "$(git merge-base HEAD "${base:-origin/main}")"..HEAD
    

    If the user passed an argument (a feature name, phase, or file list), use it to focus the scope.

  2. Dispatch the qa-checklist agent over that scope. It is the read-only gate: it scales its own depth to the size of the change, checks every repo invariant in play, and ends with an adversarial "what is missing" pass. Let it run; do not duplicate its work inline.

  3. If the change is more than a trivial single-surface edit, also fan out a small coverage pass in parallel: one agent for correctness, one for test coverage, one for dead code, each prompted for COVERAGE (report every gap with confidence and severity), not filtering.

  4. Dispatch the domain reviewer agents that qa-checklist names for the surfaces this diff touches (for example privacy-security-review, migration-safety, database-performance-reviewer for SQL, indexes, query call sites, pool or lock behavior, timeout policy, or stored-data growth, cross-platform-sync, architecture-reviewer, and on a release branch release-malware-audit). Spawn them fresh; never have the implementer review its own work.

  5. Run the deterministic floor yourself so the verdict rests on green checks, not only agent reasoning: npm run ci:changed (Biome on the changed files), npx tsc --noEmit, and npx vitest run tests/architecture.test.ts tests/localization_fixes.test.ts. Report any red.

  6. Adversarially confirm each consequential finding before acting on it (about half of raw findings do not survive a second look). Then fix every BLOCKING and SHOULD-FIX finding, in focused commits. Report what you fixed and what remains as VERIFY (needs a run or E2E) or NICE-TO-HAVE.

End with a one-line verdict: READY or NOT READY, and the list of any VERIFY items the maintainer still has to run by hand (for example npm run perf:tour, npm run test:browser, or the mobile E2E scripts). READY is advisory judgment; npm run gate is the deterministic pre-merge contract (release tier on release/**), so if it has not run green this session, list it as the first VERIFY item.

指导AI以模块化方式构建功能或修复Bug。核心原则是避免膨胀单体文件,将行为提取为独立、可测试的模块。遵循纯逻辑与状态消费分离架构,利用现有接口接缝集成,确保代码可扩展且易于维护。
需要添加新功能时 重构大型协调文件(如sim.ts, hud.ts)中的逻辑时 修复Bug时
.claude/skills/extract-and-test/SKILL.md
npx skills add levy-street/world-of-claudecraft --skill extract-and-test -g -y
SKILL.md
Frontmatter
{
    "name": "extract-and-test",
    "description": "Build features and fix bugs the clean, scalable way for World of ClaudeCraft. Use when adding a feature, refactoring logic out of a large file (sim.ts, hud.ts, renderer.ts, main.ts), or fixing a bug, especially when the change would otherwise append a block of new logic to an existing big file. Extracts self-contained behavior into a small, well-named, unit-tested module behind one of this repo's existing seams instead of growing a monolith, and fixes bugs test-first (reproduce with a failing test, then make the smallest change that turns it green). Keeps merge conflicts small and the codebase scalable for many contributors.",
    "user-invocable": true
}

Extract and test: module-first features, test-first fixes

This repo is built and maintained almost entirely by AI agents and grows by many small contributions. The thing that keeps it scalable, and keeps open-source merge conflicts small, is that new behavior lands as a focused module behind a known seam, not as another block appended to an already huge coordinator. This skill is the detailed how-to behind the root CLAUDE.md "Modularity" section. Apply it whenever you implement a feature or fix a bug.

The one decision: sibling module or monolith edit

The four logic monoliths (src/ui/hud.ts, src/sim/sim.ts, src/main.ts, src/render/renderer.ts) are coordinators, not a license to grow them: do not split them to hit a line count, and do not rewrite them as a side effect of your task, but never GROW one either. src/main.ts especially is a firewall, not a home (its client-bootstrap helpers belong in src/game/ or src/ui/ siblings). Before you add a block of new logic to one, ask:

Does this behavior need the monolith's private mutable state (the live Sim entity loop, the Hud DOM and per-frame state, the renderer's scene graph)?

  • No: it is a sibling module. Write it as its own file with a named export and a Vitest, then wire it in with a few lines (a call, a registration, a consume).
  • Yes, partly: extract the pure part (the math, the formatting, the id/state resolution) into a host-agnostic module a test imports directly, and leave the stateful side a thin consumer that calls it. This is the pure-core + thin-consumer split (reference: src/ui/unit_portrait.ts core + src/ui/unit_portrait_painter.ts, shared by the player and target frames; src/ui/xp_bar.ts is a pure xpBarView() that a snapshot test drives with no DOM).

If your edit to a monolith is more than a thin wiring of something defined elsewhere, you are probably appending behavior that wants its own module.

Use the seams this repo already has

Do not invent a new architecture. Pick the seam that matches the work:

  • render or ui needs new data or an action: extend IWorld first. IWorld is split into domain facets under src/world_api/, re-aggregated by src/world_api.ts: add the member to the matching facet file, implement it in BOTH the offline Sim (src/sim/sim.ts) and the online ClientWorld (src/net/online.ts), and update the member pins in tests/world_api_parity.test.ts in the same change. render and ui never import a concrete world. This is the load-bearing parity rule; the cross-platform-sync agent audits it.
  • New sim SYSTEM behavior (a combat, mob, social, or economy mechanic, not just a data record): its own module behind the SimContext seam (src/sim/sim_context.ts), with backing state kept on Sim as a live ctx view, never a new method cluster on the sim.ts coordinator. See src/sim/CLAUDE.md.
  • New game content (mob, quest, item, ability, zone, talent): a declarative record in src/sim/content/, merged into the flat tables by src/sim/data.ts. Never inline a content table in sim.ts.
  • New visual system: a new src/render/<thing>.ts exporting a build*() that returns a *View the renderer owns and calls. Not a new method bank on renderer.ts (templates: terrain.ts, props.ts, foliage.ts).
  • New HUD component (a self-contained window OR a per-frame frame/bar): a DOM-free pure view core (src/ui/<name>_view.ts or _core.ts, registered in the UI_PURE_CORES allowlist that tests/architecture.test.ts sweeps) plus a thin write-elided painter on the PainterHost seam (src/ui/painter_host.ts), instance-parameterized (take a descriptor or id, no hardcoded element id). A component that belongs to an extracted HUD domain lands in its src/ui/hud/<domain>/ directory and exports through that domain's index.ts (domain modules never import the Hud class; they receive narrow dependency bags; see src/ui/hud/CLAUDE.md); a standalone component stays a flat src/ui/ sibling. Reuse a painter FAMILY before writing a bespoke one (a unit-style frame is a UnitFramePainter; an extra action bar is a new ActionBarPainter(descriptor)). Full recipe: src/ui/CLAUDE.md and src/ui/hud/CLAUDE.md.
  • New server REST endpoint: a RouteDef module (server/<domain>.ts exporting routes) registered in server/http/registry.ts, never an inline route in main.ts. Scaffold with npm run new:endpoint; see server/http/CLAUDE.md.
  • New server WS command: validate every field in dispatchMessage (server/game.ts), then call the sim.* method that owns the rule. The outcome resolves in the Sim, never on the server outside it.
  • A multi-file subsystem: a directory with an index.ts barrel that exports only its public surface, plus its own short CLAUDE.md (templates: src/render/characters/, src/ui/i18n.catalog/).

When to extract, and when not to

  • Extract on the rule of three. Two similar blocks: leave them. A third copy, or a single block whose responsibility you can name in one sentence with no "and", earns its own module.
  • Do not abstract ahead of need. No helper, base class, options bag, or indirection for a single caller or a hypothetical future requirement. The right amount of structure is the minimum the current task needs. A wrong abstraction is more expensive than a little duplication.
  • Name for the behavior, not the layer. threat_table.ts, loot_roll.ts, coords.ts, not helpers.ts or utils.ts. The file name should tell a reader what one thing it owns.
  • Keep new modules host-aware. Anything reused by src/sim/ must stay DOM-free and Three-free (the tests/architecture.test.ts guard enforces this for src/sim/). Pure logic that both the sim and the UI need lives sim-side or in a neutral module both can import without breaking the import direction in src/CLAUDE.md.

Build a new module

  1. Create src/<area>/<behavior>.ts with a small, explicit public surface (one or a few named exports). Keep internals private.
  2. Add a Vitest at tests/<behavior>.test.ts that imports the module directly and asserts real behavior (not "it runs"). Tests live in tests/, not beside the source (see tests/CLAUDE.md for the idioms). For sim logic, add a determinism assertion: same seed gives the same result (expect(run()).toEqual(run())).
  3. Wire it into its consumer with the smallest possible edit (a call, a registration, a barrel re-export). The consumer stays thin.
  4. If the module is the public face of a new directory, add an index.ts barrel and a local CLAUDE.md describing only that directory's conventions.

Fix bugs test-first

  1. Reproduce in a failing test before touching the fix. Write a Vitest that exercises the real code path and fails, and confirm it fails for the reason the bug describes, not an unrelated setup error. If the buggy logic is buried in a monolith and hard to test in place, that is the signal to extract the unit under test into its own module first, then test it.
  2. Make the smallest change that turns the test green. Fix the root cause, not the symptom. Never special-case the test inputs or hard-code the expected value into the implementation.
  3. Generalize the assertion, not the fix. Add a couple of nearby cases (boundary, empty, the mirror host) so the test pins the behavior, not one example.
  4. For a high-risk or subtle fix, isolate the grader from the implementer: have one subagent write the reproducing test, a second implement the fix, and a fresh subagent review the diff for coverage (every correctness and requirement gap), so the fix is not validated by the same reasoning that produced it.

Verify, and keep the diff honest

After an extraction or fix, these stay green (run the subset your change touches):

  • npx tsc --noEmit
  • npx vitest run tests/<affected>.test.ts (or npm test for broad changes)
  • npx vitest run tests/architecture.test.ts if you touched src/sim/, or added / renamed a src/ui or src/render *_view / *_core pure core (the completeness sweep also checks UI_PURE_CORES / RENDER_PURE_CORES registration)
  • npx vitest run tests/localization_fixes.test.ts if any player-visible text or a src/sim/server emit changed (the S3 i18n guard)
  • npm run ci:changed (Biome on the files you changed; this is what the .githooks/pre-push floor runs, so clear it here, not at push time). If it flags formatting on your own files, fix with a SCOPED npx @biomejs/biome check --write <file> per touched file, never a whole-tree --write (the repo defers global Biome debt, so a whole-tree write buries your change in thousands of unrelated reformats).
  • npm run build before a merge

When the change is database-backed (SQL or a query call site, schema/indexes, query cadence or cardinality, pool/lock/timeout behavior, scheduled database work, or stored-data growth), get a read-only database-performance-reviewer checkpoint BEFORE implementing and carry its concrete bounds and evidence requirements into the test-first contract; re-run it on the finished diff.

When you extract, the diff should read as move plus import, not rewrite. If you "improved" the moved code in the same change, that is scope creep: split it into a follow-up so the extraction stays reviewable. Delete the code you replaced; leave no dead duplicate, commented-out block, or unused import behind.

Effort by model (the doctrine here is identical, only the effort scales): on Opus 4.8, after the extraction fan out a fresh subagent (or the architecture-reviewer for a src/sim/ move) to review your move-diff for COVERAGE, every parity and correctness gap, before calling it done. On the Sonnet baseline, take small verifiable steps and lean on one investigator.

Repo anti-patterns to avoid

  • Appending a new system as another // ---- banner section in sim.ts or hud.ts when it does not need that file's private state.
  • Reaching past IWorld into Sim/ClientWorld from render/ or ui/.
  • Adding a content table or balance number inline in sim.ts instead of src/sim/content/ and the tuning const blocks.
  • A helpers.ts/utils.ts grab-bag, or an abstraction with exactly one caller.
  • Splitting a monolith purely to reduce its line count, with no seam and no test.
用于在发布时自动填充World of ClaudeCraft的多语言缺失行。通过生成工作列表,指导模型将英文内容翻译并填入各语言覆盖层或匹配字典,确保占位符一致、术语锁定及标点正确,最终验证无待处理项以通过发布门禁。
I18N_RELEASE_TIER=1 门禁因待处理行失败 需要翻译或填充特定语言区域 准备包含待处理条目的发布分支
.claude/skills/i18n-locale-fill/SKILL.md
npx skills add levy-street/world-of-claudecraft --skill i18n-locale-fill -g -y
SKILL.md
Frontmatter
{
    "name": "i18n-locale-fill",
    "description": "Fill pending i18n rows across every locale for World of ClaudeCraft, the release-time workflow. Use when the release-tier gate (I18N_RELEASE_TIER=1) fails on pending rows, when asked to translate or fill locales, overlays, or matcher DICTs, or when preparing a release branch whose registry still has pending entries. Covers the worklist generator, where each scope's fills land, the placeholder and glossary contracts, and the known traps (English-in-overlay, shared DICT references, the \"todo\" guard, reword staleness, native punctuation in overlays).",
    "user-invocable": true
}

i18n locale fill (release time)

Contributors add ENGLISH only; the maintainer fills every locale at release. This skill is that fill workflow. The release-tier gate (I18N_RELEASE_TIER=1, automatic on release/** branches) hard-fails on any pending registry row, so a release is not shippable until the fill lands.

1. Generate the worklist

npm run i18n:gen        # refresh the registry first
npm run i18n:worklist   # writes one batch per language under docs/i18n-scaling/worklist/ (gitignored)

scripts/i18n_fill_worklist.mjs is data-only (no translation): each batch entry carries { scope, key, english, placeholders, siblings }.

  • main-scope keys are filled in the matching src/ui/i18n.locales/<lang>.ts overlay.
  • sim / server / admin scope keys are filled in their matcher DICTs (the worklist header in scripts/i18n_fill_worklist.mjs names the exact files).
  • humanRequired entries are blocked by default (quest narratives, names, lore, SEO copy): never machine-fill them; only autoFillable entries are fair game for a model pass.

Batches are per-language and independent: fan out one fill agent per language when the volume is large, then regenerate once at the end.

2. The fill contract

  • Translate, never transplant. The registry counts PRESENCE, not language: pasting the English value into an overlay marks the row filled and silently ships English. Do not.
  • Placeholder parity. Every {token} in the English value must appear verbatim in the fill (the worklist lists them). The scanner checks parity; a dropped token is a break.
  • Locked terminology. Classic-MMO terms per locale live in scripts/i18n_glossary.json and are locked; follow them, and extend the glossary when a new recurring term appears.
  • Matcher DICT values must be literal string copies. Never alias or share a reference between DICT rows; the matcher relies on per-row literals.
  • Native punctuation in overlays is legitimate. Russian and other locales use real em dashes; NEVER strip them. The repo copy scans deliberately exclude src/ui/i18n.locales.
  • The placeholder guard flags a bare "todo" value, which is also a real word in es/pt. Phrase such fills differently (for example "por hacer") so the guard does not trip.

3. Regenerate, verify

  1. npm run i18n:gen regenerates the resolved bundles and the status registry.
  2. Stage the regenerated artifacts in the SAME commit as the fills. The freshness gate diffs the regenerated output against the staged/committed copies; unstaged artifacts fail it.
  3. Prove completion: run the i18n steps release-tier, I18N_RELEASE_TIER=1 npm run gate (or at minimum i18n:gen + the guard tests), and confirm zero pending rows remain.

4. Reword staleness (the silent trap)

Rewording an EXISTING English value does not mark its translations pending: every locale silently keeps the old meaning. After any English copy change, diff the resolved en output between the base branch and HEAD and re-fill the touched keys in the same change.

发布前恶意代码审计技能,通过确定性扫描器与AI裁判协作,检测挖矿、后门等蓄意恶意代码。仅用于确认代码树安全,不修改文件,输出PASS或BLOCK裁决,区别于常规安全检查。
准备打标签或发布版本前 需要确认工作树无恶意代码时
.claude/skills/release-malware-audit/SKILL.md
npx skills add levy-street/world-of-claudecraft --skill release-malware-audit -g -y
SKILL.md
Frontmatter
{
    "name": "release-malware-audit",
    "description": "Release-gate scan for deliberately planted malicious code (crypto miners, data\/secret exfiltration, backdoors, RCE\/obfuscation, install hooks) across the whole working tree of World of ClaudeCraft. Use before tagging or shipping a release, or whenever you want to confirm the tree is free of malicious code. Runs the deterministic scanner, fans the read-only release-malware-audit agent across categories, and returns a single PASS \/ BLOCK verdict with confirmed findings and dismissed false positives. Distinct from privacy-security-review, which catches accidental security mistakes.",
    "user-invocable": true
}

Release malware audit: whole-tree check for planted malicious code

This is a release gate. Its one job is to answer: does this tree contain code that was deliberately written to harm users, operators, or the supply chain? Crypto miners, data/secret exfiltration, backdoors and auth bypasses, RCE/obfuscation, web3 wallet-drain / key theft (the class that would steal a user's $WOC), prompt-injection planted in the agent/skill instruction files, and package.json install hooks or risky dependencies. It does NOT look for accidental security bugs - that is privacy-security-review's job - and it never modifies code. A human acts on a BLOCK.

The work is split so each half does what it is good at:

  • scripts/malware_scan.mjs is a deterministic, high-recall FLAGGER. It greps a curated signature catalog and emits structured findings. It is deliberately noisy: a regex hit is a question, not a verdict.
  • The release-malware-audit agent is the JUDGE. It reads the flagged code in context, knows this repo's legitimate patterns (the $WOC crypto-wallet, child_process in build scripts, real auth comparisons), and decides real-vs-false-positive.

Steps

  1. Run the scanner over the whole tree:

    mkdir -p tmp && node scripts/malware_scan.mjs --json --quiet > tmp/malware_scan.json
    

    It exits non-zero whenever there are findings (expected; most are false positives). Note totalFindings and the per-category counts. A scan-failure exit (2) means fix the run before trusting any result - never report PASS off a scan that did not complete.

    npm run security:scan is the same human-readable flagger. CI and npm run security:gate run --gate, which exits non-zero only on a HIGH-severity finding that survives the path-aware priors (tests/malware_scan.test.ts asserts the tree is HIGH-clean, so a planted signature breaks npm test). This skill is the deeper, agent-judged pass on top of that.

  2. Triage by fanning out the agent. Group the findings by category. Dispatch the read-only release-malware-audit agent, one invocation per category that has findings (categories are independent, so run them in parallel in a single message). Give each agent its category's findings (or point it at tmp/malware_scan.json and the category) and have it read the flagged files and return confirmed-vs-dismissed for that category. For a small number of total findings, a single agent invocation over all of them is fine.

  3. Synthesize one verdict. Combine the agents' results into a single report:

    • PASS only if every flag is explained by legitimate behavior.
    • BLOCK if there is even one confirmed malicious finding, or an uncertain finding that cannot be cleared. The gate fails safe: when in doubt, BLOCK and explain.

    Report confirmed findings (file:line, category, why), uncertain findings needing human judgement, and a one-line dismissal summary per category so a human can spot-check. Never silently drop a flag.

What is in scope (and the seams it deliberately covers)

  • Whole source tree, including instruction markdown that an LLM executes: .claude/agents/**, .claude/skills/**, CLAUDE.md, and AGENTS.md are scanned for prompt injection / exfiltration / permission-escalation directives. Prose docs (docs/**, README.md) are out of scope - they are not executed. .env is never read.
  • package.json content check: install lifecycle hooks and newly-added transaction/web3/miner or non-registry (git/url/tarball) dependencies.
  • Path-aware priors: child_process/exec in scripts/, headless/, and tests/ is dev tooling and demoted below the gate threshold, so the HIGH band tracks real risk in shipped src/** and server/**. A --gate run (and npm test) fails only on a surviving HIGH finding, so a clean tree is green and a planted drainer is not.

Scope and limits (say these in the report, do not pretend otherwise)

  • The static line scan cannot see: aliased or multi-line or dynamically-built call forms (e.g. const f = fetch; f(url, {body: secret})), an exfil URL assembled from variables or fetched at runtime, semantically paraphrased instruction injection (the ai-* rules catch phrasings, not meaning), and anything behind eval/runtime indirection. The agent compensates by READING context, but neither runs the code in a sandbox - say so.
  • Dependencies are checked by content, not by diff or depth. node_modules is NOT walked and the lockfile's transitive tree is NOT audited. The manifest check catches a direct risky or non-registry dep and install hooks, but a malicious TRANSITIVE dependency, or a compromised version of an allowed one, is invisible here. The realistic token-theft path is new wallet-transaction code (which the web3/key-exfil rules cover) or a new dependency - pair this gate with npm audit, a lockfile diff, and a review of any package.json change.
  • Read-only. This skill never edits, reverts, or quarantines code. It produces a verdict; remediation is a human decision.

Relationship to the other reviewers

This skill owns deliberately planted malicious code; privacy-security-review owns accidental security and privacy mistakes. The full reviewer map lives in docs/qa-gate.md.

用于审查World of ClaudeCraft的GitHub Pull Request。通过获取PR数据、分类变更领域(如模拟、渲染等)、验证代码不变量及冲突范围,生成简短友好的评论式审查结果,严格遵循特定风格与i18n规范。
要求审查PR 查看PR 检查PR 包含github.com/.../pull/<n>链接 提及PR编号
.claude/skills/review-pr/SKILL.md
npx skills add levy-street/world-of-claudecraft --skill review-pr -g -y
SKILL.md
Frontmatter
{
    "name": "review-pr",
    "description": "Review a GitHub pull request for World of ClaudeCraft the way the maintainer does. Use when asked to review a PR, look at a PR, or check a PR (a github.com\/...\/pull\/<n> link or a PR number). Fetches the PR, classifies the change by domain (sim, wire\/parity, render, ui, server, i18n), verifies the repo's invariants against the real code (not the PR description), checks the merge-conflict scope, independently confirms any consequential finding, then posts a short, plain, friendly GitHub review with severity-tagged findings. Not for reviewing the local working tree (that is \/code-review).",
    "user-invocable": true
}

Review a PR (World of ClaudeCraft house style)

This repo takes many small AI-authored contributions, so review is the gate that keeps the invariants intact. A good review here is not a vibe check of the diff: it verifies the load-bearing claims against the actual code, names issues with file:line evidence and a severity, and reads like a calm human wrote it. Work through the steps below.

/code-review reviews the local working tree; THIS skill reviews a GitHub PR end to end and posts the result. They are different jobs.

What a good review looks like (the voice)

  • Short, calm, plain GitHub style. Write like a person, not an AI: no preamble, no summary-of-a-summary, no "Great work!" throat-clearing, no bulleted restatement of the diff, no hedging boilerplate. If a sentence sounds like a model wrote it, cut it.
  • No em dashes or en dashes, and no emojis. Use commas, colons, parentheses, or "to" for ranges. (You are reviewing a repo that bans them; do not introduce them yourself.)
  • Lead with what is genuinely good when it is good, then the issues. Do not flatter.
  • Every finding carries a severity and evidence: blocking / should-fix / nit, with a file:line pointer and a one-line why.
  • i18n: review English only. The maintainer does every other locale at release time. Check only that new player-visible strings are English t() keys in the right catalog. Never raise a missing-translation finding, never draft a locale string, and never ask the contributor about any non-English locale (the non-Latin overlays and the M16 gate included). All of that is release-time maintainer work.
  • Post as a plain comment review (not approve / request-changes) unless told otherwise.
  • Match the depth to the change: a one-file fix gets a tight note; a sim/wire/auth change earns the full invariant pass.

Step 1: Gather and scope

gh pr view <n> --json title,body,author,headRefName,baseRefName,state,additions,deletions,changedFiles,mergeable,mergeStateStatus,commits
gh pr diff <n> --name-only           # which files, which domains
gh pr diff <n>                       # the diff (skip the generated i18n blocks)
git fetch origin pull/<n>/head:pr-<n>-review   # local ref at the PR head
git fetch origin <baseRefName>

Conflict scope (do not trust the GitHub CONFLICTING flag for WHICH files):

git merge-tree --write-tree --name-only pr-<n>-review origin/<baseRefName>

Files printed at the top / marked CONFLICT are the true conflicts; Auto-merging lines are clean. Read files at the PR head with git show pr-<n>-review:<path>.

Step 2: Classify the change, then run that domain's invariant pass

Pick the domains the diff touches (a PR can hit several) and check each. The root and sub CLAUDE.md files are the source of truth; this is the checklist.

Sim (src/sim/**) -> determinism + purity + three-host parity.

  • Determinism: ALL randomness through Rng (src/sim/rng.ts). Never Math.random, Date.now, or performance.now. Same seed gives the same world. Watch the sneaky ones: Map/Set iteration order, object-key order, unstable sorts. A sort must be a total order (tiebreak on a stable id), not lean on input order or engine sort stability. Pathfinding/AI are classic nondeterminism hiding spots.
  • Purity: zero DOM/Three/browser imports; never imports render/, ui/, game/, net/. (tests/architecture.test.ts guards this; confirm the diff respects it.)
  • Tick-based timers count tickCount/DT, not wall-clock. Session-only fields (e.g. joinedAt) are re-derived on load, never persisted with a stale tick epoch.

Wire / parity (server/game.ts, src/net/online.ts, types.ts, entity.ts).

  • A new Entity field either round-trips BOTH ways (encoded in wireEntity / dynamicFields, decoded in applyWire) OR is deliberately server-local. If server-local, it must still be added to blankEntity in online.ts so the offline Sim and the ClientWorld mirror keep identical entity shapes (precedent: chargePath, petPath). Drift (one host has it, the other does not) is a bug.
  • Server authority: movement, combat, loot, economy resolve server-side. The client is a renderer. A client-side movement/combat decision is a finding, not a feature.
  • When in doubt, hand this to the cross-platform-sync agent (.claude/agents/).

Render (src/render/**) -> reads the world, never mutates it.

  • Thin IWorld consumer; no concrete Sim/ClientWorld coupling beyond what the file already has. New visual system is its own src/render/<thing>.ts, not a method bank on renderer.ts. Pure geometry/math extracted and unit-tested without Three.
  • Watch per-frame cost (samples/allocations in the hot path).

UI (src/ui/**, index.html) -> seam + modularity + i18n + parity + a11y.

  • IWorld only; never reach into a concrete world. A new window/panel is its own module the HUD composes (chat_window.ts pattern), not a new banner section in hud.ts. Pure clamping/geometry/formatting extracted and tested.
  • play.html CSS parity: play.html is a separate build entry that carries the same chrome DOM. CSS added to index.html for shared chrome must be mirrored into play.html or it breaks on /play. Check this explicitly (a recurring miss).
  • Persistence (window pos, settings) restores clamped to the current viewport; drag / resize no-op on mobile; check keyboard operability + aria on new controls.

Server (server/**) -> authority + auth + SQL + migration + privacy.

  • Every new route: bearer-authed and scoped to the account FROM THE TOKEN, not from client input. It must never read or mutate another account's data. Double-gate ownership (route check + the UPDATE/SELECT WHERE account_id clause).
  • SQL: parameterized ($1,$2,...). Flag any interpolation of user input.
  • Migration: schema is inline DDL re-applied every boot. Changes must be additive + idempotent (ADD COLUMN IF NOT EXISTS); JSONB load stays back-compat (old rows lack the field). Flag destructive/non-idempotent DDL. Hand to migration-safety / privacy-security-review agents for anything non-trivial. When the diff changes SQL, a database call site, indexes, query cadence/cardinality, pool or lock behavior, timeout policy, or stored-data growth, hand the scaling angle to database-performance-reviewer.
  • Privacy: no password_hash or other accounts' data returned to the client.
  • CLAUDE.md requires tests for sim/server behavior changes. A server change with no test is a finding.

i18n (any player-visible string). Review English only; the maintainer does every other locale at release time.

  • Check only that new player-visible strings are English t() keys in the right src/ui/i18n.catalog/<domain>.ts, rendered via t(). hud_chrome is the English-only catalog domain. Numbers/money/dates/percents go through the formatters, never string concat.
  • Do NOT raise any non-English i18n finding. Missing translations, the five non-Latin overlays (zh_CN, zh_TW, ja_JP, ko_KR, ru_RU), Latin-script pending rows, and the M16 completeness gate (tests/i18n_completeness.test.ts) are all release-time maintainer work, not a review finding and not a contributor ask. From the contributor's side a PR is English-only.
  • shell.ts and some catalog modules carry inline per-locale blocks that need all locales present for tsc; that is structural, not a policy violation, and still not something to flag.

The standard stale-base i18n conflict. When the only true conflicts are committed line-item locale slices (src/ui/i18n.resolved.generated/pending.ts and its sibling slices, the admin slices included), that is mechanical regen churn, not a design problem. Say so, and note the fix: merge the base and re-run the i18n build (i18n:build / i18n:admin / i18n:scan). A hand-edited or malformed generated slice (e.g. a pending.ts with rows out of sorted order, or a slice that embeds a count, hash, or timestamp) is a different thing and IS a blocker.

Step 3: Verify against the real code, and confirm before you accuse

  • Do not review the PR description, review the code. Read the actual files at the head ref, grep the surrounding conventions (the facing vector, the persistence path, whether a field is serialized), and run the targeted test (npx vitest run <file>) when you can.
  • Independently confirm any consequential or negative finding before you post it. "This is dead code", "this duplicates base", "this leaks data", "this is nondeterministic": verify each with your own grep/read/run, because a wrong strong claim is worse than a missed nit. (Example: confirm a "feature already in base" claim by checking the base branch has the routes/files; confirm "not on the wire" by grepping wireEntity.)
  • Distinguish what the diff CHANGED from what it inherited: do not flag pre-existing code the PR merely sits next to.

Step 4: Tests

Failing-first where it is a bug fix (a test that reproduces it, then the fix). Sim tests are seeded and deterministic. Pure logic is extracted so it tests without DOM/Three/GL. Note meaningful gaps (an untested branch, gesture math, the stamping half of a gate) as nits, not blockers, unless the untested thing is the actual fix.

Step 5: Write and post

Assemble the review in the voice above: a short positive opening when earned, then findings as a tight list, each with severity + file:line + one-line why, then any non-blocking notes. Then post:

gh pr review <n> --comment --body-file <path-to-review.md>
gh api repos/<owner>/<repo>/pulls/<n>/reviews --jq '.[-1] | {author:.user.login, state:.state, url:.html_url}'

Reviews post AS THE MAINTAINER. Only post to origin (levy-street), never a fork. Posting is outward-facing: if the task did not clearly ask you to post, present the draft and ask first.

Scaling up: many PRs, or one deep review

Multiple PRs, or a security/sim/wire change that deserves an adversarial pass: pre-fetch the head refs, then fan out one read-only investigator per PR (or per dimension) with a domain-tailored prompt that says READ-ONLY, do not post, return evidence-backed findings with severity. Then YOU verify the consequential findings (Step 3) and write/post each review in your own voice. Do not let a subagent author the final review prose or post it, the voice and the verify-before-accuse bar are yours to hold. Prefer the purpose-built agents (architecture-reviewer for src/sim/ determinism + the SimContext seam, cross-platform-sync, migration-safety, database-performance-reviewer, privacy-security-review, qa-checklist) for their domains.

Quick reference: domain -> first things to check

Touches Check first
src/sim/** Rng-only, no wall-clock, total-order sorts, no DOM/Three import
server/game.ts + online.ts + types.ts wire round-trip or server-local + blankEntity parity; server authority
src/render/** reads not mutates; own module; per-frame cost
src/ui/** + index.html IWorld seam; own module; play.html CSS parity; a11y/mobile; i18n
server/** routes/db token-scoped auth; parameterized SQL; additive idempotent DDL; no oversharing; tests
i18n strings English t() in catalog only; all other locales are release-time maintainer work, do not flag; line-item slice conflict = regen

ホーム - Wiki
Copyright © 2011-2026 iteam. Current version is 2.155.2. UTC+08:00, 2026-07-21 05:32
浙ICP备14020137号-1 $お客様$