Comps are shipped screens: subject present, mode readable, depth over coverage - #563
Conversation
… coverage Factory review evidence (two batches, both lanes): generated comps drift poster-ward. They render the world's atmosphere at high density, drop the surface's subject (a motorcycle forum comped with no motorcycles), and stop reading as screens a product would ship. The existing anti-vignette self-check catches the fully collapsed case but says nothing about density or subject presence, and new-work's "committed all the way" reads as a coverage instruction. Three sibling self-checks in visualize.md's comp discipline, each phrased per mode (Persuade/Operate/Read/Experience) and platform-neutral: the subject appears as the content the regions hold; the mode must be readable from the image alone; commitment is depth, not coverage, with one dominant move per viewport. new-work.md's decision-comp rule gains a clause binding the same checks so the direction round inherits them explicitly. AI-assisted (Claude Fable 5), prepared for maintainer review. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Tightens the comp-generation discipline in the visualize reference so “direction comps” read as shipped screens (subject present, mode legible, depth over coverage), and explicitly binds those same checks into the new-work decision-comp rule to prevent “committed all the way” from being interpreted as maximal coverage/density.
Changes:
- Add three new comp self-checks to
skill/reference/visualize.md: subject presence, mode legibility, and depth-over-coverage. - Amend
skill/reference/new-work.md’s decision-comp rule to explicitly require the same self-checks for decision comps.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| skill/reference/visualize.md | Adds three sibling “self-check” bullets to prevent busy atmosphere comps that omit the surface’s subject or unreadably blur the surface mode. |
| skill/reference/new-work.md | Updates the decision-comp instruction so “committed all the way” is constrained by the same subject/mode/depth checks used in visualize.md. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| Render three distinct high-fidelity north-star comps of the requested surface, with whatever generation capability exists, saved under `.impeccable/mocks/` so they survive the session. Comp at the surface's own viewport: portrait at device size for a native app or mobile-first surface, desktop landscape otherwise; a phone screen comped landscape misstates the composition before anything gets built against it. Comps are the build thread's own work, never delegated: the thread that writes the comp prompts holds the direction's full context, and it has already seen every comp when the build starts. Open every image you produce or reference by its workspace-relative path, never an absolute one: sandboxed viewers reject absolute paths, and everything under the project root has a relative path. Base them on the real content and the surface concepts already developed with the user. Three is the number: one comp invites rubber-stamping, and the spread between three is what surfaces the composition worth building. The chosen card's decision comp is the first of the three: it already renders this direction at full fidelity under this file's discipline, so this round generates two more that vary what the first held fixed, and all three go to the approval point together. Only a round that arrives with no decision comp, a degraded roll, an identity-mode page, a direction pinned without the decision round, renders all three here. | ||
|
|
||
| - A comp is a designed surface, not a picture of the subject. Lead the generation prompt with the surface's own structure, whatever regions this design actually has, named in order with their scale relationships; a page with no navigation states that instead of inventing one, and an unconventional surface states its unconventional skeleton. A prompt that leads with the world's atmosphere gets a vignette back: the model paints the fish market instead of the fish market's website. Self-check every render: if it could hang as a poster, or reads as a photograph or scene with some text on it, it is not a comp; regenerate with the layout scaffold stated more literally. | ||
| - The inverse failure fails too: a surface with none of its subject in it. The subject appears as the content the regions exist to hold: a forum about machines shows the machines, a menu shows the dishes, a player shows the work it plays, a dashboard shows the live data it watches. The world dresses the frame and never displaces what the frame exists to show. Self-check every render: point at the subject; a render that depicts everything about the world and nothing of the subject fails however faithful its atmosphere, so regenerate with the subject's imagery named region by region in the prompt. |
There was a problem hiding this comment.
Fair on the stutter: rephrased in 53a6947 to "The inverse is also a failure: a surface with none of its subject in it." AI-assisted (Claude Fable 5).
| The standing exit: every direction round offers one quiet, permanent alternative, the category standard, played straight. It is the user's door, never yours: never recommend it, never weigh it against the roll, never let it soften the dealt directions; the counterweights bind the unchosen default, not the chosen one. When the user takes it, in the canon action, a safer-steer, or plain words asking for the familiar or competitor-like path, convention becomes the commitment: ask once for two or three products this should sit alongside, make their craft level the bar, and execute the canon at full fidelity, without irony or smuggled quirk. A standing preference gets recorded as a brand commitment in PRODUCT.md. <!-- rule:skill-canon-standing-exit --> Re-roll eliminates every direction already shown, grounded and challenger alike; after two consecutive re-rolls, ask what quality is missing. You may re-roll on your own only on named factual grounds, when the assigned direction cannot carry the product's truth or task; taste is never grounds. The user may re-roll freely, and a user- or brief-pinned direction beats the roll, always. <!-- rule:skill-assigned-plus-reroll --> Present the decision visually: write an options payload with the assigned direction leading and its raised lines included, the pick card when one exists, the dealt challengers as alternates carrying their QUALITY BAR cards plus each challenger's verdict and kept line, re-roll with its safer and bolder registers, steer, plus canon enabled, and `followup: true` when the execution-contract round will follow (it does whenever image generation exists and no standing build-path preference is recorded); a degraded roll with no challengers still uses the page, as a single text-only card with re-roll. Give every card the same anatomy, thesis, palette, materials, first viewport, honest risk, and the challengers' case lines (run the script with `--schema` for the exact shape); the page renders identity from these fields, routes declined challengers to a demoted row on its own, and a challenger's catalog image rides as labeled inspiration, never as the promise of the build. Author `canonCard` too: the category standard as one honest card with the same anatomy; the page keeps it subordinate, and the counterweights still bind you. Run `node {{scripts_path}}/serve-question.mjs --start --payload <file>` (run it with `--schema` first for the exact payload shape). It daemonizes, prints the page URL and a key, and exits immediately; now open that URL for the user, in-app browser first, then the system opener, then showing the URL. Collect the choice with `--wait --key <key>`, repeating while it exits 3; the ANSWER prints as JSON. Exit 4 means the page was closed without an answer: re-present once through the structured question tool, and with no answer there either, proceed unattended with the assigned direction and state the assumptions. A harness that can leave a shell blocked in the background may instead run the script without `--start` and let it auto-open and block. Only a session where no browser can open at all, headless, CI, an eval worker, a remote shell with no display, puts the same decision through the structured question tool instead; the script self-detects these environments and exits 2 with that advice, so treat exit 2 as this fallback, never as an error to retry. <!-- rule:skill-visual-decision-page --> | ||
|
|
||
| When image generation exists, every card also declares a `sketch` path under `.impeccable/mocks/decision/` (the field keeps its wire name for compatibility; what it carries is the card's comp), the canon card included. Where the harness sandboxes its shell, start the page through the least-sandboxed command path it offers: a sandboxed shell cannot bind the board's port, and the first-attempt failure costs a retry every session. Serve the page first, then produce the comps; the page shimmer-waits per slot and the user may answer before they land. Each card's image is that direction's north-star comp at full fidelity, produced under the comp discipline in [visualize.md](visualize.md): the requested surface's first viewport, structure-led prompt, real product name and real content, no invented commercial claims, in that card's own palette, type character, and material world, committed all the way. Generation takes the same time at any fidelity, so an unfinished sketch pays sketch quality for comp cost; fairness between cards comes from equal fidelity in each card's own grammar, one surface, one aspect, never from shared unfinishedness. The frame's aspect is the surface's own: a native app or mobile-first surface comps portrait at its device viewport, a desktop web surface landscape, and the decision page adapts to either, so a phone screen comped landscape is a broken frame, not a neutral default. Produce in the order the user reads, the assigned card, then the pick, then the full-card hand, then canon, each file written with its prompt sidecar the moment it is done, so a re-roll's spend front-loads onto the cards read first; declined challengers get no comp, their catalog thumb is their face. When the harness runs subagents in parallel, fan the set out as one agent per card: each spawn is the shipped asset producer with a single-comp packet, that card's fields, PRODUCT.md, the shared frame, and the card's declared path, up to four in flight at once. A slot still empty when its agent returns is regenerated inline, and a slot still empty when the user answers is dropped without ceremony; no other supervision is owed. Without parallel subagents, generate in the main thread after serving, in the same reading order, and let the harness's own generation display carry the progress; the wait for the answer follows the last file. The chosen card's comp is not spent by the choice: on a comp-led build it enters the comp round as compositional option one, and on a code-led build it returns at the finish review as the critique reference, what the image dared that the build did not. The unchosen comps stay in `.impeccable/mocks/decision/` as the round's spent hand; they carry no approval and imply none. With no image generation, the cards carry their identity in palette chips and facts, and that page is complete, not a lesser version; the page then also demotes every challenger's catalog art to a labeled thumbnail on its own, because salience must encode the verdict, never the accident of which cards have images. <!-- rule:skill-decision-comps-full-fidelity --> <!-- rule:skill-salience-parity --> | ||
| When image generation exists, every card also declares a `sketch` path under `.impeccable/mocks/decision/` (the field keeps its wire name for compatibility; what it carries is the card's comp), the canon card included. Where the harness sandboxes its shell, start the page through the least-sandboxed command path it offers: a sandboxed shell cannot bind the board's port, and the first-attempt failure costs a retry every session. Serve the page first, then produce the comps; the page shimmer-waits per slot and the user may answer before they land. Each card's image is that direction's north-star comp at full fidelity, produced under the comp discipline in [visualize.md](visualize.md): the requested surface's first viewport, structure-led prompt, real product name and real content, no invented commercial claims, in that card's own palette, type character, and material world, committed all the way, where commitment is depth, not coverage: visualize.md's self-checks, the mode readable from the image, one dominant move, the subject present as content, bind decision comps identically. Generation takes the same time at any fidelity, so an unfinished sketch pays sketch quality for comp cost; fairness between cards comes from equal fidelity in each card's own grammar, one surface, one aspect, never from shared unfinishedness. The frame's aspect is the surface's own: a native app or mobile-first surface comps portrait at its device viewport, a desktop web surface landscape, and the decision page adapts to either, so a phone screen comped landscape is a broken frame, not a neutral default. Produce in the order the user reads, the assigned card, then the pick, then the full-card hand, then canon, each file written with its prompt sidecar the moment it is done, so a re-roll's spend front-loads onto the cards read first; declined challengers get no comp, their catalog thumb is their face. When the harness runs subagents in parallel, fan the set out as one agent per card: each spawn is the shipped asset producer with a single-comp packet, that card's fields, PRODUCT.md, the shared frame, and the card's declared path, up to four in flight at once. A slot still empty when its agent returns is regenerated inline, and a slot still empty when the user answers is dropped without ceremony; no other supervision is owed. Without parallel subagents, generate in the main thread after serving, in the same reading order, and let the harness's own generation display carry the progress; the wait for the answer follows the last file. The chosen card's comp is not spent by the choice: on a comp-led build it enters the comp round as compositional option one, and on a code-led build it returns at the finish review as the critique reference, what the image dared that the build did not. The unchosen comps stay in `.impeccable/mocks/decision/` as the round's spent hand; they carry no approval and imply none. With no image generation, the cards carry their identity in palette chips and facts, and that page is complete, not a lesser version; the page then also demotes every challenger's catalog art to a labeled thumbnail on its own, because salience must encode the verdict, never the accident of which cards have images. <!-- rule:skill-decision-comps-full-fidelity --> <!-- rule:skill-salience-parity --> |
There was a problem hiding this comment.
This clause no longer exists in its reviewed form: cb305fd trimmed it to "committed all the way; visualize.md's self-checks bind decision comps identically." Naming the individual checks inline was considered and deliberately rejected during the adversarial prose review, because an inline summary drifts the moment visualize.md changes; the single reference is the contract. AI-assisted (Claude Fable 5).
Greptile SummaryThe decision-page media contract now uses Confidence Score: 5/5No blocking failure remains. The exercised decision-page flow renders and selects canonical and legacy media payloads correctly, with focused server and browser coverage passing.
What T-Rex did
Reviews (6): Last reviewed commit: "Close the unnamed-focal-moment gap; unst..." | Re-trigger Greptile |
The deliverable died in #545; the word survived as the decision-page payload's field name, annotated everywhere it appeared with the same compatibility apology. The page and the skill text ship together and payloads are per-session, so the compatibility burden is one input alias, not a frozen name. serve-question.mjs: the card field, the answer key, the schema docs, the --schema example, the help text, and every internal identifier (compSrc, data-comp, .media.comp-pending, img.comp, comp-note) now say comp; a payload declaring the legacy sketch key still renders and answers identically. new-work.md and the asset producer drop their wire-name parentheticals. The unit suite covers the canonical answer key coming back from a legacy-key payload; the new-work e2e's declined-card stray comp stays declared as sketch, which doubles as alias coverage. AI-assisted (Claude Fable 5), prepared for maintainer review. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
Before/after evidence prepared for review: the three clearest declined factory comps (vintage moto forum, Lektor, Italian restaurant) re-rendered with the same image model and the same world/palette/content, after rewriting each session's recovered generation prompt to satisfy this PR's three self-checks. One render each, no cherry-picking. The side-by-side page was shared with the maintainer directly. AI-assisted (Claude Fable 5). |
…ywhere prompts are authored The declined moto-forum comp's prompt read 'no gradients, no rounded SaaS cards, no photography, no fake member counts, no badges, no testimonials': the reflex that rightly bans invented claims swallowed the one medium the subject lives in, and that is exactly how a motorcycle forum got comped with no motorcycles. The lektor prompt's 'no AI imagery', written by an image model, is the same fingerprint. One counterweight, phrased once per authoring surface: the comp discipline's subject-presence check (which the decision comps already bind), the asset producer's own prompt rules (a standalone agent that never reads visualize.md), and new-work's author-assets law (the path a code-led build takes without the comp round). Truth binds claims, not demonstrations; a photo of the subject doing its job is a demonstration. AI-assisted (Claude Fable 5), prepared for maintainer review. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Proven necessary by its own demo: the first re-render of the declined moto-forum comp satisfied subject-present and one-dominant-move by deleting the value proposition, leaving a members' index that told a first-time visitor nothing about what this is or why to care. Paul caught it. Quieting a region means it stops performing, not that it leaves; empty is quieter, not calmer. AI-assisted (Claude Fable 5), prepared for maintainer review. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Two independent skeptic passes over the added prose, one hunting oversteer and example bias, one hunting mode and platform damage. What they killed, and why: - The absolute 'never a medium' rule contradicted the file's own imagery-stance fixity two paragraphs up and stripped legitimate guards (an illustration-committed world, a native app screen warding off stock-photo drift). A medium ban now belongs to the committed imagery stance, never to caution, and the rule appears once per reader context instead of five times corpus-wide. - The quoted incident string and the four-example subject list taught the model the exact framings they existed to prevent. Gone; the abstract rule plus the point-at-the-subject check carry it. - 'A first-time visitor learns what this is, why it matters, and what to do' was Persuade anatomy imposed on all four modes. The guard is now mode-neutral: a quieted region keeps its information and stops performing. - 'Calm is what Operate and Read surfaces are for' contradicted operate.md's density affordance. Deleted; modes stay defined in one place. - The focal-moment count now presupposes nothing: it fires only where the direction names a focal moment, and only on same-scale rivalry, so an even, calm field stops reading as a failure. - The decision-comp clause and the mode bullet no longer restate what they can reference. Net: the prose additions drop from roughly 480 words to under 200, with no quoted strings and no example lists. AI-assisted (Claude Fable 5), prepared for maintainer review. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit cb305fd. Configure here.
Cursor's finding was real: gating the density check on a named focal moment let a busy comp pass whenever the direction named none, which is the common case on the lane that produced the busy comps. The second leg reuses the bullet's own distinction: several regions performing the concept at once is the same shout; regions doing their jobs are not. AI-assisted (Claude Fable 5). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

HELD FOR MAINTAINER REVIEW — do not merge on green. Prepared at Paul's request after the 2026-08-09/11 factory candidate reviews.
Evidence
Two factory batches (old stack and post-#531/#545, sol and opus lanes) produced comps Paul declined on the same grounds each time, verbatim:
The failure is consistent: comps render the world's atmosphere at high density, drop the surface's subject, and stop reading as screens a product would ship. The existing anti-vignette self-check in visualize.md catches the fully collapsed case (a poster) but says nothing about density or subject presence, and new-work's "committed all the way" reads as a coverage instruction.
Change
Three sibling self-checks added to visualize.md's comp discipline, mirroring the existing self-check pattern:
Plus one clause in new-work.md's decision-comp rule (
skill-decision-comps-full-fidelity) binding the same checks explicitly, since "committed all the way" was the maximalism trigger and the direction round produced busy comps too.bun run buildgreen including both prose validators. Source-only diff; no generated output staged.AI-assisted (Claude Fable 5), operating under instructions from pbakaus.
🤖 Generated with Claude Code
Note
Medium Risk
Touches the decision-page contract and ANSWER shape agents rely on; legacy
sketchaliasing limits breakage but consumers must expectcompgoing forward.Overview
Tightens north-star comp generation so decision and build-round images read as shippable screens, not atmospheric vignettes.
visualize.mdadds three self-checks alongside the existing anti-poster rule: subject must appear as region content (world dresses the frame, exclusions bind claims not media), the visitor’s job/mode must be readable without a caption, and commitment is depth over coverage (one dominant move; busy is louder, not bolder).new-work.mdand the asset producer bind the same discipline to decision comps and clarify that prompt exclusions must not strip a card’s committed imagery (e.g. photographs stay when the world uses them).Renames the decision-page payload and UI from
sketchtocompend to end: card fieldcomp, shimmer slots (comp-pending,data-comp), schema/docs, and ANSWER JSON now emitcomp.serve-question.mjsstill accepts legacysketchon input and normalizes tocompon output so older payloads keep working. Tests cover late comp streaming and legacy-key answers.Reviewed by Cursor Bugbot for commit 53a6947. Bugbot is set up for automated code reviews on this repo. Configure here.