Claude Skill

scenario-inspiration

Use when a creative task has no direction yet: finding inspiration, exploring looks or styles, proposing concept directions to pick between, building a moodboard or reference board, doing visual research, mining existing assets for a style, or escaping generic AI-looking output.

LLM Mart · 0 points · 0 views 0 listing impressions 0 install-command copies
Virus-scanned Reviewed automatically before listing.

Full trust report

Download scenario-labs-skills-skills_scenario-inspiration-dc592af.zip · 24 KB
Part of scenario-labs/skills — 97 skills

Install

skills CLI npx skills add https://github.com/scenario-labs/skills/tree/main/skills/scenario-inspiration
Claude Code claude plugin marketplace add https://llmmart.ai/marketplace.json && claude plugin install scenario-labs-skills@llmmart
Git git clone https://github.com/scenario-labs/skills.git

The skills CLI installs just this skill, for any of its supported agents. Claude Code installs the whole scenario-labs/skills collection as a plugin from our marketplace. Git is the plain clone.

Skill manifest

Scenario Inspiration

Overview

Asked for inspiration, an agent averages. It returns the most typical answer for the brief, so every user with a similar brief gets the same look. This skill trades that for four phases: prime, widen, choose, board. Connection and scope: see the scenario skill in this repo. If a sibling skill named here is missing from your available skills, ask the user to install it (npx skills add scenario-labs/skills --skill <name>); unattended, proceed from tool schemas and flag the gap.

Four moves carry most of the value. Name the reflex answer for this brief and the answer of someone merely avoiding that reflex, then rule out both, because an agent told to be original lands on the second-obvious answer. Randomize the operator, never the subject: what varies is the transformation applied to the brief, and a random subject is just noise. When you generate candidates yourself instead of searching for them, ask yourself for a distribution rather than an answer, and work from its tail. Then make the user pick, because options that never resolve are a gallery, not direction.

Quick reference

Phase Do Detail
1. Prime Locked constraints, the open axis, both reflexes, what counts as a hit references/widen.md
2. Widen Four lanes plus wildcard draws; over-gather, near and far widen.md, references/sources.md
3. Choose Three or four mutually exclusive directions one named axis apart, plus an escape hatch references/choose.md
4. Board The pick becomes a collection, every reference annotated with its job references/moodboard.md

Four lanes feed phase 2. Ask the user first, for three things they already love and one they cannot stand; unattended, take those from the task instructions and continue without them if it names none. Then search with target: "assets" twice, once over the team's own work (public omitted) and once over the public catalog (public: true), and last the open web, which is not a search call. Public asset hits carried metadata.prompt, the wording that produced them, and target: "models" hits carried exampleAssetIds at authoring time: free style research either way. images: {like, unlike} steers by example in both directions.

Draw far domains yourself with scripts/wildcard.py, run from the skill directory (python3 scripts/wildcard.py --count 4). A model asked for something random samples its own habits; the script samples a corpus and prints its seed, so a draw can be replayed or deliberately never repeated.

Worked example: a puzzle game's world map, nothing decided

  1. Prime. Locked: 16:9, readable at phone size. Open: everything else. Reflex: candy-colored isometric islands. Second reflex: the same islands, muted and "cozy". Both are out of bounds now. A hit is a map whose regions read apart in grayscale. Run the obvious query once and keep it as the baseline to beat.
  2. Widen. search the project for anything already on brand, then public: true at query_semantic_ratio: 0.8 and again at the keyword default, reading the prompts on the best hits. Draw four wildcards, run each as its own query, and keep near, middle, and far finds rather than only the strangest.
  3. Choose. Name the axis first (here, how the world is depicted), then four positions on it. Each gets a title, an intent line, two or three references shown with asset_display, and who it wins for and when it fails. Say what you cut. Ask which is closest and what they would take from another, and offer the escape hatch. When nobody can answer, take the pick from the task instructions, else choose the option that best satisfies the hit line from prime, say which and why, mark it provisional, and keep going.
  4. Board. collection_create the winner, then copy in every foreign reference: public assets belong to their own team, and collection_add_assets on one returned 403 at authoring time. asset_download, curl -L, upload_asset. asset_update each with its reason, tag the anti-references, hand the collection id to scenario-image or scenario-consistency.

Common mistakes

  • Skipping prime and searching the brief's own words, which returns the category reflex sorted by relevance.
  • Four options that are one idea in four colors. If picking A does not rule out B, they are not directions.
  • Presenting only the survivors. Naming what was cut, and why, is what makes the rest credible.
  • Calling a set varied without checking it against what the literal query already returned.
  • Treating every strange find as a keeper. It earns a slot only when you can name what it connects to and what it is worth.
  • Boarding whatever came back. Every reference needs a job (light, color, composition, material, shape, subject, environment) or it is decoration.
  • Mixing lighting worlds on one board: a hard-flash reference and a soft-window reference cancel at generation time.
  • Handing a model an 18-image board. Reduce to three to six role-tagged references first.
  • Shipping the undirected default when the brief asked for none of it: subject centered and facing the lens, posed, evenly lit, everything in focus, a processed gloss. Every axis a prompt leaves open (framing, moment, lens, time of day, light) is filled with the model's most average answer, so name each one.
Files (skills)
  • references
    • choose.md 7.3 KB
      # The choice
      
      ## Cut many to a few
      
      Never present the search results. Results are material; options are authored. Over-generate first, then reduce, by one of two rules:
      
      - **Grid.** Name two or three axes (say depiction x palette temperature x detail density), sketch the cells, and keep one best candidate per cell. The set spans the space by construction rather than by luck.
      - **Rerank.** From 20 to 40 candidates, pick one at a time: each next option maximizes fit to the brief minus its similarity to the nearest option already picked. Nearest, not average. Averaging lets a cluster of near-duplicates survive as long as the set looks spread out overall, and one near-duplicate is exactly what should disqualify a candidate.
      
      Select for how different the options **look**, not for how different their parameters were. Four seeds of one prompt is not an option set, however far apart the seeds are.
      
      ## How many
      
      Option count follows the user's state, not a house number.
      
      | Their state                                           | Options       |
      | ----------------------------------------------------- | ------------- |
      | Deciding between two directions they already hold     | 2             |
      | Exploring, no formed preference (the usual case)      | 3 or 4        |
      | Asking to see range, with a preference to filter with | 5, on request |
      
      Three to four is a reasoned default, not a measured optimum: it is about as many things as anyone holds side by side, and too much choice hurts most when preferences are still unformed, which is the normal state early in a brief. Three concepts is a long-standing industry convention rather than a finding. Do not claim research settles the number.
      
      ## The bar: mutual exclusivity
      
      If picking A does not rule out B, they are not directions, they are one idea in four colors. Test it by writing what each option gives up. An option that gives up nothing is not on the board.
      
      Every option needs a constituency. Name the kind of brief or audience that would pick it. If you cannot say who would choose C, C is filler and the set is really three options plus padding.
      
      **No decoys.** Delete any option that is worse than another on every dimension you stated. This rules out the familiar extravagant / safe / balanced trio, where two concepts exist to be rejected. If it is not an option you would happily execute, it does not belong in the set.
      
      ## Name the axis in the question
      
      Put the axis before the options, not after: "these four vary the lighting, everything else held constant" beats "here are four options". The named axis is what makes the pick diagnostic and it teaches the user the vocabulary they will steer with next round.
      
      Vary one named axis per round by default. When a round deliberately spans several axes to find range, say so and label each option's position on every axis, or the comparison turns into a bag of unrelated features and the answer stops meaning anything.
      
      Write labels in strict parallel: same shape, same attribute order, roughly the same length, one differing term. "Warm low-key, tight crop" against "cool low-key, tight crop" is comparable. "Moody" against "something with more energy and maybe a wider shot" is not, and the difference silently destroys the information in the reply.
      
      ## What each option carries
      
      | Field      | Content                                                                      |
      | ---------- | ---------------------------------------------------------------------------- |
      | Title      | A name someone would repeat in a meeting, not "Option B"                     |
      | Intent     | One line: what this direction is doing                                       |
      | Position   | Where it sits on the named axis                                              |
      | References | Two or three images, one `asset_display` call each, never pasted as raw URLs |
      | Wins when  | The brief or audience this is right for                                      |
      | Fails when | The condition under which it is wrong, stated as plainly                     |
      | Odds       | Safe consensus, or long shot                                                 |
      
      Show all options together in one message rather than one at a time. Marking which are the consensus and which came off the tail gives a director the axis they actually care about; a relevance ranking does not. Say it in those words, not as a number, because the estimate behind it is not calibrated.
      
      ## Around the options
      
      **Watch the order.** Position drives picks: the ends of a list get attention the middle does not. Rotate which conceptual pole lands in which slot between rounds, and never let position encode a recommendation. If you have one, say it in words after the pick, or offer it as a read the user is free to discount.
      
      **Show the discards.** Two or three lines naming what was cut and why. A set where everything survived reads as pattern matching on the shape of a good answer; a set with visible abandonments reads as judgment. This is the cheapest credibility available.
      
      **Always offer a real escape hatch**, phrased as an option rather than a courtesy, and enumerate its useful forms so it is not a dead end: none of these, a mix of two, the right idea but wrong execution, or wrong axis entirely.
      
      **"I cannot decide" means the options are too close.** The fix is more spread on the named axis, not fewer options and not the same question asked again.
      
      ## Ask for the pick, then the reason
      
      Ask for the choice first and the reason second, and keep the reason optional. Making someone justify a preference before forming it distorts the preference, so the order matters: choose, then explain, and never block on the explanation.
      
      Do not leave the reason as an open field, which asks for structured critique on the spot. Offer the handles from the axis you varied instead: "was it the light, the palette, the framing, or the subject?" turns an unanswerable question into a one-word answer that still names the attribute.
      
      When the round matters, ask for a graft instead of a favorite: "which is closest, and what would you take from one of the others?" A cross-option answer such as "C's lighting on A's composition" carries far more than a ranking, and it is how directors talk anyway.
      
      ## Rounds, not one big list
      
      For a wide-open brief, narrow progressively. Round one settles the axis with the widest visible spread, round two varies within the branch that survived, round three refines. Say which round this is and what it decides, so nobody thinks they are approving final art.
      
      After every answer, echo what it settled in the user's own vocabulary: "locked: cool palette, low key. Still open: framing." A series of picks then accumulates into a brief, and a wrong inference gets corrected before it compounds.
      
      ## When nobody can answer
      
      A non-interactive run still has to choose. Take the pick from the task instructions when they name one. Otherwise select the option that best satisfies the checkable "hit" line written during prime, say which one you chose and why in one sentence, mark it provisional, and carry on. Stopping to wait for an answer that cannot arrive is the worse failure.
      
      ## The losers are not waste
      
      Keep them. A rejected direction is a labeled anti-reference, and `search` with `images: {unlike: [...]}` turns it into an active filter for the rest of the project. Park the near misses in a short list the user can return to, so a good idea rejected for this brief survives to the next one.
      
    • moodboard.md 9.5 KB
      # The board: building it, storing it, spending it
      
      ## Name the artifact first
      
      Users say "moodboard" for five different things. Ask, or state which one you are making.
      
      | Artifact     | What it is                                                             | Size                |
      | ------------ | ---------------------------------------------------------------------- | ------------------- |
      | Moodboard    | Tone and direction, interpretable, early                               | 15 to 20 images     |
      | Style frame  | One fully rendered frame of the real deliverable, final quality        | 1 or 2 rival        |
      | Lookbook     | Sequenced pages narrating one production's look                        | 8 to 20 pages       |
      | Vis dev pack | Exploratory art solving a world: characters, environments, key moments | Varies              |
      | Style guide  | Enforceable rules with numeric bounds and a named owner                | Read in one sitting |
      
      Only the style guide binds. A board sets direction, and the output interprets it; work rejected for not matching a board one to one is a misuse of the board, so state which axes are locked and which stay open.
      
      ## Anatomy
      
      Every reference carries three fields. Write them as you add it, not afterwards.
      
      - **Role**: light, color, composition, material and texture, shape and silhouette, subject and styling, or environment. An image that fits no role is decoration and goes.
      - **Why**: one line tying it to a decision on this project, not a description of the picture.
      - **Take**: the single attribute to extract. "The falloff, not the palette." One mechanic per reference, named, and no more than two references carrying the same mechanic into one output.
      
      Counts that hold up: under 10 images is underspecified, over 25 means you are still collecting instead of deciding. Budget 2 to 3 anti-references per 4 to 8 positives. Spend more effort tagging and cutting than gathering; removal is the cure for a board that is pretty but not directive, including for images you like.
      
      **One world per axis.** One lighting quality, one key level, one palette temperature, one stylization level, one detail density. A hard-flash reference and a soft-window reference on the same board cancel at generation time. If both are genuinely wanted, that is two boards and two directions, not an average.
      
      **No single source dominates.** If one artist, film, or property supplies most of the board, the output reads as a knockoff of it.
      
      The strongest anti-reference is a matched pair: the same subject rendered on-style and off-style. For a generation pipeline, produce that pair yourself. The undirected half is the brief's own prompt with its mood adjectives and quality tags struck (they preserve nothing, so the default comes back unchanged) and its anti-goals rewritten as positive states, or sent to `negative_prompt` where the schema has one. The directed half feeds that result back as a subject reference and keeps the same text, adding every staging axis named (framing, moment, lens, time of day, light) plus the grade written from the board's look axes, so the named axes are the only thing that changed between the two. The pair is an anti-reference for the board, so it runs prompt-only; when the directed half is also the deliverable, it carries the board's reduced references as well (the hero as style reference, the undirected output as subject reference), the prompt keeps the staging axes, and the written grade shrinks to what a style reference cannot carry. Either way, confirm in `model_schema_get` that the reference field is optional, since the undirected half runs without one, and hold `seed` fixed across the pair where the schema exposes it. A side by side states a rule that a paragraph cannot.
      
      ## The collection is the board
      
      | Need                   | Tool                                        | Fact that bites                                                              |
      | ---------------------- | ------------------------------------------- | ---------------------------------------------------------------------------- |
      | Create                 | `collection_create` (write)                 | Takes `name` only, no description field                                      |
      | Add references         | `collection_add_assets` (write)             | Any number of ids; an already-filed id is skipped, not an error              |
      | Annotate one reference | `asset_update` (write)                      | `metadata.tags` replaces the whole set; `metadata.description` holds the why |
      | Tag a role             | `asset_add_tags` (write)                    | Additive, and the tag namespace is shared with models                        |
      | Set the hero           | `collection_update` (write)                 | `thumbnail` is how the board reads at a glance                               |
      | Read it back           | `collections_list`, `collection_get` (read) | `collection_get` returns the record, not the assets                          |
      | List its assets        | `search` with `filters.collection_ids`      | This is the retrieval path, not `collection_get`                             |
      
      All of these are catalog tools: get schemas with `scenario_tools_search` and run them through the executor matching each `permission`, or reconnect with `?toolsets=full`.
      
      Because a collection has no description field, the board's thesis lives in its name. Name it for the direction and the subject, not "moodboard 2".
      
      **A public asset from another team cannot join your collection.** `collection_add_assets` on one returned 403 Forbidden at authoring time. It is still a valid `search` seed and `asset_display` renders it, but to board it you need your own copy: `asset_download`, `curl -L` the returned URL, then `upload_asset` (multipart: `file_name`, `content_type`, `kind`, `file_size`) and `upload_asset_complete`. Two things about that copy. `asset_download` returns a png re-encode unless you ask for another `format`, so the file can land larger than the original and the upload is sized off the copy, not the source. And `upload_asset` answers with `part_size`, `total_parts`, per-part `content_length`, and an `instructions` string: follow those rather than assuming one PUT, because anything past `part_size` comes back as several parts. Same path for anything arriving from outside Scenario.
      
      ## Spending the board
      
      A model cannot read 18 images. Reduce to three to six, each tagged with the job it does at generation time: style reference (aesthetic and rendering), structure reference (composition and layout), subject reference (identity). A style reference carries look. It cannot enforce an exact hex color, typography, object placement, or a subject's identity: route brand colors through a color parameter where the schema has one, and type and logos through a compositing step. Check the model's own schema for what it accepts and how many, and remember file fields take asset ids even when named `...Url`.
      
      Build the prompt from the board's named axes, never from mood adjectives or quality tags. "Cinematic", "beautiful", "stylized", and "epic" preserve nothing, and neither do "ultra sharp", "hyper detailed", "crisp", "8K", or "HDR". Shape family, value range, material behavior, detail density and where the rest areas sit, lighting direction and quality, palette as dominant plus secondary plus accent: those survive the trip into a prompt.
      
      Rewrite every anti-goal as a positive state before it reaches a prompt. "Not cluttered" becomes "generous negative space, one subject centered". Send a negation to a `negative_prompt` field only when `model_schema_get` shows the model has one, and never paste "no X" into the prompt itself.
      
      When a style reference is attached, drop the style adjectives from the prompt and let it carry subject and content only, because the two fight. When a structure reference is attached, the prompt carries style and palette and never restates the layout. With no reference, the prompt carries every axis explicitly: the look axes above (shape family, value range, material behavior, detail density, lighting direction and quality, palette) and the five staging axes (framing, moment, lens, time of day, light).
      
      `asset_describe` on the hero returns a promptable synthesis of its look; that line plus the axes is a stronger opening prompt than either alone (see `scenario-asset-analysis`).
      
      ## Reusing a board later
      
      - Load it: `search` with `filters.collection_ids: ["col_..."]`. Hits carried their own `description` at authoring time, so annotations written with `asset_update` come back alongside the images.
      - Steer by it: `search` with `images: {like: [ids from the board], unlike: [the anti-references]}`. This is the only place a stored anti-reference does work rather than sit in a note.
      - Extend it: run the widen loop again with the board as the near end of the distance ladder, so round two moves rather than restating round one.
      - Hand it off: the collection id plus the three to six reduced references is the whole brief for `scenario-image`, `scenario-consistency`, `scenario-game-assets`, or `scenario-video-ads`.
      
      ## Scoring output against the board
      
      Grade every batch on four axes against the hero and the anti-references: silhouette, palette, materials, detail density. Then three readability tests borrowed from game production: it must read in grayscale, at distance, and in motion. Generate in small batches varying one variable at a time, so a failure names its cause.
      
      When a look is finally right, write the recipe down beside the board: the seed, the prompt with its slot values, the parameter set, and the reference asset ids. A direction that only exists as a habit gets re-derived by the next person, slightly differently.
      
    • sources.md 6.1 KB
      # Where references actually come from
      
      ## Rule zero
      
      A reference informs a prompt. It never ships. Do not reproduce one compositionally, do not drop one into the deliverable as a placeholder to swap later, and never cite a reference you did not actually look at. Take one named mechanic per reference ("pinned silhouette, detail scrolls past it"), not "the vibe".
      
      Describing a living artist's style by name in a prompt is both a rights risk and a moderation risk (see `scenario-moderation`). Name the attributes instead: line weight, palette relationship, edge treatment, value structure. The attributes are what you wanted anyway, and they survive a model switch.
      
      ## Lane 1: the team's own assets
      
      The most skipped lane, and usually the best one, because it is already on brand and already licensed. `search` with `target: "assets"` and `public` omitted searches the current project. Run it at both ends of `query_semantic_ratio`: keyword matches the asset's stored text, so 0.8 is what finds a concept that text never spelled out.
      
      Existing collections are prior art. `collections_list`, then `search` with `filters.collection_ids`, tells you what direction this team already chose once.
      
      ## Lane 2: the Scenario public catalog
      
      `search` with `public: true` reaches assets published by other teams, and it carries two things a normal image search does not.
      
      - Asset hits include `metadata.prompt`, the wording that produced the image. Read it. A prompt is a better souvenir than a JPEG, because it transfers.
      - Model hits (`target: "models"`) included `shortDescription`, `tags`, and `exampleAssetIds` at authoring time. A style model's examples are a finished board for that look, free to browse with `asset_display`, and the model itself is then runnable.
      
      A public asset stays owned by its team. Display it, seed searches with it, read its prompt; to put it on your board you need your own copy (see [moodboard.md](moodboard.md)).
      
      ## Lane 3: the open web
      
      | Source                   | Reachable                              | Key | Notes                                                                                                                   |
      | ------------------------ | -------------------------------------- | --- | ----------------------------------------------------------------------------------------------------------------------- |
      | Pinterest                | No, see below                          | n/a | `robots.txt` ends `User-agent: *` / `Disallow: /`                                                                       |
      | Are.na                   | Yes, `api.are.na/v2`                   | No  | `/channels/<slug>/contents?per=N`; image blocks carry `image.display.url`                                               |
      | The Met                  | Yes, `collectionapi.metmuseum.org`     | No  | `/public/collection/v1/search?q=&hasImages=true`, then `/objects/<id>`; check `isPublicDomain`, download `primaryImage` |
      | Openverse                | Yes, `api.openverse.org/v1`            | No  | Returns `license` and `attribution`; filter them, several forbid derivatives                                            |
      | Cleveland Museum of Art  | Yes, `openaccess-api.clevelandart.org` | No  | `/api/artworks/?q=&has_image=1`; keep `share_license_status: "CC0"`, image at `images.web.url`                          |
      | Wikimedia Commons        | Yes, rate limited                      | No  | Send a descriptive User-Agent and back off on 429                                                                       |
      | Art Institute of Chicago | API yes, images unreliable             | No  | `api.artic.edu/api/v1/artworks/search`; its image host may refuse a fetch                                               |
      
      Are.na is the closest legitimate equivalent to a public moodboard service: channels are user-curated reference collections, and the API serves them without a key. Fetch a channel the user named, on request. Do not sweep the site, and do not present blocks as licensed assets; a channel is someone's reading list, not a rights clearance.
      
      Text search often beats image search here. Learning that a look is called a specific movement, or that a technique has a name, gives you a query seed that works in every other lane. An image you cannot name is hard to search with; a name is not.
      
      **Pinterest.** Its `robots.txt` allowlists named crawlers and closes with `User-agent: *` / `Disallow: /`, so an agent is disallowed from the whole site. Do not fetch it, do not scrape it, and do not route around it with a mirror or an undocumented feed. Its own API is no help either: the read endpoints are scoped to the authenticated account, so it reaches that user's own boards and nobody else's, and even that needs an approved app. Say all of this plainly and offer the route that works: ask the user to open the board themselves and hand over the images. Unattended, treat the board as a source you cannot reach, run the other lanes, and name it in the handover as the one input nobody supplied. Their board is still the best input in this document; it just arrives through them.
      
      ## Lane 4: the user
      
      Ask for three things they already love and one they cannot stand, in any medium. It is the cheapest lane and the highest yield: the seed comes from the person who has to live with the result, and two teams briefing the same agent stop receiving the same answer.
      
      When they name something you cannot see, do not guess. Ask for the file, the URL, or the exact title. Unattended, take these from the task instructions, and when it names none, run the other three lanes and say in the handover that nobody supplied a seed.
      
      ## Bringing an outside image in
      
      Anything from lanes 3 and 4 has to become an asset in your project before it can be boarded or used as a reference. Save the file with `curl -L`, which follows the redirects these hosts use, then take the upload and annotation path in [moodboard.md](moodboard.md).
      
      Keep the source URL in the asset's description as you go. A board whose references cannot be traced back is unusable the moment someone asks where an image came from, and for a CC-licensed source the attribution string is part of the trace.
      
    • widen.md 13.3 KB
      # Prime, then widen
      
      ## Prime: four lines before any search
      
      Chance favors a prepared mind, and an unprimed search returns whatever the brief's own words already contain. Write these down first, in the conversation, so later finds have something to bind to.
      
      1. **Locked**: the constraints that cannot move (ratio, engine budget, existing characters, legibility floor).
      2. **Open**: the one axis actually up for decision. Name it. Everything downstream varies along it.
      3. **Hit**: what a good find looks like, in a sentence that could be checked. "Regions read apart in grayscale" is checkable; "feels premium" is not.
      4. **Both reflexes**: the obvious answer for this brief, and the answer of someone who is merely avoiding the obvious answer. Rule out both. An agent told to be original converges on the second-obvious answer, so it has to be named to be dodged.
      
      Then run the literal, obvious query once and keep the result. That baseline is not a candidate set; it is the control. Anything the widening produces has to include things the baseline did not, or the widening did nothing and you should say so instead of claiming variety.
      
      ## Say which one you mean
      
      Novelty is an item this team has not seen. Diversity is a set whose items are unlike each other. Unexpectedness is an item unlike what the obvious approach returns. Serendipity is unexpected and relevant at once. Asking for diversity when you mean unexpectedness gets you a well-spread set of obvious things. Aim for maximum distance from the reference subject subject to a hard relevance floor, not a free blend of the two.
      
      ## Operators, not adjectives
      
      "Explore broadly" produces variations. These are moves with an input and an output.
      
      Randomize the operator, never the subject. The subject stays exactly what the brief asked for; what varies is the transformation applied to it. A random subject is noise, and it is the reason agent "creativity" usually reads as irrelevance.
      
      | Operator             | The move                                                                                                                                                    |
      | -------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- |
      | Constraint inversion | Write the brief's 3 to 6 unstated rules ("lighting is naturalistic", "the camera is at eye level"), then drop or negate exactly one per variant             |
      | Constraint injection | Add an arbitrary obligatory element the brief never asked for, and hold the rest of the brief fixed                                                         |
      | Bisociation          | Collide the subject with a second frame that is internally rule-rich and rarely co-occurs. If the connection is immediately visible, the frame is too close |
      | Blend                | List A's elements, list B's, name the structure they share, project a chosen subset of each, then run the blend to see what it implies                      |
      | Purpose over surface | State the brief's function ("move heavy things up a shaft safely"), hold it fixed, and find domains that solve it by a different mechanism                  |
      | Nth association      | Ban the top three obvious associates by name before generating, which forces the flat end of the associative hierarchy instead of the strongest link        |
      | Cross-brief          | Retrieve assets that score well against two distinct earlier briefs in this session at once                                                                 |
      
      The test that separates a real analogy from a decorative one: do the mechanisms map, or only the labels? Cross-brief is the one operator that cannot return something irrelevant, because every candidate is already relevant to something the user asked for.
      
      ## Ask yourself for a distribution, not an answer
      
      The operators above widen what you search for. This one widens what you propose, and it is the direct counter to the opening problem: an aligned model asked for one idea returns its most typical one, because the preference data behind alignment rewards familiar text. Asking for the distribution instead relieves that pressure (Verbalized Sampling, arXiv 2510.01171).
      
      1. Write k candidates, each with your own estimate of how likely you were to produce it. Five to ten is enough.
      2. Name the head and discard it out loud, with a one-line reason each. Prime already named the top one; this catches the next few.
      3. Generate again from below the threshold, and build the option set from there.
      4. Carry the estimate into the option set, so a director can see which direction is the consensus and which is the long shot.
      
      The numbers are the model's guesses about itself, not calibrated probabilities. They are good for ordering candidates and for setting a discard threshold. They are not a measurement, so never present one as a percentage of anything real.
      
      This composes with the operators rather than replacing them: draw a wildcard, apply an operator, then ask for the distribution of what that combination could become.
      
      ## The dial: three stops, not a slider
      
      | Stop      | When                      | Settings                                                                          |
      | --------- | ------------------------- | --------------------------------------------------------------------------------- |
      | **Tight** | Executing a decided brief | One query, no wildcards, keep the closest hits                                    |
      | **Open**  | Default                   | Two or three queries on different axes, one wildcard card, both semantic settings |
      | **Wide**  | Nothing decided yet       | Four or more queries, four wildcard cards, a wander chain, far rung included      |
      
      Keep pure randomness to about one slot per set, in its own labeled lane rather than mixed into the main results. An unexpected item that turns out to be irrelevant costs more than it buys.
      
      ## The distance ladder
      
      Sample near, middle, and far, then let evaluation pick. Do not commit to "as far as possible". Measure distance in mechanism rather than in surface topic: a domain that solves the same problem by another means is useful, and a domain that is merely unrelated is not.
      
      Far sampling raises variance rather than the average: more hits and more misses. Generate more candidates on the far rung and expect to discard most of them.
      
      ## Query craft
      
      - **Two or three queries on different axes**, never one. One query returns near-duplicates of a single template. Vary subject, treatment, and graphic language across the set.
      - **Search the feeling, not the category.** Querying the category name returns the category reflex delivered to your desk.
      - **Check the anchor noun is not half a fixed compound.** "Light bulb", "hard surface", and "brass instrument" hijack a query toward the compound.
      - **Anchor an abstract treatment with a concrete noun**, or the results turn into stock abstraction.
      - **Never search a brand you intend to resemble.** You get a knockoff of it, and so does the output.
      
      ## The Scenario search dials
      
      `search` is free, so run several. The dials that change what comes back:
      
      | Dial                     | Behavior                                                                                                                                                                                                  |
      | ------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
      | `query_semantic_ratio`   | 0 (default) is keyword and matches the asset's stored text, so a concept word returned nothing at authoring time while images of exactly that thing sat in the project. 0.8 searches meaning. Run both    |
      | `public`                 | Omitted or false searches the team's own assets; `true` searches the public catalog                                                                                                                       |
      | `images: {like, unlike}` | Steer by example in both directions. Seeds may reappear in their own results                                                                                                                              |
      | `filters`                | `kind`, `tags`, `created_after`, `collection_ids`, `model_id`, `privacy`                                                                                                                                  |
      | `sort_by`                | Ignored while semantic search is active                                                                                                                                                                   |
      | `target: "models"`       | Keyword beats semantic for named styles, but misses by returning nothing at all: re-run at 0.8 before concluding the catalog lacks a look. Each hit carries `shortDescription`, `tags`, `exampleAssetIds` |
      
      Run the same brief at both ends of `query_semantic_ratio` and look at what only one of them found. The keyword pass surfaces literal but odd matches, the semantic pass surfaces conceptual ones, and the difference between the two lists is where the surprises are. Running one setting and calling it a search is the most common way to miss them.
      
      Keep `unlike` short. Negative examples deserve much less weight than positives, and a query stacked with them stops pointing at a chosen region of the space and starts pointing at an arbitrary one, which is the mechanical cause of results that are random but irrelevant.
      
      Two payloads make public search worth more than a normal image search. Public asset hits carry `metadata.prompt`, the exact wording that produced them, which is style research you can read rather than guess at. Public model hits carry `exampleAssetIds`, a ready-made board for that look: `asset_display` a handful before deciding anything.
      
      `estimatedTotalHits` is not a result count. At authoring time it came back large next to an empty `assets` array, so never report it as "found N".
      
      ## The wander chain
      
      A deterministic walk that reaches places no direct query does, using nothing but similarity search:
      
      1. `search` your best query, take the top hit.
      2. `search` again with `images: {like: [that hit]}` and take the fifth or so result, not the first.
      3. Repeat three or four times.
      
      Each hop is small, the accumulation is not, and every step lands on a real asset rather than an invented idea. It is fully reproducible, so a chain that found something good can be written down and re-run.
      
      ## Wildcard draws
      
      [../scripts/wildcard.py](../scripts/wildcard.py) draws far-domain cards from a curated corpus with a real RNG, spread so no two cards in a draw share a facet value or a domain cluster.
      
      ```bash
      python3 scripts/wildcard.py --count 4                 # four cards, fresh seed, printed
      python3 scripts/wildcard.py --count 4 --seed 20260816 # replay an earlier draw
      python3 scripts/wildcard.py --count 6 --facets domain,strategy --json
      python3 scripts/wildcard.py --list # facets, pool sizes, clusters
      ```
      
      A card is a lens over the fixed subject, not a replacement for it: a card reading "shipbreaking beaches" applied to a potion icon asks what a potion icon looks like when it borrows that world's scale, corrosion, and labor, not for a picture of a shipyard. Run the domain as its own `search`, apply the strategy and constraint to what comes back, and discard the cards that go nowhere; that is expected, not failure.
      
      Name the card you drew alongside the result it produced, so the user can pin it or ask for a re-draw. The printed seed matters twice: it replays a draw that worked, and it is the record of what a session was given, so two sessions with the same brief can be checked for having received different starting points.
      
      ## What goes wrong, and the counter
      
      - **The first reference anchors everything downstream.** Counting ideas will not detect it, because the count stays healthy while every idea carries the seed's features; compare features against the seed instead. For depth, seed with exactly one uncommon reference up front. For breadth, withhold references until after a first blind pass, or supply several from distinct categories.
      - **The first three ideas are warmup.** Generate past them before presenting anything.
      - **Every user converges.** Vary the wildcard seed per session and the operators per round, so two people with the same brief do not receive the same four directions.
      - **Round two restates round one.** Keep a running list of what this session already proposed and reject a candidate that sits too close to it. Novelty measured against an archive beats novelty asserted.
      - **Strangeness is not serendipity.** An unexpected find qualifies only when all three hold: it was unexpected, you can articulate the connection to the task, and you can state its concrete value. Two out of three is noise.
      
      ## Audit the set before presenting it
      
      Cover distinct categories rather than producing more ideas inside one. The failure signature is a long list that collapses into two kinds of thing, and the fix is a category requirement, not "generate more".
      
      Then two checks you can actually run. Does the set contain anything the baseline query did not return? And is each item far from its nearest reference, rather than the set being far on average? A set can look spread out while hiding a cluster of near-duplicates, and the nearest one is what gives that away.
      
  • scripts
    • wildcard.py 15.8 KB
      #!/usr/bin/env python3
      """Draw wildcard cards: far-domain lenses for widening a creative brief.
      
      An agent asked to "pick something random" does not sample, it averages: the
      same handful of domains, palettes, and techniques come back every session.
      This script draws instead. It samples from a curated corpus with a real RNG,
      and it enforces spread, so no two cards in one draw share a facet value and no
      two cards come from the same domain cluster.
      
      Run by the agent during the widen step of the scenario-inspiration skill.
      Standard library only, no network, no credits.
      
          python3 wildcard.py --count 4
          python3 wildcard.py --count 4 --seed 20260816 --json
          python3 wildcard.py --count 3 --facets domain,strategy,constraint
          python3 wildcard.py --list
      """
      
      from __future__ import annotations
      
      import argparse
      import json
      import random
      import sys
      
      # Domains are grouped into clusters so a draw cannot return four flavors of the
      # same idea. One cluster contributes at most one card per draw.
      DOMAIN_CLUSTERS: dict[str, list[str]] = {
          "deep-nature": [
              "hydrothermal vent chimneys",
              "slime mold growth fronts",
              "lichen colonies on granite",
              "cephalopod chromatophores",
              "moth wing scales at magnification",
              "salt flat crystallization",
              "mangrove root systems",
              "termite mound ventilation shafts",
          ],
          "built": [
              "brutalist parking structures",
              "roadside bus stop pavilions",
              "stepwells cut into rock",
              "timber stave churches",
              "rooftop accretion in dense housing",
              "cooling tower interiors",
              "capsule tower apartments",
              "irrigation terraces on a hillside",
          ],
          "craft": [
              "patched and re-patched work textiles",
              "carved and painted folk figures",
              "strip-woven cloth sewn into panels",
              "tin-glazed blue and white pottery",
              "weaving workshop color samplers",
              "gold-seam ceramic repair",
              "carved horn and antler tools",
              "hand-drawn carpet cartoons",
          ],
          "industry": [
              "shipbreaking beaches",
              "textile mill bobbin walls",
              "foundry pour on night shift",
              "container port gantry cranes",
              "printing press make-ready sheets",
              "fish cannery lines",
              "quarry cutting faces",
              "grain elevator interiors",
          ],
          "science": [
              "cloud chamber particle tracks",
              "schlieren airflow photography",
              "anatomical teaching plates",
              "radio telescope dish arrays",
              "diffraction patterns from crystals",
              "bathymetric survey charts",
              "electron micrographs of alloys",
              "weather balloon instrument packs",
          ],
          "vernacular": [
              "hand-painted truck decoration",
              "laundromat signage lettering",
              "roadside shrine assemblages",
              "skate park concrete patina",
              "market stall tarpaulin colors",
              "barbershop wall diagrams",
              "pigeon loft architecture",
              "allotment shed improvisation",
          ],
          "stage": [
              "carved theatrical masks",
              "carnival float construction",
              "rod and string puppet mechanisms",
              "ceremonial firefighter coats",
              "circus rigging and guy lines",
              "liturgical vestment embroidery",
              "cut leather shadow puppets",
              "pageant lighting rigs",
          ],
          "archive": [
              "botanical lithograph plates",
              "portolan navigation charts",
              "seed catalogue covers",
              "fire insurance maps",
              "silent film title cards",
              "naval signal flag manuals",
              "mail order catalogue plates",
              "typographic specimen books",
          ],
          "frontier": [
              "polar research station interiors",
              "deep mine cage descents",
              "high altitude balloon gondolas",
              "desert seismic survey camps",
              "submarine control rooms",
              "glacier ice core libraries",
              "volcano monitoring huts",
              "orbital debris tracking screens",
          ],
          "market": [
              "night market lighting",
              "fishmonger ice displays",
              "apothecary drawer walls",
              "vending machine banks",
              "flower auction halls",
              "spice sack geometry",
              "hardware store bin walls",
              "bakery window staging",
          ],
      }
      
      POOLS: dict[str, list[str]] = {
          "strategy": [
              "swap the figure and the ground",
              "make the background the subject",
              "age it two hundred years, then repair it",
              "build it for someone half the size",
              "remove the most expensive element",
              "state the opposite and mean it",
              "keep only the silhouette, rebuild the rest",
              "borrow the joinery, discard the shape",
              "design the packaging before the thing",
              "take the second-most-obvious answer",
              "make the repair the most visible part",
              "let the process leave its marks",
              "do it in the wrong material",
              "honor the error instead of hiding it",
              "reduce until one thing remains, then add back one",
              "move the light, not the camera",
              "treat it as evidence, not as illustration",
              "shift it one climate over",
              "shift it one century over",
              "give it a smell, then draw that",
              "show it mid-repair rather than finished",
              "ask what the night shift sees",
              "make the cheap version, then the sacred version",
              "keep the rhythm, change everything else",
          ],
          "constraint": [
              "readable as a silhouette in solid black",
              "no more than three values",
              "every element on a strict grid",
              "nothing perfectly straight",
              "the subject occupies under fifteen percent of frame",
              "symmetry broken exactly once",
              "no faces visible",
              "all edges soft, no hard boundary",
              "must survive being scaled to 32 pixels",
              "negative space carries the read",
              "no text anywhere",
              "a single light source, no fill",
              "the horizon never appears",
              "repetition with one deliberate error",
              "nothing machined, everything hand-made",
              "one material throughout",
              "square frame, and it stays square",
              "the subject is partly occluded",
              "no pure black and no pure white",
              "one continuous unbroken contour",
          ],
          "light": [
              "single hard key with black falloff",
              "overcast north light, no shadows",
              "sodium vapor street orange",
              "underwater caustics",
              "candlelight at eye level",
              "backlit fog with visible beams",
              "fluorescent tube ceiling wash",
              "moonlight with practical windows",
              "rim light against a dark field",
              "bounce off a strongly colored wall",
              "firelight from below",
              "sunrise raking across texture",
              "overhead noon with short shadows",
              "even studio softbox, flat",
              "neon spill on wet ground",
              "projector beam through dust",
              "screen glow on faces",
              "stage followspot with a hard edge",
              "clerestory shafts across a floor",
              "headlamp beam in darkness",
              "refrigerated case cold white",
              "golden hour long shadows",
              "silhouette against a bright sky",
              "lightning flash frozen mid-frame",
          ],
          "palette": [
              "two colors only, plus paper white",
              "near-monochrome with one accent",
              "complementary split at low saturation",
              "warm neutrals against cold shadow",
              "full desaturation except skin tones",
              "high-key pastels, no true black",
              "black, bone, and oxide red",
              "analogous greens climbing to yellow",
              "duotone, ink over a tinted ground",
              "fluorescent accent over a muted base",
              "earth pigments only",
              "metallic on matte black",
              "washed denim and rust",
              "cyan shadows, amber highlights",
              "one hue, rotated through value only",
              "print misregistration as color",
              "sun-bleached plastics",
              "jewel tones on velvet black",
              "chalk and charcoal on grey",
              "the obvious palette, inverted",
          ],
          "material": [
              "worn enamel over steel",
              "unfired clay",
              "oiled hardwood",
              "brushed aluminium",
              "waxed canvas",
              "blown glass with bubbles",
              "cast concrete with form marks",
              "felted wool",
              "lacquered paper",
              "corroded bronze",
              "extruded plastic with visible seams",
              "pressed tin",
              "woven cane",
              "resin with suspended particles",
              "raw silk",
              "galvanized mesh",
              "burnished leather",
              "terrazzo aggregate",
              "salt-crusted rope",
              "crackle-glazed ceramic",
          ],
          "technique": [
              "risograph two-pass print",
              "gouache on toned paper",
              "silverpoint drawing",
              "cel animation over painted backgrounds",
              "cyanotype contact print",
              "linocut with visible tool marks",
              "airbrushed pulp cover art",
              "technical isometric line drawing",
              "collaged cut paper",
              "wet plate photography",
              "flat vector with hard shadows",
              "oil impasto on board",
              "pixel art on a fixed palette",
              "stop motion photographed under lights",
              "screen print with halftone dots",
              "ink wash with reserved whites",
              "graphite rendering with sheen",
              "photogrammetry with mesh artifacts",
              "stained glass leading",
              "tapestry weave with visible warp",
              "scratchboard, white on black",
              "marbled paper floated on water",
              "blueprint reversal",
              "embroidery on canvas",
          ],
          "camera": [
              "worm's-eye at ankle height",
              "top-down flat lay",
              "wide angle with edge distortion",
              "long lens compressed portrait",
              "macro at material scale",
              "long lens through foreground clutter",
              "isometric three-quarter",
              "dead-center symmetrical",
              "over-the-shoulder into depth",
              "extreme close on one detail",
              "wide establishing with a tiny figure",
              "handheld and tilted off-axis",
              "reflected in a curved surface",
              "framed through a doorway",
              "high corner, surveillance angle",
              "flatbed scan, no perspective",
          ],
          "mood": [
              "patient and unhurried",
              "brittle tension",
              "ceremonial gravity",
              "offhand and unposed",
              "exhausted after effort",
              "reverent",
              "gleeful and unruly",
              "clinical detachment",
              "nostalgic without sentiment",
              "ominous but still",
              "convivial and crowded",
              "solitary and self-sufficient",
              "newly abandoned",
              "freshly built and unused",
              "weathered but maintained",
              "improvised under pressure",
              "festive at closing time",
              "watchful",
              "quietly triumphant",
              "bureaucratically dull",
          ],
      }
      
      FACET_ORDER = [
          "domain",
          "strategy",
          "constraint",
          "light",
          "palette",
          "material",
          "technique",
          "camera",
          "mood",
      ]
      
      DEFAULT_FACETS = ["domain", "strategy", "constraint", "light", "palette", "technique"]
      
      
      def facet_capacity(facet: str) -> int:
          """How many distinct cards a facet can supply in one draw.
      
          Domain is capped by cluster count, not by domain count: one cluster
          contributes at most one card, which is what keeps a draw from returning
          four variations on the same idea.
          """
          if facet == "domain":
              return len(DOMAIN_CLUSTERS)
          return len(POOLS[facet])
      
      
      def draw(count: int, facets: list[str], rng: random.Random) -> list[dict[str, str]]:
          """Draw `count` cards, spread across every requested facet.
      
          No facet value repeats within a draw, and each card's domain comes from a
          different cluster. Raises ValueError when a facet cannot supply `count`
          distinct values.
          """
          if count < 1:
              raise ValueError("count must be at least 1")
      
          unknown = [f for f in facets if f != "domain" and f not in POOLS]
          if unknown:
              raise ValueError(f"unknown facet(s): {', '.join(sorted(unknown))}")
          if not facets:
              raise ValueError("at least one facet is required")
      
          for facet in facets:
              capacity = facet_capacity(facet)
              if count > capacity:
                  raise ValueError(
                      f"count {count} exceeds what facet '{facet}' can spread over "
                      f"({capacity} distinct values)"
                  )
      
          columns: dict[str, list[str]] = {}
          for facet in facets:
              if facet == "domain":
                  clusters = rng.sample(sorted(DOMAIN_CLUSTERS), count)
                  columns["domain"] = [rng.choice(DOMAIN_CLUSTERS[c]) for c in clusters]
                  columns["cluster"] = clusters
              else:
                  columns[facet] = rng.sample(POOLS[facet], count)
      
          ordered = [f for f in FACET_ORDER if f in facets]
          cards = []
          for i in range(count):
              card: dict[str, str] = {"label": chr(ord("A") + i) if i < 26 else str(i + 1)}
              for facet in ordered:
                  card[facet] = columns[facet][i]
                  if facet == "domain":
                      card["cluster"] = columns["cluster"][i]
              cards.append(card)
          return cards
      
      
      def render(cards: list[dict[str, str]], seed: int) -> str:
          lines = [f"seed: {seed}  (re-draw this exact set with --seed {seed})", ""]
          for card in cards:
              header = card["label"]
              if "domain" in card:
                  header = f"{header}. {card['domain']}  [{card['cluster']}]"
              lines.append(header)
              for facet in FACET_ORDER:
                  if facet == "domain" or facet not in card:
                      continue
                  lines.append(f"   {facet:<10} {card[facet]}")
              lines.append("")
          return "\n".join(lines).rstrip() + "\n"
      
      
      def render_list() -> str:
          lines = ["facet       pool  notes"]
          domains = sum(len(v) for v in DOMAIN_CLUSTERS.values())
          lines.append(
              f"{'domain':<11} {domains:>4}  "
              f"{len(DOMAIN_CLUSTERS)} clusters, one card each per draw"
          )
          for facet in FACET_ORDER:
              if facet == "domain":
                  continue
              lines.append(f"{facet:<11} {len(POOLS[facet]):>4}")
          lines.append("")
          lines.append("clusters: " + ", ".join(sorted(DOMAIN_CLUSTERS)))
          lines.append("default facets: " + ",".join(DEFAULT_FACETS))
          return "\n".join(lines) + "\n"
      
      
      def main(argv: list[str] | None = None) -> int:
          parser = argparse.ArgumentParser(
              description="Draw far-domain wildcard cards for a creative brief."
          )
          parser.add_argument(
              "--count", type=int, default=4, help="how many cards to draw (default 4)"
          )
          parser.add_argument(
              "--seed",
              type=int,
              default=None,
              help="RNG seed; omitted means a fresh random seed, printed so the draw repeats",
          )
          parser.add_argument(
              "--facets",
              default=",".join(DEFAULT_FACETS),
              help=f"comma-separated facets, or 'all'. Default: {','.join(DEFAULT_FACETS)}",
          )
          parser.add_argument("--json", action="store_true", help="emit JSON")
          parser.add_argument(
              "--list", action="store_true", help="show facets, pool sizes, and clusters"
          )
          args = parser.parse_args(argv)
      
          if args.list:
              sys.stdout.write(render_list())
              return 0
      
          raw = args.facets.strip()
          facets = list(FACET_ORDER) if raw == "all" else [f.strip() for f in raw.split(",")]
          facets = [f for f in facets if f]
      
          seed = args.seed if args.seed is not None else random.SystemRandom().randrange(2**31)
      
          try:
              cards = draw(args.count, facets, random.Random(seed))
          except ValueError as exc:
              # parser.error() prints usage and exits 2; it never returns.
              parser.error(str(exc))
      
          if args.json:
              sys.stdout.write(json.dumps({"seed": seed, "cards": cards}, indent=2) + "\n")
          else:
              sys.stdout.write(render(cards, seed))
          return 0
      
      
      if __name__ == "__main__":
          raise SystemExit(main())
      
  • SKILL.md 6.3 KB
    ---
    name: scenario-inspiration
    description: "Use when a creative task has no direction yet: finding inspiration, exploring looks or styles, proposing concept directions to pick between, building a moodboard or reference board, doing visual research, mining existing assets for a style, or escaping generic AI-looking output. Also when a saved Scenario collection should drive a new batch as art direction. Keywords: inspiration, moodboard, references, art direction, style exploration, concepts, serendipity, ideation, surprise me."
    license: MIT
    ---
    
    # Scenario Inspiration
    
    ## Overview
    
    Asked for inspiration, an agent averages. It returns the most typical answer for the brief, so every user with a similar brief gets the same look. This skill trades that for four phases: **prime**, **widen**, **choose**, **board**. Connection and scope: see the `scenario` skill in this repo. If a sibling skill named here is missing from your available skills, ask the user to install it (`npx skills add scenario-labs/skills --skill <name>`); unattended, proceed from tool schemas and flag the gap.
    
    Four moves carry most of the value. Name the reflex answer for this brief and the answer of someone merely avoiding that reflex, then rule out both, because an agent told to be original lands on the second-obvious answer. Randomize the operator, never the subject: what varies is the transformation applied to the brief, and a random subject is just noise. When you generate candidates yourself instead of searching for them, ask yourself for a distribution rather than an answer, and work from its tail. Then make the user pick, because options that never resolve are a gallery, not direction.
    
    ## Quick reference
    
    | Phase     | Do                                                                                     | Detail                                                   |
    | --------- | -------------------------------------------------------------------------------------- | -------------------------------------------------------- |
    | 1. Prime  | Locked constraints, the open axis, both reflexes, what counts as a hit                 | [references/widen.md](references/widen.md)               |
    | 2. Widen  | Four lanes plus wildcard draws; over-gather, near and far                              | widen.md, [references/sources.md](references/sources.md) |
    | 3. Choose | Three or four mutually exclusive directions one named axis apart, plus an escape hatch | [references/choose.md](references/choose.md)             |
    | 4. Board  | The pick becomes a collection, every reference annotated with its job                  | [references/moodboard.md](references/moodboard.md)       |
    
    Four lanes feed phase 2. Ask the user first, for three things they already love and one they cannot stand; unattended, take those from the task instructions and continue without them if it names none. Then `search` with `target: "assets"` twice, once over the team's own work (`public` omitted) and once over the public catalog (`public: true`), and last the open web, which is not a `search` call. Public asset hits carried `metadata.prompt`, the wording that produced them, and `target: "models"` hits carried `exampleAssetIds` at authoring time: free style research either way. `images: {like, unlike}` steers by example in both directions.
    
    Draw far domains yourself with [scripts/wildcard.py](scripts/wildcard.py), run from the skill directory (`python3 scripts/wildcard.py --count 4`). A model asked for something random samples its own habits; the script samples a corpus and prints its seed, so a draw can be replayed or deliberately never repeated.
    
    ## Worked example: a puzzle game's world map, nothing decided
    
    1. **Prime.** Locked: 16:9, readable at phone size. Open: everything else. Reflex: candy-colored isometric islands. Second reflex: the same islands, muted and "cozy". Both are out of bounds now. A hit is a map whose regions read apart in grayscale. Run the obvious query once and keep it as the baseline to beat.
    2. **Widen.** `search` the project for anything already on brand, then `public: true` at `query_semantic_ratio: 0.8` and again at the keyword default, reading the prompts on the best hits. Draw four wildcards, run each as its own query, and keep near, middle, and far finds rather than only the strangest.
    3. **Choose.** Name the axis first (here, how the world is depicted), then four positions on it. Each gets a title, an intent line, two or three references shown with `asset_display`, and who it wins for and when it fails. Say what you cut. Ask which is closest and what they would take from another, and offer the escape hatch. When nobody can answer, take the pick from the task instructions, else choose the option that best satisfies the hit line from prime, say which and why, mark it provisional, and keep going.
    4. **Board.** `collection_create` the winner, then copy in every foreign reference: public assets belong to their own team, and `collection_add_assets` on one returned 403 at authoring time. `asset_download`, `curl -L`, `upload_asset`. `asset_update` each with its reason, tag the anti-references, hand the collection id to `scenario-image` or `scenario-consistency`.
    
    ## Common mistakes
    
    - Skipping prime and searching the brief's own words, which returns the category reflex sorted by relevance.
    - Four options that are one idea in four colors. If picking A does not rule out B, they are not directions.
    - Presenting only the survivors. Naming what was cut, and why, is what makes the rest credible.
    - Calling a set varied without checking it against what the literal query already returned.
    - Treating every strange find as a keeper. It earns a slot only when you can name what it connects to and what it is worth.
    - Boarding whatever came back. Every reference needs a job (light, color, composition, material, shape, subject, environment) or it is decoration.
    - Mixing lighting worlds on one board: a hard-flash reference and a soft-window reference cancel at generation time.
    - Handing a model an 18-image board. Reduce to three to six role-tagged references first.
    - Shipping the undirected default when the brief asked for none of it: subject centered and facing the lens, posed, evenly lit, everything in focus, a processed gloss. Every axis a prompt leaves open (framing, moment, lens, time of day, light) is filled with the model's most average answer, so name each one.
    

Comments (0)

Sign in to join the conversation.

No comments yet.

Reviews (0)

No reviews yet.

Related