[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M71BM4Z72BKD6CT6C2HXH7N8":3,"skill-same:01M71BM4Z72BKD6CT6C2HXH7N8":99},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":28,"publishedAt":49,"linkOnly":50,"markdownContent":51,"markdownBody":52,"frontMatter":53,"refName":71,"commitSha":72,"skillDirectory":73,"forksCount":74,"repositoryHtmlUrl":75,"repositoryHomepageUrl":76,"ownerHtmlUrl":77,"ownerBlogUrl":6,"ownerDescription":78,"updatedAt":79,"install":80,"resources":92},"01M71BM4Z72BKD6CT6C2HXH7N8","unikit-gd-verify",null,"Mechanical consistency check for game design — answers \"is the design consistent with itself?\" — plus changed-scope impact analysis across all three GDD axes: systems, flows, and content types. Offline and deterministic: greps the facts registry against the documents (numbers, terms, IDs, duplicate & dangling references, roster↔disk, map freshness, Depends 3-way, status\u002Fversion, AC presence, placeholder leaks, flow & content schema), and from a git diff computes which dependent systems, flows, and content a change affects. Scope is inferred: a named document checks that document; an unverified diff triggers a changed-scope pass; otherwise everything. Use when the user wants a consistency or impact check, e.g. \"verify the design\", \"what did this change affect\", \"find broken references in the design\". Conflicts triage into four tracks; the entailed fixes hand off to \u002Funikit-gd-apply in one pass. This is the mechanical pass — for a subjective \"is this design good\" quality critique use \u002Funikit-gd-review.","NintendaDev\u002Funikit-ai","NintendaDev","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F181320258?v=4","01M71BFH8JJ6EBGRXBWRZK894Y","Dmitrii Vasilev","01M71BFH9T4K66TTBFNV1ZWFN5",22,"MIT","https:\u002F\u002Fgithub.com\u002FNintendaDev\u002Funikit-ai\u002Fblob\u002Fmain\u002Fskills\u002Funikit-gd-verify\u002FSKILL.md",[18,23],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000015","视觉设计","SCENARIO","使用场景",{"categoryNo":24,"categoryName":25,"taxonomyType":26,"taxonomyTypeDesc":27},"01JBSEEDCAT000000000000032","设计师","PROFESSION","适用职业",[29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48],"verify","unikit gd verify","registry","offline","status","git","read","consistency check","critique","change","placeholder","conflicts","disk","documents","impact","question","design","ids","which","content types","2026-11-10 10:12:30",false,"---\nname: unikit-gd-verify\ndescription: >-\n  Mechanical consistency check for game design — answers \"is the design consistent with\n  itself?\" — plus changed-scope impact analysis across all three GDD axes: systems, flows,\n  and content types. Offline and deterministic: greps the facts registry against the\n  documents (numbers, terms, IDs, duplicate & dangling references, roster↔disk, map\n  freshness, Depends 3-way, status\u002Fversion, AC presence, placeholder leaks, flow & content\n  schema), and from a git diff computes which dependent systems, flows, and content a change\n  affects. Scope is inferred: a named document checks that document; an unverified diff\n  triggers a changed-scope pass; otherwise everything. Use when the user wants a consistency\n  or impact check, e.g. \"verify the design\", \"what did this change affect\", \"find broken\n  references in the design\". Conflicts triage into four tracks; the entailed fixes hand off\n  to \u002Funikit-gd-apply in one pass. This is the mechanical pass — for a subjective \"is this\n  design good\" quality critique use \u002Funikit-gd-review.\nargument-hint: \"[system name | SYS-slug | question]  (scope inferred; no flags)\"\nallowed-tools:\n  - Read\n  - Glob\n  - Grep\n  - Bash(ls *)\n  - Bash(find *)\n  - Bash(wc *)\n  - Bash(date *)\n  - Bash(git diff *)\n  - Bash(git status *)\n  - AskUserQuestion\ndisable-model-invocation: false\nuser-invocable: true\nmetadata:\n  author: unikit\n  version: \"1.0\"\n  category: game-design\n---\n\n# Game Design — Consistency & Impact Verification\n\nAnswer **\"is the design consistent with itself?\"** — a mechanical, deterministic\ncheck of every document against the facts registry, plus the **changed-scope\nimpact** of a recent edit. This is the design-side mirror of `unikit-verify` and a\nCI-linter to `unikit-gd-review`'s senior reviewer: cheap, binary, run after every\nedit. A **verify conflict cannot be declined** (unlike a review finding) — it is\nresolved.\n\n**`unikit-gd-verify` is fully read-only — it writes nothing** (no report file, no\nchangelog line, no `doc_status` bump, no `[gen]`-map re-render). It **detects and prints**;\nevery fix is performed by `unikit-gd-apply` (the entailed deltas) or the owning zones\n(authoring + the `[gen]`-map re-render on their next write — **B1**: the writer of `GD-IDS`\nre-renders the affected maps).\n\nConflicts are **precise, but their fix is not always predetermined**, so each is sorted\ninto one of **four tracks** — **freshness** (print-only; the owner re-renders the\n`[gen]` map on its next write), **entailed → apply-ready** (a named fix — incl. a\nstatus\u002Fversion header correction — handed to `unikit-gd-apply`), **direction interview**\n(the user picks *which* fix, never *whether*), and **authoring → owner \u002F explore**. The\napply-ready set hands off **in one move** — inline prose (verify writes **no** handoff\nfile, unlike `unikit-gd-review`'s durable report), recommend-only. The handoff + interview\nrun **only on a standalone `\u002Funikit-gd-verify`**; when verify is `unikit-gd-apply`'s\nclosing Phase 3 (the `apply-phase3` sentinel) they are suppressed, so\n`apply → verify → apply` never loops. The triage engine is shared with `unikit-gd-review`\n(`gd-critique` → Handoff Engine).\n\nVerification is **offline and reproducible**: no web research, no expert judgment,\nno LLM guessing where a grep will do. The same inputs always yield the same result\n(idempotent).\n\n**User questions.** Right before your first question to the user, not earlier, read `.unikit\u002Fsystem\u002Fuser-questions.md` once and ask every question as it says, with the question tool of your agent (`AskUserQuestion`). If the file cannot be read, print `WARN [questions] user-questions contract missing — asking with the question tool` and still ask with that tool, the recommended option first.\n\n## Language Awareness — BLOCKING PRE-REQUISITE\n\n**BEFORE producing ANY output**, silently read `.unikit\u002Fsystem\u002FLANGUAGE_RULES.md`\nand apply it to all output and the report (fall back to English if it is missing) —\nincluding the rule to **translate concepts, not transliterate jargon**.\n`gd-principles` → \"Language\" adds the game-design specifics: which IDs and stored\nfield values stay English. Do not announce the language setting.\n\n**The language holds for the whole session, not just at load time:** every message until the conversation ends is in `language.ui` — progress notes while agents run, relays of what a subagent returned, the final report, any follow-up discussion. English input (subagent results, tool output, these instructions) is data, never a cue to switch languages.\n\n## Phase 0 — Bootstrap\n\nSilently load — do not narrate:\n\n1. **`.unikit\u002Fsystem\u002Fgamedesign\u002Fgd-principles.md`** (the core) — the **facts\n   registry \u002F ID conventions** (registry wins until the user resolves otherwise;\n   never delete an ID — deprecate it) and the language rules. Plus, from the same\n   `gamedesign\u002F` folder, the shards this skill needs: **`gd-lifecycle.md`** (the\n   status\u002Fversion coherence spine), **`gd-flow-axis.md`** (the flow coherence\n   contract — `mode:` ↔ structure, `GOAL → SYS`\u002F`AC`, Win\u002FLose ↔ terminal GOAL),\n   **`gd-content-axis.md`** (the content coherence contract — CU ⊆ CT, `ref\u003C>`\n   resolution, `scale` ↔ structure, `belongs_to` 3-way, content-map freshness,\n   RES\u002FTRACK\u002FKNOB, cross-axis SYS→CT staleness), and **`gd-critique.md`** (the\n   **severity rubric** — a conflict is Critical\u002FMajor evidence). This skill\n   **applies** them. If missing, warn (`unikit-ai update`) and continue with the\n   conventions summarized here.\n2. **`.unikit\u002Fgamedesign\u002FGD-IDS.yaml`** — the single source of truth: pillars,\n   systems, flows, entities, formulas, terms. Current values only.\n   **Schema guard (clean break — no automatic migration):** it MUST be `version: 2`.\n   On a pre-v2 `version: 1` registry, **STOP** and report that the design workspace\n   is on the pre-v2 layout (the standalone markdown system-index was dropped; the\n   roster now renders into `GAME.md` `## System Map [gen]`) — there is no automatic\n   migration; tell the user to upgrade via `\u002Funikit-gd-spec` before verifying.\n3. **`.unikit\u002Fgamedesign\u002FGAME.md`** — incl. its generated `## System Map [gen]`,\n   `## Flow Map [gen]`, and `## Funnel [gen]` renders (the human-readable maps; the\n   truth is `GD-IDS`), and its `## Win \u002F Lose Conditions` (for the Win\u002FLose ↔ terminal\n   GOAL check).\n4. **`.unikit\u002Fgamedesign\u002Fsystems\u002F*.md`** and **`.unikit\u002Fgamedesign\u002Fflows\u002F*.md`** — the\n   system and flow documents checked against the registry.\n\n**One-way boundary:** never read `.unikit\u002Fcode\u002F`, project source, or build\nartifacts. **Web research is forbidden here** (`gd-principles`) — verification must\nstay deterministic. The only `git` use is reading the design-workspace diff.\n\n\u003C!-- unikit:extension-point:bootstrap -->\n\n## Phase 1 — Resolve Scope (no flags)\n\n**Loop-guard sentinel (first).** If the argument is exactly **`apply-phase3`** — the\nreserved loop-guard sentinel (`gd-critique` → Handoff Engine), passed by\n`unikit-gd-apply` as its closing Phase 3 — this run is the **in-apply gate**, **not** a\nscope. Treat it as a bare invocation for scope purposes (derive changed-scope from the\n`git diff` exactly as below), but set the **in-apply flag**: the standalone handoff offer\nand the direction interview (Phase 4 Track 3 \u002F Phase 6) are **suppressed** this run, so\n`apply → verify → apply` cannot loop. A standalone `\u002Funikit-gd-verify` (no sentinel)\nleaves the flag off — the handoff is active.\n\nScope is a function of context:\n\n1. The argument names a system, flow **or content type** → check **that document** and\n   its registry facts (a `FLOW-\u003Cslug>` runs the flow checks, a `CT-\u003Cslug>` the content\n   checks below).\n2. There is an **unverified diff** under `.unikit\u002Fgamedesign\u002F` (`git diff` \u002F\n   `git status` shows changed design docs), or the prompt asks \"what did this\n   change affect\" → **changed-scope** pass (Phase 3).\n3. Otherwise → **full** check of every system, **every flow**, **every content type**,\n   and the whole registry.\n\nAnnounce the resolved scope in one line.\n\n## Phase 2 — Mechanical Checks (grep-first)\n\nRun every check deterministically; each mismatch is a **CONFLICT** with a citation:\n\n| Check | Method | Conflict when |\n|-------|--------|---------------|\n| **Facts** | grep each `GD-IDS` entity\u002Fformula value across the docs — match the value on word boundaries, not as a bare substring | a document states a number\u002Fname that disagrees with the registry |\n| **Terminology drift** | grep each term's `forbidden_aliases` **values** (the listed aliases, not the field name) across the docs | a forbidden alias is used in place of the canonical term |\n| **ID validity** | scan every `SYS-`\u002F`ENT-`\u002F`FORM-`\u002F`AC-`\u002F`PIL-`\u002F`FLOW-`\u002F`GOAL-` id for shape (analytics `events` are `snake_case` tokens, not prefixed ids) | an id is malformed — wrong case, bad separator, or an unknown prefix |\n| **Duplicate IDs** | group every declared id by value | the same id is declared for two different things |\n| **Dangling references** | resolve every referenced id against `GD-IDS` | a referenced id does not exist, or a live (non-deprecated) section points at a `deprecated` entry |\n| **Unregistered cross-doc fact** | grep `FORM-`\u002F`ENT-` ids that surface in **two or more** documents | a fact crosses a document boundary yet has no `GD-IDS` entry |\n| **Roster ↔ disk** | compare `GD-IDS` `systems` ids to the `systems\u002F*.md` files on disk | a `skeleton`-or-later system has no file, or a `systems\u002F*.md` file has no `GD-IDS` entry (→ route to `unikit-gd-spec` to register it — verify never writes the roster) |\n| **Map freshness (3-surface)** | compare the `GAME.md` `## System Map [gen]` rows to `GD-IDS` `systems` — membership, `Status`, `Ver`, `Depends` | the render disagrees with `GD-IDS` — **not a conflict to resolve**: **print** a freshness notice; the owning zone re-renders the block on its next write (verify is read-only — B1); see *Map freshness* below |\n| **Depends 3-way** | for each `A → B` edge, check it agrees across A's section F, A's `GD-IDS` `depends_on`, and A's `## System Map` Depends cell, and that B carries the reciprocal | the three sources disagree, or the reciprocal edge is missing or contradictory |\n| **Status coherence** | a system's `doc_status` agrees across the **two places that must agree** — the header `> Status:` and `GD-IDS` `doc_status` (enum `not-started · skeleton · detailed`) | the two disagree for a system — system docs only; see the carve-outs below |\n| **Version coherence** | the header `Version` and `GD-IDS` `version` agree; a `not-started` system carries **no** version, a `skeleton`-or-later system carries one | the two disagree, or a `skeleton`+ system is missing a version \u002F a `not-started` system has one |\n| **AC presence** | for a `detailed`-or-later system, section H is non-empty and every `AC-\u003Csys>-N` id is unique | a `detailed`+ system has an empty H, or repeats an `AC-\u003Csys>-N` — gaps in the numbering are **not** a conflict (numbering is stable after an AC is removed) |\n| **Placeholder leak** | grep `[To be designed]` inside `detailed`-or-later documents (a `\u003C!-- deferred -->` marker is **intentional** — never a leak) | a `detailed`+ document still carries a skeleton `[To be designed]` placeholder |\n| **Core-floor coherence** | for a `detailed` document, check that **no core section carries `\u003C!-- deferred -->`** — the core-set per zone (`gd-lifecycle`: system `A\u002FB\u002FC\u002FD\u002FH` · flow `A\u002FB` · content `A\u002FB\u002FC`) | a `detailed`+ document defers a **core** section — the status was raised past the floor (the soft guard in `gd-authoring` was bypassed); route to the owning zone to author the core section or lower the status. A deferred **non-core** section is **not** a conflict (it is the inferred `detailed · partial` — see the render below) |\n\nThe registry is authoritative: when a document disagrees with `GD-IDS`, the\nregistry wins until the user resolves it the other way (`gd-principles`).\n\n**Map freshness — print-only, not a conflict.** The `## System Map [gen]` block in\n`GAME.md` is a deterministic **render** of `GD-IDS` `systems` (`gd-lifecycle` →\nLifecycle & Status), so a disagreement is a *freshness* issue, never a coherence\nconflict to resolve. On any of —\n\n- a `GD-IDS` system **missing from the map** (no row);\n- a **phantom row** in the map with no matching `GD-IDS` system;\n- a row whose **Status \u002F Ver \u002F Depends** differs from `GD-IDS`,\n\n— **print** a freshness notice naming the stale rows (`## System Map [gen] stale —\n\u003Crows>; owner re-renders on next write`). verify is **read-only**: it does **not**\nre-render the map. The owning zone re-renders on its next write — **B1**: the writer of\n`GD-IDS` (`unikit-gd-spec` for the System Map, `unikit-gd-flow` \u002F `unikit-gd-content` for\ntheirs) re-renders the affected `[gen]` block with the same deterministic render (group\nby category, sort by tier then design order, display-precedence on\n`deprecated`\u002F`implemented`). A `systems\u002F*.md` file with **no `GD-IDS` entry** (the\nRoster ↔ disk check) is likewise **routed**: the roster is `unikit-gd-spec`'s to write,\nso verify routes the user to `\u002Funikit-gd-spec` to register the system.\n\n**Deferred markers, the `· partial (n\u002Fm)` render, and the self-check (all three maps).**\nA `\u003C!-- deferred -->` marker is an **intentional** omission (`gd-lifecycle` — a section\nthe author chose to skip at this depth), **never** a placeholder leak. Its only\nmechanical consequence at verify time is the **render**: a `detailed`+ document carrying\n≥1 `\u003C!-- deferred -->` should show **`· partial (n\u002Fm)`** appended to its row Status in the\nrelevant `## *Map [gen]`, where **n = the count of deferred non-core sections** (those\ncarrying the marker) and **m = the document's total deferrable (non-core) sections**\n(`gd-lifecycle` → the canonical render format + per-zone core-set). This applies\nidentically to the **System, Flow, and Content** maps; like all freshness it is\n**print-only, not a coherence conflict** — verify does **not** re-render (the owner\nappends the suffix on its next re-render), and the status value itself stays the read-only\nenum (`· partial` is a render annotation, not a `doc_status`, and is **not** part of the\ntwo-place status\u002Fversion coherence). **Self-check (marker ⟺ render):** every document with\n≥1 `\u003C!-- deferred -->` must render `· partial (n\u002Fm)` in its map row, **and** every\n`· partial` suffix in a map must correspond to a document that actually carries the\nmarker — a mismatch in either direction is a **freshness** discrepancy, **printed** (the\nowner fixes it on re-render). Annotate the freshness notice with the count, e.g.\n`## System Map [gen] stale (partial 2\u002F5 on SYS-combat); owner re-renders`.\n\n**Scope & carve-outs (Status \u002F Version \u002F AC \u002F Placeholder).** These four checks\nread the **system** spine only — the header ↔ `GD-IDS` pair of a `systems\u002F*.md`\ndocument (the `## System Map [gen]` render is *not* a coherence surface — its\nagreement is handled by *Map freshness* above):\n\n- **Lifecycle-enum scope.** `GAME.md` (`drafted | approved`) and `CONCEPT.md`\n  (`exploring | drafted | approved`) keep their **own** lifecycle enums — a\n  `Status: approved` there is correct and is **never** a status conflict.\n- **Display precedence.** A system with `status: deprecated` legitimately shows\n  `deprecated` in the `## System Map [gen]` Status over its underlying `doc_status`;\n  the read-only `implemented` value (a code-set display overlay) behaves the same.\n  Both are display overlays in the **render** — never part of the two-place header ↔\n  `GD-IDS` `doc_status` comparison. The companion **`GD-IDS` `implemented_version`**\n  field (also code-set, by `unikit-verify` on all-AC-met) is a code-owned field —\n  **not** a `doc_status` and **not** a `version` — so it never participates in Status\n  or Version coherence and is never flagged as drift.\n- **Non-id metadata (`research:`).** The `GD-IDS` `research:` field — a **path pointer**\n  to the explore research that seeded an artifact (written by `unikit-gd-spec`\n  add-system on a **system** row, by `unikit-gd-flow` on a **flow** `flows[]` row, and by\n  `unikit-gd-content` on a **content type** `content_types[]` row) — is non-semantic\n  metadata, **not** a registry id and **not** a `doc_status` \u002F `version`. It is excluded\n  from status\u002Fversion coherence on all three axes, and the id-resolving checks pass it\n  over **by construction**: **Dangling references** only resolves id tokens\n  (`SYS-`\u002F`ENT-`\u002F`FORM-`\u002F`AC-`\u002F`PIL-`\u002F`FLOW-`\u002F`GOAL-`\u002F`CT-`\u002F`CU-`), and **Unregistered\n  cross-doc fact** only greps `FORM-`\u002F`ENT-` ids — a folder path matches neither — so no\n  special-case logic is needed.\n\n### Axis-aware checks — flow + content (load on demand)\n\nBeyond the system checks above, the registry may carry **flows** and **content\ntypes**, each with its own check family — the mirror of the system checks plus the\naxis-specific ones. When `GD-IDS` `flows` and\u002For `content_types` is **non-empty**, load\nthe matching family from `{{skills_dir}}\u002F{{self_name}}\u002Freferences\u002Faxis-checks.md` and run\nit; an empty `flows: []` \u002F `content_types: []` (or no key) → **skip that family\nsilently** (not a conflict). The registry-wins rule and the freshness-vs-conflict\ndistinction apply exactly as above — freshness is **print-only** (the owner re-renders).\n\n| Registry has | Family (in `references\u002Faxis-checks.md`) — coverage |\n|--------------|----------------------------------------------------|\n| `flows` non-empty | the **flow** family: GOAL-id validity, dangling goal-targets, flow status\u002Fversion 2-place, flow Depends 3-way, wiring-mode-vs-structure, win\u002Flose-vs-terminal-goal, funnel continuity, flow\u002Ffunnel map freshness (`Realized` cross-axis derived) |\n| `content_types` non-empty | the **content** family: CT\u002FCU-id validity, CU-fields-subset-CT, ref-target resolution, scale-vs-structure, belongs-to 3-way, content status\u002Fversion 2-place, content map freshness, RES\u002FTRACK\u002FKNOB fact coherence |\n\nThe **cross-axis impact** of a system edit on dependent flows \u002F content types is the\nreverse-edge walk in **Phase 3** (it stays here — it is impact analysis, not a per-axis\ncheck).\n\n## Phase 3 — Changed-Scope Impact (when a diff is unverified)\n\nCompute the blast radius of a recent edit:\n\n1. **Changed set** = `git diff HEAD` (and `git status`) restricted to\n   `.unikit\u002Fgamedesign\u002F` → the systems whose documents changed on disk. (There is no\n   stored \"pending re-verify\" state to re-scan — status records readiness only; a change\n   is carried by the git diff + version, not by a `doc_status`.)\n2. Walk `GD-IDS` `depends_on` edges (rendered in the `## System Map` Depends column)\n   to the **transitive closure** of systems that depend (directly or indirectly) on\n   a changed one.\n3. Classify each affected system into an **Affected** table:\n\n   | System \u002F Flow | Relation | Verdict |\n   |---------------|----------|---------|\n   | SYS-enemy-ai | depends on SYS-combat (changed) | **Needs Review** |\n   | SYS-economy | soft dep, no touched interface | **Still Valid** |\n   | SYS-loot | uses a removed AC | **Likely Stale** |\n   | FLOW-first-session | exercises SYS-combat (changed) via GOAL→AC | **Needs Review** |\n\n   Verdicts: **Still Valid** \u002F **Needs Review** \u002F **Likely Stale**.\n4. **Print the impact** (verify writes nothing):\n   - **Print the Affected table** to the console — the changed system + every dependent\n     with its verdict. verify does **not** write the `Affected (gd-verify):` line into\n     section K (it is read-only); the owner records that line on its next authoring touch\n     if it acts on the impact (`gd-authoring` → Delta Discipline).\n   - For each affected **dependent** with a `Needs Review` \u002F `Likely Stale` verdict,\n     **recommend** a re-author pass to its owner — verify does **not** bump any\n     `doc_status` (status records readiness only; a re-author bumps `Ver`, not status).\n   - **Idempotent:** re-running on the same diff yields the same Affected table — there is\n     no state to mutate.\n\n**Cross-axis impact (system → flow, one-way).** A system edit can stale a **flow** that\nexercises it (through `GOAL → SYS` \u002F `GOAL → AC`) — `gd-flow-axis` → Flow Axis. Extend\nthe pass across the axis (skip when `flows: []`):\n\n- **Reverse-edge walk:** for each changed **system**, find every flow whose\n  `flows[].depends_on` includes it, or whose `goals[].targets` reference it\n  (`GOAL → SYS` \u002F `GOAL → AC`). Those flows join the **Affected** table as **flow rows**\n  (Relation: `exercises SYS-x (changed)`), with the same Still Valid \u002F Needs Review \u002F\n  Likely Stale verdicts (a flow using a **removed** `AC` is Likely Stale). The reverse\n  does **not** hold — editing a flow never stales a system.\n- **Print impact (dependent flow):** list affected flows in the printed Affected table.\n  For each `Needs Review` \u002F `Likely Stale` dependent flow, **recommend** a re-author pass\n  to `unikit-gd-flow` — verify writes **nothing** (no `doc_status` bump, no `FLOW.md`\n  header write, no section-F note, no `## Flow Map [gen]` re-render). Acting on the\n  recommendation (the `Ver+1` + changelog touch) is the owner's call.\n\n**Cross-axis impact (system → content type, one-way).** A system edit can stale a\n**content type** that feeds it (through `belongs_to` \u002F a `ref\u003CSYS>` field) —\n`gd-content-axis` → Content Axis. Extend the pass across the axis (skip when\n`content_types: []`):\n\n- **Reverse-edge walk:** for each changed **system**, find every content type whose\n  `content_types[].belongs_to` names it, or whose `CT.fields` carry a `ref\u003CSYS>` to it.\n  Those types join the **Affected** table as **content rows** (Relation: `feeds SYS-x\n  (changed)`), with the same Still Valid \u002F Needs Review \u002F Likely Stale verdicts (a type\n  whose consuming system removed a relied-on contract is Likely Stale). The reverse does\n  **not** hold — editing a content type never stales a system.\n- **Print impact (dependent CT):** list affected types in the printed Affected table.\n  For each `Needs Review` \u002F `Likely Stale` dependent type, **recommend** a re-author pass\n  to `unikit-gd-content` — verify writes **nothing** (no `doc_status` bump, no\n  `CONTENT-TYPE.md` header write, no section-F note, no `## Content Map [gen]`\n  re-render). Acting on the recommendation is the owner's call.\n\n## Phase 4 — Triage Conflicts (4 tracks)\n\nA verify conflict is **precise** (the grep found a real disagreement) but its **fix is\nnot always predetermined**, and it can **never be declined** — only resolved or routed.\nUsing the shared **handoff engine** (`gd-critique` → Handoff Engine), sort every conflict\ninto one of **four tracks**:\n\n1. **Freshness — print-only** — verify is read-only, so it **prints**, never fixes. The\n   `[gen]`-map **freshness** (Phase 2) is announced as a stale-rows notice; the owning zone\n   re-renders on its next write (**B1**). A status \u002F version header ↔ `GD-IDS` disagreement\n   (where `GD-IDS` is the machine truth) is **not** healed here — its correction (set the\n   header to `GD-IDS`) is a clean entailed fix and goes to Track 2.\n\n2. **Entailed → apply-ready** — the conflict's fix passes the silent **ENTAILED** criterion\n   (one concrete target · the correct value already authoritative in `GD-IDS` · exactly one\n   local fix · no external knowledge) but needs an **owner write** verify cannot make\n   (verify writes nothing): a **status \u002F version header** to correct to `GD-IDS`, a\n   **duplicate id** to renumber, a **terminology drift** to swap to the canonical term, a\n   **dangling reference** to repoint. Put it in the **apply-ready** set — the named fix\n   handed to `unikit-gd-apply` (Phase 6) as a prose delta, authored by the owner, not here.\n\n3. **Direction fork → interview** — the conflict admits **more than one valid direction**:\n   a **value conflict** (the document or the registry could each be right), a **dangling\n   `GOAL → SYS` \u002F `AC`** fixable three ways across three zones, a **roster ↔ disk** mismatch\n   (register vs delete), an **unregistered cross-doc `FORM-`\u002F`ENT-`** (register vs remove).\n   The user picks the **direction** — never *whether* to act (decline-vs-direction,\n   `gd-critique`). The interview is **direction-only** and batched, asked with the question tool of your agent (`AskUserQuestion`); it is **suppressed under the in-apply flag** (Phase 1 sentinel):\n\n   ```\n   The question tool of your agent (`AskUserQuestion`): CONFLICT — \u003Cdoc\u002Fsection> vs GD-IDS: \u003Cthe disagreement>. Which direction?\n   Options:\n   1. Fix as A — e.g. registry is right → correct the document\n   2. Fix as B — e.g. document is right → update GD-IDS to \u003CX> (with approval; record it)\n   3. This is authoring \u002F needs a decision → route to the owner or \u002Funikit-gd-explore\n   ```\n\n   There is **no \"Decline\"** — a consistency conflict is a fact, not an opinion. A chosen\n   A\u002FB that is a clean local edit becomes an **apply-ready** prose delta (it joins Track 2);\n   option 3 routes it to Track 4.\n\n4. **Authoring → owner \u002F explore** — the conflict needs **authoring**, not a mechanical\n   fix: an **empty section H** \u002F **missing AC**, a **placeholder leak** in a `detailed`+\n   document, a **core section deferred past the floor**. It is neither entailed nor a\n   direction pick — route it to the owning zone (`unikit-gd-system` \u002F `unikit-gd-flow` \u002F\n   `unikit-gd-content` \u002F `unikit-gd-spec`), or to `\u002Funikit-gd-explore` when it needs a\n   design decision first.\n\nverify never writes the registry — it is read-only; the registry-wins rule still governs\nthe **direction** of a fix (apply \u002F the owner sets the document to match `GD-IDS`), and a\ndeprecated ID is never deleted. Log every conflict + its track + resolution in the printed\nreport (Phase 5). The coherence-vs-presence split still holds underneath: a **coherence**\nconflict (status \u002F version \u002F Depends 3-way, where `GD-IDS` is authoritative) is now\n**Track 2** (entailed → apply-ready — the header corrected to `GD-IDS`), and the\n`[gen]`-map **freshness** is **Track 1** (print-only); a **presence** conflict (empty H,\nduplicate id, placeholder leak, unregistered cross-doc fact) is Track 2 (entailed →\napply-ready) or Track 4 (authoring), resolved by editing the document, never the registry.\n\n## Phase 5 — Report (printed to the console)\n\n**verify is read-only — the report is printed to the console, never written to a file.**\nA clean full PASS is a single chat line. On `CONFLICTS FOUND` or a changed-scope pass,\nprint the full report block:\n\n```markdown\n# Verify: \u003Cscope> — \u003CYYYY-MM-DD>\n> Result: \u003CPASS | CONFLICTS FOUND>  ·  Scope: \u003CSYS-slug | changed | all>\n\n## Conflicts\n| Severity | Document \u002F Section | Check | Conflict (evidence) | Recommended fix |\n|----------|--------------------|-------|---------------------|-----------------|\n\n## Affected (changed-scope only)\n| System \u002F Flow | Relation | Verdict |\n|---------------|----------|---------|\n\n## Freshness\n\u003C[gen]-map rows stale → owner re-renders on next write (B1), or \"up to date\">\n```\n\nThis is **printed**, not a file — a verify pass is ephemeral and cheap to re-run (the\nsingle-session verify → apply pair is by design: a `\u002Fclear` between them is fixed by\nre-running verify). The asymmetry with `unikit-gd-review` (which leaves a durable\ntwo-bucket report) is intentional. When the same conflict recurs across systems, record it\nas a `gamedesign` `library` rule via `\u002Funikit-memory --module gamedesign` — durable domain\nknowledge, not re-discovered each pass.\n\n## Phase 6 — Handoff (standalone only; inline prose, recommend-only)\n\n> **LOOP-GUARD.** This phase runs **only on a standalone `\u002Funikit-gd-verify`**. Under the\n> **in-apply flag** (the `apply-phase3` sentinel resolved in Phase 1), **skip this phase\n> entirely** — verify prints freshness (Track 1) and the report (Phase 5), but never offers\n> a handoff back to `unikit-gd-apply`. That is the silent gate that stops\n> `apply → verify → apply` from looping.\n\nWhen Tracks 2 and 3 produced **apply-ready deltas** (the entailed fixes + the\ndirection-resolved edits), hand them to `unikit-gd-apply` **in one move** rather than\nrouting each conflict into an owner skill by hand. verify's handoff is **inline prose from\nthis session** — it writes **no** file (Phase 5): verify **prints the deltas as plain\nprose** (each citing its `target` + `zone`), then ends with a **bare `\u002Funikit-gd-apply`**.\nA bare `\u002Funikit-gd-apply` (no argument, no fence) reads the deltas from the **last verify\noutput in the session** — apply's no-arg session mode.\n\n**Hand off — recommend-only (never a `Skill` call).** Neither `unikit-gd-review` nor\n`unikit-gd-verify` carries `Skill` in `allowed-tools`; each **prints** the\n`\u002Funikit-gd-apply` recommendation for the user to run, and on Codex the auto-invoke nudge\nruns it — the two handoff tails are identical by contract.\n\n\u003C!-- unikit:agents codex -->\n### Auto-invoke the handoff — BLOCKING PRE-REQUISITE\n\nWhen this phase prints the `\u002Funikit-gd-apply` recommendation, do not ask the user to run it by\nhand: invoke `unikit-gd-apply` once, bare — it reads the printed deltas from this session.\nIf you have a `Skill` tool that accepts arguments, call it with that skill, in full and unchanged, then follow the skill.\nOtherwise Read `{{skills_dir}}\u002Funikit-gd-apply\u002FSKILL.md` in full, treat it as the instructions of this step and\ncarry them out here, in this session, now.\nThis is a single handoff: let `unikit-gd-apply` route the deltas to the owners (it closes with its own\n`apply-phase3` verify — no loop).\nDo not print a command for the user to run and do not stop.\nOnly if that file cannot be read, the printed command is the recommend-only fallback.\n\u003C!-- unikit:end -->\n\n- **apply-ready non-empty:** print the deltas as plain prose (each citing `target` +\n  `zone`), then the bare command on its own line —\n  ```\n  \u002Funikit-gd-apply\n  ```\n  `unikit-gd-apply` reads the printed deltas from the session (no file, no argument —\n  verify writes none), dispatches them to the owning zones, and closes with its own\n  `apply-phase3` verify pass. A single-zone set is bounced to its owner by apply's GATE 2.\n- **apply-ready empty** (only freshness + authoring \u002F research routes): **no apply\n  handoff** — list the Track-4 routes instead (`\u002Funikit-gd-system` \u002F `\u002Funikit-gd-flow` \u002F\n  `\u002Funikit-gd-content` \u002F `\u002Funikit-gd-spec`, or `\u002Funikit-gd-explore` for the ones needing a\n  design decision).\n\n## Final: Compact Report\n\nFollow the **Handoff Tail contract** (`gd-critique` → Handoff Engine): the runnable\ncommand is the **last block** on screen — the report and any route note go above it,\nnothing prints after it. Under the `apply-phase3` sentinel the handoff is\n**suppressed**, so there is no command tail (the loop-guard).\n\nPrint the compact report:\n\n```\nScope: \u003CSYS-slug | changed | all>\nResult: \u003CPASS | CONFLICTS FOUND (\u003Cn>)>\nChecks: facts · terms · IDs · dup-IDs · dangling · unregistered-fact · roster↔disk · map-freshness · Depends-3way · status · version · AC-presence · placeholder · core-floor — \u003Cpass\u002Ffail each>\nFlow checks (when flows exist): GOAL-ids · dangling-GOAL · flow-status\u002Fversion · flow-Depends-3way · mode↔structure · win\u002Flose↔terminal-GOAL · funnel-continuity · flow\u002Ffunnel-freshness — \u003Cpass\u002Ffail each>\nContent checks (when content_types exist): CT\u002FCU-ids · CU⊆CT · ref\u003C>-resolve · scale↔structure · belongs_to-3way · content-status\u002Fversion · content-map-freshness · RES\u002FTRACK\u002FKNOB · cross-axis SYS→CT — \u003Cpass\u002Ffail each>\nAffected (changed-scope): \u003Ck systems + flows + content types — Needs Review: …, Likely Stale: …>\nFreshness: \u003C## System Map [gen] stale — \u003Crows> (· partial n\u002Fm where deferred); owner re-renders | up to date>\nTracks: \u003Capply-ready: N · direction-interview: N · authoring\u002Fexplore: N>\nHandoff: \u003Cprinted deltas + bare \u002Funikit-gd-apply | apply-ready empty → routes only | in-apply (apply-phase3) → suppressed>\nReport: \u003Cprinted to console | none (clean PASS)>\n```\n\nThe actionable routes when apply-ready is empty live in the `Tracks` line above —\nread them there. No summary document beyond the conditional report file.\n\n**Then end with the handoff as the LAST block** — one command, nothing after it:\n\n- **apply-ready non-empty** → printed deltas (each citing `target` + `zone`), then\n  `🛠️ \u002Funikit-gd-apply` (bare — apply reads them from the session)\n- **apply-ready empty, a conflict needs a design call** → `🔎 \u002Funikit-gd-explore`\n- **apply-ready empty, authoring only** → the matching owner: `🔧 \u002Funikit-gd-system`\n  \u002F `\u002Funikit-gd-flow` \u002F `\u002Funikit-gd-content` \u002F `\u002Funikit-gd-spec`\n- **clean PASS** → `🔍 \u002Funikit-gd-review \u003Csystem>` (fresh session)\n- **in-apply (`apply-phase3`)** → suppressed — no command tail.\n\nNothing prints after the command — no recap, no description of what the called\nskill does next.\n\n## Ownership Boundaries\n\n- **Owns:** nothing on disk — `unikit-gd-verify` is **fully read-only**. It produces a\n  **console** conflict report + Affected table, and **prints** freshness \u002F coherence\n  recommendations; every fix is performed by `unikit-gd-apply` (the apply-ready deltas) or\n  the owning zones (authoring + the `[gen]`-map re-render on their next write — **B1**: the\n  writer of `GD-IDS` re-renders the affected maps).\n- **Read-only:** every design document, `GD-IDS.yaml`, and `GAME.md` (incl. all\n  `[gen]`-map blocks) — verify writes none of them.\n- **Not this skill:** quality judgment → `unikit-gd-review`; applying the apply-ready set\n  in one pass → `unikit-gd-apply` (the handoff is **recommend-only** — verify prints the\n  command, never invokes it); authoring → `unikit-gd-system` (systems) \u002F `unikit-gd-flow`\n  (flows) \u002F `unikit-gd-content` (content types) \u002F `unikit-gd-spec` (`GAME.md` + the roster);\n  a conflict needing a design decision → `unikit-gd-explore`.\n- **Never:** write **any** file (no report file, no `Affected (gd-verify):` line, no\n  `doc_status` bump, no `[gen]`-map re-render — verify carries no `Write`\u002F`Edit`\u002F`mkdir`);\n  use web research; guess where a grep settles it; change a `GD-IDS` value; delete or\n  renumber an ID; write the roster (route to `unikit-gd-spec`); carry `Skill`\u002F`Agent` in\n  `allowed-tools` or run `unikit-gd-apply` itself (the handoff is a printed prose\n  recommendation read by apply's no-arg session mode); offer the handoff or run the\n  direction interview when invoked as apply's Phase 3 (the `apply-phase3` loop-guard); read\n  the code workspace or project source.\n\n## Quick Reference\n\n```\n\u002Funikit-gd-verify SYS-combat        → check one system → triage conflicts (4 tracks) → handoff apply-ready to \u002Funikit-gd-apply\n\u002Funikit-gd-verify                   → unverified diff → changed-scope impact; else full check\n\u002Funikit-gd-verify what did that change affect  → changed-scope impact from git diff\n\u002Funikit-gd-verify all               → full registry + roster + map-freshness + Depends pass\n# internal: \u002Funikit-gd-apply passes apply-phase3 as its Phase 3 — verify suppresses the handoff\u002Finterview (loop-guard)\n```\n","# Game Design — Consistency & Impact Verification\n\nAnswer **\"is the design consistent with itself?\"** — a mechanical, deterministic\ncheck of every document against the facts registry, plus the **changed-scope\nimpact** of a recent edit. This is the design-side mirror of `unikit-verify` and a\nCI-linter to `unikit-gd-review`'s senior reviewer: cheap, binary, run after every\nedit. A **verify conflict cannot be declined** (unlike a review finding) — it is\nresolved.\n\n**`unikit-gd-verify` is fully read-only — it writes nothing** (no report file, no\nchangelog line, no `doc_status` bump, no `[gen]`-map re-render). It **detects and prints**;\nevery fix is performed by `unikit-gd-apply` (the entailed deltas) or the owning zones\n(authoring + the `[gen]`-map re-render on their next write — **B1**: the writer of `GD-IDS`\nre-renders the affected maps).\n\nConflicts are **precise, but their fix is not always predetermined**, so each is sorted\ninto one of **four tracks** — **freshness** (print-only; the owner re-renders the\n`[gen]` map on its next write), **entailed → apply-ready** (a named fix — incl. a\nstatus\u002Fversion header correction — handed to `unikit-gd-apply`), **direction interview**\n(the user picks *which* fix, never *whether*), and **authoring → owner \u002F explore**. The\napply-ready set hands off **in one move** — inline prose (verify writes **no** handoff\nfile, unlike `unikit-gd-review`'s durable report), recommend-only. The handoff + interview\nrun **only on a standalone `\u002Funikit-gd-verify`**; when verify is `unikit-gd-apply`'s\nclosing Phase 3 (the `apply-phase3` sentinel) they are suppressed, so\n`apply → verify → apply` never loops. The triage engine is shared with `unikit-gd-review`\n(`gd-critique` → Handoff Engine).\n\nVerification is **offline and reproducible**: no web research, no expert judgment,\nno LLM guessing where a grep will do. The same inputs always yield the same result\n(idempotent).\n\n**User questions.** Right before your first question to the user, not earlier, read `.unikit\u002Fsystem\u002Fuser-questions.md` once and ask every question as it says, with the question tool of your agent (`AskUserQuestion`). If the file cannot be read, print `WARN [questions] user-questions contract missing — asking with the question tool` and still ask with that tool, the recommended option first.\n\n## Language Awareness — BLOCKING PRE-REQUISITE\n\n**BEFORE producing ANY output**, silently read `.unikit\u002Fsystem\u002FLANGUAGE_RULES.md`\nand apply it to all output and the report (fall back to English if it is missing) —\nincluding the rule to **translate concepts, not transliterate jargon**.\n`gd-principles` → \"Language\" adds the game-design specifics: which IDs and stored\nfield values stay English. Do not announce the language setting.\n\n**The language holds for the whole session, not just at load time:** every message until the conversation ends is in `language.ui` — progress notes while agents run, relays of what a subagent returned, the final report, any follow-up discussion. English input (subagent results, tool output, these instructions) is data, never a cue to switch languages.\n\n## Phase 0 — Bootstrap\n\nSilently load — do not narrate:\n\n1. **`.unikit\u002Fsystem\u002Fgamedesign\u002Fgd-principles.md`** (the core) — the **facts\n   registry \u002F ID conventions** (registry wins until the user resolves otherwise;\n   never delete an ID — deprecate it) and the language rules. Plus, from the same\n   `gamedesign\u002F` folder, the shards this skill needs: **`gd-lifecycle.md`** (the\n   status\u002Fversion coherence spine), **`gd-flow-axis.md`** (the flow coherence\n   contract — `mode:` ↔ structure, `GOAL → SYS`\u002F`AC`, Win\u002FLose ↔ terminal GOAL),\n   **`gd-content-axis.md`** (the content coherence contract — CU ⊆ CT, `ref\u003C>`\n   resolution, `scale` ↔ structure, `belongs_to` 3-way, content-map freshness,\n   RES\u002FTRACK\u002FKNOB, cross-axis SYS→CT staleness), and **`gd-critique.md`** (the\n   **severity rubric** — a conflict is Critical\u002FMajor evidence). This skill\n   **applies** them. If missing, warn (`unikit-ai update`) and continue with the\n   conventions summarized here.\n2. **`.unikit\u002Fgamedesign\u002FGD-IDS.yaml`** — the single source of truth: pillars,\n   systems, flows, entities, formulas, terms. Current values only.\n   **Schema guard (clean break — no automatic migration):** it MUST be `version: 2`.\n   On a pre-v2 `version: 1` registry, **STOP** and report that the design workspace\n   is on the pre-v2 layout (the standalone markdown system-index was dropped; the\n   roster now renders into `GAME.md` `## System Map [gen]`) — there is no automatic\n   migration; tell the user to upgrade via `\u002Funikit-gd-spec` before verifying.\n3. **`.unikit\u002Fgamedesign\u002FGAME.md`** — incl. its generated `## System Map [gen]`,\n   `## Flow Map [gen]`, and `## Funnel [gen]` renders (the human-readable maps; the\n   truth is `GD-IDS`), and its `## Win \u002F Lose Conditions` (for the Win\u002FLose ↔ terminal\n   GOAL check).\n4. **`.unikit\u002Fgamedesign\u002Fsystems\u002F*.md`** and **`.unikit\u002Fgamedesign\u002Fflows\u002F*.md`** — the\n   system and flow documents checked against the registry.\n\n**One-way boundary:** never read `.unikit\u002Fcode\u002F`, project source, or build\nartifacts. **Web research is forbidden here** (`gd-principles`) — verification must\nstay deterministic. The only `git` use is reading the design-workspace diff.\n\n\u003C!-- unikit:extension-point:bootstrap -->\n\n## Phase 1 — Resolve Scope (no flags)\n\n**Loop-guard sentinel (first).** If the argument is exactly **`apply-phase3`** — the\nreserved loop-guard sentinel (`gd-critique` → Handoff Engine), passed by\n`unikit-gd-apply` as its closing Phase 3 — this run is the **in-apply gate**, **not** a\nscope. Treat it as a bare invocation for scope purposes (derive changed-scope from the\n`git diff` exactly as below), but set the **in-apply flag**: the standalone handoff offer\nand the direction interview (Phase 4 Track 3 \u002F Phase 6) are **suppressed** this run, so\n`apply → verify → apply` cannot loop. A standalone `\u002Funikit-gd-verify` (no sentinel)\nleaves the flag off — the handoff is active.\n\nScope is a function of context:\n\n1. The argument names a system, flow **or content type** → check **that document** and\n   its registry facts (a `FLOW-\u003Cslug>` runs the flow checks, a `CT-\u003Cslug>` the content\n   checks below).\n2. There is an **unverified diff** under `.unikit\u002Fgamedesign\u002F` (`git diff` \u002F\n   `git status` shows changed design docs), or the prompt asks \"what did this\n   change affect\" → **changed-scope** pass (Phase 3).\n3. Otherwise → **full** check of every system, **every flow**, **every content type**,\n   and the whole registry.\n\nAnnounce the resolved scope in one line.\n\n## Phase 2 — Mechanical Checks (grep-first)\n\nRun every check deterministically; each mismatch is a **CONFLICT** with a citation:\n\n| Check | Method | Conflict when |\n|-------|--------|---------------|\n| **Facts** | grep each `GD-IDS` entity\u002Fformula value across the docs — match the value on word boundaries, not as a bare substring | a document states a number\u002Fname that disagrees with the registry |\n| **Terminology drift** | grep each term's `forbidden_aliases` **values** (the listed aliases, not the field name) across the docs | a forbidden alias is used in place of the canonical term |\n| **ID validity** | scan every `SYS-`\u002F`ENT-`\u002F`FORM-`\u002F`AC-`\u002F`PIL-`\u002F`FLOW-`\u002F`GOAL-` id for shape (analytics `events` are `snake_case` tokens, not prefixed ids) | an id is malformed — wrong case, bad separator, or an unknown prefix |\n| **Duplicate IDs** | group every declared id by value | the same id is declared for two different things |\n| **Dangling references** | resolve every referenced id against `GD-IDS` | a referenced id does not exist, or a live (non-deprecated) section points at a `deprecated` entry |\n| **Unregistered cross-doc fact** | grep `FORM-`\u002F`ENT-` ids that surface in **two or more** documents | a fact crosses a document boundary yet has no `GD-IDS` entry |\n| **Roster ↔ disk** | compare `GD-IDS` `systems` ids to the `systems\u002F*.md` files on disk | a `skeleton`-or-later system has no file, or a `systems\u002F*.md` file has no `GD-IDS` entry (→ route to `unikit-gd-spec` to register it — verify never writes the roster) |\n| **Map freshness (3-surface)** | compare the `GAME.md` `## System Map [gen]` rows to `GD-IDS` `systems` — membership, `Status`, `Ver`, `Depends` | the render disagrees with `GD-IDS` — **not a conflict to resolve**: **print** a freshness notice; the owning zone re-renders the block on its next write (verify is read-only — B1); see *Map freshness* below |\n| **Depends 3-way** | for each `A → B` edge, check it agrees across A's section F, A's `GD-IDS` `depends_on`, and A's `## System Map` Depends cell, and that B carries the reciprocal | the three sources disagree, or the reciprocal edge is missing or contradictory |\n| **Status coherence** | a system's `doc_status` agrees across the **two places that must agree** — the header `> Status:` and `GD-IDS` `doc_status` (enum `not-started · skeleton · detailed`) | the two disagree for a system — system docs only; see the carve-outs below |\n| **Version coherence** | the header `Version` and `GD-IDS` `version` agree; a `not-started` system carries **no** version, a `skeleton`-or-later system carries one | the two disagree, or a `skeleton`+ system is missing a version \u002F a `not-started` system has one |\n| **AC presence** | for a `detailed`-or-later system, section H is non-empty and every `AC-\u003Csys>-N` id is unique | a `detailed`+ system has an empty H, or repeats an `AC-\u003Csys>-N` — gaps in the numbering are **not** a conflict (numbering is stable after an AC is removed) |\n| **Placeholder leak** | grep `[To be designed]` inside `detailed`-or-later documents (a `\u003C!-- deferred -->` marker is **intentional** — never a leak) | a `detailed`+ document still carries a skeleton `[To be designed]` placeholder |\n| **Core-floor coherence** | for a `detailed` document, check that **no core section carries `\u003C!-- deferred -->`** — the core-set per zone (`gd-lifecycle`: system `A\u002FB\u002FC\u002FD\u002FH` · flow `A\u002FB` · content `A\u002FB\u002FC`) | a `detailed`+ document defers a **core** section — the status was raised past the floor (the soft guard in `gd-authoring` was bypassed); route to the owning zone to author the core section or lower the status. A deferred **non-core** section is **not** a conflict (it is the inferred `detailed · partial` — see the render below) |\n\nThe registry is authoritative: when a document disagrees with `GD-IDS`, the\nregistry wins until the user resolves it the other way (`gd-principles`).\n\n**Map freshness — print-only, not a conflict.** The `## System Map [gen]` block in\n`GAME.md` is a deterministic **render** of `GD-IDS` `systems` (`gd-lifecycle` →\nLifecycle & Status), so a disagreement is a *freshness* issue, never a coherence\nconflict to resolve. On any of —\n\n- a `GD-IDS` system **missing from the map** (no row);\n- a **phantom row** in the map with no matching `GD-IDS` system;\n- a row whose **Status \u002F Ver \u002F Depends** differs from `GD-IDS`,\n\n— **print** a freshness notice naming the stale rows (`## System Map [gen] stale —\n\u003Crows>; owner re-renders on next write`). verify is **read-only**: it does **not**\nre-render the map. The owning zone re-renders on its next write — **B1**: the writer of\n`GD-IDS` (`unikit-gd-spec` for the System Map, `unikit-gd-flow` \u002F `unikit-gd-content` for\ntheirs) re-renders the affected `[gen]` block with the same deterministic render (group\nby category, sort by tier then design order, display-precedence on\n`deprecated`\u002F`implemented`). A `systems\u002F*.md` file with **no `GD-IDS` entry** (the\nRoster ↔ disk check) is likewise **routed**: the roster is `unikit-gd-spec`'s to write,\nso verify routes the user to `\u002Funikit-gd-spec` to register the system.\n\n**Deferred markers, the `· partial (n\u002Fm)` render, and the self-check (all three maps).**\nA `\u003C!-- deferred -->` marker is an **intentional** omission (`gd-lifecycle` — a section\nthe author chose to skip at this depth), **never** a placeholder leak. Its only\nmechanical consequence at verify time is the **render**: a `detailed`+ document carrying\n≥1 `\u003C!-- deferred -->` should show **`· partial (n\u002Fm)`** appended to its row Status in the\nrelevant `## *Map [gen]`, where **n = the count of deferred non-core sections** (those\ncarrying the marker) and **m = the document's total deferrable (non-core) sections**\n(`gd-lifecycle` → the canonical render format + per-zone core-set). This applies\nidentically to the **System, Flow, and Content** maps; like all freshness it is\n**print-only, not a coherence conflict** — verify does **not** re-render (the owner\nappends the suffix on its next re-render), and the status value itself stays the read-only\nenum (`· partial` is a render annotation, not a `doc_status`, and is **not** part of the\ntwo-place status\u002Fversion coherence). **Self-check (marker ⟺ render):** every document with\n≥1 `\u003C!-- deferred -->` must render `· partial (n\u002Fm)` in its map row, **and** every\n`· partial` suffix in a map must correspond to a document that actually carries the\nmarker — a mismatch in either direction is a **freshness** discrepancy, **printed** (the\nowner fixes it on re-render). Annotate the freshness notice with the count, e.g.\n`## System Map [gen] stale (partial 2\u002F5 on SYS-combat); owner re-renders`.\n\n**Scope & carve-outs (Status \u002F Version \u002F AC \u002F Placeholder).** These four checks\nread the **system** spine only — the header ↔ `GD-IDS` pair of a `systems\u002F*.md`\ndocument (the `## System Map [gen]` render is *not* a coherence surface — its\nagreement is handled by *Map freshness* above):\n\n- **Lifecycle-enum scope.** `GAME.md` (`drafted | approved`) and `CONCEPT.md`\n  (`exploring | drafted | approved`) keep their **own** lifecycle enums — a\n  `Status: approved` there is correct and is **never** a status conflict.\n- **Display precedence.** A system with `status: deprecated` legitimately shows\n  `deprecated` in the `## System Map [gen]` Status over its underlying `doc_status`;\n  the read-only `implemented` value (a code-set display overlay) behaves the same.\n  Both are display overlays in the **render** — never part of the two-place header ↔\n  `GD-IDS` `doc_status` comparison. The companion **`GD-IDS` `implemented_version`**\n  field (also code-set, by `unikit-verify` on all-AC-met) is a code-owned field —\n  **not** a `doc_status` and **not** a `version` — so it never participates in Status\n  or Version coherence and is never flagged as drift.\n- **Non-id metadata (`research:`).** The `GD-IDS` `research:` field — a **path pointer**\n  to the explore research that seeded an artifact (written by `unikit-gd-spec`\n  add-system on a **system** row, by `unikit-gd-flow` on a **flow** `flows[]` row, and by\n  `unikit-gd-content` on a **content type** `content_types[]` row) — is non-semantic\n  metadata, **not** a registry id and **not** a `doc_status` \u002F `version`. It is excluded\n  from status\u002Fversion coherence on all three axes, and the id-resolving checks pass it\n  over **by construction**: **Dangling references** only resolves id tokens\n  (`SYS-`\u002F`ENT-`\u002F`FORM-`\u002F`AC-`\u002F`PIL-`\u002F`FLOW-`\u002F`GOAL-`\u002F`CT-`\u002F`CU-`), and **Unregistered\n  cross-doc fact** only greps `FORM-`\u002F`ENT-` ids — a folder path matches neither — so no\n  special-case logic is needed.\n\n### Axis-aware checks — flow + content (load on demand)\n\nBeyond the system checks above, the registry may carry **flows** and **content\ntypes**, each with its own check family — the mirror of the system checks plus the\naxis-specific ones. When `GD-IDS` `flows` and\u002For `content_types` is **non-empty**, load\nthe matching family from `{{skills_dir}}\u002F{{self_name}}\u002Freferences\u002Faxis-checks.md` and run\nit; an empty `flows: []` \u002F `content_types: []` (or no key) → **skip that family\nsilently** (not a conflict). The registry-wins rule and the freshness-vs-conflict\ndistinction apply exactly as above — freshness is **print-only** (the owner re-renders).\n\n| Registry has | Family (in `references\u002Faxis-checks.md`) — coverage |\n|--------------|----------------------------------------------------|\n| `flows` non-empty | the **flow** family: GOAL-id validity, dangling goal-targets, flow status\u002Fversion 2-place, flow Depends 3-way, wiring-mode-vs-structure, win\u002Flose-vs-terminal-goal, funnel continuity, flow\u002Ffunnel map freshness (`Realized` cross-axis derived) |\n| `content_types` non-empty | the **content** family: CT\u002FCU-id validity, CU-fields-subset-CT, ref-target resolution, scale-vs-structure, belongs-to 3-way, content status\u002Fversion 2-place, content map freshness, RES\u002FTRACK\u002FKNOB fact coherence |\n\nThe **cross-axis impact** of a system edit on dependent flows \u002F content types is the\nreverse-edge walk in **Phase 3** (it stays here — it is impact analysis, not a per-axis\ncheck).\n\n## Phase 3 — Changed-Scope Impact (when a diff is unverified)\n\nCompute the blast radius of a recent edit:\n\n1. **Changed set** = `git diff HEAD` (and `git status`) restricted to\n   `.unikit\u002Fgamedesign\u002F` → the systems whose documents changed on disk. (There is no\n   stored \"pending re-verify\" state to re-scan — status records readiness only; a change\n   is carried by the git diff + version, not by a `doc_status`.)\n2. Walk `GD-IDS` `depends_on` edges (rendered in the `## System Map` Depends column)\n   to the **transitive closure** of systems that depend (directly or indirectly) on\n   a changed one.\n3. Classify each affected system into an **Affected** table:\n\n   | System \u002F Flow | Relation | Verdict |\n   |---------------|----------|---------|\n   | SYS-enemy-ai | depends on SYS-combat (changed) | **Needs Review** |\n   | SYS-economy | soft dep, no touched interface | **Still Valid** |\n   | SYS-loot | uses a removed AC | **Likely Stale** |\n   | FLOW-first-session | exercises SYS-combat (changed) via GOAL→AC | **Needs Review** |\n\n   Verdicts: **Still Valid** \u002F **Needs Review** \u002F **Likely Stale**.\n4. **Print the impact** (verify writes nothing):\n   - **Print the Affected table** to the console — the changed system + every dependent\n     with its verdict. verify does **not** write the `Affected (gd-verify):` line into\n     section K (it is read-only); the owner records that line on its next authoring touch\n     if it acts on the impact (`gd-authoring` → Delta Discipline).\n   - For each affected **dependent** with a `Needs Review` \u002F `Likely Stale` verdict,\n     **recommend** a re-author pass to its owner — verify does **not** bump any\n     `doc_status` (status records readiness only; a re-author bumps `Ver`, not status).\n   - **Idempotent:** re-running on the same diff yields the same Affected table — there is\n     no state to mutate.\n\n**Cross-axis impact (system → flow, one-way).** A system edit can stale a **flow** that\nexercises it (through `GOAL → SYS` \u002F `GOAL → AC`) — `gd-flow-axis` → Flow Axis. Extend\nthe pass across the axis (skip when `flows: []`):\n\n- **Reverse-edge walk:** for each changed **system**, find every flow whose\n  `flows[].depends_on` includes it, or whose `goals[].targets` reference it\n  (`GOAL → SYS` \u002F `GOAL → AC`). Those flows join the **Affected** table as **flow rows**\n  (Relation: `exercises SYS-x (changed)`), with the same Still Valid \u002F Needs Review \u002F\n  Likely Stale verdicts (a flow using a **removed** `AC` is Likely Stale). The reverse\n  does **not** hold — editing a flow never stales a system.\n- **Print impact (dependent flow):** list affected flows in the printed Affected table.\n  For each `Needs Review` \u002F `Likely Stale` dependent flow, **recommend** a re-author pass\n  to `unikit-gd-flow` — verify writes **nothing** (no `doc_status` bump, no `FLOW.md`\n  header write, no section-F note, no `## Flow Map [gen]` re-render). Acting on the\n  recommendation (the `Ver+1` + changelog touch) is the owner's call.\n\n**Cross-axis impact (system → content type, one-way).** A system edit can stale a\n**content type** that feeds it (through `belongs_to` \u002F a `ref\u003CSYS>` field) —\n`gd-content-axis` → Content Axis. Extend the pass across the axis (skip when\n`content_types: []`):\n\n- **Reverse-edge walk:** for each changed **system**, find every content type whose\n  `content_types[].belongs_to` names it, or whose `CT.fields` carry a `ref\u003CSYS>` to it.\n  Those types join the **Affected** table as **content rows** (Relation: `feeds SYS-x\n  (changed)`), with the same Still Valid \u002F Needs Review \u002F Likely Stale verdicts (a type\n  whose consuming system removed a relied-on contract is Likely Stale). The reverse does\n  **not** hold — editing a content type never stales a system.\n- **Print impact (dependent CT):** list affected types in the printed Affected table.\n  For each `Needs Review` \u002F `Likely Stale` dependent type, **recommend** a re-author pass\n  to `unikit-gd-content` — verify writes **nothing** (no `doc_status` bump, no\n  `CONTENT-TYPE.md` header write, no section-F note, no `## Content Map [gen]`\n  re-render). Acting on the recommendation is the owner's call.\n\n## Phase 4 — Triage Conflicts (4 tracks)\n\nA verify conflict is **precise** (the grep found a real disagreement) but its **fix is\nnot always predetermined**, and it can **never be declined** — only resolved or routed.\nUsing the shared **handoff engine** (`gd-critique` → Handoff Engine), sort every conflict\ninto one of **four tracks**:\n\n1. **Freshness — print-only** — verify is read-only, so it **prints**, never fixes. The\n   `[gen]`-map **freshness** (Phase 2) is announced as a stale-rows notice; the owning zone\n   re-renders on its next write (**B1**). A status \u002F version header ↔ `GD-IDS` disagreement\n   (where `GD-IDS` is the machine truth) is **not** healed here — its correction (set the\n   header to `GD-IDS`) is a clean entailed fix and goes to Track 2.\n\n2. **Entailed → apply-ready** — the conflict's fix passes the silent **ENTAILED** criterion\n   (one concrete target · the correct value already authoritative in `GD-IDS` · exactly one\n   local fix · no external knowledge) but needs an **owner write** verify cannot make\n   (verify writes nothing): a **status \u002F version header** to correct to `GD-IDS`, a\n   **duplicate id** to renumber, a **terminology drift** to swap to the canonical term, a\n   **dangling reference** to repoint. Put it in the **apply-ready** set — the named fix\n   handed to `unikit-gd-apply` (Phase 6) as a prose delta, authored by the owner, not here.\n\n3. **Direction fork → interview** — the conflict admits **more than one valid direction**:\n   a **value conflict** (the document or the registry could each be right), a **dangling\n   `GOAL → SYS` \u002F `AC`** fixable three ways across three zones, a **roster ↔ disk** mismatch\n   (register vs delete), an **unregistered cross-doc `FORM-`\u002F`ENT-`** (register vs remove).\n   The user picks the **direction** — never *whether* to act (decline-vs-direction,\n   `gd-critique`). The interview is **direction-only** and batched, asked with the question tool of your agent (`AskUserQuestion`); it is **suppressed under the in-apply flag** (Phase 1 sentinel):\n\n   ```\n   The question tool of your agent (`AskUserQuestion`): CONFLICT — \u003Cdoc\u002Fsection> vs GD-IDS: \u003Cthe disagreement>. Which direction?\n   Options:\n   1. Fix as A — e.g. registry is right → correct the document\n   2. Fix as B — e.g. document is right → update GD-IDS to \u003CX> (with approval; record it)\n   3. This is authoring \u002F needs a decision → route to the owner or \u002Funikit-gd-explore\n   ```\n\n   There is **no \"Decline\"** — a consistency conflict is a fact, not an opinion. A chosen\n   A\u002FB that is a clean local edit becomes an **apply-ready** prose delta (it joins Track 2);\n   option 3 routes it to Track 4.\n\n4. **Authoring → owner \u002F explore** — the conflict needs **authoring**, not a mechanical\n   fix: an **empty section H** \u002F **missing AC**, a **placeholder leak** in a `detailed`+\n   document, a **core section deferred past the floor**. It is neither entailed nor a\n   direction pick — route it to the owning zone (`unikit-gd-system` \u002F `unikit-gd-flow` \u002F\n   `unikit-gd-content` \u002F `unikit-gd-spec`), or to `\u002Funikit-gd-explore` when it needs a\n   design decision first.\n\nverify never writes the registry — it is read-only; the registry-wins rule still governs\nthe **direction** of a fix (apply \u002F the owner sets the document to match `GD-IDS`), and a\ndeprecated ID is never deleted. Log every conflict + its track + resolution in the printed\nreport (Phase 5). The coherence-vs-presence split still holds underneath: a **coherence**\nconflict (status \u002F version \u002F Depends 3-way, where `GD-IDS` is authoritative) is now\n**Track 2** (entailed → apply-ready — the header corrected to `GD-IDS`), and the\n`[gen]`-map **freshness** is **Track 1** (print-only); a **presence** conflict (empty H,\nduplicate id, placeholder leak, unregistered cross-doc fact) is Track 2 (entailed →\napply-ready) or Track 4 (authoring), resolved by editing the document, never the registry.\n\n## Phase 5 — Report (printed to the console)\n\n**verify is read-only — the report is printed to the console, never written to a file.**\nA clean full PASS is a single chat line. On `CONFLICTS FOUND` or a changed-scope pass,\nprint the full report block:\n\n```markdown\n# Verify: \u003Cscope> — \u003CYYYY-MM-DD>\n> Result: \u003CPASS | CONFLICTS FOUND>  ·  Scope: \u003CSYS-slug | changed | all>\n\n## Conflicts\n| Severity | Document \u002F Section | Check | Conflict (evidence) | Recommended fix |\n|----------|--------------------|-------|---------------------|-----------------|\n\n## Affected (changed-scope only)\n| System \u002F Flow | Relation | Verdict |\n|---------------|----------|---------|\n\n## Freshness\n\u003C[gen]-map rows stale → owner re-renders on next write (B1), or \"up to date\">\n```\n\nThis is **printed**, not a file — a verify pass is ephemeral and cheap to re-run (the\nsingle-session verify → apply pair is by design: a `\u002Fclear` between them is fixed by\nre-running verify). The asymmetry with `unikit-gd-review` (which leaves a durable\ntwo-bucket report) is intentional. When the same conflict recurs across systems, record it\nas a `gamedesign` `library` rule via `\u002Funikit-memory --module gamedesign` — durable domain\nknowledge, not re-discovered each pass.\n\n## Phase 6 — Handoff (standalone only; inline prose, recommend-only)\n\n> **LOOP-GUARD.** This phase runs **only on a standalone `\u002Funikit-gd-verify`**. Under the\n> **in-apply flag** (the `apply-phase3` sentinel resolved in Phase 1), **skip this phase\n> entirely** — verify prints freshness (Track 1) and the report (Phase 5), but never offers\n> a handoff back to `unikit-gd-apply`. That is the silent gate that stops\n> `apply → verify → apply` from looping.\n\nWhen Tracks 2 and 3 produced **apply-ready deltas** (the entailed fixes + the\ndirection-resolved edits), hand them to `unikit-gd-apply` **in one move** rather than\nrouting each conflict into an owner skill by hand. verify's handoff is **inline prose from\nthis session** — it writes **no** file (Phase 5): verify **prints the deltas as plain\nprose** (each citing its `target` + `zone`), then ends with a **bare `\u002Funikit-gd-apply`**.\nA bare `\u002Funikit-gd-apply` (no argument, no fence) reads the deltas from the **last verify\noutput in the session** — apply's no-arg session mode.\n\n**Hand off — recommend-only (never a `Skill` call).** Neither `unikit-gd-review` nor\n`unikit-gd-verify` carries `Skill` in `allowed-tools`; each **prints** the\n`\u002Funikit-gd-apply` recommendation for the user to run, and on Codex the auto-invoke nudge\nruns it — the two handoff tails are identical by contract.\n\n\u003C!-- unikit:agents codex -->\n### Auto-invoke the handoff — BLOCKING PRE-REQUISITE\n\nWhen this phase prints the `\u002Funikit-gd-apply` recommendation, do not ask the user to run it by\nhand: invoke `unikit-gd-apply` once, bare — it reads the printed deltas from this session.\nIf you have a `Skill` tool that accepts arguments, call it with that skill, in full and unchanged, then follow the skill.\nOtherwise Read `{{skills_dir}}\u002Funikit-gd-apply\u002FSKILL.md` in full, treat it as the instructions of this step and\ncarry them out here, in this session, now.\nThis is a single handoff: let `unikit-gd-apply` route the deltas to the owners (it closes with its own\n`apply-phase3` verify — no loop).\nDo not print a command for the user to run and do not stop.\nOnly if that file cannot be read, the printed command is the recommend-only fallback.\n\u003C!-- unikit:end -->\n\n- **apply-ready non-empty:** print the deltas as plain prose (each citing `target` +\n  `zone`), then the bare command on its own line —\n  ```\n  \u002Funikit-gd-apply\n  ```\n  `unikit-gd-apply` reads the printed deltas from the session (no file, no argument —\n  verify writes none), dispatches them to the owning zones, and closes with its own\n  `apply-phase3` verify pass. A single-zone set is bounced to its owner by apply's GATE 2.\n- **apply-ready empty** (only freshness + authoring \u002F research routes): **no apply\n  handoff** — list the Track-4 routes instead (`\u002Funikit-gd-system` \u002F `\u002Funikit-gd-flow` \u002F\n  `\u002Funikit-gd-content` \u002F `\u002Funikit-gd-spec`, or `\u002Funikit-gd-explore` for the ones needing a\n  design decision).\n\n## Final: Compact Report\n\nFollow the **Handoff Tail contract** (`gd-critique` → Handoff Engine): the runnable\ncommand is the **last block** on screen — the report and any route note go above it,\nnothing prints after it. Under the `apply-phase3` sentinel the handoff is\n**suppressed**, so there is no command tail (the loop-guard).\n\nPrint the compact report:\n\n```\nScope: \u003CSYS-slug | changed | all>\nResult: \u003CPASS | CONFLICTS FOUND (\u003Cn>)>\nChecks: facts · terms · IDs · dup-IDs · dangling · unregistered-fact · roster↔disk · map-freshness · Depends-3way · status · version · AC-presence · placeholder · core-floor — \u003Cpass\u002Ffail each>\nFlow checks (when flows exist): GOAL-ids · dangling-GOAL · flow-status\u002Fversion · flow-Depends-3way · mode↔structure · win\u002Flose↔terminal-GOAL · funnel-continuity · flow\u002Ffunnel-freshness — \u003Cpass\u002Ffail each>\nContent checks (when content_types exist): CT\u002FCU-ids · CU⊆CT · ref\u003C>-resolve · scale↔structure · belongs_to-3way · content-status\u002Fversion · content-map-freshness · RES\u002FTRACK\u002FKNOB · cross-axis SYS→CT — \u003Cpass\u002Ffail each>\nAffected (changed-scope): \u003Ck systems + flows + content types — Needs Review: …, Likely Stale: …>\nFreshness: \u003C## System Map [gen] stale — \u003Crows> (· partial n\u002Fm where deferred); owner re-renders | up to date>\nTracks: \u003Capply-ready: N · direction-interview: N · authoring\u002Fexplore: N>\nHandoff: \u003Cprinted deltas + bare \u002Funikit-gd-apply | apply-ready empty → routes only | in-apply (apply-phase3) → suppressed>\nReport: \u003Cprinted to console | none (clean PASS)>\n```\n\nThe actionable routes when apply-ready is empty live in the `Tracks` line above —\nread them there. No summary document beyond the conditional report file.\n\n**Then end with the handoff as the LAST block** — one command, nothing after it:\n\n- **apply-ready non-empty** → printed deltas (each citing `target` + `zone`), then\n  `🛠️ \u002Funikit-gd-apply` (bare — apply reads them from the session)\n- **apply-ready empty, a conflict needs a design call** → `🔎 \u002Funikit-gd-explore`\n- **apply-ready empty, authoring only** → the matching owner: `🔧 \u002Funikit-gd-system`\n  \u002F `\u002Funikit-gd-flow` \u002F `\u002Funikit-gd-content` \u002F `\u002Funikit-gd-spec`\n- **clean PASS** → `🔍 \u002Funikit-gd-review \u003Csystem>` (fresh session)\n- **in-apply (`apply-phase3`)** → suppressed — no command tail.\n\nNothing prints after the command — no recap, no description of what the called\nskill does next.\n\n## Ownership Boundaries\n\n- **Owns:** nothing on disk — `unikit-gd-verify` is **fully read-only**. It produces a\n  **console** conflict report + Affected table, and **prints** freshness \u002F coherence\n  recommendations; every fix is performed by `unikit-gd-apply` (the apply-ready deltas) or\n  the owning zones (authoring + the `[gen]`-map re-render on their next write — **B1**: the\n  writer of `GD-IDS` re-renders the affected maps).\n- **Read-only:** every design document, `GD-IDS.yaml`, and `GAME.md` (incl. all\n  `[gen]`-map blocks) — verify writes none of them.\n- **Not this skill:** quality judgment → `unikit-gd-review`; applying the apply-ready set\n  in one pass → `unikit-gd-apply` (the handoff is **recommend-only** — verify prints the\n  command, never invokes it); authoring → `unikit-gd-system` (systems) \u002F `unikit-gd-flow`\n  (flows) \u002F `unikit-gd-content` (content types) \u002F `unikit-gd-spec` (`GAME.md` + the roster);\n  a conflict needing a design decision → `unikit-gd-explore`.\n- **Never:** write **any** file (no report file, no `Affected (gd-verify):` line, no\n  `doc_status` bump, no `[gen]`-map re-render — verify carries no `Write`\u002F`Edit`\u002F`mkdir`);\n  use web research; guess where a grep settles it; change a `GD-IDS` value; delete or\n  renumber an ID; write the roster (route to `unikit-gd-spec`); carry `Skill`\u002F`Agent` in\n  `allowed-tools` or run `unikit-gd-apply` itself (the handoff is a printed prose\n  recommendation read by apply's no-arg session mode); offer the handoff or run the\n  direction interview when invoked as apply's Phase 3 (the `apply-phase3` loop-guard); read\n  the code workspace or project source.\n\n## Quick Reference\n\n```\n\u002Funikit-gd-verify SYS-combat        → check one system → triage conflicts (4 tracks) → handoff apply-ready to \u002Funikit-gd-apply\n\u002Funikit-gd-verify                   → unverified diff → changed-scope impact; else full check\n\u002Funikit-gd-verify what did that change affect  → changed-scope impact from git diff\n\u002Funikit-gd-verify all               → full registry + roster + map-freshness + Depends pass\n# internal: \u002Funikit-gd-apply passes apply-phase3 as its Phase 3 — verify suppresses the handoff\u002Finterview (loop-guard)\n```\n",{"name":5,"metadata":54,"description":7,"allowed-tools":58,"argument-hint":69,"user-invocable":70,"disable-model-invocation":50},{"author":55,"version":56,"category":57},"unikit","1.0","game-design",[59,60,61,62,63,64,65,66,67,68],"Read","Glob","Grep","Bash(ls *)","Bash(find *)","Bash(wc *)","Bash(date *)","Bash(git diff *)","Bash(git status *)","AskUserQuestion","[system name | SYS-slug | question]  (scope inferred; no flags)",true,"main","ae3c6dfffd26d9b45b9d96d71ba2c122c50b67ae","skills\u002Funikit-gd-verify",1,"https:\u002F\u002Fgithub.com\u002FNintendaDev\u002Funikit-ai","https:\u002F\u002Funikit.nintenda.dev","https:\u002F\u002Fgithub.com\u002FNintendaDev","Unity Developer. Building games and UniKit AI","2026-11-08 15:05:51",{"source":8,"skillName":5,"commands":81,"prompt":91,"zipAvailable":70},[82,85,88],{"tool":83,"command":84},"npx","npx skills add NintendaDev\u002Funikit-ai --skill unikit-gd-verify",{"tool":86,"command":87},"bunx","bunx skills add NintendaDev\u002Funikit-ai --skill unikit-gd-verify",{"tool":89,"command":90},"pnpm","pnpm dlx skills add NintendaDev\u002Funikit-ai --skill unikit-gd-verify","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002FNintendaDev\u002Funikit-ai\u002Fblob\u002Fmain\u002Fskills\u002Funikit-gd-verify\u002FSKILL.md",[93],{"path":94,"resourceType":95,"resourceTypeDesc":96,"sizeBytes":97,"sourceHtmlUrl":98},"references\u002Faxis-checks.md","REFERENCE","参考文档",9652,"https:\u002F\u002Fgithub.com\u002FNintendaDev\u002Funikit-ai\u002Fblob\u002Fmain\u002Fskills\u002Funikit-gd-verify\u002Freferences\u002Faxis-checks.md",[100,125,149,171,190,216],{"skillNo":101,"name":55,"nameZh":6,"description":102,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":103,"categories":104,"keywords":108,"publishedAt":49},"01M71BQ00EXGX51PPCDY7VG334","Initialize the UniKit framework in a project. Scans the current project to detect the engine and real tech stack, then generates the base framework documents that give AI agents context about the project — the resolved project description, the architecture doc, AGENTS.md, and the user-editable .unikit\u002Fconfig.yaml. This is the one-time, whole-project setup run before any other unikit skill. Use whenever the user wants to initialize, set up, or onboard the framework, e.g. \"initialize unikit\", \"init the framework\", \"set up unikit\", \"set up the project\", \"configure AI context\", \"scan my project and set it up\", \"bootstrap the project\". It also actualizes the config of a project already set up — say \"update the config\", \"add missing settings\", \"actualize configuration\", \"fix my config\". On a set-up project it offers the actions to choose from.","https:\u002F\u002Fgithub.com\u002FNintendaDev\u002Funikit-ai\u002Fblob\u002Fmain\u002Fskills\u002Funikit\u002FSKILL.md",[105],{"categoryNo":106,"categoryName":107,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000023","Skill与智能体开发",[55,109,110,111,112,42,113,114,115,116,35,117,118,119,34,120,121,122,123,124],"project","time","actions","fix","architecture","stack","run","update","write","config","edit","context","initialize","tech","scan","use",{"skillNo":126,"name":127,"nameZh":6,"description":128,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":129,"categories":130,"keywords":135,"publishedAt":49},"01M71BPRTMKW7FRAZZBN44NW5Q","unikit-verify","Verify a completed implementation against the plan in .unikit\u002Fcode\u002Fplans\u002F. Checks that every task was implemented, nothing was forgotten, the code compiles, the recorded test run still matches the code, and {{engine_name}} conventions are followed. Use after \u002Funikit-implement completes, or when the user says \"verify\", \"check the work\", \"did we miss anything\". For code review use \u002Funikit-review instead.","https:\u002F\u002Fgithub.com\u002FNintendaDev\u002Funikit-ai\u002Fblob\u002Fmain\u002Fskills\u002Funikit-verify\u002FSKILL.md",[131,134],{"categoryNo":132,"categoryName":133,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000007","代码审查",{"categoryNo":106,"categoryName":107,"taxonomyType":21,"taxonomyTypeDesc":22},[136,29,137,138,139,140,115,35,117,119,34,141,142,124,143,144,145,146,147,148],"unikit verify","powershell","code review","phase","plan","for","system","implement","check","engine","research","name","quality",{"skillNo":150,"name":151,"nameZh":6,"description":152,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":153,"categories":154,"keywords":155,"publishedAt":49},"01M71BPM35M5ETPA4E7EKQYRWD","unikit-todo","Manage the project's TODO list in .unikit\u002FTODO.md — capture work to remember for later, not to do right now. Use it to add a deferred item, mark a todo complete, or show the list. The point is to park tasks you don't want to act on in the moment but don't want to forget. Trigger on \"add a todo\", \"add this to the todo list\", \"put X on the todo list\", \"remind me to...\", \"don't forget to...\", \"note this for later\", \"we should do this later\", \"mark this todo done\", \"what's on the todo list\", \"what's left to do\". This is only for parking reminders — to actually plan or do the work now, use \u002Funikit-plan, \u002Funikit-implement, or \u002Funikit-execute.","https:\u002F\u002Fgithub.com\u002FNintendaDev\u002Funikit-ai\u002Fblob\u002Fmain\u002Fskills\u002Funikit-todo\u002FSKILL.md",[],[156,157,158,159,109,160,161,162,163,164,165,166,140,167,168,169,35,117,119,170],"unikit todo","todo","remind","show","todo list","only","now","you","done","tasks","work","me","reminders","later","act",{"skillNo":172,"name":173,"nameZh":6,"description":174,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":175,"categories":176,"keywords":178,"publishedAt":49},"01M71BPEQDVD7DTGFQBQJQ7JKY","unikit-skills-context","Customize how a built-in unikit skill behaves in this specific project by writing workflow overrides into its skill-context file. These are per-skill workflow rules (e.g. \"\u002Funikit-review should also flag TODO comments\", \"\u002Funikit-implement should run tests after each task\"), not coding conventions. Use when the user wants to change, customize, or override how a particular unikit skill works in this project — \"customize the review skill\", \"make \u002Funikit-fix always add logging here\", \"the implement skill should do X differently\", \"add a skill rule for \u002Funikit-commit\". Use \"validate\" to find stale overrides against updated base skills. For a general coding convention (not tied to one skill) use \u002Funikit-rules; to derive rules from past mistakes use \u002Funikit-evolve.","https:\u002F\u002Fgithub.com\u002FNintendaDev\u002Funikit-ai\u002Fblob\u002Fmain\u002Fskills\u002Funikit-skills-context\u002FSKILL.md",[177],{"categoryNo":106,"categoryName":107,"taxonomyType":21,"taxonomyTypeDesc":22},[179,120,109,112,180,181,182,183,184,185,186,187,157,38,188,115,189,35,117,119],"unikit skills context","coding conventions","writing","when","workflow","commit","review","general coding","text","how","past",{"skillNo":191,"name":192,"nameZh":6,"description":193,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":194,"categories":195,"keywords":203,"publishedAt":49},"01M71BP7K5KEGJV4ASRKPG1DM8","unikit-rules","Add a short, project-specific rule, convention, or override to .unikit\u002FRULES.md — the quick-capture inbox for this project's rules (common rules always load; topic files in .unikit\u002Frules\u002F load when the work matches), automatically loaded by \u002Funikit-implement (later promotable via \u002Funikit-memory migrate-rules). Works only with a rule typed as a prompt — it does NOT read files, folders, URLs, or PDFs. Cross-checks the knowledge base (RULES_INDEX.md) to avoid duplicating core\u002Fstack entries. Use for one-line conventions and corrections: \"add a rule\", \"remember this\", \"convention\", \"always do X\", \"never use Y\", \"from now on do Z\", or when the user corrects agent behavior and wants it remembered; also \"split the rules into topics\" (optimise), \"clean up the rules\" (prune), \"shorten RULES.md\" (compact), by keyword or in plain words. If the user points to a source (file, folder, URL, PDF, article, book) or wants to research\u002Fdocument framework usage, use \u002Funikit-memory; for architecture decisions use ARCHITECTURE.md.","https:\u002F\u002Fgithub.com\u002FNintendaDev\u002Funikit-ai\u002Fblob\u002Fmain\u002Fskills\u002Funikit-rules\u002FSKILL.md",[196,199,202],{"categoryNo":197,"categoryName":198,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000002","文档处理",{"categoryNo":200,"categoryName":201,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000021","资料检索与研究",{"categoryNo":106,"categoryName":107,"taxonomyType":21,"taxonomyTypeDesc":22},[204,205,206,207,109,208,209,210,211,212,113,213,187,214,114,169,35,117,119,215],"Rules","unikit rules","quick","PDF","clean","knowledge","files","URL","migrate","batch","knowledge base","prune",{"skillNo":217,"name":218,"nameZh":6,"description":219,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":220,"categories":221,"keywords":222,"publishedAt":49},"01M71BP02S49HHD4R5X6N12C9Q","unikit-rules-registry","Orchestrate the remote rules registry — the shared registry (often connected as a local folder or git repo) that the project's rules are published to and pulled from. Three modes, picked from the user's wording: create scaffolds a new local rules registry (\"create a local rules registry\", \"init a rules registry\"); update migrates\u002Fpromotes local knowledge-base rules from .unikit\u002Fmemory\u002F into the remote registry with automatic semver bumps (\"migrate local rules to the remote registry\", \"promote my rules to the registry\", \"push local rules\", \"publish local rules\", \"update the rules registry\"); sync pulls registry updates back into memory (\"sync the rules registry\", \"pull registry updates\"). Pass \"--module \u003Cid>\" to scope to one knowledge-base module. This skill ONLY orchestrates the CLI (`unikit-ai rules *`) — it never edits .unikit.json or .unikit\u002Fmemory\u002F sources directly.","https:\u002F\u002Fgithub.com\u002FNintendaDev\u002Funikit-ai\u002Fblob\u002Fmain\u002Fskills\u002Funikit-rules-registry\u002FSKILL.md",[],[31,204,223,224,109,225,209,226,212,227,116,35,117,34,228,229,230,231,232,233],"unikit rules registry","shared","local","remote","create","ai rules","automatic","semver","knowledge-base","as","three"]