Imported from DrBit-64/chess-workbench (
AGENTS.md). Install upstream withnpx skills add DrBit-64/chess-workbench. Copyright stays with the author.
AGENTS.md
Project overview
ChessWorkbench is a single-user, local-first chess knowledge workbench for organizing theory, interactive training, game review, and AI-assisted content import. The internal model is a position graph (not a PGN tree), and the system enforces a strict four-layer separation: Source → Knowledge → Repertoire → Exercise.
Current phase: Stage 8P portable AI-extraction contract after accepted Stage 6.
See PLANS.md for current tasks and docs/development-plan.md for the full roadmap.
Repository layout
chess-workbench/
├── AGENTS.md ← this file
├── PLANS.md ← current task plan
├── Makefile ← single entry-point for all verification
├── README.md
├── frontend/
│ └── src/
│ ├── app/ ← router shell, layouts
│ ├── components/ ← shared presentational components
│ ├── logic/api/ ← HTTP client + generated API types
│ ├── types/ ← OpenAPI-generated TypeScript types
│ └── test/ ← Vitest setup
├── backend/
│ ├── src/chess_workbench/
│ │ ├── api/ ← Sanic routes, middleware, error handling
│ │ ├── domain/ ← chess rules, position identity (no HTTP deps)
│ │ ├── schemas/ ← Pydantic API contracts
│ │ ├── services/ ← application logic
│ │ └── store/ ← SQLAlchemy models, repositories, migrations
│ ├── migrations/ ← Alembic migrations
│ └── tests/
├── docs/
│ ├── agent/HANDOFF.md ← short-term handoff state
│ ├── decisions/ ← Architecture Decision Records
│ ├── chess-workbench-project-description.md
│ └── development-plan.md
├── scripts/ ← codegen, coverage checks, smoke test
├── data/ ← runtime SQLite, sources, engines (gitignored)
└── .agents/skills/ ← shared agent skills
Required workflow
Before editing
- Run
git status --short. - Read
PLANS.mdanddocs/agent/HANDOFF.md. - Read the relevant ADR in
docs/decisions/if touching architecture-sensitive code. - Inspect the relevant implementation and existing tests.
- Do not assume another agent's uncommitted edits are complete or correct.
After editing
- During an iterative single-task change, run only the smallest formatter, type checker and test selection that directly exercises the changed behavior. Do not run full suites, cumulative acceptance, smoke or unrelated checks merely for reassurance. Run the broader Stage/full gates only when the user requests them, the change genuinely crosses those boundaries, or the user is closing a Stage for acceptance.
- This is primarily a personal, local-first site. During feature discovery, prove the concrete user-visible or artifact-level outcome before expanding defensive coverage. Test volume must be proportional to the implementation and actual risk: prefer one focused regression for a bug or critical persisted-data invariant, and do not build exhaustive combinatorial or cross-dialect proof suites merely to anticipate hypothetical future failures. It is acceptable to fix non-critical product bugs as they are encountered. Coverage and broad acceptance gates remain end-of-Stage/CI checks, not an iterative development ritual.
- Review
git diff --statfor unintended changes. - Update
docs/agent/HANDOFF.md. - Summarize: files changed, tests run and results, failures, assumptions, remaining risks.
- Do not commit, rebase, reset, or delete files without explicit permission.
Commands
All commands run from the repository root.
| Action | Command |
|---|---|
| Install all dependencies | make bootstrap |
| Format (backend) | make backend-format |
| Lint (backend) | make backend-lint |
| Type check (backend) | make backend-typecheck |
| Backend tests + coverage | make backend-test |
| Backend full check | make backend-check |
| Format (frontend) | make frontend-format |
| Lint (frontend) | make frontend-lint |
| Type check (frontend) | make frontend-typecheck |
| Frontend tests | make frontend-test |
| Frontend build | make frontend-build |
| Frontend full check | make frontend-check |
| Regenerate OpenAPI + TS types | make contracts |
| Check contract drift | make check-contracts |
| Full verify (all checks) | make verify |
| Smoke test (start services) | make smoke |
| Stage 2A acceptance | make acceptance-stage-2a |
| Stage 2B acceptance | make acceptance-stage-2b |
| Stage 2C acceptance | make acceptance-stage-2c |
| Stage 2D acceptance | make acceptance-stage-2d |
| Full Stage 2 acceptance | make acceptance-stage-2 |
| Stage 3A acceptance | make acceptance-stage-3a |
| Stage 3B acceptance | make acceptance-stage-3b |
| Stage 3C acceptance | make acceptance-stage-3c |
| Stage 3D acceptance | make acceptance-stage-3d |
| Full Stage 3 acceptance | make acceptance-stage-3 |
| CI entry point | make acceptance |
Engineering rules
- Do not introduce unapproved large frameworks.
- Do not add distributed architecture ahead of schedule.
- Authoritative data is written only through the backend SQL API.
- Frontend
chess.jsis for instant interaction only; all persisted moves must be validated bypython-chess. - PGN is an import/export format, not the internal model. The internal model is the Position/MoveEdge graph.
- AI output must not bypass human review and enter the official knowledge base.
- WebSocket is for lightweight invalidation notifications only, not as a replacement for the HTTP API.
- Critical domain behavior must have tests.
- New architectural decisions are written in
docs/decisions/as ADRs. - Do not copy the reducer/ZeroMQ/full-mirror/Remote-ESM pattern from the sibling project.
- Code must prioritize clarity, readability, and debuggability over abstraction.
- All API schemas use
extra="forbid"; never silently ignore unknown fields. - Persisted moves use standard lowercase UCI.
position_keyusesstandard:v1:<canonical-fen first 4 fields>format. Halfmove clock and fullmove number are excluded from graph identity.- Occurrences carry course-specific context (order, NAG, comments); global edges do not.
- Source, Knowledge, Repertoire, and Exercise are separate domain layers.
- Use explicit archiving with reference protection; no hard deletes that cascade into shared Position/MoveEdge rows.
- UTC for all persisted timestamps. UUIDs for all entity IDs.
- Expected-version optimistic concurrency with
stale_versionerror code. - Minimum coverage: 80% line / 75% branch; key domain modules at least 90%.
- No real Lichess/OpenAI calls in PR tests; use fixtures only.
- Tests must be deterministic; random/property tests must print and fix their seed.
Agent division
Current operator override: all subsequent repository work is performed by Codex because the
DeepSeek API price has increased. Do not invoke DeepCode, $delegate-deepcode, or prepare manual
DeepCode packets unless the operator explicitly reverses this rule.
- Deep Code (DeepSeek-V4-Flash): executes small, bounded work after the behavior and acceptance
oracle are already defined — local code search/explanation, documentation, formatting, type
fixes, focused unit tests, configuration edits, clear single-module bugs and already-designed
small features. Default to thinking enabled with
higheffort; non-thinking is only for purely mechanical work, andmaxis not the routine default. - Codex (OpenAI): architecture design, cross-module changes, complex debugging, formal verification, security review, final diff review, task planning and scoping, ambiguous requirements.
V4-Flash task packets must name the relevant files, invariants that must remain unchanged, exact acceptance commands and the permitted edit boundary. Prefer one independently verifiable behavior per packet. Tests and generated contracts may accompany their owning module, but a task that needs changes across more than two unrelated implementation modules belongs to Codex or must first be split by Codex.
Deep Code escalation rules
Deep Code must stop implementation, leave the worktree recoverable and report evidence instead of guessing when any of the following is true:
- the task requires changing public architecture, an unspecified API/interface, database schema, protocol, authentication, authorization or a concurrency/state-machine invariant;
- more than two unrelated implementation modules need modification;
- existing tests contradict the requested behavior or the requested oracle appears incorrect;
- the root cause remains unclear after inspecting the named code and reproducing the failure;
- implementation requires an assumption not stated in the task, a new dependency or a material expansion of scope;
- the same attempted fix fails twice, or the focused gate exposes a new failure outside the task boundary.
On escalation, report the reproduction, inspected files, best current hypothesis, attempted changes and exact blocking decision. Do not weaken tests, coverage floors, type checks, lint rules or warnings-as-errors to obtain a pass.
Low-risk Flash work with a complete deterministic gate may continue without an individual Codex review when the current task packet explicitly permits it. Batch related medium-risk changes for one Codex review. High-risk work goes directly to Codex. These review tiers do not grant permission to commit: no agent commits unless the user explicitly authorizes it.
Work is coordinated through Git, PLANS.md, docs/agent/HANDOFF.md, and ADRs —
not by sharing raw chat history.
Codex-led automatic delegation
The user talks only to Codex. When a V4-Flash packet satisfies the rules above, Codex may invoke
the project skill $delegate-deepcode; the skill starts DeepCode in a private PTY, waits for its
completion notification and returns control to the same Codex turn. The user does not manually
relay prompts or completion reports.
Codex must inspect the actual diff and independently run the focused oracle before accepting a delegated result. A DeepCode completion message is evidence, never approval. Ambiguous failures, architecture or interface decisions, cross-module fixes and a repeated failed correction remain Codex work. Neither agent may auto-commit.
Runtime transport under .agent-sync/ is disposable and gitignored. Durable task state remains in
PLANS.md, docs/agent/HANDOFF.md and Git. A delegated DeepCode process (identified by
DEEP_AGENT_RUN_ID) must never invoke $delegate-deepcode recursively.