Repository navigation
Description
Problem
The toolkit gets a user's approval of the wireframes once, at the Stage 3 gate. Every change after that goes from requirement to MDL with no visual check by the person who asked for it:
- a new requirement in the middle of the build;
- a greenfield page;
- a change to a screen in a live
.mpr.
The user first sees the change when they click through the built app. That is the pattern in #232: the LOOK was skipped and the user found UX defects by hand. In #291 the defects were designed in and then built faithfully.
The proposal: for every change that alters what a user sees, show a before/after wireframe first, ask "is this right?", stop, and build only after a yes. Then show the built page next to the approved design. That gives "a direct visualization of what's happening" without leaving the chat.
What exists today
| Change kind | Exists | Gap |
|---|---|---|
| New screen, Stage 3 (migration/requirements) | One annotated wireframe per screen, design/prototype.html, Steps 3b/3c (skills/design-artifacts.md); CAC-4 (skills/checkpoints/checkpoint-design.md); Stage 3 ✋ (skills/conversion-runbook.md) |
Mostly covered. Approval is per stage, and nothing records which wireframe version the user saw. |
| New screen, greenfield | skills/ui-preflight-pages.md Step 1: no wireframe means STOP. bin/lib/artifact-manifest.tsv wireframes row excludes greenfield. |
Missing. The agent draws a wireframe to clear its own STOP, and nobody approves it. |
| Mid-build requirement | Drift-sync "visually observable" re-render (conversion-runbook.md §3b, skills/iterative-build-loop.md); [sync: … UNSYNCED] gate |
Missing. The re-rendered wireframe is never shown to the user. The gate checks that the sync happened, not that anyone approved it. |
Changed screen on a live .mpr |
skills/existing-app-change.md Stage 3 "wireframes only for screens that change"; ground rule 4 "as-is before to-be" (text); ui-preflight-pages.md Step 0 already runs DESCRIBE PAGE |
Partial. No as-is visual and no side-by-side. |
| Non-UI (entities, microflows, security) | Stage 3 Mermaid in architecture/blueprint.md; BRD as-is/to-be text; role-to-access table |
Partial. Nothing per change shows a before/after. |
| Verify the build | skills/ui-loop.md + project-bin/look-ledger.sh (screenshot), project-bin/page-fidelity.js (docs/PAGE-FIDELITY.tsv), skills/module-review.md stage 4, obligations look / fidelity |
Partial. These compare against the current wireframe, approved or not. No single artifact shows the approved design next to the built page. |
Proposed loop
Run by the lead session, because subagents cannot ask the user:
- Classify. Is the change visually observable? Reuse the drift-sync filter.
- If it is trivial (a label or one field), show an inline text diff and go to step 5.
- If it is non-UI, render the equivalent instead: a Mermaid
classDiagrambefore/after for entities, a behaviour table (input → outcome) for microflows, an access-matrix diff for security. Use theDESCRIBE/SHOWoutput the change already fetched.
- Propose. Write
design/proposals/<date>-<slug>/.before.*, taken from the cheapest existing source, in this order:- the last LOOK screenshot;
- the current wireframe;
- a rough wireframe drawn from the
DESCRIBE PAGEoutput that preflight Step 0 already fetched; - a screenshot the user drops in.
after.html, built fromds.csswith its binding table, as in design-artifacts Step 3.proposal.html, showing before and after side by side, with changed regions outlined and a status strip (Proposed → Approved → Building → Built → Verified).
- Show it. Per-host options are in the next section.
- Ask, then stop. Offer Approve · Change (say what) · Drop, plus "something else". Render the question per
skills/interview-protocol.md§3, then end the turn. - Record. Add a
PROJECT.mdrow:Wireframe approved: <Screen> (design/proposals/…) sha256:<8> | CONFIRMED, with the drift-sync marker. Copyafter.htmloverdesign/wireframes/<Screen>.html. Every existing check then reads the approved version with no code change. - Build. Run the normal loop unchanged. The status strip mirrors the Live Checklist.
- Verify. The existing
ui-loop.mdscreenshot becomesbuilt.png, andproposal.htmlgains an approved | built column. Answer the four LOOK questions against it. Thepage-fidelity.jsrow is unchanged.
Where it shows, per host
The loop needs three facts from the separate host-detection work: can the user render a local file, can the agent screenshot it, and is the session remote.
| Host | Show | Agent sees it |
|---|---|---|
| Claude Code desktop (local) | Click the path in chat to open it in the Browser pane | Yes. Reload can serve stale HTML, so write a new revision filename each time. |
| Claude Code CLI (local) | open / xdg-open / start, as bin/init-project.sh does for the guide, or a private Artifact |
Via Playwright |
| Claude Code web / cloud / remote-control | Private Artifact, republished to the same URL | Yes. The preview pane is unavailable in remote-control. |
| VS Code + Copilot | Integrated Browser (local .html), Simple Browser (needs http.server), Live Preview ext. code -r opens the source only. |
Usually no |
| Cursor | Built-in browser via "Open in Browser" on the HTML tab; Design Mode for annotating | Agent browser tools |
| Windsurf (docs now Devin Desktop) | Browser Previews of a local server; "Send element" to Cascade | Partly |
| Codex | App in-app browser (file-backed previews, comment mode); Browser plugin; CLI uses OS open |
App + plugin |
| Headless / CI / unattended | Files plus a log path | No. Record ASSUMED (opt-in unattended only), queue the proposal, and surface it at the next attended gate. |
Minimal design
- New skill
skills/propose-before-build.md. It holds the 7 steps, skip rules, the before-source ladder, a compare-page HTML template, and a host table that defers to host detection. It ends on a denominator: "N of N changed screens have a proposal folder and a CONFIRMED/ASSUMED row". - Routing row in
bin/lib/skill-routing.tsv. Agentslead, stages3,5, tierexperimental, groupdesign. A lead-only row renders into no agent stub, and the experimental tier is never the reason a gate fails. - One-line hooks in on-demand skills only:
design-artifacts.md, for wireframes edited after Stage 3 approval;- the
existing-app-change.mdStage 3 row, for the as-is visual; - the
iterative-build-loop.mddrift-sync rule, so a visual re-render is approved before the marker flips.
- No new obligation in v1. The existing
lookandfidelityobligations already verify againstdesign/wireframes/<Screen>.html, which is now the approved version. - No script in v1, per
skills/skills-over-scripts.mdrow 4 and its "Adding a new capability" rule: use the skill by hand twice first. A small compare-page helper can come later if that proves tedious. - v2, after field use:
- a gate-check join with no mxcli: a
design/wireframes/*.htmlcommitted after Stage 3 approval with noWireframe approved:row (or waiver) reports; - add greenfield to the
wireframesmanifest row.
- a gate-check join with no mxcli: a
- Behaviour A/B. Not needed for v1, because no baseline text and no stub is touched. Still run
render-routing.sh --checkand a retrieval check on real phrasings (CLAUDE.md rule 8). An A/B is needed before promotion to baseline, before any line goes intoconversion-runbook.mdorui-preflight-pages.md, or before a stub changes. The behaviour suite is on the unmergedtests/behaviour-suitebranch.
Cost / performance
- Zero added mxcli or mxbuild calls. The "before" image reuses an existing screenshot, the wireframe, or the
DESCRIBE PAGEthat preflight Step 0 already runs. The "built" image reuses theui-loop.mdscreenshot. The build still runs oneexec.shand mxbuild per script ([field 2026-10-17] Gate cost: full deploy mxbuild per small script, no check-only or batch mode, no global lock #444 is about that cost and must not grow). - Tokens: about 3–8k per changed screen (edit the wireframe and fill the compare template), plus one ask-and-wait turn. That is an estimate, not a measurement. Human latency dominates.
- Skip when:
- the change is not visually observable;
- the lightweight carve-out applies (use an inline diff);
- the user said "no visual":
Proposal mode: off | inlineinPROJECT.md, in the same style asInterview mode; - the screen was already approved in the Stage 3 prototype and this is its first build.
Risks
- Approval fatigue. Batch per slice or phase: one page, one question, "approve all / one by one". When more than about 5 screens change at once, route back to Stage 3 instead.
- Wireframe vs real Atlas rendering. Prefer a real screenshot as "before" and label "after" as intent, not pixels. The approved | built column is where drift shows, and the LOOK judges it. B0
check-design-reaches-app.shcovers the token gap. Do not move wireframes to Atlas classes (skills/existing-app-assurance.md). - A "before" drawn from describe output is lossy. Label it so and prefer a screenshot.
- Rubber-stamp. Approval proves the user saw the design, not that it suits several roles and objects. That is Usability/flow defects pass every gate: proposal for a Stage-3 interaction-model deliverable and gate #291's job.
- Renderer creep. Keep it as a skill; see skills-over-scripts.
Open questions
- Approval granularity: per screen, per change, or per phase with batching? I recommend per change, batched.
- v2 join verdict for an edited wireframe with no approval row:
FAILorMANUAL? - For an existing app with no screenshot on disk: accept a describe-derived "before", or start the app once for a real screenshot? A real screenshot costs an app start, not mxbuild.
- Should non-UI proposals share the proposal folder, or ride on the drift-sync decision row only?
- Unattended runs: queue the proposal as
ASSUMED, or block page scripts for that screen until an attended session approves? - Should the proposal page carry Usability/flow defects pass every gate: proposal for a Stage-3 interaction-model deliverable and gate #291's "two objects, two roles" walk for the changed screen?
- Which host-detection output will this consume?
Next steps
- Draft
skills/propose-before-build.md(experimental, lead-only) plus its routing row; runbin/render-routing.sh --check. - Use it by hand on two real changes: one mid-build requirement on a greenfield or requirements-driven app, and one change to an existing
.mpr. Record per change:- tokens spent;
- wall time to approval;
- whether the user changed the proposal;
- whether the built page diverged.
- Decide from that evidence whether to add the v2 join, a compare-page helper, and promotion (with a behaviour A/B).
Sources
- Toolkit @
2fcdf5e: files named above; related Usability/flow defects pass every gate: proposal for a Stage-3 interaction-model deliverable and gate #291, Page review (LOOK) never happens during the build: owed list hit 106, user found the UX defects by hand #232, [idea] Build loop: visual check per page during the build + state save-then-check explicitly; route MCP-owner asks upstream #173, [field 2026-10-17] Gate cost: full deploy mxbuild per small script, no check-only or batch mode, no global lock #444, ask 9: the Stage 3 gate accepts one wireframe for an app of twenty screens #107. - Claude Code desktop Browser pane: https://code.claude.com/docs/en/desktop
- Claude Code preview reports:
https://claudeissues.com/issue/65443-desktop-preview-pane-serves-stale-html-doesnt-refresh-on-reload-after-the-file-c, https://claudeissues.com/issue/48466-preview-pane-pdf-image-html-unavailable-in-remote-control-sessions ,https://claudeissues.com/issue/59568-vscode-extension-clicking-local-html-file-links-in-chat-no-longer-opens-embedded - VS Code Integrated Browser: https://code.visualstudio.com/docs/debugtest/integrated-browser
- VS Code CLI: https://code.visualstudio.com/docs/configure/command-line
- VS Code Live Preview: https://github.com/microsoft/vscode-livepreview
- Cursor (forum): https://forum.cursor.com/t/open-html-files-directly-in-the-agent-window/165015 , https://forum.cursor.com/t/using-agent-to-open-simple-browser-in-ide/129518
- Windsurf / Devin Desktop previews: https://docs.windsurf.com/windsurf/previews
- Codex in-app browser: https://developers.openai.com/codex/app/browser ; IDE: https://developers.openai.com/codex/ide/features
Caveat: the VS Code, Codex and Windsurf pages were read through search summaries, not fetched directly. The Cursor claims come from its forum.
Generated by Claude Code
Activity
MendixMau commentedon Oct 21, 2026
Linked: #508 is narrowed to a model change view (before/after of the documents a script touches, or between two commits), to serve as this loop's picture for non-UI changes. It is parked until the hand trial of this loop on two real changes shows the picture is wanted.
Generated by Claude Code
MendixMau commentedon Nov 3, 2026
Parked (maintainer decision, 2026-11-03). Good direction, but it changes the process path in every entry mode. Revisit after the Stage 3 interaction-model gate (#291 / #333) lands, since that gives the wireframe a mechanical contract to approve against.
Generated by Claude Code