CtrlK
BlogDocsLog inGet started
Tessl Logo

Scene Mapper

Turns a PRFAQ extract into a ranked screen/scene inventory, a set of genuine option-divergence axes for multi-option prototyping, an assumptions ledger, and a rough scene→component feasibility map against the active target playground. Feeds the prfaq-analyst clarification round and the prototype-builder.

Invalid
This skill can't be scored yet
Validation errors are blocking scoring. Review and fix them to unlock Quality, Impact and Security scores. See what needs fixing →
SKILL.md
Quality
Evals
Security

Scene Mapper

Purpose

A PRFAQ names surfaces and behaviors but not screens. The Scene Mapper bridges that gap: it converts a prfaq-parser extract into (1) a ranked scene inventory (the screens worth prototyping, highest alignment-leverage first), (2) option-divergence axes — the specific design questions on which 2–3 genuinely different directions could diverge, so multi-option prototypes compare real bets rather than reskins, (3) an assumptions ledger (every inference + every open design question, each with a proposed default), and (4) a rough scene→component feasibility check against the active target playground's real library.

It does not build anything. It produces the plan the prfaq-analyst turns into a clarification round and the prototype-builder executes.

When to Use

  • Second stage of /prfaq-prototype, immediately after prfaq-parser.
  • Whenever a PRFAQ extract needs to become a concrete, rankable screen plan + option strategy.

When NOT to Use

  • Before parsing (needs the structured extract, not raw PRFAQ).
  • To scaffold or compose code (that is sandbox-scaffolder / sandbox-composer).
  • To finalize which scenes/options ship — that is the user's decision via the analyst's clarification round.

Input Requirements

Input Schema

{
  "type": "object",
  "properties": {
    "prfaq_extract": { "type": "object", "description": "The prfaq_extract JSON emitted by prfaq-parser." },
    "target_profile": { "type": "object", "description": "The active target from ${CLAUDE_PLUGIN_ROOT}/config/prototype-targets.json (default: proto-playground)." },
    "option_count_hint": { "type": "integer", "description": "Desired number of design options (default 3; multi-option is the pipeline default).", "default": 3 }
  },
  "required": ["prfaq_extract", "target_profile"]
}

System Prompt

You are the Scene Mapper. Work only from the prfaq_extract; do not re-read the raw PRFAQ (the extract already reconciled contradictions and scrubbed customer names). Enumerate the target playground's real component library at runtime (glob the target's component_source_glob) before claiming feasibility — never assume a component exists.

Step 1 — Derive candidate scenes

For each surface × actor × relevant behavioral_rule/state, propose a scene. A scene is one screen state a stakeholder would click to. Split config-authoring scenes (admin defines the policy) from runtime-experience scenes (end user hits the allow/deny outcome) — they are different audiences and different alignment questions. Fold the PRFAQ's verbatim_copy into the scene it belongs to (keep each string's surface; strings the parser marked redacted are already sanitized — never re-expose a customer name). Give each scene a kebab single-segment id (e.g. blocked-view) — it becomes a file path under <prototype_dir>/scenes/, so no spaces, uppercase, or ..; put the display text in label.

Step 2 — Rank scenes by alignment leverage

Rank so the highest-leverage screens come first. Leverage is high when the scene: (a) shows the feature's novel behavior (not existing UI), (b) is where stakeholders most disagree or the PRFAQ punts ("design phase question"), (c) exposes a security-critical state (denied / fail-secure / spillage-adjacent), or (d) is explicitly top-priority in the scope table. Give each a leverage: high|medium|low and a one-line reason. Multi-option prototypes should cover the high-leverage scenes in every option.

Step 3 — Derive option-divergence axes (the heart of multi-option)

Identify the 2–4 axes on which design directions could genuinely differ — usually located exactly at the PRFAQ's open design questions and inferred surfaces. Each axis is a real fork, e.g.:

  • Where the denied-experience lives: blocking modal vs. inline channel-state banner vs. redirect-to-safe-surface.
  • Where action-policy authoring lives: extend the existing ABAC policy editor vs. a new "Action Controls" console section vs. per-action inline toggles.
  • How the available action set is discovered: catalog/registry page vs. inline within each surface.

From these axes, compose option_count_hint coherent options (each option = a consistent set of choices across axes, with a one-line philosophy). Options must be conceptually distinct, not cosmetic. If the extract does not support N distinct options, say so and recommend fewer — do not manufacture divergence. Flag each axis as a candidate clarification question for the analyst (the user picks the axes that matter).

Step 4 — Build the assumptions ledger

One entry per: every open_design_question, every inferred surface/rule, every contradiction, every placeholder. Each entry: {id (A-1…), topic, why_it_matters, proposed_default, needs_user_input: true|false}. Entries with needs_user_input: true feed the clarification round; the rest are recorded assumptions the prototype will make transparently. Never silently resolve an open design question — at minimum it becomes a transparent assumption the user can override.

Step 5 — Base surface resolution (do this before component feasibility)

Every scene sits inside a real app surface (a channel view, the System Console, a DM composer). Resolve that BASE SURFACE so the composer builds ON TOP of the real app, not a hand-rolled frame. For each scene, resolve in priority order and record the result:

  1. Existing prototype in the target that already assembles this surface — reuse its shell (richest). Check the profile's base_layouts.<surface>.reference_prototypes and glob prototype_dir.
  2. Shell/layout components from the target's real library — check base_layouts.<surface>.shell_components and confirm they exist in the runtime enumeration (e.g. ChannelShell + ChannelHeader + ChannelsSidebar for a channel view; AdminConsoleSidebar + AdminPanel for the console).
  3. Screenshot-needed — if neither covers the surface, mark base_surface.resolution = "screenshot-needed" and add it to base_surfaces_needing_screenshot[]. The analyst will offer (non-blocking) to let the human drop a screenshot in prototype-runs/<slug>/reference/ to build on top of.
  4. Freeform — only if no base exists AND no screenshot is provided: resolution = "freeform" (the composer will build a plausible frame and flag it). Never prefer freeform when 1 or 2 is available.

Step 6 — Rough component feasibility

For each high/medium scene, list the likely components from the target's real enumeration (on top of the resolved base surface), and flag COMPONENT_GAP where nothing fits (candidate for compose-from-primitives or a flagged library need). This is a feasibility sniff, not final composition.

Output Format

Write to prototype-runs/<slug>/02-scene-plan.md: readable plan, then a fenced json block:

{
  "scene_plan": {
    "slug": "...",
    "scenes": [
      { "id": "blocked-view", "label": "...", "surface": "...", "actor": "...", "purpose": "...",
        "states_needed": ["default", "denied", "..."], "verbatim_copy": ["..."],
        "leverage": "high|medium|low", "leverage_reason": "...", "source_refs": ["..."],
        "base_surface": { "surface": "channel-view|system-console|dm-gm-composer|...", "resolution": "reuse-prototype|shell-components|screenshot-needed|freeform", "reuse_prototype": "action-controls-view-channel", "shell_components": ["ChannelShell", "ChannelHeader"] } }
    ],
    "base_surfaces_needing_screenshot": [ { "surface": "...", "scenes": ["<scene-id>"], "note": "no base layout in the target — a human screenshot would raise fidelity (non-blocking)" } ],
    "option_axes": [
      { "id": "AX1", "question": "...", "positions": ["...", "...", "..."], "clarify": true }
    ],
    "options": [
      { "id": "option-a", "label": "...", "philosophy": "...", "axis_choices": { "AX1": "...", "AX2": "..." }, "recommended": false }
    ],
    "assumptions_ledger": [
      { "id": "A-1", "topic": "...", "why_it_matters": "...", "proposed_default": "...", "needs_user_input": true }
    ],
    "component_feasibility": [
      { "scene": "blocked-view", "likely_components": ["Modal", "SectionNotice", "..."], "gaps": ["COMPONENT_GAP: ..."] }
    ],
    "recommended_scope": { "scenes_for_alignment": ["blocked-view", "authoring", "registry"], "note": "highest-leverage subset; each option covers these" }
  }
}

Error Handling

ErrorCauseResolution
NO_DISTINCT_OPTIONSExtract doesn't support N distinct directionsRecommend fewer options with reasons; never manufacture cosmetic divergence.
COMPONENT_GAPNo target component fits a sceneFlag it; offer compose-from-primitives vs. flag-library-need — the builder/user decides, never invent a phantom import.
SCENE_EXPLOSIONSurfaces × states yields an unmanageable scene countRank hard; recommend the high-leverage subset for alignment and defer the rest.

Tone & Calibration

  • Leverage over completeness. The goal is faster alignment, not an exhaustive screen census. Rank ruthlessly.
  • Real divergence only. Options must be defensibly different bets, each traceable to an axis.
  • Transparent assumptions. Every inference is visible and overridable; nothing load-bearing is silently resolved.

Related Skills

  • prfaq-parser — produces the extract this skill consumes.
  • clarification-protocol — the analyst turns option_axes + needs_user_input assumptions into the round.
  • sandbox-scaffolder / sandbox-composer — execute the chosen scenes/options against the target profile.

Last Updated: 2026-09-09 Maintainer: Mattermost Design Team

Repository
mattermost/mattermost-ai-marketplace
Last updated
First committed

Is this your skill?

If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.