원본 저장소의 제목, 예시, 코드, 표, 링크, 이미지를 유지해 표시합니다.
Model
Turn the verb-first story map into a noun-first Object Map before UI gets built. AEP's spine (/aep-envision → /aep-map) plans what the user does; this skill plans the objects the user acts on — which objects appear, what their fields are, how they nest, and what actions hang off each. Structure only: look, voice, and journey stay in /aep-calibrate (visual-design, copy-tone, ux-flow).
The one rule: a story-map slice cuts scope, not interface type. Keep the backbone's one-step-one-screen as object-first structure; translating it into a wizard is the trap this skill exists to prevent.
Where this fits:
/aep-envision → /aep-map → /aep-model → [ /aep-calibrate ] → /aep-dispatch → /aep-launch → /aep-build → /aep-wrap → /aep-reflect
▲ you are here (UI-facing products)Session: Main, interactive with user (object boundaries + IA need human review) Input: Product definition (product/index.yaml split mode, product-context.yaml v1) + stories, architecture.domain_model from product-context.yaml Output: product/object-model.yaml (cross-capability ontology) + one product/maps/<capability>/object-map.yaml per UI-facing capability (status: approved); thin calibration.history entry + changelog in product-context.yaml
Schemas: templates/object-model-schema.yaml, templates/object-map-schema.yaml. Process detail: the four ORCA rounds + the object-first/task-oriented decision framework are canonical in references/orca-process.md — read it before mining in Step 1.
When this skill applies
Run /aep-model for UI-facing products/capabilities only. A capability is UI-facing when it declares the object-model quality dimension (set by /aep-envision), or declares visual-design/ux-flow, or has user-facing stories (non-null activity whose module is kind: ui). Pure-backend/CLI products skip it — there are no user-perceived objects to model.
If nothing is UI-facing, say so and route the user straight to /aep-dispatch.
Before Starting
File resolution: the split-vs-V1 probe and mode semantics are canonical in references/file-resolution.md — read it when the active mode is unclear. In split mode model reads the product definition (personas, capabilities, activities, quality_dimensions) from product/index.yaml and stories, architecture.domain_model from product-context.yaml; in V1 mode it reads everything from product-context.yaml. In both modes it writes the standalone artifacts under product/ (create the directory in V1) — the object model is a stable design file; product-context.yaml carries the reference to it.
If stories is empty, run /aep-map first. If no product definition exists, run /aep-envision first.
Mode detection:
- Establishment — no
product/object-model.yamlyet → full ORCA over all
UI-facing capabilities.
- Extension — it exists → focused pass over only NEW objects/capabilities not
yet covered (e.g., a later layer introduced new activities). Extend approved maps and re-gate only the delta.
Step 1: Generate (or refine) the Draft (ORCA, automated)
If `/aep-map` already wrote draft artifacts (product/object-model.yaml and product/maps/<cap>/object-map.yaml with status: draft), read and refine them — preserve their provenance/source_evidence, fill gaps, and fix obvious errors. Generate fresh only when no draft exists. (Set provenance.generated_by/status to reflect reality — aep-map for an untouched draft, refined in place here.)
Run the four ORCA rounds per references/orca-process.md, then the representation pass — this step is agent-driven, so mine the evidence first:
- Round O — Objects (Noun Foraging): forage nouns, promote user-perceived
things, demote implementation nouns, record source_evidence + confidence.
- Round R — Relationships (Nested Object Matrix): set cardinality + nesting
per object pair; cross-capability → object-model, capability-local → object-map.
- Round C — CTAs (object × role matrix): hang every story/activity verb onto
its object, tagged by persona, with placement, priority, and from_story.
- Round A — Attributes: rank each object's fields core / secondary / metadata.
- Representation hints: project primary objects into
collection+detail
views and pick each capability's anchor_object. IA only, no visual design.
Write:
product/object-model.yaml— the cross-capability ontology
(provenance.reviewed: false).
product/maps/<capability>/object-map.yamlper UI-facing capability with
`status: draft`, including the coverage index (story → objects/screens; screen ids use the canonical <object-id>:<view> grammar). Use capabilities[] ids for <capability>; in v1/single-journey (no capabilities[]) use one default capability = the project slug.
Default every flow to object_first. Only add an interaction_modes entry to mark a flow task_oriented, with a reason grounded in the decision framework.
Postcondition: product/object-model.yaml and one draft object-map.yaml per UI-facing capability exist; every noun foraged from an activity maps to an object (or is justified implementation-only) and every UI story's verbs map to a CTA (coverage complete). Nothing has been asked of the user yet.
Step 2: Review Gate (the human decides)
Object boundaries and IA are the highest-leverage design decisions here — same error-cost logic as the /aep-map System Map gate. Present the draft compactly (objects, the NOM, primary screens, any task-flow exceptions) and ask a SHORT set of high-leverage questions, one at a time:
- Object boundaries — are these the objects the user actually thinks in? Any
wrong names, bad merges, or missing splits? (Surface every low-confidence object explicitly.)
- Primary anchor — per capability, which object should the user see / choose
first?
- Task-flow exceptions — which flows should be explicit wizards (onboarding /
checkout / one-shot) instead of object-first? Capture the reason.
Apply the answers to the draft. Keep the questions few — this is a gate, not a redesign workshop; taste decisions stay in /aep-calibrate (see the intro).
Step 3: Approve & Write
On approval:
- Set each reviewed
product/maps/<capability>/object-map.yaml→
status: approved, approved_by: human, approved_at: <ISO 8601>.
- Set
product/object-model.yamlprovenance.reviewed: true(+reviewed_at). - Back-annotate stories: add
object_model_refsto UI stories the map covers,
e.g. object_model_refs: ["product/maps/dashboard/object-map.yaml#order"]. Keep it a thin reference — the map body never goes into product-context.yaml.
- Append a thin record to
calibration.historyinproduct-context.yaml:
- dimension: object-model
calibrated_at: "<ISO date>"
calibrated_from_layer: <layer> # the active layer whose UI stories this approval unblocks
mode: establishment # or extension
artifact_path: "product/maps/<capability>/object-map.yaml"
summary: "Approved object-first IA for <capability> — N primary objects, M task-flow exceptions"- Append a
changelogentry (type: map_update, author: human,
sections_changed: [calibration, stories]).
Step 4: Validate YAML & Commit
# Validate every YAML touched (globs that match nothing are skipped)
ok=1; for f in product/object-model.yaml product-context.yaml product/maps/*/object-map.yaml; do
[ -f "$f" ] || continue
npx js-yaml "$f" > /dev/null || { echo "YAML FAIL: $f"; ok=0; }
done; [ "$ok" = 1 ] && echo "YAML OK"If it fails, fix before committing — see references/yaml-guardrails.md for the common product-context.yaml pitfalls (colons in list items, embedded quotes, @/{/}, nested sub-lists).
Then commit the design artifacts directly to the integration branch per /aep-git-ref "Control-Plane Commits" (resolve $BASE per /aep-git-ref "Resolving $BASE"): git add product/ product-context.yaml, commit feat: object model — approved object-first IA for <capabilities>, push to $BASE.
Postcondition: YAML OK printed and the commit is on $BASE.
Next Step
Object model approved. Heavy taste dimensions next (if planned), then dispatch:
/aep-calibrate visual-design # look & feel (optional, if a .5 layer plans it)
/aep-dispatch # inject object-map slices and start building
