mirror of
https://github.com/pbakaus/impeccable.git
synced 2026-09-14 17:29:05 +08:00
codex/release-signed-bundle-cli
219 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
cb305fdca1 |
Two adversarial reviews later, the discipline says half as much
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> |
||
|
|
e91c273361 |
The density check cuts competition, never content
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> |
||
|
|
e867487d55 |
Ban fabrications, never media: counter the exclusion-list reflex everywhere 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> |
||
|
|
248a4a699a |
Retire the sketch era's wire name: the field is comp, sketch is an alias
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> |
||
|
|
62e90a257f |
Comps are shipped screens: subject present, mode readable, depth over 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> |
||
|
|
dc4e4a4bd6 |
Denoise the design hook and let agents self-serve confident ignores (#508)
* Denoise the design hook and let agents self-serve confident ignores (#497)
The directive footer now emits in full once per session (a one-line
reminder after), the DESIGN.md staleness note is mentioned once per
session, rule descriptions dedupe within an emission, and the per-line
ignore suggestion shrinks to the bare rule/value pair. The footer and
hooks.md replace the confirmation-gated ignore policy with a three-way
triage: fix real problems, self-serve the narrowest ignore for confident
false positives or sanctioned exceptions and disclose it (with an honest
--reason), ask when unsure. Self-serve stops at ignore-value, and the
footer now gives a runnable hook-admin.mjs command instead of a slash
command agents cannot execute.
Measured on a seeded lab session replaying 11 hook events: 33,658 to
14,063 chars of agent-visible output (-58%).
AI-assisted (Cursor agent), directed and reviewed by @abdulwahabone.
Co-authored-by: Cursor <cursoragent@cursor.com>
* Preserve the policy footer and honor maxChars under constrained budgets
Greptile's runtime check found two pre-existing clamp gaps that matter
more now that the full policy emits once per session: the last-resort
tail slice cut the footer off an over-budget emission, and the DESIGN.md
staleness note was appended after clamping, pushing past maxChars.
The clamp now gives the footer the budget first, clipping the finding
line and downgrading full to short policy when needed. The staleness
note defers, without consuming its session flag, to a later emission
with room.
AI-assisted (Cursor agent), directed and reviewed by @abdulwahabone.
Co-authored-by: Cursor <cursoragent@cursor.com>
* Harden the constrained-budget clamp: keep findings, honest flags, guaranteed note
Review follow-ups from Bugbot and Greptile on the clamp fix:
- The clamp retries with the short policy before dropping finding lines
that fit beside it, and a grouped result that kept only a file header
no longer counts as a fit.
- The full-footer session flag commits only when the full policy
actually survived the clamp, so a downgraded emission does not mark
the session as having seen a policy it never received.
- Render paths reserve room for a pending DESIGN.md staleness note, so
it is delivered inside the budget on the first emission instead of
deferring behind full emissions indefinitely.
AI-assisted (Cursor agent), directed and reviewed by @abdulwahabone.
Co-authored-by: Cursor <cursoragent@cursor.com>
* Route the Cursor deny cap through the clamp and match the whole footer
Bugbot follow-up: cursorBlockMessage tail-sliced at 4000 chars after
render, which the default 8000-char budget made reachable, and a cut
that spared the footer's opening words still committed the session
flag. The 4000 cap now feeds through the renderer's footer-preserving
clamp, and commitFooterShown matches the complete footer text instead
of a sentinel.
AI-assisted (Cursor agent), directed and reviewed by @abdulwahabone.
Co-authored-by: Cursor <cursoragent@cursor.com>
* Reconcile hook.test.mjs expectations with main's per-platform quoting
Three tests fell out of sync when main's quoteCommandArg change (#533,
building on #476) met this branch's footer/hint rework. Test-only
changes; production logic untouched:
- The full-footer test now accepts either close quote after the
hook-admin.mjs path, since quoteCommandArg single-quotes absolute
paths on POSIX and double-quotes them on Windows. The short-footer
guard rejects `node '` and `node "` alike.
- The #476 hostile-value test asserts the new bare
`ignore-value <rule> '<value>'` hint format. The security property is
unchanged: the value still passes through quoteCommandArg, so
$(touch pwned) stays single-quoted and inert.
- The #533 test previously asserted a concrete quoted `--file` path in
the footer; directiveFooter() now carries only literal placeholders,
so that surface is gone. The per-platform assertion moves to the
per-finding ignore hint, the remaining user-visible surface where
scanned file content flows through quoteCommandArg.
Prepared with AI assistance (Claude Code).
Co-Authored-By: Claude <noreply@anthropic.com>
* Fix two Bugbot findings: Cursor prefix budget and footer-cutting tail slice
Both flagged by Cursor Bugbot on PR #508 after the main merge; both real.
1. cursorBlockMessage computed min(maxChars, 4000 - prefix), so a
configured maxChars at or below the Cursor ceiling never charged the
BLOCK_PREFIX against the budget: the final deny text could exceed
maxChars by the prefix length, and appendDesignSystemNoteOnce's size
check lost exactly the room designNoteReserve had held back. The
prefix now comes off whichever limit binds. Default-config behavior
is unchanged (min(8000, 4000) - 60 equals the old 4000 - 60).
2. The note reservation is subtracted after renderTemplate's 500-char
floor, so the clamp can run below the budget clampLastLine assumed
safe, and its last-resort path tail-sliced the rendered text, cutting
the policy footer (the failure mode this PR exists to eliminate) when
a deep file path met a pending DESIGN.md note. The reservation order
stays (the staleness-note delivery guarantee at floor budgets depends
on it); the last resort now drops the finding line and clips the head
instead, so the footer survives every path. New regression test pins
it: 6 findings, 100-char path, maxChars 500, reserveChars 134.
Prepared with AI assistance (Claude Code).
Co-Authored-By: Claude <noreply@anthropic.com>
* Charge the Cursor deny prefix after the renderer's floor, not before
Greptile's runtime check caught the residual from
|
||
|
|
181212cb2d |
Map polish's evidence and verify steps per platform (#550)
* Map polish's evidence and verify steps per platform polish.md was the last command reference verifying through web-only vocabulary after #546 gave the pipeline its native leg. Three targeted mappings, following the in-file precedent new-work.md set (the classify-triage-polish-verify flow itself is platform-neutral, so no polish.native.md): - Evidence gathering: desktop and mobile sizes on the web; the shipped device classes on simulator, emulator, or hardware on native, per the platform reference's Verifying the build section. - Verify checklist layouts: phone and tablet size classes, both orientations where supported, on native. - Verify checklist "supported browsers": native has none, so the analogues are named (runtime warnings, dropped frames, supported OS versions). Assisted-by: Claude Code * fix: branch the verify checklist web-vs-native explicitly Copilot follow-up: the parenthetical style could read as both term sets applying on native. The two bullets now branch explicitly, and the shared items (console errors, layout shift, latency, image loading) stay unbranched since they apply everywhere. Assisted-by: Claude Code * fix: restore runtime warnings to the native verify branch greptile follow-up: the explicit-branch restyle dropped the runtime warnings requirement the parenthetical carried; folding it into "console errors everywhere" hid it behind web vocabulary. It is back as its own item in the native branch. Assisted-by: Claude Code |
||
|
|
19786e7a22 |
Native leg for the verify-and-review pipeline (#546)
* Give the verify-and-review pipeline a native leg The build-verify-review loop assumed a browser end to end while the comp side of the system was already platform-aware: new-work.md, visualize.md, and the asset producer all comp a native app portrait at its device viewport, and then the verification steps asked for desktop and mobile browser screenshots of it. Concretely: - new-work.md step 7 ordered detect.mjs on every hookless build with no platform guard. routing.md declares the detector web-only and the design hook skips native projects, so a native build was always hookless and always ordered to run an HTML rule engine over Swift/Kotlin/RN code. The playbook now guards it: web-only, and on native the reviewer's floor check is the named slop gate. - The inspection round and the SKILL.src.md batched-round principle named desktop and mobile as the only viewports. Both now map per platform: web keeps desktop and mobile; native inspects the shipped device classes per OS, captured from the simulator or emulator. - ios.md and android.md carried no verification guidance at all, so nothing told a native run how to produce the screenshots the evidence chain depends on. Each gains a Verifying the build section: simctl / adb capture commands, dark-appearance and type-scale checks, and the simulator-vs-hardware honesty line. - The finish reviewer judged native builds blind: it never runs context.mjs and its packet carried no platform guidance. On native the packet now includes the platform reference path(s) and a no-detector-ran line, and the reviewer's Input Contract says to judge in the platform's conventions. Assisted-by: Claude Code * fix: address PR review bot findings - greptile: carry the capture's device selector through the state-changing verification commands (simctl appearance, adb uimode and font_scale); unqualified forms fail with several targets attached - Copilot: align new-work.md's cross-reference with the actual heading (Verifying the build) - Copilot: give the finish reviewer's Input Contract the native filename example new-work.md establishes (phone.png / tablet.png, suffixed per OS on adaptive) Assisted-by: Claude Code * fix: identify simulators by UDID, not display name greptile follow-up: display names can collide across booted simulators, so the capture and appearance commands now both key on the UDID from simctl list devices booted. Assisted-by: Claude Code |
||
|
|
045865918a |
Held for review: agent placeholder substitution, reviewer recapture contract, base-directory script form (#544)
* Resolve {{scripts_path}} in the agent bodies Codex ships
Three code paths emit an agent body: the degraded fallback reference, the
.toml nested inside the skill for Codex, and the native agent file. Only the
nested .toml skipped placeholder substitution and rule-marker stripping, so
the codex and .agents dists shipped `node {{scripts_path}}/embed-prompt.mjs`
verbatim in the asset producer, and every caller had to substitute the token
itself at load time.
All three now render through renderAgentBody(), and the new regression test
asserts a runnable embed-prompt command on each emitted surface plus a
synthetic agent proving markers and placeholders resolve in the nested .toml.
Prepared by an AI agent (Claude Code) under pbakaus's instruction.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* Give the finish reviewer's screenshots one fixed address
The Input Contract asked for "desktop and mobile screenshot paths captured by
the parent" and named none, so each session invented a filename and the
verdict pass went looking for a recapture that was never written there. Two
reviewer passes burned on that in the eval runs.
The parent now captures and recaptures to .impeccable/review/desktop.png and
.impeccable/review/mobile.png, and the reviewer reads those two first,
treating a brief-named path as the fallback for a parent that wrote elsewhere.
Prepared by an AI agent (Claude Code) under pbakaus's instruction.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* Lead Setup with the base directory the runtime reports
The rendered claude and codex skills opened with
`node .claude/skills/impeccable/scripts/context.mjs`, a project-relative path
that resolves in this repo and in nothing a user installs: a personal or
plugin install puts the scripts outside the project entirely. The working form
was already in the text, parenthesized, after the one that fails.
Setup now leads with `node <skill-base-dir>/scripts/context.mjs` and says once
that the base directory resolves every scripts-path command in the skill and
its references, leaving the project-relative path as the fallback for runtimes
that report no base directory.
Prepared by an AI agent (Claude Code) under pbakaus's instruction.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* Answer the Copilot review: brittle model assertion, missing review dir
Assert that {{model}} resolved rather than that it resolved to "GPT", which
belongs to PROVIDER_PLACEHOLDERS and can change without touching what the test
guards. And have the parent create .impeccable/review/ when the harness does
not, so a fresh project's first capture has somewhere to land.
Prepared by an AI agent (Claude Code) under pbakaus's instruction.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* Make the review-screenshot contract directory-based, not web-viewport-named
Two amendments to the recapture contract from review feedback:
1. The canonical location is the directory .impeccable/review/, one file
per captured viewport; desktop.png and mobile.png are the web case,
not the contract. Baking web-viewport names into the reviewer's spec
would have hardened a web assumption into paths that a native
(ios/android/adaptive) build cannot honestly write.
2. Precedence restored to explicit-beats-convention: paths the calling
brief names are authoritative when the files exist; the canonical
directory is where the reviewer looks when the brief names none or a
named path is missing. This avoids stale canonical files from an
earlier run silently winning over fresh explicit paths. The observed
failure (the verdict round inventing a round-stamped filename) stays
fixed: recapture happens over the same files, and invented filenames
are still called out as pointing at nothing.
Assisted-by: Claude Code
---------
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
|
||
|
|
fc05472a20 |
Restore reduced-motion animation guidance (#540)
* Restore reduced-motion build guidance Restores the accessibility requirement and verification step to the animation playbook, with a regression test that keeps it on the build path. Implemented and validated with OpenAI Codex assistance under standing maintainer authorization. * Harden reduced-motion guidance regression Normalizes CRLF input and accepts either reduced-motion spelling so the contract stays portable and intent-focused. Implemented and validated with OpenAI Codex assistance under standing maintainer authorization. * Anchor skill reference test to its module Resolve the repository fixture path from the test module so the regression test is independent of the caller's working directory. This change was prepared with AI assistance under maintainer authorization. * Clarify reduced-motion guidance Replace the double negative in the canonical animation guidance and keep the source contract aligned with the clearer wording. This change was prepared with AI assistance under maintainer authorization. |
||
|
|
dbff0880e6 |
Decision page: full-fidelity comps, raise cycler, declined sizing, canon order, full card anatomy (#545)
* Polish the decision page: raise cycler, declined height, canon order, full card anatomy Field feedback from the first real rolls of the verdict-routed hand: - Several raises stacked on the assigned card blew it out of proportion. More than one raise now renders as a compact cycler: one visible, a counter, click or Enter advances. A single raise stays inline. - Declined cards inherited the row's stretch alignment, so a narrow card stood at the tallest contender's height, a strange stilt beside the hand. They now size to their content. - Deck order becomes a gradient of standing: contenders, then the canon, then declined dead last. The canon between full alternates and the demoted row reads as the familiar door rather than the last resort after the rejects. - Root cause of bare-bones challenger and canon cards in the field: the --schema example only gave the assigned card palette, materials, and risk, and models author payloads by imitating the example, so the "same anatomy on every card" instruction lost to it every time. The example now carries full anatomy on every card and the schema note says a card with no palette chips is an authoring gap, not a data gap. AI-assisted change. Co-Authored-By: Claude Code <noreply@anthropic.com> * Decision cards carry full-fidelity comps instead of sketches Field verdict on the sketch contract: the sketches came back too simple to inform the choice, and generation takes the same time at any fidelity, so the deliberately-unfinished frame paid comp cost for sketch quality. The decision card's image is now that direction's north-star comp, produced under visualize.md's comp discipline (structure-led prompt, real name and content, no invented commercial claims), saved under .impeccable/mocks/ with its prompt sidecar. Fairness between cards comes from equal fidelity in each card's own grammar rather than shared unfinishedness. The chosen card's comp is never spent by the choice: on a comp-led build it enters the comp round as compositional option one (visualize.md now generates two variations beside it; a round arriving with no decision comp still renders all three), and on a code-led build it returns at the finish review as the critique reference. Produce order still front-loads a re-roll's spend onto the cards read first. serve-question keeps the sketch field's wire name for payload compatibility; docs, schema paths, shimmer labels, and the answer directive (CHOSEN COMP) speak comp. AI-assisted change. Co-Authored-By: Claude Code <noreply@anthropic.com> * fix: address PR review bot findings on the comp round - Producer still forced sketches (cursor, high): the asset producer's Decision Sketches contract still mandated deliberately unfinished matte sketches, so the parallel path would keep shipping sketch-era images. The section is now Decision Comps: full-fidelity north-star comp, structure-led prompt, equal commitment across siblings, no invented claims, sidecar written. - Mocks collided with the approval check (cursor, high): decision comps now live under .impeccable/mocks/decision/, visualize.md scopes the no-approval finding to comp-round output, new-work.md states the unchosen hand implies no approval, and the code-led finish packet names the chosen decision comp as the critique reference in the approved-comp slot. - Raise cycler announces (greptile, both P1s): a visually hidden aria-live region reads out the newly active raise and its position on advance; initial render stays quiet. - Declined width in the vertical deck (cursor, medium): align-self: flex-start shrank declined cards to content width in the portrait column layout, where the cross axis is horizontal; they stretch there and keep content height in the row layout. AI-assisted change. Co-Authored-By: Claude Code <noreply@anthropic.com> * fix: raise cycler tooltip and label name both input modes Copilot: the tooltip said Click while the control also answers Enter and Space; the title and a new aria-label now say activate/press Enter. AI-assisted change. Co-Authored-By: Claude Code <noreply@anthropic.com> * fix: finish reviewer exempts decision comps from the approval check cursor[bot] follow-through: the reviewer's Persistence check still treated any comps under .impeccable/mocks/ as approval-gated, and the reviewer never reads visualize.md by design, so code-led and spent-hand rounds could draw a false skipped-approval finding. The check now scopes to comp-round comps, exempts .impeccable/mocks/decision/ as the direction round's dealt hand, and defines how a code-led build's decision comp is judged in the approved-comp slot: the critique reference, under the no-approved-comp fidelity rules plus what the image dared that the build did not. AI-assisted change. Co-Authored-By: Claude Code <noreply@anthropic.com> * fix: the critique reference is its own reviewer input, not the approved-comp slot cursor[bot]: passing the code-led decision comp through the approved-comp slot dragged in that slot's obligations (inventory-first reading, the fidelity matrix, Truth's shipped-asset demand for every image-native region), which contradicts code-led's premise. The input contract now names it a separate labeled critique-reference input that nothing binding "the approved comp" touches, and Fidelity defines its treatment where the no-approved-comp rules live: provocation, not spec; no matrix, citations, or asset obligations; its dares enter material_fixes as ordinary fixes. AI-assisted change. Co-Authored-By: Claude Code <noreply@anthropic.com> --------- Co-authored-by: Claude Code <noreply@anthropic.com> |
||
|
|
c70bcbf6b4 |
Direction round: verdict-routed hand, MY PICK card, salience parity, Safer/Bolder registers (#531)
* Route the direction hand by verdict, add the pick card, enforce salience parity The decision round previously rendered every dealt challenger as an equal full card whatever the weighing said, so a world that fused poorly (an underwater world dealt to a flower shop) sat at the same visual weight as the assigned direction, and concept-level fusion had no surviving output. Three changes, all presentation-layer; the dice, the assignment, and the two-axis weighing are untouched: - Verdict routing: the weighing closes with wins / competitive / declined per challenger, decided before any borrowing. Declined challengers render demoted (narrow, quiet, catalog art as a labeled thumb, "Adopt anyway"), reordered to the end of the deck by the page itself, still adoptable, never silently dropped. Donations return as named "raised by" lines on the assigned card: a declined challenger donates ambition and system discipline, never its clothes. - The pick card: one card for the model's top-ranked grounded candidate when the dice assigned another, kicker MY PICK, honest familiarity risk on its face. One card, never a ranked list, never the lead position; the anti-menu rule survives with exactly this carve-out. - Salience parity: a card's imagery weight is capped by the assigned card's. With a text-only assigned card (no image generation in the harness), full-bleed catalog heroes demote to labeled thumbs, so what looks important is the verdict's call, never rendering luck. serve-question payload gains additive fields (verdict, kept, raised); old payloads render unchanged. concept-seed's rendered instructions carry the verdict/donation contract and the pick-card carve-out. Covered by two Playwright tests in the new-work e2e suite (verdict routing + parity). Design exploration and rationale were worked through with the maintainer; research grounding is impeccable.style/research lessons 3-5. AI-assisted change. Co-Authored-By: Claude Code <noreply@anthropic.com> * Add Safer/Bolder re-roll registers to the direction round The re-roll gains the user's steering wheel on the familiar-to-bold axis. The decision page renders two register buttons beside the plain re-roll (payload: reroll: { registers: ["safer", "bolder"] }; booleans still work), the answer carries the chosen register, and concept-seed gains --register. The design constraint that shaped the implementation: a register changes only what a round INSTRUCTS, never what it DEALT. The same key and reroll count reproduce the same deal whatever the register, so the exclusion chain never forks and the reproduction contract holds with no API change. - bolder: the dealt foreign forms become the whole hand, every challenger a full card; the first-dealt challenger leads (assignment by deal order, so the dice still choose). The pick card sits out; the canon stays. - safer: the round's dealt hand is spent unseen and stays excluded; the model presents its remaining conventional grounded candidates (at most three) plus the canon executed against named competitors. This is the one sanctioned lineup of the model's own ranked list, existing only by explicit user request. Works degraded (needs no catalog); bolder degrades to a plain grounded round, disclosed. Registers are user steering, never the model's to pre-select. Covered by a concept-seed unit test (same-deal invariant, validation) and a Playwright test (button, answer field, REGISTER directive). AI-assisted change. Co-Authored-By: Claude Code <noreply@anthropic.com> * Add the execution-contract round: comp-led or code-led, chosen after the direction The build previously went comp-led for everyone, silently: a generated comp led and the build chased it, which produces the boldest compositions and also the measured worst-of-both-worlds failure (ambitious design landed poorly, no motion, fix rounds after). Models already defect from it by quietly skipping comp generation, which is unsanctioned code-led with no contract to catch it. This makes the fork explicit and both paths defection-proof: - Comp-led: the comp is law and non-optional once chosen; visualize.md and the comp-is-king build phases run as today. - Code-led: no comp of this page, skipped by contract rather than drift. The QUALITY BAR boards still calibrate finish, and the ambition moves into the written direction contract (FIRST VIEWPORT plus a named signature interaction and motion grammar), audited by the finish reviewer in behavior. Not a discount on commitment. Placement: a second round on the same open table, right after the direction lands. Sketches stay in the direction round (they pick the world); comps are what code-led skips (they bind the composition). The chosen world sets the default lead; the user flips freely; a standing preference recorded in PRODUCT.md skips the round on later surfaces; with no image generation there is no fork, code-led is the only path. Mechanism: serve-question gains payload-level followup: true, which keeps the detached server alive after a pick (exactly like re-roll), swaps the page to the loading hand instead of goodbye, marks the answer with followup: true so --wait keeps the table, and prints a FOLLOWUP OPEN directive telling the agent to deliver the next round via --update. Covered by a Playwright test driving the full two-round flow. AI-assisted change. Co-Authored-By: Claude Code <noreply@anthropic.com> * fix: address PR review bot findings - Degraded safer register no longer contradicts itself (greptile, Copilot, cursor): the degraded template previously said "the assigned index is suspended; the user picks" and then emitted ASSIGNED INDEX, the mandatory build instruction, and the restated footer anyway. The degraded safer path now suppresses the assignment machinery entirely, matching the non-degraded safer round, and restates the user-picks behavior for truncated readers instead. - A declined card's declared sketch no longer renders a full media face (Copilot): the renderer ignores sketch slots on declined cards outright, so a stray sketch cannot buy back the salience the verdict took away. - Bolder rounds no longer carry the generic weighing instruction (cursor): it measures against the assigned grounded direction, which the bolder register suspends; a leader-relative variant weighs the fused challengers against the first-dealt leader instead. All three pinned by new assertions in tests/concept-seed.test.mjs and tests/new-work-e2e.test.mjs. AI-assisted change. Co-Authored-By: Claude Code <noreply@anthropic.com> * fix: followup never arms the loading hand in blocking serve mode cursor[bot] caught a client/server disagreement: the page interpolated its FOLLOWUP constant from the payload alone, so a followup: true payload served in blocking mode (no --start) would leave the browser on a loading hand that nothing resolves, since a blocking server exits on any pick and has no update channel. The page constant is now armed only when the server is detached, blocking rounds get the goodbye screen as before, and new-work.md states that followup belongs only on a detached round; blocking and structured-tool channels run the build-path round as its own second question. Pinned in tests/serve-question.test.mjs. AI-assisted change. Co-Authored-By: Claude Code <noreply@anthropic.com> * Add card-kind choice telemetry and the bolder routing disambiguation The choice ping previously fired only when a dealt catalog challenger won, so pick-share and canon-share had no denominator and the decision page's new spectrum could not be measured. The ping now fires once per resolved attended round on API-dealt rolls: --kind names which card class won (assigned / pick / challenger / canon), --chosen carries the catalog id only when a dealt challenger won, and --register rides along when the round came from a steered hand. Grounded candidates' names never leave the machine (the ping carries the kind alone), the legacy id-only shape stays valid, and DO_NOT_TRACK / IMPECCABLE_NO_TELEMETRY still disable the ping entirely. The seed's TELEMETRY block teaches the new invocation. Also the naming-collision guard: "bolder" said while a direction round is open routes to the Bolder hand register, never the bolder refinement command; one line each in bolder.md and new-work.md. The /api/chosen field additions land in a sister impeccable-site PR; the API ignores unknown fields meanwhile, so this is safe to ship first. AI-assisted change. Co-Authored-By: Claude Code <noreply@anthropic.com> * fix: ping test survives a DO_NOT_TRACK shell cursor[bot]: the pingChosen unit test cleared only IMPECCABLE_NO_TELEMETRY, so a developer shell with DO_NOT_TRACK set failed the success-path assertions. The test now clears both, restores prior values in finally, and passes under DO_NOT_TRACK=1. AI-assisted change. Co-Authored-By: Claude Code <noreply@anthropic.com> --------- Co-authored-by: Claude Code <noreply@anthropic.com> |
||
|
|
d417ff1f01 |
Craft floor: theme the surfaces you did not draw
A well-made site was audited for what separates it from a competent one, and the answer was not its ingredients. It runs the default stack, Next and Tailwind and Geist, with no world and no unusual technique. What it has is attention to the surfaces a browser renders for you: 29 focus-visible rules, 15 scrollbar rules, and styled text selection, caret, underline offset and scroll behaviour. Those are the cheapest signal that a page was built rather than assembled, and the ones a model skips most reliably, because nobody asks for them and nothing looks broken without them. The floor already covers contrast, depth, spacing, measure, motion and states; this is the layer under all of it. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
ca7981f669 |
Comp outranks the brief: close the inventory sandbagging gap
probe-compking-sol-4 (evals) executed its staged inventory faithfully and still lost the comp: the brief had already recorded the comp's materials down (low-contrast textures, a 70-path lake against the comp's hundreds, a sculpted plate as flat CSS), and the build thread never loads visualize.md, so nothing told it the comp wins that disagreement. The comp-is-king block now says the record gets corrected upward, that the comparison runs against the freshly reopened comp rather than memory, and that a texture under a near-opaque wash is not shipped material. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
bcfb7efc46 |
The comp is king: phased reproduction doctrine
Phase one is near-pixel-perfect reproduction at the comp's breakpoint, with exactly three concessions (closest font, icons unless a library was chosen, genuine comp defects); the overlap comparison is the authority because models systematically believe their code recreation succeeded when it did not, and regions that keep losing the comparison ship as composited rendered assets instead. Phase two brings the reproduction to life (interaction, motion, responsiveness), and anything beyond the comp inherits the recorded system, never invented container chrome. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
b1c5707fde |
Cross-harness, cross-OS: boot-time tool detection and native-first image gen
context.mjs now probes cwebp/sips/magick/ffmpeg once (which/where per OS) and prints IMAGE_TOOLS, replacing macOS-specific prose; the IMAGE_GEN_AVAILABLE directive leads with the harness-native tool so a present OpenAI key stops reading as an instruction to bill it; and the sandboxed board-start guidance sheds codex vocabulary. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
1052f6c3a4 |
Start the decision page escalated in sandboxed harnesses
Sandboxed shells cannot bind the board's port; every codex session paid one failed start before retrying escalated. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
b89b4c41d3 |
Trim the spawn tax: no agent-def reads, long waits, one converter probe
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
08c2323b51 |
Rebuild without asking, spawn the producer always, read the comp as a system
Three lessons from the Tortuga containment-map run. The first rebuild directive now executes immediately, informing the user instead of asking permission to fix a failure; consultation waits for a second rebuild verdict or user-approved content at risk. The asset producer spawns on every subagent-capable run even when produce looks empty, because its manifest is the independent check on the inventory's media and the skipped spawn marks every all-CSS failure to date. And the inventory now opens by reading the comp as a design system (component grammar, corners, line weights, elevation, type ramp), because the sections the comp does not show get built from that record, and without it the fallback is the stock kit: square boxes, 1px grids, bentos, hard shadows. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
7b202c3223 |
Textures are raster by name alone
The condensation pass folded the old textures-are-raster-by-default sentence into the medium gate's lighting-and-depth clause, and the next codex run drove straight through the gap: woven cotton as 'layered CSS textures', a black nylon band as plain CSS, and a physical evidence-tag CTA as CSS shapes, so the produce bucket stayed empty and the asset producer was never called. The gate now names textures explicitly, woven cloth, paper grain, fabric, leather, brushed metal, with no depth argument owed, and calls 'layered CSS textures' what it is: not a medium. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
827dfeb95e |
The primary action is signature material, not chrome
The Tortuga comp dissolves the Install CTA's edge into the storm's particles; the build shipped a plain rectangle with four decorative dots, and neither the builder nor the reviewer's rebuild findings named it. The inventory now gives the primary action its own row and medium, naming the shrink-to-border-trick failure as the compliance-token version of commitment, and the reviewer's fidelity matrix lists the primary action's treatment among the salient elements, with a physically-worked CTA rendered as a plain rectangle scored contradicted. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
38d2c393dc |
Prove the hero before building past it
The Tortuga run showed the finish machinery working end to end, roll, challengers, approved comp, honest labels, independent reviewer, an earned rebuild verdict at the user checkpoint, and still cost the user a full build to learn the hero undersold the comp: a glyph storm at a tenth of the approved density under type half as compressed. Both misses were visible the moment the first viewport rendered. Two cheap gates front-load that discovery. The build section gains a hero checkpoint: capture the first viewport and set it beside the comp's before any later section, judging scale and density as quantities. The inventory gains the same quantitative discipline: field and texture regions record density and coverage, and TYPE rows name the compression class and render one headline word against the comp before anything is built on the face. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
bd1763764a |
Pull compositions from the deal until the expanded catalog ships
The composition pool (stagings) is not ready: too thin to help, and its draws crowd the decision it rides along with. concept-seed.mjs stops rendering the staging block by default; IMPECCABLE_COMPOSITIONS=1 re-enables it for catalog development, and the draw machinery, rating-weighted selection, and mode scoping stay intact and tested for its return. new-work.md drops the dress-the-staging-challengers instruction and the FORM contract's staging clauses; the surface-scope roll still assigns which of the model's own structures gets built. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
861682eebb |
Give the finish reviewer and documenter craft-floor authority
Codex's own post-mortem of the second hamster-wheel session: it loaded the kicker ban, shipped five kickers anyway, and then the reviewer and documenter 'compounded it by accepting, and even canonizing, the invented label style'. Nothing downstream of the builder ever re-read the floor. The reviewer gains check 6, Floor: read craft-floor.md (now the one skill reference it may read, passed in its inputs) and hold the screenshots against the Refuse list; a banned element is a material fix even when it matches nothing in the comp, because fidelity cannot authorize what the floor refuses. The documenter gains the mirror rule: a floor refusal lands in its not-canonized line as a carried defect, never in DESIGN.md as a rule future surfaces inherit. Also updates the live-reference contract test to match the applier's condensed no-server sentence, which still carries the same guarantee. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
28af30eff0 |
Condense the grown skill files and harden the reviewer's verdict
Three subagent audits reviewed the files that grew through the last rounds of patches. Their honest verdict: dense, not bloated; roughly 430 words of true redundancy came out with no rule lost, and every cut they flagged as removing compliance pressure was skipped. Highlights: approval recording now has one owner in visualize.md, the asset producer's crop ban went from three statements to the deliberate pair, its two transparency passages carried contradictory defaults (resolved toward true alpha first), and the 450-word medium-gate wall split into three paragraphs at zero cost. The producer also gained a mode-seam sentence so a sketch run cannot return an asset manifest. The reviewer's verdict is no longer soft: a derived disposition line (rebuild / fix / ship) opens every return, computed from the matrix rather than felt, recomputed after the verdict pass, and never softenable by the parent, who must report it verbatim. The second hamster-wheel run showed the parent inventing 'PASS WITH FIXES' over a matrix with MATERIAL contradicted on the focal element. Two additions from the same session's evidence: hard offset shadows outside a neobrutalist world join the craft floor's refusals (codex invents them without fail), and hookless harnesses must run detect.mjs once before the finish review, because codex has no hooks and the detector otherwise never sees the build at all. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
e54fd13a33 |
Close the line-art loophole and widen the rebuild directive
The second codex hamster-wheel run read the medium gate and still assigned a shaded, perspectived technical illustration to 'Authored SVG geometry': the world was an instruction booklet, so the affinity clause's 'diagrams' blessed the downgrade, and the page shipped as flat clipart against an illustration-grade comp. The gate now says style does not move the boundary: perspective, shading, figure drawing, or dense mechanical detail is illustration however line-drawn it looks, and authored SVG ends where drawing skill begins. The craft floor's sketchy-SVG rule carries the same sentence. The reviewer in that run built an honest matrix, MATERIAL contradicted on the focal element, and still emitted it as a fixable item the parent answered with CSS. The rebuild directive now fires when MATERIAL is contradicted on the focal element, not only when TYPE falls with it, and every asset-requiring fix must say 'produce: <region>' so it cannot be answered as a style tweak. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
f8a34335cb |
Let the surface own the sketch and comp aspect
A landscape frame was the silent default at every generation site, which is a composition error before the build starts for native apps and mobile-first surfaces. The sketch frame, the asset producer's single-sketch contract, and the comp instruction now state it: portrait at device viewport when the surface is a phone screen, landscape for desktop web. The decision page adapts in kind: portrait art overrides the 16/10 slot with its own exact ratio so nothing crops, and the deck narrows so portrait cards line up side by side. The --schema guidance tells the model the page handles either. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
4432b92bbb |
Harden the comp-to-build translation after the hamster-wheel failure
A codex greenfield build produced an excellent approved comp and then an abysmal page, and the reviewer approved it. The failure chain: the implementation inventory downgraded a photographic hero to 'silhouette in SVG' and sculpted panels to 'material finish: CSS'; the builder read 'no photography on hand' as a license to avoid photographic rendering; QA looked at one full-page thumbnail; the reviewer was spawned with the builder's forked history and then scored fix claims instead of pixels; and the output contract had no way to say 'rejected'. The fixes, stage by stage: - The inventory's medium column gets a gate: a human figure, product object, machinery, or lit material is raster whatever the stack, and such regions are regenerated cleanly at asset resolution with the comp and its embedded prompt as reference. Never cropped from the comp, whose effective resolution is reference grade; the asset producer's direct bucket closes the same hole. Dropping an image-native region is a user decision at the approval point. - Generated imagery is a material, not a claim: evidence rules bind assertions, never render fidelity. - The build thread's inspection becomes a region-by-region side-by-side against the comp at legible scale, never one full-page thumbnail. - The reviewer spawns fresh, never with forked history (fork_turns: 0 in codex), and gains a rejection lane: when TYPE, MATERIAL, and the focal element are all contradicted, the first material fix is a rebuild directive the parent surfaces to the user instead of patching. Verdict passes score recaptures only; the parent's fix narration is not evidence. - The verdict-loop ceiling softens: two rounds ends an unattended run, but an attended session puts the open-items table in front of the user and lets them fund another round; any round that resolves nothing stops the loop. - Comp approval joins the roll as skip-proof: question-tool errors fall back to the decision page, delegation is recorded in the brief and the sidecar and disclosed up front, and the reviewer treats comps with no recorded pick as a material finding. - Craft floor: system display faces (Impact, Arial Black) as an own-world display voice and unicode glyphs standing in for icon systems are named failures. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
bb07a7519b |
Record the approved comp in its prompt sidecar
The surface brief was the only carrier of which comp got approved, and eval transcripts show models routinely skip writing it, leaving the choice unrecoverable. The comp's .json prompt sidecar already travels with the mocks folder across sessions and machines, so the approval now gets marked there too. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
5f4b58d06d |
Merge pull request #433 from pbakaus/live-v2-rewrite
Live v2: root manifest, mount-ack protocol, AST scaffolder, mechanical accept |
||
|
|
430d74a12b |
The stack is the user's decision, and code is a medium of ambition
Two field observations. Greenfield projects with no framework never got asked what to build on: the interview covered product truth and banned aesthetic questions, and the model silently picked a scaffold the user never chose. Init now asks once, static HTML, a named framework, or a delegated choice plus any deploy constraint, and records the outcome under a new optional Stack section, including the delegation itself, so later work knows the choice was offered. And the medium guidance named raster a dozen times while naming WebGL once, so models never reached for vector or GPU code unprompted. The affinity now runs both ways at the decision point: precise geometry, shape systems, diagrams, expressive motion, shaders, and anything interactive are vector and GPU territory, where a raster flattens what should move, scale, and respond. The sketchy-SVG ban states its own scope: it bans SVG imitating pictures, never SVG doing geometry. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
fa1177ed9c |
Ship native subagent definitions for GitHub Copilot and Cursor
The github and cursor providers previously received only the generated
degraded/ inline fallbacks. Both harnesses support real custom subagents,
so the build now emits them from the same skill/agents/ source:
- GitHub Copilot: .github/agents/impeccable-<role>.agent.md with portable
frontmatter only (name + description; omitting tools grants all tools,
and Copilot has no documented model/effort/max-turns equivalents).
- Cursor: .cursor/agents/impeccable-<role>.md with name, description,
model: inherit, is_background: false, and readonly derived from the
agent's tool list (true only for the finish reviewer, which declares
neither Write nor Edit). effort/max-turns are skipped because Cursor's
effort option requires an explicit model id.
Agent bodies now also resolve {{scripts_path}} and strip rule markers in
the shared agentFormat pipeline, which fixes the previously unresolved
placeholder in the emitted Claude asset-producer agent.
The CLI installer places agents per scope: project installs write
<repo>/.github/agents/ and <repo>/.cursor/agents/; user-level installs
write ~/.copilot/agents/ (Copilot's user dir, not ~/.github/) and
~/.cursor/agents/, overwriting stale impeccable-* copies. Because
Copilot lets user-level agents shadow same-named project ones, a project
install warns when shadowing copies exist; Cursor gives project agents
precedence, so no warning there.
new-work.md and visualize.md extend their harness-naming clauses with
the Cursor and Copilot invocations. The degraded/ fallbacks keep
shipping for surfaces where the model still fails to delegate.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
||
|
|
47b875a7e3 |
One prompt carrier across every harness: embed-prompt.mjs
The prompt behind a generated image was recorded three different ways, a sidecar in the eval harness, nothing in the skill's API tool, nothing for native tools, so intent survived or vanished depending on where you ran. One dependency-free script now embeds the prompt inside the image itself, PNG tEXt or JPEG COM with a sidecar fallback for other formats, idempotent, and reads it back from any impeccable-generated file. The API tool embeds automatically; the prose directs every native-tool generation through it; copies between machines and harnesses keep their intent. Comps meanwhile are declared the build thread's own work, never delegated, and the comp-skeleton guidance now asks for the surface's actual regions instead of prescribing navs onto pages that have none. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
39532a65a2 |
Comps are pages not vignettes, and the prompt travels with the asset
Two findings from the first human-validated probe. The comps rendered as scene vignettes because the generation prompts led with the world's atmosphere; the model painted the fish market instead of the fish market's website. The comp guidance now demands the page's literal skeleton in the prompt, nav and its items, headline block, sections in order, footer, with a self-check: a render that could hang as a poster is not a comp. And generation context is part of the asset: the thread that wrote a prompt knows what the image contains and why, so build- critical imagery prefers the build thread, and subagent-produced assets must carry their prompts, via the tool's new sidecar or the manifest, read by the builder before composing. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
25934b9f6f |
The contract survives the compiler, and the roll has no skip condition
Transcript archaeology on the failed gallery batch split the binding break three ways. One model authored a complete, correct contract that Astro then erased: the compiler strips a slot's leading comment while keeping deeper ones, so the contract now belongs to the root layout's body as its first child, and the first production build gets grepped for the seed key, because a contract the build erased is a contract nobody can audit. Another model simply skipped the roll and built the exact category default the seed exists to refuse; the roll step now states outright that it has no substitute and no skip condition. The third failure was the worker watchdog, fixed separately. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
7cd43c0365 |
The contract carries the exit condition, because the file outlives attention
Two probe runs on two different harnesses built complete pages and declared done without ever entering the finish sequence: the reference was read once near turn four and the finish choreography had fallen out of attention thirty turns later. The one text a model rereads on every edit is its own artifact, so the direction contract now closes with a FINISH line naming the exit condition verbatim: unreviewed and undocumented is unfinished; this build ends with the finish review, the verdict, and DESIGN.md. A page that looks complete with that line undischarged is not done, it is abandoned at the finish line. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
8b6324d1b9 |
View every image by its workspace-relative path
A sandboxed harness rejected view_image on an absolute path to a mock the model had itself just produced under .impeccable/mocks/, killing the run. The relative-path rule existed only for downloaded quality-bar cards; it now covers every image the flow produces or references, in the comp round and in the asset producer's comparison step. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
880199697e |
fix: Cursor notify pattern covers every dispatchable event type
cursor[bot]: the background-terminal notify regex predated variant_mount_failed (and manual_edit_apply / prefetch), so on Cursor a failed mount exited the one-shot poll without waking the agent and the error card sat unanswered. The pattern now lists every type the dispatch loop handles. This work was produced with AI assistance (Claude Code). Co-Authored-By: Claude Code <noreply@anthropic.com> |
||
|
|
26f54d15c2 |
feat: just-in-time event instructions + frontier default for the LLM e2e agent
Field feedback from two more Codex sessions drove both changes.
JIT instructions (live/instructions.mjs): every event live-poll prints
now carries _instructions, the authoritative next step for that exact
situation with real ids, paths, and line numbers substituted, and only
the active path's rules (a svelte-component session never sees JSX
guidance). The boot payload carries loop instructions the same way.
Instructions are versioned with the scripts, so they cannot drift from
behavior, and live.md's plumbing can keep shrinking toward contract plus
craft guidance. The Codex poll-discipline failure observed in the field
("the long poll was started, but I yielded the task instead of actively
servicing its result") gets a named anti-pattern in both the harness
policy and the boot instructions.
LLM e2e agent: default provider/model moves from Claude Haiku 4.5 to
OpenAI gpt-5.6-terra at medium reasoning effort via an Anthropic-shaped
shim over the ai SDK (the three call sites stay provider-agnostic;
Anthropic and DeepSeek remain selectable). The harness should exercise
the model tier that actually drives live sessions. Both the react and
sveltekit fixtures pass end to end with terra driving the trimmed
live.md and the new _instructions.
This work was produced with AI assistance (Claude Code).
Co-Authored-By: Claude Code <noreply@anthropic.com>
|
||
|
|
b4f1c1786e |
docs: trim live.md hot path from 740 to 330 lines
First-time setup (config schema, framework table, adapters, drift, the whole CSP flow) moves to reference/live-setup.md, loaded only when the boot reports config_missing/config_invalid or cspChecked is absent. The per-session prose is compressed without dropping any pinned phrase, MUST rule, schema, or example; the boot payload documentation now names the inlined surface brief. All live-reference pins and both prose gates pass. This work was produced with AI assistance (Claude Code). Co-Authored-By: Claude Code <noreply@anthropic.com> |
||
|
|
33a1c5fcae |
Ban kickers outright: one eyebrow above a heading is one too many
The detector's repeated-section-kickers rule waited for three tracked labels before calling the pattern; generated pages earn the finding on the first one. Retire that id and replace it with kicker-above-heading, which flags any tracked-caps or small-caps label block sitting directly above an h1-h4 or heading-role element, at full warning severity. The candidate gate absorbs the false-positive shapes the repetition count used to paper over: editorial category-and-date meta lines, breadcrumbs with separators, legal and chapter numbering, application panel context labels, nav landmarks before page titles, and stat callouts with the label below the number. Hero-scale h1 eyebrows stay with hero-eyebrow-chip so one element gets one finding, and the static cascade now carries font-variant so small-caps kickers register. The craft floor entry moves from caution to ban in the same breath. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
6a7d75b6fe |
Bound the finish by verdict, not by count, and teach the matrix medium and type
The hard stop landed one step early: one review, one batched fix, one recapture, then done, with nobody ever judging whether the fixes reached the quality the findings named. A recapture measures positions; the model then presented mechanical confirmation as artistic success over a page whose display face, material, and hero legibility had all drifted from the approved comp. The finish now ends on a verdict: the recaptured screenshots go back to the same reviewer, which scores every material fix resolved, partial, or unresolved and names at most three regressions the batch introduced, no new hunt. Partial and unresolved fixes earn exactly one more round; two rounds is the ceiling, the second verdict ends the work whatever it says, and the final verdict table goes to the user as it stands, open items included. Three blindnesses from the same run close alongside. The matrix gains two mandatory rows: TYPE, where a display face of a different character is contradicted however the layout matches, and MATERIAL, where flat CSS standing in for painted, textured, or dimensional artwork is contradicted regardless of placement. And the Truth check now requires every produced asset visibly present in the screenshots, because a paper texture at 0.16 opacity is a compliance token, not a shipped material. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
5b6b331785 |
fix: preview-truth CSS supersession + cascade ordering on Svelte accept
Field failure from a real Codex session: accepting a variant into Pitch.svelte appended 23 selectors and removed none, so the source's old .decisions grid rules re-attached through the kept root class and forced the accepted board into a stale three-column layout; some appended base rules also landed after the source's media block, weakening the mobile cascade. Two mechanical fixes: - Preview truth: the scaffolder records the seeded selectors (the source rules that styled the replaced selection, which the isolated preview never applied). On accept, any seeded selector the variant does not re-declare is removed; the selector-loss postcondition treats those removals like compiler prunes. A regression test reproduces the exact Pitch shape end to end. - Cascade order: reconciliation inserts new base rules BEFORE existing top-level media blocks instead of appending after them. Init-latency reductions from the same transcript: - live.mjs inlines the resolved surface brief (removes three surface-brief.mjs round-trips including a --help miss before first poll). - The wrap/scaffold payload carries componentStubMarkup, and live.md instructs editing stubs in place (the session read the manifest + stub back and then deleted/recreated the files). - live.md notes that a busy default port usually means the dev server is already running (the session spawned a duplicate). This work was produced with AI assistance (Claude Code). Co-Authored-By: Claude Code <noreply@anthropic.com> |
||
|
|
09a33bc58b |
One sketch, one agent: retire the batch producer and its supervision
The batch producer was the clumsy piece: one subagent owning eight jobs needed heartbeat rules, reclaim windows, and a page full of fallbacks to survive its own opacity. The unit of work is now a single card. With parallel subagents, the set fans out one agent per card, up to four in flight, landing everything in roughly the time of one; a single-sketch agent has no planning phase and no batch to stall, so a failure costs one slot and its remedies fit one sentence: regenerate an empty slot when its agent returns, drop it when the user answers first. Without parallel subagents, the main thread generates in reading order after serving, and the harness's own generation display carries the progress. The page-side streaming is unchanged; it never cared who writes the files. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
ca88ea008b |
Patience while sketches land, honesty when standing in
Field data: the first image of a real batch took ninety seconds and the page's 150-second fallback then silently promoted catalog art to full bleed, unlabeled, which is exactly the this-is-your-design misread the picture-in-picture treatment exists to prevent. The policy is now patience while there is progress: a slot shows its inspiration only after waiting four minutes with nothing landing anywhere on the page for four minutes, the stand-in is dimmed and labeled 'inspiration · sketch pending', and polling continues so the real sketch still swaps in whenever it arrives. Slots with no inspiration keep the honest elapsed shimmer instead of folding. The parent's reclaim rule matches: files landing steadily is health at any pace, and only total silence, no first file in three minutes, takes the batch back inline. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
0eb443d29b |
Bound the hand, greek the copy, and treat waiting as supervision
A codex field run dealt six challengers into an eight-sketch batch behind an opaque subagent, and the user stared at a page of shimmer asking whether anything was happening at all. Four fixes from that run. A hand now holds at most three challengers, the rest banked for re-rolls, so fairness within the hand stops multiplying into a queue. Sketches greek everything but the product's real name and one real headline, because an invented spec, price, or ship date in a sketch is a claim PRODUCT.md never made, and comps have solved this for a century. Sketch production follows the user's reading order with the first file doubling as the producer's heartbeat, and the parent's --wait loop checks the sketch directory each pass, reclaiming the batch inline when two minutes pass with nothing landed. And a failed --start now captures the daemon's stderr to a per-key log and names the sandbox as the usual suspect, instead of reporting only that failure occurred. The shimmer counts its elapsed seconds, and gives up at 150 instead of 300. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
d89ee5f87c |
Deal every card the same hand: anatomy, sketches, and the standing door
The decision page compared unlike things: the grounded direction was a wall of text beside curated catalog art, the catalog art read as a promise of the build, the weighing silently shrank the challenger set, and the standing exit hid in the footer under the cards it must not soften. Every card now shares one anatomy (thesis, palette chips, material tags, first viewport, case, risk), every dealt challenger is presented with the weighing written on it rather than applied to it, the catalog image rides picture-in-picture as labeled inspiration with the lightbox a click away, and canonCard renders the category standard as one honest, subordinate card. When image generation exists, each card declares a sketch slot the page polls: serve first, generate after, through one shared deliberately unfinished frame, so the comparison stays about direction instead of rendering luck. The asset producer takes the batch when subagents exist; the chosen sketch returns in ANSWER to seed at most one comp probe, and the comp round still renders its full set. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
2d66c9acf1 |
Merge origin/main into live-v2-rewrite
Resolves bun.lock (regenerated) and package.json (both sides' devDependency changes kept: main's @babel/parser bump, this branch's svelte addition). |
||
|
|
c9213835e7 |
Review fidelity against the comp itself, not the builder's summary of it
A codex run turned an approved comp into a related second art direction and the finish reviewer passed it: the review anchored on the direction contract, a lossy abstraction the builder wrote, and every element that abstraction dropped passed silently. Four changes close that chain. The reviewer inventories the comp's salient elements before reading the contract and classifies each one (match, adaptation, missing, contradicted, added without approval), with adaptations citing the answer, brief, accessibility need, or product truth that forced them, and fidelity failures outranking craft in material_fixes. The visualize inventory gate records compositional commitments alongside asset media, since the 150-word contract cannot carry them. The north-star allowance now says what it permits: translation, never recomposition. And the finish sequence recaptures the same viewports once after the fix batch, so what the documenter records is what actually shipped. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
17dabf4b7e |
Live v2: root manifest, mount-ack protocol, AST scaffolder, mechanical accept
A ground-up hardening of live mode, driven by a production session in a nested-app monorepo that hit six distinct failure classes. Full design rationale in docs/LIVE-REWRITE-PLAN.md; every Codex-reported failure now has a mechanical fix and a regression test. Roots: live/roots.mjs resolves appRoot/repoRoot/contextRoot once at boot (keyed on dev-server configs, not monorepo brand markers), persists a manifest, and every live CLI re-anchors onto it at startup, so a helper run from the wrong directory can no longer fork session state. Context files are discovered upward to the git root. Render truth: variant_mounted / variant_mount_failed events give the journal per-variant mount state; failures reach the agent's poll queue, raise a persistent error card with Retry (no more localStorage wipe), and an attach probe names root/dev-server mismatches explicitly. The browser rehydrates from the server when localStorage is gone. Svelte: the scaffolder now parses with the app's own svelte 5 compiler. Control flow survives (an each collection crosses the contract as one structured prop), keyed each blocks hydrate synthetic keys, and anything a detached preview cannot support falls back to source-preview instead of shipping a wrong scaffold. Preview modules live in per-publish revision directories, defeating stale transform caches. Accept: CSS is reconciled, not appended. Matching selectors are replaced, params bake from params.json kinds, the compiler's unused-selector pass prunes superseded rules (pre-existing dead rules protected), a selector- loss postcondition refuses any write that would drop hand-written rules, and live-complete refuses to finish while live plumbing remains in source. Also: framework registry (live/frameworks/) with a crash-safe injection journal, session-store snapshot caching with read-only reads, protocol enum consolidation, steer Send button, honest DESIGN-panel empty states. Testing: new unit suites (roots, AST scaffolder, accept CSS, accept pipeline, framework conformance); e2e now fails on preview-tree 404s, proves computed-style mount for every variant, drives the Tune panel through baked params, and injects failures (broken mounts, republish, storage loss). New runtime fixtures: monorepo-nested-vite (repo root != app root) and vite8-sveltekit-stateful (each blocks + state). Nightly full-matrix cron. An independent adversarial review pass preceded this commit; its blocker and major findings are fixed and regression-tested. This work was produced with AI assistance (Claude Code). Co-Authored-By: Claude Code <noreply@anthropic.com> |