Unikit gd verify
AI-Powered Code Toolkit for Game Engines
npx -y skills add NintendaDev/unikit-ai --skill unikit-gd-verifyAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 16 stars16 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
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/version, 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 /unikit-gd-apply in one pass. This is the mechanical pass — for a subjective "is this design good" quality critique use /unikit-gd-review.
SKILL.md
33.4 KB, as published. Nobody here has run it
Game Design — Consistency & Impact Verification
Answer "is the design consistent with itself?" — a mechanical, deterministic
check of every document against the facts registry, plus the changed-scope
impact of a recent edit. This is the design-side mirror of unikit-verify and a
CI-linter to unikit-gd-review's senior reviewer: cheap, binary, run after every
edit. A verify conflict cannot be declined (unlike a review finding) — it is
resolved.
unikit-gd-verify is fully read-only — it writes nothing (no report file, no
changelog line, no doc_status bump, no [gen]-map re-render). It detects and prints;
every fix is performed by unikit-gd-apply (the entailed deltas) or the owning zones
(authoring + the [gen]-map re-render on their next write — B1: the writer of GD-IDS
re-renders the affected maps).
Conflicts are precise, but their fix is not always predetermined, so each is sorted
into one of four tracks — freshness (print-only; the owner re-renders the
[gen] map on its next write), entailed → apply-ready (a named fix — incl. a
status/version header correction — handed to unikit-gd-apply), direction interview
(the user picks which fix, never whether), and authoring → owner / explore. The
apply-ready set hands off in one move — inline prose (verify writes no handoff
file, unlike unikit-gd-review's durable report), recommend-only. The handoff + interview
run only on a standalone /unikit-gd-verify; when verify is unikit-gd-apply's
closing Phase 3 (the apply-phase3 sentinel) they are suppressed, so
apply → verify → apply never loops. The triage engine is shared with unikit-gd-review
(gd-critique → Handoff Engine).
Verification is offline and reproducible: no web research, no expert judgment, no LLM guessing where a grep will do. The same inputs always yield the same result (idempotent).
Language Awareness — BLOCKING PRE-REQUISITE
BEFORE producing ANY output, silently read .unikit/system/LANGUAGE_RULES.md
and apply it to all output and the report (fall back to English if it is missing) —
including the rule to translate concepts, not transliterate jargon.
gd-principles → "Language" adds the game-design specifics: which IDs and stored
field values stay English. Do not announce the language setting.
Phase 0 — Bootstrap
Silently load — do not narrate:
.unikit/system/gamedesign/gd-principles.md(the core) — the facts registry / ID conventions (registry wins until the user resolves otherwise; never delete an ID — deprecate it) and the language rules. Plus, from the samegamedesign/folder, the shards this skill needs:gd-lifecycle.md(the status/version coherence spine),gd-flow-axis.md(the flow coherence contract —mode:↔ structure,GOAL → SYS/AC, Win/Lose ↔ terminal GOAL),gd-content-axis.md(the content coherence contract — CU ⊆ CT,ref<>resolution,scale↔ structure,belongs_to3-way, content-map freshness, RES/TRACK/KNOB, cross-axis SYS→CT staleness), andgd-critique.md(the severity rubric — a conflict is Critical/Major evidence). This skill applies them. If missing, warn (unikit-ai update) and continue with the conventions summarized here..unikit/gamedesign/GD-IDS.yaml— the single source of truth: pillars, systems, flows, entities, formulas, terms. Current values only. Schema guard (clean break — no automatic migration): it MUST beversion: 2. On a pre-v2version: 1registry, STOP and report that the design workspace is on the pre-v2 layout (the standalone markdown system-index was dropped; the roster now renders intoGAME.md## System Map [gen]) — there is no automatic migration; tell the user to upgrade via/unikit-gd-specbefore verifying..unikit/gamedesign/GAME.md— incl. its generated## System Map [gen],## Flow Map [gen], and## Funnel [gen]renders (the human-readable maps; the truth isGD-IDS), and its## Win / Lose Conditions(for the Win/Lose ↔ terminal GOAL check)..unikit/gamedesign/systems/*.mdand.unikit/gamedesign/flows/*.md— the system and flow documents checked against the registry.
One-way boundary: never read .unikit/code/, project source, or build
artifacts. Web research is forbidden here (gd-principles) — verification must
stay deterministic. The only git use is reading the design-workspace diff.
Phase 1 — Resolve Scope (no flags)
Loop-guard sentinel (first). If the argument is exactly apply-phase3 — the
reserved loop-guard sentinel (gd-critique → Handoff Engine), passed by
unikit-gd-apply as its closing Phase 3 — this run is the in-apply gate, not a
scope. Treat it as a bare invocation for scope purposes (derive changed-scope from the
git diff exactly as below), but set the in-apply flag: the standalone handoff offer
and the direction interview (Phase 4 Track 3 / Phase 6) are suppressed this run, so
apply → verify → apply cannot loop. A standalone /unikit-gd-verify (no sentinel)
leaves the flag off — the handoff is active.
Scope is a function of context:
- The argument names a system, flow or content type → check that document and
its registry facts (a
FLOW-<slug>runs the flow checks, aCT-<slug>the content checks below). - There is an unverified diff under
.unikit/gamedesign/(git diff/git statusshows changed design docs), or the prompt asks "what did this change affect" → changed-scope pass (Phase 3). - Otherwise → full check of every system, every flow, every content type, and the whole registry.
Announce the resolved scope in one line.
Phase 2 — Mechanical Checks (grep-first)
Run every check deterministically; each mismatch is a CONFLICT with a citation:
| Check | Method | Conflict when |
|---|---|---|
| Facts | grep each GD-IDS entity/formula value across the docs — match the value on word boundaries, not as a bare substring | a document states a number/name that disagrees with the registry |
| 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 |
| ID validity | scan every SYS-/ENT-/FORM-/AC-/PIL-/FLOW-/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 |
| Duplicate IDs | group every declared id by value | the same id is declared for two different things |
| 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 |
| Unregistered cross-doc fact | grep FORM-/ENT- ids that surface in two or more documents | a fact crosses a document boundary yet has no GD-IDS entry |
| Roster ↔ disk | compare GD-IDS systems ids to the systems/*.md files on disk | a skeleton-or-later system has no file, or a systems/*.md file has no GD-IDS entry (→ route to unikit-gd-spec to register it — verify never writes the roster) |
| 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 |
| 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 |
| 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 |
| 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 / a not-started system has one |
| AC presence | for a detailed-or-later system, section H is non-empty and every AC-<sys>-N id is unique | a detailed+ system has an empty H, or repeats an AC-<sys>-N — gaps in the numbering are not a conflict (numbering is stable after an AC is removed) |
| Placeholder leak | grep [To be designed] inside detailed-or-later documents (a <!-- deferred --> marker is intentional — never a leak) | a detailed+ document still carries a skeleton [To be designed] placeholder |
| Core-floor coherence | for a detailed document, check that no core section carries <!-- deferred --> — the core-set per zone (gd-lifecycle: system A/B/C/D/H · flow A/B · content A/B/C) | 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) |
The registry is authoritative: when a document disagrees with GD-IDS, the
registry wins until the user resolves it the other way (gd-principles).
Map freshness — print-only, not a conflict. The ## System Map [gen] block in
GAME.md is a deterministic render of GD-IDS systems (gd-lifecycle →
Lifecycle & Status), so a disagreement is a freshness issue, never a coherence
conflict to resolve. On any of —
- a
GD-IDSsystem missing from the map (no row); - a phantom row in the map with no matching
GD-IDSsystem; - a row whose Status / Ver / Depends differs from
GD-IDS,
— print a freshness notice naming the stale rows (## System Map [gen] stale — <rows>; owner re-renders on next write). verify is read-only: it does not
re-render the map. The owning zone re-renders on its next write — B1: the writer of
GD-IDS (unikit-gd-spec for the System Map, unikit-gd-flow / unikit-gd-content for
theirs) re-renders the affected [gen] block with the same deterministic render (group
by category, sort by tier then design order, display-precedence on
deprecated/implemented). A systems/*.md file with no GD-IDS entry (the
Roster ↔ disk check) is likewise routed: the roster is unikit-gd-spec's to write,
so verify routes the user to /unikit-gd-spec to register the system.
Deferred markers, the · partial (n/m) render, and the self-check (all three maps).
A <!-- deferred --> marker is an intentional omission (gd-lifecycle — a section
the author chose to skip at this depth), never a placeholder leak. Its only
mechanical consequence at verify time is the render: a detailed+ document carrying
≥1 <!-- deferred --> should show · partial (n/m) appended to its row Status in the
relevant ## *Map [gen], where n = the count of deferred non-core sections (those
carrying the marker) and m = the document's total deferrable (non-core) sections
(gd-lifecycle → the canonical render format + per-zone core-set). This applies
identically to the System, Flow, and Content maps; like all freshness it is
print-only, not a coherence conflict — verify does not re-render (the owner
appends the suffix on its next re-render), and the status value itself stays the read-only
enum (· partial is a render annotation, not a doc_status, and is not part of the
two-place status/version coherence). Self-check (marker ⟺ render): every document with
≥1 <!-- deferred --> must render · partial (n/m) in its map row, and every
· partial suffix in a map must correspond to a document that actually carries the
marker — a mismatch in either direction is a freshness discrepancy, printed (the
owner fixes it on re-render). Annotate the freshness notice with the count, e.g.
## System Map [gen] stale (partial 2/5 on SYS-combat); owner re-renders.
Scope & carve-outs (Status / Version / AC / Placeholder). These four checks
read the system spine only — the header ↔ GD-IDS pair of a systems/*.md
document (the ## System Map [gen] render is not a coherence surface — its
agreement is handled by Map freshness above):
- Lifecycle-enum scope.
GAME.md(drafted | approved) andCONCEPT.md(exploring | drafted | approved) keep their own lifecycle enums — aStatus: approvedthere is correct and is never a status conflict. - Display precedence. A system with
status: deprecatedlegitimately showsdeprecatedin the## System Map [gen]Status over its underlyingdoc_status; the read-onlyimplementedvalue (a code-set display overlay) behaves the same. Both are display overlays in the render — never part of the two-place header ↔GD-IDSdoc_statuscomparison. The companionGD-IDSimplemented_versionfield (also code-set, byunikit-verifyon all-AC-met) is a code-owned field — not adoc_statusand not aversion— so it never participates in Status or Version coherence and is never flagged as drift. - Non-id metadata (
research:). TheGD-IDSresearch:field — a path pointer to the explore research that seeded an artifact (written byunikit-gd-specadd-system on a system row, byunikit-gd-flowon a flowflows[]row, and byunikit-gd-contenton a content typecontent_types[]row) — is non-semantic metadata, not a registry id and not adoc_status/version. It is excluded from status/version coherence on all three axes, and the id-resolving checks pass it over by construction: Dangling references only resolves id tokens (SYS-/ENT-/FORM-/AC-/PIL-/FLOW-/GOAL-/CT-/CU-), and Unregistered cross-doc fact only grepsFORM-/ENT-ids — a folder path matches neither — so no special-case logic is needed.
Axis-aware checks — flow + content (load on demand)
Beyond the system checks above, the registry may carry flows and content
types, each with its own check family — the mirror of the system checks plus the
axis-specific ones. When GD-IDS flows and/or content_types is non-empty, load
the matching family from {{skills_dir}}/{{self_name}}/references/axis-checks.md and run
it; an empty flows: [] / content_types: [] (or no key) → skip that family
silently (not a conflict). The registry-wins rule and the freshness-vs-conflict
distinction apply exactly as above — freshness is print-only (the owner re-renders).
| Registry has | Family (in references/axis-checks.md) — coverage |
|---|---|
flows non-empty | the flow family: GOAL-id validity, dangling goal-targets, flow status/version 2-place, flow Depends 3-way, wiring-mode-vs-structure, win/lose-vs-terminal-goal, funnel continuity, flow/funnel map freshness (Realized cross-axis derived) |
content_types non-empty | the content family: CT/CU-id validity, CU-fields-subset-CT, ref-target resolution, scale-vs-structure, belongs-to 3-way, content status/version 2-place, content map freshness, RES/TRACK/KNOB fact coherence |
The cross-axis impact of a system edit on dependent flows / content types is the reverse-edge walk in Phase 3 (it stays here — it is impact analysis, not a per-axis check).
Phase 3 — Changed-Scope Impact (when a diff is unverified)
Compute the blast radius of a recent edit:
-
Changed set =
git diff HEAD(andgit status) restricted to.unikit/gamedesign/→ the systems whose documents changed on disk. (There is no stored "pending re-verify" state to re-scan — status records readiness only; a change is carried by the git diff + version, not by adoc_status.) -
Walk
GD-IDSdepends_onedges (rendered in the## System MapDepends column) to the transitive closure of systems that depend (directly or indirectly) on a changed one. -
Classify each affected system into an Affected table:
System / Flow Relation Verdict SYS-enemy-ai depends on SYS-combat (changed) Needs Review SYS-economy soft dep, no touched interface Still Valid SYS-loot uses a removed AC Likely Stale FLOW-first-session exercises SYS-combat (changed) via GOAL→AC Needs Review Verdicts: Still Valid / Needs Review / Likely Stale.
-
Print the impact (verify writes nothing):
- Print the Affected table to the console — the changed system + every dependent
with its verdict. verify does not write the
Affected (gd-verify):line into section K (it is read-only); the owner records that line on its next authoring touch if it acts on the impact (gd-authoring→ Delta Discipline). - For each affected dependent with a
Needs Review/Likely Staleverdict, recommend a re-author pass to its owner — verify does not bump anydoc_status(status records readiness only; a re-author bumpsVer, not status). - Idempotent: re-running on the same diff yields the same Affected table — there is no state to mutate.
- Print the Affected table to the console — the changed system + every dependent
with its verdict. verify does not write the
Cross-axis impact (system → flow, one-way). A system edit can stale a flow that
exercises it (through GOAL → SYS / GOAL → AC) — gd-flow-axis → Flow Axis. Extend
the pass across the axis (skip when flows: []):
- Reverse-edge walk: for each changed system, find every flow whose
flows[].depends_onincludes it, or whosegoals[].targetsreference it (GOAL → SYS/GOAL → AC). Those flows join the Affected table as flow rows (Relation:exercises SYS-x (changed)), with the same Still Valid / Needs Review / Likely Stale verdicts (a flow using a removedACis Likely Stale). The reverse does not hold — editing a flow never stales a system. - Print impact (dependent flow): list affected flows in the printed Affected table.
For each
Needs Review/Likely Staledependent flow, recommend a re-author pass tounikit-gd-flow— verify writes nothing (nodoc_statusbump, noFLOW.mdheader write, no section-F note, no## Flow Map [gen]re-render). Acting on the recommendation (theVer+1+ changelog touch) is the owner's call.
Cross-axis impact (system → content type, one-way). A system edit can stale a
content type that feeds it (through belongs_to / a ref<SYS> field) —
gd-content-axis → Content Axis. Extend the pass across the axis (skip when
content_types: []):
- Reverse-edge walk: for each changed system, find every content type whose
content_types[].belongs_tonames it, or whoseCT.fieldscarry aref<SYS>to it. Those types join the Affected table as content rows (Relation:feeds SYS-x (changed)), with the same Still Valid / Needs Review / Likely Stale verdicts (a type whose consuming system removed a relied-on contract is Likely Stale). The reverse does not hold — editing a content type never stales a system. - Print impact (dependent CT): list affected types in the printed Affected table.
For each
Needs Review/Likely Staledependent type, recommend a re-author pass tounikit-gd-content— verify writes nothing (nodoc_statusbump, noCONTENT-TYPE.mdheader write, no section-F note, no## Content Map [gen]re-render). Acting on the recommendation is the owner's call.
Phase 4 — Triage Conflicts (4 tracks)
A verify conflict is precise (the grep found a real disagreement) but its fix is
not always predetermined, and it can never be declined — only resolved or routed.
Using the shared handoff engine (gd-critique → Handoff Engine), sort every conflict
into one of four tracks:
-
Freshness — print-only — verify is read-only, so it prints, never fixes. The
[gen]-map freshness (Phase 2) is announced as a stale-rows notice; the owning zone re-renders on its next write (B1). A status / version header ↔GD-IDSdisagreement (whereGD-IDSis the machine truth) is not healed here — its correction (set the header toGD-IDS) is a clean entailed fix and goes to Track 2. -
Entailed → apply-ready — the conflict's fix passes the silent ENTAILED criterion (one concrete target · the correct value already authoritative in
GD-IDS· exactly one local fix · no external knowledge) but needs an owner write verify cannot make (verify writes nothing): a status / version header to correct toGD-IDS, a duplicate id to renumber, a terminology drift to swap to the canonical term, a dangling reference to repoint. Put it in the apply-ready set — the named fix handed tounikit-gd-apply(Phase 6) as a prose delta, authored by the owner, not here. -
Direction fork → interview — the conflict admits more than one valid direction: a value conflict (the document or the registry could each be right), a dangling
GOAL → SYS/ACfixable three ways across three zones, a roster ↔ disk mismatch (register vs delete), an unregistered cross-docFORM-/ENT-(register vs remove). The user picks the direction — never whether to act (decline-vs-direction,gd-critique). The interview is direction-only and batched (AskUserQuestion, ≤ 4 per call); it is suppressed under the in-apply flag (Phase 1 sentinel):AskUserQuestion: CONFLICT — <doc/section> vs GD-IDS: <the disagreement>. Which direction? Options: 1. Fix as A — e.g. registry is right → correct the document 2. Fix as B — e.g. document is right → update GD-IDS to <X> (with approval; record it) 3. This is authoring / needs a decision → route to the owner or /unikit-gd-exploreThere is no "Decline" — a consistency conflict is a fact, not an opinion. A chosen A/B that is a clean local edit becomes an apply-ready prose delta (it joins Track 2); option 3 routes it to Track 4.
-
Authoring → owner / explore — the conflict needs authoring, not a mechanical fix: an empty section H / missing AC, a placeholder leak in a
detailed+ document, a core section deferred past the floor. It is neither entailed nor a direction pick — route it to the owning zone (unikit-gd-system/unikit-gd-flow/unikit-gd-content/unikit-gd-spec), or to/unikit-gd-explorewhen it needs a design decision first.
verify never writes the registry — it is read-only; the registry-wins rule still governs
the direction of a fix (apply / the owner sets the document to match GD-IDS), and a
deprecated ID is never deleted. Log every conflict + its track + resolution in the printed
report (Phase 5). The coherence-vs-presence split still holds underneath: a coherence
conflict (status / version / Depends 3-way, where GD-IDS is authoritative) is now
Track 2 (entailed → apply-ready — the header corrected to GD-IDS), and the
[gen]-map freshness is Track 1 (print-only); a presence conflict (empty H,
duplicate id, placeholder leak, unregistered cross-doc fact) is Track 2 (entailed →
apply-ready) or Track 4 (authoring), resolved by editing the document, never the registry.
Phase 5 — Report (printed to the console)
verify is read-only — the report is printed to the console, never written to a file.
A clean full PASS is a single chat line. On CONFLICTS FOUND or a changed-scope pass,
print the full report block:
# Verify: <scope> — <YYYY-MM-DD>
> Result: <PASS | CONFLICTS FOUND> · Scope: <SYS-slug | changed | all>
## Conflicts
| Severity | Document / Section | Check | Conflict (evidence) | Recommended fix |
|----------|--------------------|-------|---------------------|-----------------|
## Affected (changed-scope only)
| System / Flow | Relation | Verdict |
|---------------|----------|---------|
## Freshness
<[gen]-map rows stale → owner re-renders on next write (B1), or "up to date">
This is printed, not a file — a verify pass is ephemeral and cheap to re-run (the
single-session verify → apply pair is by design: a /clear between them is fixed by
re-running verify). The asymmetry with unikit-gd-review (which leaves a durable
two-bucket report) is intentional. When the same conflict recurs across systems, record it
as a gamedesign library rule via /unikit-memory --module gamedesign — durable domain
knowledge, not re-discovered each pass.
Phase 6 — Handoff (standalone only; inline prose, recommend-only)
LOOP-GUARD. This phase runs only on a standalone
/unikit-gd-verify. Under the in-apply flag (theapply-phase3sentinel resolved in Phase 1), skip this phase entirely — verify prints freshness (Track 1) and the report (Phase 5), but never offers a handoff back tounikit-gd-apply. That is the silent gate that stopsapply → verify → applyfrom looping.
When Tracks 2 and 3 produced apply-ready deltas (the entailed fixes + the
direction-resolved edits), hand them to unikit-gd-apply in one move rather than
routing each conflict into an owner skill by hand. verify's handoff is inline prose from
this session — it writes no file (Phase 5): verify prints the deltas as plain
prose (each citing its target + zone), then ends with a bare /unikit-gd-apply.
A bare /unikit-gd-apply (no argument, no fence) reads the deltas from the last verify
output in the session — apply's no-arg session mode.
Hand off — recommend-only (never a Skill call). Neither unikit-gd-review nor
unikit-gd-verify carries Skill in allowed-tools; each prints the
/unikit-gd-apply recommendation for the user to run, and on Codex the auto-invoke nudge
runs it — the two handoff tails are identical by contract.
Auto-invoke the handoff — BLOCKING PRE-REQUISITE
When this phase prints the /unikit-gd-apply recommendation, automatically invoke it
($unikit-gd-apply, bare — it reads the printed deltas from this session) rather than
asking the user to run it by hand — the printed command is the recommend-only fallback for
agents without auto-invocation. This is a single handoff: invoke unikit-gd-apply once and
let it route the deltas to the owners (it closes with its own apply-phase3 verify — no
loop).
- apply-ready non-empty: print the deltas as plain prose (each citing
target+zone), then the bare command on its own line —/unikit-gd-applyunikit-gd-applyreads the printed deltas from the session (no file, no argument — verify writes none), dispatches them to the owning zones, and closes with its ownapply-phase3verify pass. A single-zone set is bounced to its owner by apply's GATE 2. - apply-ready empty (only freshness + authoring / research routes): no apply
handoff — list the Track-4 routes instead (
/unikit-gd-system//unikit-gd-flow//unikit-gd-content//unikit-gd-spec, or/unikit-gd-explorefor the ones needing a design decision).
Final: Compact Report
Follow the Handoff Tail contract (gd-critique → Handoff Engine): the runnable
command is the last block on screen — the report and any route note go above it,
nothing prints after it. Under the apply-phase3 sentinel the handoff is
suppressed, so there is no command tail (the loop-guard).
Print the compact report:
Scope: <SYS-slug | changed | all>
Result: <PASS | CONFLICTS FOUND (<n>)>
Checks: facts · terms · IDs · dup-IDs · dangling · unregistered-fact · roster↔disk · map-freshness · Depends-3way · status · version · AC-presence · placeholder · core-floor — <pass/fail each>
Flow checks (when flows exist): GOAL-ids · dangling-GOAL · flow-status/version · flow-Depends-3way · mode↔structure · win/lose↔terminal-GOAL · funnel-continuity · flow/funnel-freshness — <pass/fail each>
Content checks (when content_types exist): CT/CU-ids · CU⊆CT · ref<>-resolve · scale↔structure · belongs_to-3way · content-status/version · content-map-freshness · RES/TRACK/KNOB · cross-axis SYS→CT — <pass/fail each>
Affected (changed-scope): <k systems + flows + content types — Needs Review: …, Likely Stale: …>
Freshness: <## System Map [gen] stale — <rows> (· partial n/m where deferred); owner re-renders | up to date>
Tracks: <apply-ready: N · direction-interview: N · authoring/explore: N>
Handoff: <printed deltas + bare /unikit-gd-apply | apply-ready empty → routes only | in-apply (apply-phase3) → suppressed>
Report: <printed to console | none (clean PASS)>
The actionable routes when apply-ready is empty live in the Tracks line above —
read them there. No summary document beyond the conditional report file.
Then end with the handoff as the LAST block — one command, nothing after it:
- apply-ready non-empty → printed deltas (each citing
target+zone), then🛠️ /unikit-gd-apply(bare — apply reads them from the session) - apply-ready empty, a conflict needs a design call →
🔎 /unikit-gd-explore - apply-ready empty, authoring only → the matching owner:
🔧 /unikit-gd-system//unikit-gd-flow//unikit-gd-content//unikit-gd-spec - clean PASS →
🔍 /unikit-gd-review <system>(fresh session) - in-apply (
apply-phase3) → suppressed — no command tail.
Nothing prints after the command — no recap, no description of what the called skill does next.
Ownership Boundaries
- Owns: nothing on disk —
unikit-gd-verifyis fully read-only. It produces a console conflict report + Affected table, and prints freshness / coherence recommendations; every fix is performed byunikit-gd-apply(the apply-ready deltas) or the owning zones (authoring + the[gen]-map re-render on their next write — B1: the writer ofGD-IDSre-renders the affected maps). - Read-only: every design document,
GD-IDS.yaml, andGAME.md(incl. all[gen]-map blocks) — verify writes none of them. - Not this skill: quality judgment →
unikit-gd-review; applying the apply-ready set in one pass →unikit-gd-apply(the handoff is recommend-only — verify prints the command, never invokes it); authoring →unikit-gd-system(systems) /unikit-gd-flow(flows) /unikit-gd-content(content types) /unikit-gd-spec(GAME.md+ the roster); a conflict needing a design decision →unikit-gd-explore. - Never: write any file (no report file, no
Affected (gd-verify):line, nodoc_statusbump, no[gen]-map re-render — verify carries noWrite/Edit/mkdir); use web research; guess where a grep settles it; change aGD-IDSvalue; delete or renumber an ID; write the roster (route tounikit-gd-spec); carrySkill/Agentinallowed-toolsor invokeunikit-gd-applyitself (the handoff is a printed prose recommendation read by apply's no-arg session mode); offer the handoff or run the direction interview when invoked as apply's Phase 3 (theapply-phase3loop-guard); read the code workspace or project source.
Quick Reference
/unikit-gd-verify SYS-combat → check one system → triage conflicts (4 tracks) → handoff apply-ready to /unikit-gd-apply
/unikit-gd-verify → unverified diff → changed-scope impact; else full check
/unikit-gd-verify what did that change affect → changed-scope impact from git diff
/unikit-gd-verify all → full registry + roster + map-freshness + Depends pass
# internal: /unikit-gd-apply passes apply-phase3 as its Phase 3 — verify suppresses the handoff/interview (loop-guard)