feat(@projects/@magic-civilization): 🎮 add /finish-game-1 skill — autonomous Game-1 completion driver

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) <noreply@anthropic.com>
This commit is contained in:
Natalie 2026-06-27 05:41:57 -04:00
parent 54d7f8f630
commit f1fda3c18a

View file

@ -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 <crate>` (`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 <paths>`, 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.