Commit Graph
142 Commits
Author SHA1 Message Date
Paul BakausandClaude Fable 5 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>
2026-07-29 17:45:45 -07:00
Paul BakausandClaude Fable 5 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>
2026-07-29 17:45:45 -07:00
Paul BakausandGitHub 5f4b58d06d Merge pull request #433 from pbakaus/live-v2-rewrite
Live v2: root manifest, mount-ack protocol, AST scaffolder, mechanical accept
2026-07-29 13:12:23 -07:00
Paul BakausandClaude Fable 5 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>
2026-07-28 16:42:56 -07:00
Paul BakausandClaude Fable 5 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>
2026-07-28 16:16:57 -07:00
Paul BakausandClaude Fable 5 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>
2026-07-28 13:39:48 -07:00
Paul BakausandClaude Fable 5 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>
2026-07-28 13:27:03 -07:00
Paul BakausandClaude Fable 5 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>
2026-07-28 09:47:36 -07:00
Paul BakausandClaude Fable 5 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>
2026-07-27 20:27:44 -07:00
Paul BakausandClaude Fable 5 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>
2026-07-27 20:05:37 -07:00
Paul BakausandClaude Code 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>
2026-07-27 19:32:30 -07:00
Paul BakausandClaude Code 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>
2026-07-27 19:20:02 -07:00
Paul BakausandClaude Code 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>
2026-07-27 19:03:39 -07:00
Paul BakausandClaude Fable 5 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>
2026-07-27 18:55:52 -07:00
Paul BakausandClaude Fable 5 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>
2026-07-27 18:51:32 -07:00
Paul BakausandClaude Code 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>
2026-07-27 18:45:07 -07:00
Paul BakausandClaude Fable 5 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>
2026-07-27 18:19:25 -07:00
Paul BakausandClaude Fable 5 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>
2026-07-27 18:10:56 -07:00
Paul BakausandClaude Fable 5 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>
2026-07-27 17:49:21 -07:00
Paul BakausandClaude Fable 5 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>
2026-07-27 17:03:05 -07:00
Paul Bakaus 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).
2026-07-27 15:22:51 -07:00
Paul BakausandClaude Fable 5 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>
2026-07-27 15:13:27 -07:00
Paul BakausandClaude Code 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>
2026-07-27 15:09:40 -07:00
Paul BakausandClaude Fable 5 916b0a1fdf Generate degraded-mode fallback references from the subagent definitions
Harnesses with no subagent capability now run each role inline from the
same single source. The build emits reference/degraded/<role>.md for every
agent in skill/agents/ (role name is the agent name minus the impeccable-
prefix), stripping frontmatter and prepending the inline-substitution
preamble. These pass through the same provider-block compilation and
placeholder replacement as ordinary reference files, so <codex> blocks and
{{placeholders}} resolve per target, and they land in the committed harness
dirs on build:release like every reference file.

Repoint the three capability-first fallback sites in the prose at the
generated files: new-work.md reviewer and documenter fallbacks, and
visualize.md asset-producer fallback.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-25 19:16:17 -07:00
Paul BakausandClaude Fable 5 6769b1879a The polish ceiling covers the whole cycle, and the handoffs end it
Probe attribution on Opus 5 showed the screenshot bound working (42
to 16) while the real burner ran free: five rounds of node -e
micro-edits, eight rebuilds, and inline defect hunts absorbed the
reviewer's and documenter's jobs until the turn cap killed the run
mid-hunt. The two-round ceiling now names scans, micro-edits, and
rebuilds; after the second round the build thread stops polishing and
ships the rest through the reviewer (one batched fix pass, one
rebuild, stop) and the documenter.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-25 19:16:17 -07:00
Paul BakausandClaude Code 3d2ffe9007 Drop internal filename cross-references from routed reference text
Copilot's review point stands: reference files load per-command, so a
bare "see optimize.md" / "typeset.md" is not meaningful in the routed
context. The guidance reads self-contained now.

Prepared with AI assistance (Claude Code), directed by @pbakaus.

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-07-25 18:25:35 -07:00
Paul BakausandClaude Code 24e24265d1 Refresh stale metric and library references in the command docs
From issue #395, the items still present after the v4 consolidation:

- optimize.md led its interactivity section with FID, retired as a Core
  Web Vital in March 2024 when INP replaced it. The section heading and
  both metric lists now name INP.
- optimize.md recommended react-virtualized, superseded by react-window
  from the same author; the line now points at react-window and TanStack
  Virtual, matching overdrive.md.
- overdrive.md's WebGPU support matrix predated Firefox 141/147 shipping
  it on Windows/macOS and Safari 26 shipping it across Apple platforms.
- audit.md listed "missing will-change" as a defect while animate.md and
  optimize.md both instruct applying it sparingly and never preemptively;
  the audit line now flags overuse instead of absence.
- harden.md allowed 14px mobile body text while typeset.md sets a 16px
  ordinary floor; harden now matches the floor, reserving 14px for
  secondary text, and names the iOS Safari input-zoom consequence.

The issue's other items (Framer Motion naming, Popmotion, polish
duration cap, humor guidance, HSL phrasing in quieter) were already
resolved by the v4 reference rewrite.

Prepared with AI assistance (Claude Code), directed by @pbakaus.

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-07-25 18:19:25 -07:00
Paul BakausandClaude Fable 5 8634c538fb Verification is two bounded rounds, never a loop
Opus 5 turned the iterate-with-screenshots-until-it-meets-the-bar
instruction into 42 screenshot trips and 150 tool calls per build,
about forty dollars of cache churn a page, before ever reaching the
reviewer. Verification now batches: one desktop-and-mobile round after
the full build, fixes applied together, one confirming round, ceiling
two. Craft-floor's checks share those renders instead of earning
separate trips; per-tweak iteration is live mode's channel.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-24 18:43:04 -07:00
Paul BakausandClaude Fable 5 bb57be4243 Documenter subagent, reviewer handoff contract, asset gate
From the paired Opus and Codex manual-run analyses. DESIGN.md moves to
the end of the flow and into a shipped documenter subagent that derives
the system from the built artifact: a rulebook written before the build
gets defended against reality, and a half-stable DESIGN.md hands the
design-system detector an unstable target that buries the build in
noise and invites laundering. The finish reviewer gains the handoff
that failed three times live: the parent captures desktop and mobile
screenshots and passes paths, the reviewer never attempts to render
and names missing inputs in one line, the parent verifies the
five-section return and respawns once on empty. Fidelity against the
approved comp joins its checks; the card keeps commitment only. The
comp ingredient inventory becomes a written gate with raster-by-default
materials and no gradient-as-texture, comps persist under
.impeccable/mocks, the degraded seed names the sandboxed-exec cause,
and the finish line is explicit: a clean detector pass is not finished.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-24 17:09:33 -07:00
Paul BakausandClaude Fable 5 253f8e510c Concept machinery: survive truncation, builds, and loud briefs
The release-gate audit traced four ways the roll's output was defeated
downstream of a perfectly healthy seed. Gemini's harness keeps only the
tail of tool output, so the header-only ASSIGNED INDEX never reached
the model in 18 of 18 samples; the seed now restates the assignment
and key at the end of its output. Astro strips frontmatter comments,
so half the anthropic contracts vanished from built artifacts; the
contract now must survive the production build as an HTML comment in
emitted markup. A brief that paints its own picture (the album named
Soft Cathedrals) converged every arm regardless of assigned index; its
literal reading now joins the rut with at most one candidate. And Opus
under 4.0.1 skipped the seed 42% of the time while hand-authoring
plausible contracts; the finish reviewer now verifies FORM carries a
corroborable seed key before any craft point.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-24 15:33:44 -07:00
Paul BakausandClaude Fable 5 ffe869f4d0 Drop the turn-cap exception from the visualize mandate
Paul's call: the build-exhaustion failure only exists inside eval
workers with hard turn budgets no real harness exposes, and the clause
doubled as a hedge door for skipping the comp round. The eval-side fix
belongs in the worker's max-turns, not in skill prose.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-23 11:10:59 -07:00
Paul BakausandClaude Fable 5 e76ff27adf Eval-found fixes: workspace-relative cards, build outranks comps at caps
The release-gate campaign confirmed two skill bugs with transcripts.
Sandboxed harnesses reject absolute paths, so following the CHOSEN
CARD directive with the absolute card-base path failed view_image; the
directive and the quality-bar clause now say download into the
workspace and open the relative path. And under the openai worker's
turn cap, models spent the budget on init, cards, and comp generation
and never built the page (a third of small-n supplement slices); the
visualize mandate gains its one exception: at a hard cap the shipped
page outranks optional imagery.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-23 10:35:22 -07:00
Paul BakausandClaude Fable 5 73dec5d159 Subagent authorization becomes a central harness counter
Paul's call: the reviewer-local authorization patch covered one
command while the harness gate silently disables every shipped
subagent, critique panels and the manual-edit applier included. The
argument now lives beside the autonomy counter in context.mjs, emitted
as tool-result content every run: invoking the skill is the user
request such gates ask for; spawn where a reference directs; the
in-thread substitute is for absent capability only and gets disclosed
in one line. new-work keeps the reviewer mechanics and drops the
now-central argument.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-23 10:35:22 -07:00
Paul BakausandClaude Fable 5 4dc2b4d694 Finish reviewer: the skill invocation authorizes its subagents
A live session on a harness whose guidance gates subagent use on user
request resolved the conflict silently against the skill: it never
spawned the reviewer, stretched the no-subagents fallback to cover
permission hesitancy, and self-reviewed with all the context that made
its choices feel correct. Three tightenings: invoking the skill IS the
user request that authorizes its shipped subagents; the fallback is
for harnesses lacking the capability, not for hesitancy; a substituted
review gets disclosed in one line at finish, never silently.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-23 10:35:22 -07:00
Paul BakausandClaude Fable 5 dbe0c12b91 Live: stop the preflight writing source, cache the resolution
The polling-rework preflight wrote the variant scaffold into source during the
poll lease, before the agent acted. On source-preview targets (React/Vue/Vite,
everything but the svelte-component path) that write full-reloaded the
framework; a browser caught mid-reload missed the agent's variant write and the
SSE done, and sat stranded at 0/N.

Restore the 3.5 single-atomic-edit semantics: the preflight still resolves the
element location and computes the scaffold, but --defer-source-write leaves
source untouched and hands the agent the wrapper text plus the picked source
range. The agent splices variants into the wrapper and replaces the range in
one write, so the framework reloads exactly once. The svelte-component path is
untouched (it never writes route source). The missed-completion recovery stays
as defense in depth.

Also cache the resolved source file per target signature (locator + route):
the ~7.6s tree search re-ran on every generate for the same element; a hit now
points the helper straight at the file via --file, invalidated when the target
changes or a resolution fails.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-22 22:49:44 -07:00
Paul BakausandClaude Fable 5 4cd5ea7547 Add TanStack Router + Start support to live mode
Live mode had no TanStack coverage: a TanStack Start user hit disconnects
and static previews because there is no static index.html to inject and no
adapter for the SSR root document.

- New tanstack-adapter.mjs, modeled on the SvelteKit/Nuxt adapters: detects
  a TanStack Start project (@tanstack/react-start + src/routes/__root.tsx)
  and patches the __root document to mount a generated dev-only React
  component (src/impeccable/ImpeccableLiveRoot) that appends the live bundle
  on the client after hydration, carrying the ?token= param via
  buildLiveScriptSrc. Patch/unpatch round-trips byte-for-byte and is
  idempotent; refuses to clobber an unmanaged file at the component path.
- Wire detection into live-inject.mjs (insert + remove + gitignore),
  ordered so SvelteKit/Nuxt win and a plain TanStack Router SPA falls
  through to the baseline Vite index.html path.
- tanstack-router-vite fixture (baseline, no adapter) and tanstack-start
  fixture (SSR adapter), both with runtime blocks. Both pass the full
  live-e2e cycle (handshake, steer, pick, Go, cycle, accept, carbonize,
  reloadProbe).
- Unit tests for detection + patch round-trip + apply/remove; tanstack-start
  branches in framework-fixtures.test.mjs; live.md framework table + adapter note.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-22 22:49:44 -07:00
Paul BakausandClaude Fable 5 d4d02b69f2 Live: overlay preview is the verification channel; disconnects resume
Two prose fixes from the 3.5-to-4.0.1 forensic diff of a real user
regression (15-minute tweaks, repeated disconnects, agent abandoning
the picker). The craft-fold made every generate cycle pay the verify-
the-built-result loop the overlay already provides to the human; live
cycles now verify by construction and run the full check once at
accept. And nothing framed a dropped SSE or closed tab as resumable,
while the client toasts "Session ended", so agents rationalized
bailing to direct edits; the journal is canonical and reopening
continues the session.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-22 22:49:44 -07:00
Paul BakausandClaude Fable 5 bcdf38881e Command first, capability second
"When the harness can X, do Y" hands the model an exit before the
command arrives; the observed reviewer skip walked through exactly that
door. The three gated constructions now lead with the imperative,
present the decision visually, open the chosen card, spawn the finish
reviewer, and carry their fallbacks as trailing clauses for sessions
that genuinely lack the capability. Constructions that already led with
the command keep their routing clauses unchanged.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-22 12:23:07 -07:00
Paul BakausandClaude Fable 5 0bbb63b62a Ship the finish reviewer as a named subagent; ungate the asset producer
The eb686f36 session read the separate-reviewer rule and spawned
nothing: an unnamed "separate agent" is an improvisation prompt, not an
affordance. The skill now ships impeccable-finish-reviewer next to the
asset producer: persistence first, ceiling against the card and comp
second, contract promise by promise, truth; ordered material fixes
back to the parent, no editing, no second detector. new-work names it
so the finish step invokes a thing that exists.

The asset producer was gated providers: codex, so Claude Code never
shipped it; the gate is removed and its two codex-only workflow lines
made provider-neutral with codex blocks.

Dist rebuild still deferred for the running campaign.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-22 12:23:06 -07:00
Paul BakausandClaude Fable 5 91d310696d Canonicalize the visualize flow; put the added prose on a diet
codex.md becomes visualize.md and loads for every harness with any
image generation, native or the API fallback: after the direction
locks, three distinct compositional comps are rendered and put before
the user for approval, in-harness when it can display images,
otherwise on the decision page. Three is the number; one comp invites
rubber-stamping, and this approval round has repeatedly produced the
most compositional and ambitious work, so new-work now marks it
never-skipped. The codex-only subagent stays as a codex note.

The recent rule additions are tightened by a third: the asset and
imagery bullets merge into one, the canon exit loses its restatements,
the DESIGN.md-rule and chosen-card and ceiling clauses each shed their
second clause saying the first clause again. Same laws, fewer words;
prose that grows without bound recreates the attention gravity it was
written to fight.

Dist rebuild still deferred; the release-gate campaign reads the
pinned dist.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-22 12:23:06 -07:00
Paul BakausandClaude Fable 5 e409bec7b5 Canon standing exit, chosen-card directive, and the ambition fixes
From Paul's approved UX and the eb686f36 session post-mortem:

The standing exit: direction rounds carry a quiet, permanent "Play it
straight" action (payload flag canon, reserved id) on the decision page
and as the last structured-tool option. It is the user's door, never
the model's: never recommended, never weighed against the roll, and
choosing it swaps the bar rather than lowering it, two or three named
reference products become the craft level, canon executed at full
commitment. Safer/conventional steers resolve here, never to a
stranger re-roll.

Session fixes, each mechanical where possible: the ANSWER line now
names the chosen card's hero and board and directs opening them before
code (the session built from text alone after viewing a different
world's card); generation scale joins the imagery rule (a library of
centered 128px subjects foreclosed the atmospheric hero); DESIGN.md
rules are checked against the world's native devices and never added
to silence a hook finding (the session banned arcade lettering's own
offset shadow and laundered 8px through the ramp); staging joins the
FORM contract block (the axis was dropped silently at world-choice);
the finishing reviewer audits the ceiling against the QUALITY BAR card
after persistence (floor rigor was disguising unreached ambition); the
icon-tile clause names hand-drawn icons as remedy, not target.

Dist rebuild deferred: the release-gate campaign reads the pinned dist.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-22 12:23:06 -07:00
Paul BakausandClaude Fable 5 9dade04bbf Text fallback presents surviving challengers as alternates
The structured-tool channel collapsed to a single direction plus
re-roll, which read as "the system only ever offers one idea" next to
the multi-card decision page. Both channels now share one structure,
assigned direction leading, the one or two fused challengers that
survived the weighing as named alternates, re-roll with steer, and
differ only in richness. The anti-lineup rule stays precise: what never
appears is a ranked menu of the model's own grounded candidates; dealt
challengers carry no ranking rut.

Note: dist rebuild deliberately deferred; the release-gate campaign is
running against the pinned dist and rebuilding mid-run aborts it.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-22 12:23:06 -07:00
Paul BakausandClaude Fable 5 13c2ae5aa4 DESIGN.md joins the persistence gate
With the PRODUCT.md skip fixed, the Opus smoke unmasked the adjacent
gap: the model builds a new world and never writes DESIGN.md (zero
attempts), so the worker's requiresDesign assertion correctly fails the
run. Same disease, same treatment: DESIGN.md is now part of recording
the decision, written before the first build edit in the same stretch
as the direction contract, and the finishing reviewer checks
persistence first, before any craft point is scored.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-22 00:05:18 -07:00
Paul BakausandClaude Fable 5 c0ee4f3cac Build mandate: author the assets, generate the imagery
The truth split already permits full-fidelity demonstration data, but
permission at selection time was not holding at build time: models that
would not author covers, names, or thumbnails compensated with chrome,
which is the content-starved look the detector hunts. Two build rules
make it a mandate: every blank the ask round left open is authored at
production fidelity (content is authorable, claims are labelable,
nothing is omittable; unanswered commercial claims ship as marked
placeholders with a replacement list), and when image generation is
available, generating the build's imagery is part of building rather
than a nicety.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-21 23:49:01 -07:00
Paul BakausandClaude Fable 5 5a3c8fd18e Degraded roll keeps the decision page as its channel
A live retest showed the model dropping to the structured question tool
when the roll degraded: with no challengers and no cards it judged the
page pointless and presented one option in plain text. The degraded seed
output and the new-work rule now both state that degradation changes the
cards, not the channel; a browser session presents the assigned
direction as a single text-only card with re-roll on the decision page.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-21 23:30:58 -07:00
Paul BakausandClaude Fable 5 6e8cdfa581 Counter the harness autonomy directive from inside the working turn
A traced Claude Code injection asserts for whole model families that the
user is not watching and cannot answer questions; it ships default-on
with no off switch, and it suppressed every interactive step of a live
run (interview skipped, PRODUCT.md inferred, decision page never
served). Prose in a reference file loses that argument, placement wins
it: context.mjs now emits AUTONOMY_DIRECTIVE_CHECK as tool-result
content in the working turn, telling the model such a claim is a
harness default, never session evidence, and to probe once with the
question tool before inferring. init.md makes the same test mechanical:
tool presence proves an answer mechanism, one real probe round is
required, inference afterward must be labeled and disclosed in the
first reply. The degraded concept-seed path now also tells the model to
disclose the degraded roll instead of presenting it as a full one.
Image-gen signaling stays positive-only per Paul: key present emits the
capability, absence stays silent so harness-native tools are not
suppressed.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-21 23:02:25 -07:00
Paul BakausandClaude 5575a027dc Flag and repair drift in Impeccable's own project artifacts
v4 changed PRODUCT.md's shape and retired the register axis, so an
upgraded project can carry answers nothing reads. Nothing measured that.

Two tiers, and the split is a performance contract:

- Boot (context.mjs, emitting CONTEXT_STALE) spends only what a boot
  already spends: markdown already in memory, a bounded set of stats,
  the small JSON files the boot reads anyway. No new directory walks.
  One directive for the whole set, throttled to once a week per project
  so a finding the user declined does not reappear tomorrow.
- doctor.mjs runs the deep pass on demand: git drift, ignore lists
  validated against the live rule registry, hook script paths that stop
  resolving, and the monorepo workspace sweep. --fix applies only the
  migrations that carry no decision.

Findings are data, not prose, so the boot directive, the text report and
--json all render one set. Severity says what should happen: auto (fix on
the next write anyway), mention (state once), route (name the command
that owns the repair).

PRODUCT.md now carries a schema stamp so the checks stop reconstructing a
file's vintage from which sections it happens to have. Schema version,
not release version: a record written by 4.0.0 is not stale under 4.0.1.
DESIGN.md gets no stamp, because it follows the external design.md spec
that Stitch lints and every DESIGN.md signal is measurable without one.

The highest-value catch is a project that resolves to web while carrying
native build files, including a monorepo app inheriting a root record
that says web. That one costs output quality silently; nothing failed
before.

doctor follows the hooks/pin pattern rather than the Commands table, so
it stays out of the design menu and the count stays at 23.

Also corrects CLAUDE.md, which still documented the register axis,
reference/brand.md, reference/product.md, eleven deleted domain reference
files, and an extractRegister() whose only occurrence in the repo was
that sentence.

Prepared with AI assistance (Claude Code).

Co-Authored-By: Claude <noreply@anthropic.com>
2026-07-21 21:50:40 -07:00
Paul BakausandClaude Fable 5 b0a7deb688 serve-question: self-detect headless environments, capability-first routing
The env-var bypass (IMPECCABLE_QUESTION_DISABLED) relied on the harness
remembering to set it. The script now also self-detects CI, SSH-without-
display, and displayless Linux and exits 2 with the structured-question
advice; --no-open skips detection (caller opens the URL itself, as the
tests do) and IMPECCABLE_QUESTION_FORCE=1 overrides it. new-work.md now
frames the decision-page rule by capability: open a browser if you can,
structured question tool if you cannot, exit 2 means fallback not error.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-21 20:53:37 -07:00
Paul BakausandClaude 6d47843867 Stop losing DESIGN.md and native platform refs across init
Bugbot flagged the "resume without rerunning context.mjs" instruction
after init. It is right, and the gap is wider than the platform half it
named: context.mjs has two output branches, and the no-PRODUCT.md branch
omits DESIGN.md, the native platform references, and the unrecognized
`## Platform` warning. Because the skill never reruns the script once
init writes PRODUCT.md, whatever that first run withheld is gone for the
whole session. A greenfield iOS project would be designed without
reference/ios.md ever loading, and a project carrying DESIGN.md without
PRODUCT.md never saw its own design system.

The two halves need different fixes. DESIGN.md is authority in its own
right and does not depend on PRODUCT.md existing, so context.mjs now
emits it on both branches. Platform is unknowable before PRODUCT.md
exists, so no change to the script can recover it; init.md, the one step
that learns the answer, now loads ios.md / android.md / both right after
recording a native platform, and SKILL.src.md says so where it tells the
agent not to rerun.

Verified end to end against a temp project on both branches.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-07-21 20:33:05 -07:00
Paul BakausandClaude 9213e1bcd1 Fix stale section pointer and critique score denominators
Two true positives from the Bugbot review on PR #397.

document.md seed mode told the agent to run "Select one direction" for
paths A, D, or E. new-work.md has neither that heading nor the A/D/E
lettering since the workshop was restructured into named subsections, so
a literal read could skip the world-and-surface flow entirely. Point at
"Create or replace the visual world" and "Commit the world" instead.

critique.md let the heuristic table renormalize to an applicable maximum
when heuristics are scored n/a, but the report template hardcoded ??/40,
the rating bands only mapped raw numbers out of 40, and the persisted
meta carried total_score with no denominator. Trends could silently
compare 24/32 against 30/40 as if they were the same scale. The template
now prints the applicable max, the bands fall back to percentages for
partial sets, the snapshot records max_score and na_heuristics, and the
trend line states its denominator or breaks it out per run when they
disagree. critique-storage.mjs serializes frontmatter key-agnostically,
so the new keys need no code change.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-07-21 20:07:25 -07:00