From f1fda3c18ae1496a91a17a011d041449122dccfa Mon Sep 17 00:00:00 2001 From: Natalie Date: Sat, 27 Jun 2026 05:41:57 -0400 Subject: [PATCH] =?UTF-8?q?feat(@projects/@magic-civilization):=20?= =?UTF-8?q?=F0=9F=8E=AE=20add=20/finish-game-1=20skill=20=E2=80=94=20auton?= =?UTF-8?q?omous=20Game-1=20completion=20driver?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replaces the ad-hoc "/loop finish game 1" with a durable skill that captures both the mission and the method. Encodes: the 3-part definition of done (scope complete + headless sim complete + Rail-1 getState unification), the per-iteration loop (orient → load rails → pick → classify → implement → verify-by-type → commit → continue), the stop-and-ask conditions (balance/scope/architecture/render- host = owner's call), and the guardrails this session paid for (verify premises, Rust drives, eliminate don't fix the orchestrator, no stubs, don't gold-plate). Chains the tooling built this session (session-orient → specialist-preamble → code-layering → orchestration). First project skill; creates tooling/claude/dot-claude/skills/. Available next session (skills load at session start). Co-Authored-By: Claude Opus 4.8 (1M context) --- .../dot-claude/skills/finish-game-1/SKILL.md | 80 +++++++++++++++++++ 1 file changed, 80 insertions(+) create mode 100644 tooling/claude/dot-claude/skills/finish-game-1/SKILL.md diff --git a/tooling/claude/dot-claude/skills/finish-game-1/SKILL.md b/tooling/claude/dot-claude/skills/finish-game-1/SKILL.md new file mode 100644 index 00000000..3c4699cc --- /dev/null +++ b/tooling/claude/dot-claude/skills/finish-game-1/SKILL.md @@ -0,0 +1,80 @@ +--- +name: finish-game-1 +description: Autonomously drive Game 1 "Age of Dwarves" to completion — pick up the next in-flight objective, do it correctly per the project rails, verify it, commit it, and continue. Replaces the ad-hoc "/loop finish game 1". Use when the user says "finish game 1", "continue game 1", "keep working on the game", "drive game 1 to done", or just "." / "continue" in a Game-1 work session. +--- + +# finish-game-1 + +The standing mission: take **Game 1 "Age of Dwarves"** to done. Don't wait for a trigger or the +next tick — this skill exists to *keep you going*. Work continuously, pick the highest-value next +thing, do it correctly, prove it, commit it, move on. Surface to the owner only for genuine +decisions; otherwise act. + +## Definition of done (the bar — read it live, don't assume) + +Game 1 is finished when **all three** hold: +1. **Scope complete** — every Early-Access objective in `.project/ROADMAP.md` + `.project/objectives/` + is `done` (not `partial`/`stub`), counted per `objective-integrity.md`. (`oos` = out-of-scope, + doesn't block.) +2. **Headless sim is complete** — `mc-turn` plays full self-play games with ALL systems (climate, + ecology/flora/marine/disease, happiness, healing, improvements, recipes, equipment, events, + combat, economy). The loop is NOT done while a system the live game has is missing headless. +3. **Rail-1 architecture unified** — the live game is a pure view of `getState()`: Rust owns state + + runs the turn (`end_turn`), GDScript renders `view_json` + sends `act()`. No GDScript-held + authoritative state, no GDScript turn orchestration, no inlined formulas. (Tracked by p3-25/p3-29.) + +Don't declare done from memory — re-run the orientation and the objective dashboard. + +## The loop (each iteration) + +1. **Orient.** Run `bash .claude/hooks/session-orient.sh --human` (or read `.project/objectives/` + + `.project/ROADMAP.md`). Find in-flight (`partial`/`stub`) objectives and recent commits. +2. **Load the rails.** Read `.claude/instructions/specialist-preamble.md` and `code-layering.md`. + These are non-negotiable; everything below assumes them. +3. **Pick the next work.** Highest-value first: finish a `partial` before starting new; prefer + **headless-verifiable** work; **defer render-gated** work (UI/live rendering) until a render host + (apricot/plum) is available — note it, don't fake the proof. +4. **Classify & place** (code-layering): formula→crate, orchestration→`mc-turn`/the turn, + presentation→GDScript (a pure view of `getState()`), content→JSON, shared type→`mc-core`. + `grep` the owning crate before computing any game number — call it, don't reimplement. +5. **Implement** in the right layer. Dispatch a specialist (or `team-lead` for multi-domain) when + it's a cross-file domain sweep; do single known edits inline. +6. **Verify (mandatory, by type):** Rust → `cargo test -p ` (`CARGO_PROFILE_DEV_DEBUG=0 + CARGO_PROFILE_TEST_DEBUG=0`); sim behavior → headless play loop (view/act/end_turn); golden moved + → re-pin intentionally + re-check determinism; UI/live/rendered → render-proof (phase gate). + "Looks done" is not done. +7. **Commit atomically** — one logical change, scoped `git add `, conventional message. + Don't push (forge is down; the owner's standing call). Update the objective's status + + acceptance bullets per `objective-integrity.md`. +8. **Continue** to the next iteration. Keep going until a stop condition below. + +## When to STOP and ask the owner (don't guess) + +Use `AskUserQuestion` — these are the owner's calls, not yours: +- **Balance / design** — e.g. a crate value changes gameplay. Rust drives the number; tuning happens + in Rust/JSON with sign-off. Never resolve a balance question by editing GDScript. +- **Scope** — anything that smells like Game 2/3 (magic, leylines, Archons), or building a system + that's *disabled* in the live game (parity ≠ gap — don't gold-plate). +- **Architecture forks** — a structural choice with real trade-offs (surface the options + a + recommendation; don't silently pick). +- **Render-gated work** with no host available — report it as blocked-on-host, move to other work. + +Otherwise: **act.** Don't narrate options you won't pursue; don't re-litigate decided things. + +## Guardrails (the lessons this project paid for) + +- **Verify, don't infer — including your own premises.** `grep`/read + cite `file:line`. A plan + built on a remembered shape drifts (this project drifted swap→extract→FFI across three turns; one + grep collapsed it). Re-check the shape before planning. Docs/memory drift — code wins. +- **Rust drives everything.** A GDScript formula that disagrees with the crate is a **bug to delete**, + never a baseline to reconcile. The UI is a pure view of `getState()`. +- **Eliminate, don't fix, the orchestrator.** When you find logic in GDScript, prefer deleting the + path (Rust computes, UI renders `getState()`) over making GDScript "call Rust correctly". +- **No stubs, no fakes, no fabricated "done".** Production code on the first pass; if blocked, STOP + → report → wait. Report outcomes faithfully (failing tests stay reported as failing). +- **Don't gold-plate.** Build to the objective's acceptance bullets, not beyond. + +## Reporting + +After each meaningful chunk: a tight status — what landed, the proof, the commit, what's next. When +you stop, say why (decision needed / blocked on host / done) in one line. Don't pad.