AGENT SKILL

state-model

Orchestrator — author the flow-anchored logical domain model (entities, state machines, events/commands, read models, policies, logical contracts) from an approved user-flow map, running one domain-modeling framework per session, before UX variation work

License 许可
MIT
最近更新
2026-11-10
Stars
★ 1
Forks
0

01 前言 Front Matter

name
state-model
type
research
version
v0.1
invocation
orchestrator
description
Orchestrator — author the flow-anchored logical domain model (entities, state machines, events/commands, read models, policies, logical contracts) from an approved user-flow map, running one domain-modeling framework per session, before UX variation work
visual_tier
visual
argument-hint
[optional: topic, user-flow, or feature] [--synthesize] [--no-chunk]
context_intake
scoped

03 SKILL.md 正文

Pack Availability Guard

Before telling the user to run a skill from another project-local pack, check .agents/project.json.enabled_packs. If the target pack is not enabled, recommend npx skillpacks install <pack> from the project shell, instead of the target skill. Only the currently running skill and skills verified available in the active session or project-local install state are directly recommendable. For unavailable pack skills, recommend npx skillpacks install <pack-or-skill>; for unavailable base skills, recommend npx skillpacks init before the skill.

State Model — Orchestrator

Invoke as /state-model.

This is an orchestrator skill that authors the logical domain/state/logic model anchored to an approved user-flow map, running one domain-modeling framework per session and synthesizing their outputs into a single canonical domain model plus a model-tree manifest. It sits after /user-flow-map, before /ux-variations in the product-design prototype pipeline.

The model it produces is a property of the flow, not of any one UI presentation: UX variations re-skin the same underlying entities, actions, and states, so authoring the logical model once gives /ux-variations and /ui-interview a real substrate to present, and turns /spec-interview into "harden this model to production" rather than "invent it."

Logical only. This skill owns entities, value objects, aggregates, state machines, events, commands, read models, policies, and logical command/query contracts (request/response/error shapes). It does not own physical concerns — storage engines, real endpoints/URLs, authentication, migrations, indexes, or deployment. Those stay owned by /spec-interview downstream. See Constraints.

Follow docs/prototype-session-loop-convention.md for prototype-phase routing, state storage, approval boundaries, and task classification. This skill is a prototype-phase orchestrator: its live loop cursor is filesystem existence of per-framework intermediates, not a Pattern A selected-framework run manifest. It does not use tasks/todo.md for framework progress.

Architecture — Orthogonal Sibling To The Flow Tree

state-model is an orthogonal sibling of the flow tree, not a stage inside it:

  • The flow-tree route array stays a locked six-step sequence (user-flow-map, ux-variations, ui-interview, prototype, consolidate-variations, spec-interview). This skill does not appear in or modify that array. Ordering is enforced by next-step recommendations, not the route enum.
  • This skill owns its own design/model-tree-{topic}.yaml manifest, a domain-shaped sibling to design/flow-tree-{topic}.yaml.
  • On synthesis it writes an optional top-level model_tree_ref pointer into the flow-tree manifest so downstream skills can discover the model. The pointer is backward-compatible and never required.
  • Flow bindings are authoritative in the model-tree only. Every model element records flow_bindings[] pointing at flow-tree nodes. These bindings are never duplicated into the flow tree, to prevent drift.

Prerequisites

  • Hard: an approved design/flow-tree-{topic}.yaml (or design/{slug}/flow-tree-{topic}.yaml) and its companion design/user-flow-{topic}.md user-flow doc must exist. If they do not, stop and recommend /user-flow-map [topic] first — the logical model anchors to named flow nodes, so there must be a flow to anchor to.
  • Soft: read these if they exist:
    • research/positioning.md, research/journey-map.md, research/icp.md — domain language and lifecycle context.
    • Existing design/ux-variations-*.md, design/ui-requirements-*.md — only as supplementary domain evidence; the model must not encode any single UI presentation.
    • research/glossary.md (or scoped) — existing ubiquitous-language terms.

Execution Model — Prototype Session Loop (intra-skill substep chunking)

This orchestrator runs as a prototype-phase intra-skill substep loop per docs/prototype-session-loop-convention.md (Intra-Skill Substep Chunking + Shared Context Brief). Each invocation starts cold, resolves its state from the filesystem, runs one heavy phase, and stops. The user advances the loop by clearing context and re-invoking /state-model with the same topic argument.

Three-tier state, exactly as the convention defines it:

Tier Store Role
Machine cursor design/model-tree-{topic}.yaml (committed, post-approval synthesized manifest) Authoritative model state. Written only at synthesis, never as a live run-manifest.
Shared context brief design/{slug}/_working/state-model-{topic}-brief.md (flat: design/_working/...) Pure context, no step list: confirmed scope/assumptions, the flow nodes in play, the planned framework set + run order with each framework's thesis, ubiquitous-language seeds, carried cross-framework decisions.
Per-framework intermediates design/{slug}/state-model-{topic}/{framework}.md (flat: design/state-model-{topic}/...) One framework's logical findings each. Their existence IS the cursor — the next pending framework is the first planned framework whose intermediate file does not yet exist.

pending = planned-frameworks − existing-intermediates. The brief carries no status field and is never a rival ledger. There is no design/flow-tree.schema.json change for the cursor and no tasks/todo.md use.

Per-session shape

setup session       §0 scope → §1 run-order detection → §2 load flow context
                    → present the Domain Modeling Scope Checkpoint inline → on confirm,
                      write the brief (pure context) → STOP
   → framework       read brief + scan which {framework}.md intermediates exist
   sessions          → run the first pending framework inline → write its intermediate
   (one per fw)      → append cross-framework facts to the brief → STOP / re-invoke
      → assemble+approve session   when all planned intermediates exist (or --synthesize):
                                   §4 assemble domain-model-{topic}.md + model-tree-{topic}.yaml
                                   → ONE alignment-page review → confirmed gate
                                   → on approval write canonical doc + manifest + flow-tree
                                     model_tree_ref back-pointer + archive brief/intermediates

State resolution (resolve the first match)

State Detected when Heavy phase this session Emits / stops with
A — done canonical design/domain-model-{topic}.md and design/model-tree-{topic}.yaml exist — done; emit next-skill route (§5)
B — synthesize brief exists, all planned framework intermediates exist, no canonical domain model (also forced by --synthesize) synthesis + assemble+approve (§4) the single domain-model alignment page
C — run framework brief exists, ≥1 planned framework pending run next pending framework inline (§3) framework intermediate written, re-invoke handoff
E — setup no brief and no canonical (cold start, after the hard prerequisite is satisfied) scope → run-order detection → load context → Scope Checkpoint → write brief (§0–§2) Domain Modeling Scope Checkpoint, then brief written

Fold for small domains. When run-order detection plans fewer than 3 frameworks (or --no-chunk is passed), do not spend fresh-context round-trips per framework: run setup, all framework passes, and synthesis straight through in one session, writing no brief and no intermediates, exactly as a single pass through §0–§4. Chunk only when the planned framework count is ≥ 3.

Approval: exactly one final gate. The framework sessions are pre-approval _working/-band drafting — they write intermediates, not canonical artifacts, so no checkpoint inside them authorizes a canonical write. The Domain Modeling Scope Checkpoint (setup) and any per-framework coverage checkpoints are confirmations, not approvals. The single binding alignment-page review → confirmed gate is in the assemble+approve session and approves the whole model at once.


Process

0. Product-Path Scope Resolution

Resolve scope by product path before using code or app structure as a hint:

  1. If $ARGUMENTS names a non-archived research/{slug}/ directory or a product-path ID whose scope_path points there, use that path. Treat {slug} as the product/app name, not the ICP, audience, or segment label.
  2. If $ARGUMENTS names only research/_archive/{slug}/ or a manifest entry with status: archived or legacy status: abandoned, stop and warn that the path is archived; do not write or update scoped outputs there.
  3. Read research/.progress.yaml when present. Normalize legacy active_path to active_paths on read and write back active_paths on manifest updates. Treat legacy abandoned as archived; exclude archived, abandoned, deferred, revisit_candidate, promoted, and any scope_path under research/_archive/ from active target selection.
  4. If active product paths exist in the manifest, use those paths. If multiple active paths exist, ask which one to target.
  5. If no active manifest target exists, list non-archived product directories under research/, excluding research/_archive/ and dot directories. Auto-select only when exactly one exists; ask when multiple exist.
  6. If no product directories exist, use flat single-product mode.
  7. Detect monorepo/app/package structure only as a secondary hint.

When product path {slug} is active, read and write pre-prototype design artifacts under design/{slug}/ and treat top-level design/*.md files as flat-mode documents. The topic slug derives from the flow-tree topic being modeled.

1. Run-Order Detection

Inspect the approved flow tree and user-flow doc to plan which of the six domain-modeling frameworks run, and in what order. All six are available; the engagement determines the set and sequence the way journey-map detects mode.

The six frameworks:

  • event-modeling — timeline of events/commands/read-models across the flow; best first when the flow is workflow-heavy and temporal.
  • event-storming — big-picture domain-event discovery; best first when the domain is novel or vocabulary is unsettled.
  • domain-model — DDD entities, value objects, aggregates, and aggregate boundaries.
  • state-machine — statecharts for each stateful subject (states, transitions, events, guards, actions).
  • data-model — logical ERD: entities, attributes, relationships, cardinalities (logical, never physical storage).
  • contract-map — logical command/query contracts: request/response/error shapes per action (logical I/O, never real endpoints).

Detection signals (read from the flow tree and user-flow doc):

  • Domain novelty / unsettled vocabulary → lead with event-storming, then domain-model.
  • Workflow/temporal complexity (many ordered steps, handoffs, async waits) → lead with event-modeling.
  • High stateful-entity count (many statuses, lifecycles, approval/retry transitions) → ensure state-machine runs and weight it early.
  • High entity/relationship count (rich data with many associations) → ensure data-model runs.
  • Many distinct user/system actions per screen → ensure contract-map runs.
  • Simple domains (few entities, one or two flows, settled vocabulary) → plan a reduced set (e.g. domain-model + state-machine, or add data-model) and fold per the Execution Model.

Always include domain-model (the DDD spine). Order the rest by the dominant signal; data-model and contract-map typically run after the conceptual frameworks so they can reference settled entities and states. Record the planned set, order, and the one-line rationale per framework.

2. Load Flow Context + Domain Modeling Scope Checkpoint (setup session)

  • Read the approved design/{flow-tree, user-flow}-{topic} artifacts: flow nodes, screens/routes, actions, decisions, branches, states, failure paths, handoffs.
  • Read soft prerequisites (positioning, journey, glossary) for domain language.
  • Identify the candidate ubiquitous-language seeds the flow already implies.

Present a Domain Modeling Scope Checkpoint inline as the final message text of its own turn (never only as mid-turn text in a turn that ends with a tool call). Cover:

  • The flow nodes in play and the topic being modeled.
  • The detected framework set + run order, with the one-line rationale per framework.
  • Confirmed assumptions about domain boundaries and explicit non-goals (especially the logical-only boundary — no storage/endpoints/auth/migrations).
  • Candidate ubiquitous-language seeds.

Ask the user to confirm, correct, or adjust the framework set/order in the next turn. This checkpoint is a confirmation, not a final approval. On confirmation, write the shared context brief to design/{slug}/_working/state-model-{topic}-brief.md (flat: design/_working/state-model-{topic}-brief.md) containing pure context only — confirmed scope/assumptions, the flow nodes in play, the planned framework set + order with each framework's thesis, ubiquitous-language seeds, and carried decisions — with no step list and no status field. Then STOP and emit the Terminal handoff format from docs/prototype-session-loop-convention.md: state the brief was written, name the first pending framework to run in plain English (what that framework models, never only its internal {framework-slug}), and give the exact resolved next command with {topic} filled in, e.g. /state-model alignment-page-review, so the first framework runs in its own cold spec session (§3). (Unless folding per the Execution Model, in which case continue directly to §3.)

3. Run Next Pending Framework (framework session)

Each framework session resolves its work purely from the filesystem: read the brief, scan which {framework}.md intermediates already exist under design/{slug}/state-model-{topic}/, and run the first planned framework whose intermediate does not yet exist.

Run that one framework inline against the flow context in the brief, producing logical findings only, and write them to design/{slug}/state-model-{topic}/{framework}.md. Each intermediate must, where the framework applies:

  • Name the model elements it introduces or refines (entities/value-objects/aggregates, states/transitions, events, commands, read models, policies, contracts).
  • Record each element's flow_bindings — which flow node(s) it reads, writes, triggers, displays, or transitions — using flow-tree node references.
  • Map state-machine states to UI states (maps_to_ui_state) where a flow state exists, so UX variations can present them.
  • Flag any term that belongs in the ubiquitous-language glossary.
  • Keep strictly to logical concerns; defer every physical concern to /spec-interview with an explicit note rather than inventing storage/endpoint/auth detail.

Append any cross-framework facts (renamed entities, merged aggregates, newly discovered events) to the brief so later frameworks inherit them. Then STOP and emit the Terminal handoff format from docs/prototype-session-loop-convention.md. After writing, recalculate pending: if frameworks remain, the handoff states the intermediate just written, names the next pending framework in plain English (what it models, never only its internal {framework-slug}), and gives the exact resolved next command with {topic} filled in, e.g. /state-model alignment-page-review; if none remain, the handoff points to the synthesis session (§4) and gives its exact command, e.g. /state-model alignment-page-review. Continue-vs-stop framing follows that convention's Routing Rules.

4. Synthesis + Assemble & Approve (assemble session)

Enter when the brief exists, all planned framework intermediates exist, and no canonical domain model exists yet (also forced by /state-model --synthesize [topic]).

Assemble the per-framework intermediates plus the brief into:

  1. Canonical doc design/domain-model-{topic}.md (flat) or design/{slug}/domain-model-{topic}.md, with sections: ubiquitous-language glossary, entities (with kind, attributes, relationships), state machines (states, transitions, maps_to_ui_state), events, commands, read models, policies, logical contracts, an evidence/flow-binding matrix, assumptions/confidence, and explicit physical-concern deferrals to /spec-interview.
  2. Synthesized manifest design/model-tree-{topic}.yaml (flat) or design/{slug}/model-tree-{topic}.yaml, per the design/model-tree.schema.json contract and the shape below.

Build the one alignment page (alignment/state-model-{topic}.html) rendering the full proposed domain model, the flow-binding matrix, the state-machine/ERD diagrams (visual tier), assumptions/confidence, the proposed file changes, the glossary-additions gate, and the approval gate. Stop for compiled YAML.

On approval (compiled YAML with no unresolved negative feedback):

  • Write design/domain-model-{topic}.md and design/model-tree-{topic}.yaml.
  • Write the optional top-level model_tree_ref pointer into the flow-tree manifest (design/{flow-tree}-{topic}.yaml), pointing at the new model-tree path. Do not touch the flow-tree route array or duplicate any binding into the flow tree.
  • Append only user-approved glossary terms to the target glossary per the glossary write-forward convention.
  • Archive the brief and per-framework intermediates under docs/history/archive/YYYY-MM-DD/HHMMSS/<original-working-path> (archive-at-canonical-write timing).
  • Emit the downstream next-step route (§5).

5. Next Steps (after synthesis only)

After the canonical domain model and model-tree are written, recommend the first match:

  1. Default → check .agents/project.json.enabled_packs for product-design; if enabled, recommend /ux-variations [specific-user-flow] — the variation work now has a real logical substrate to present. Name the specific user flow from the flow tree.
  2. If product-design is not enabled, recommend npx skillpacks install product-design from the project shell first.
  3. Never recommend /spec-interview here — it is many steps downstream and owns the physical-model hardening pass.

Do not emit cross-skill routing before synthesis is approved and written. While a framework or the synthesis page is pending, the only continuation route is re-invoking /state-model with the same topic argument.

Output

  • Setup session: the Domain Modeling Scope Checkpoint (inline) + the shared context brief.
  • Framework session: one design/{slug}/state-model-{topic}/{framework}.md intermediate per planned framework.
  • Assemble session: design/domain-model-{topic}.md, design/model-tree-{topic}.yaml, the flow-tree model_tree_ref back-pointer, and the alignment/state-model-{topic}.html review page.

model-tree-{topic}.yaml shape

Same envelope as design/flow-tree.schema.json (schema_version, topic, mode/product_path, source_artifacts, kebab id pattern, additionalProperties:false, status enum proposed|confirmed|rejected|deferred). Body:

  • flow_tree_ref (binding anchor) + frameworks[] (record of which frameworks were run/synthesized).
  • entities[] — kind: entity|value-object|aggregate-root; attributes, relationships with cardinality, lifecycle_ref to a state machine.
  • state_machines[] — subject, states (each with optional maps_to_ui_state), transitions (event/guard/action).
  • events[], commands[], read_models[], policies[].
  • contracts[] — kind: command|query; request/response/error shapes, logical only.
  • Every element carries flow_bindings[]: {flow_node_ref, access: reads|writes|triggers|displays|transitions}. Bindings live in the model-tree only and are never duplicated into the flow tree.

Alignment Page

When this skill produces durable deliverables (research, specs, plans, reports, prototypes, or any document output), build a full-depth HTML alignment page following ALIGNMENT-PAGE.md in this skill's directory. Output: alignment/state-model-{topic}.html.

Archive-First Replacement Policy

  • Before replacing or substantively rewriting an existing canonical design document (design/**/*.md, design/**/*.yaml), copy the current file to docs/history/archive/YYYY-MM-DD/HHMMSS/<original-relative-path>.
  • Preserve the archived snapshot exactly; do not edit it after creating it.
  • After the archive snapshot exists, write the updated document to the original canonical path.
  • New files do not need archive snapshots. Append-only updates do not need archive snapshots unless an existing section is regenerated or rewritten.

Constraints

  • Logical only. Do not specify storage engines, databases, real endpoints/URLs, authentication/authorization mechanisms, migrations, indexes, deployment, or any physical architecture. When a physical concern arises, record it as an explicit deferral to /spec-interview, not as a decision. The model captures what the domain is, not how it is stored or served.
  • Anchor to the flow, not to a UI. The model is a property of the user flow. Do not encode any single UX variation or UI presentation. UX variations re-skin the same entities/actions/states.
  • Bindings are authoritative in the model-tree only. Never duplicate flow_bindings into the flow tree; never modify the flow-tree route array. The only flow-tree write is the optional model_tree_ref pointer.
  • One heavy phase per session. Run setup, one framework, or synthesis per invocation; advance by re-invoking /state-model. Fold to a single session only for fewer-than-3-framework domains or --no-chunk. Do not queue framework work in tasks/todo.md or hand it to /exec.
  • Synthesis requires at least one framework intermediate. Do not synthesize from zero evidence.
  • The live cursor is per-framework intermediate existence; the model-tree is written only at synthesis as the post-approval manifest, never as a live run-manifest.
  • Present the model before writing canonical artifacts; exactly one binding alignment gate, at synthesis.
  • When recommending a skill from another pack, verify pack availability through .agents/project.json.enabled_packs.

Default Shipping Contract

Follow the shared shipping contract convention in CLAUDE.md.

04 同仓库更多 Skills