← Testing HQ
Brain · Round 4 · live parity click-through

The extraction is fine. The playbook is where it falls apart.

First round run after the #2988 write-path fixes shipped, and the first with real screenshots. Rounds 1–3 asked "did the AI read the business correctly?" and the answer was consistently yes. This round asks the next question — "does the founder get a playbook worth reading?" — and the answer is no, for one specific, fixable reason.

Account peytonworkprojects@gmail.com (Ambre Studio data, Round 3 carry-over) Surface platform.mystflo.com/brain Run date 2026-07-31 Cost $0 — existing stored state re-observed, no new AI reads
Read this first — what this round did NOT do. No new research pass was run. Every observation below is of data already stored on this account from Round 3, re-rendered by production code that now includes the #2988 fixes. That makes this a clean test of the display and write layer, and explicitly not a re-test of extraction quality. Where a finding could plausibly be stale Round-3 data rather than live behaviour, it is labelled as such rather than asserted.
1 · What the founder actually sees

Captured with a new Playwright harness (tests/e2e/brain-parity-capture.spec.ts) so the next round is a re-run, not another hand-driven browser session. Full-page captures — nothing cropped at the fold. Mobile is graded first: the canon takes the worse of the two widths.

Brain playbook at 1440px, full page
Desktop — 1440×900, full page. The Branding block is visibly the largest single element on the page, dwarfing the sections a founder actually needs to act on.
Brain playbook at 375px, full page
Mobile — 375×812, full page. The same block occupies roughly 40% of total scroll height. This is the view most founders will meet first.
Harness caveat, stated rather than hidden. The 1440 run missed two of its six intended section shots — the selectors matched the sticky nav pills instead of the section headings. Content coverage is unaffected (both landing captures are full-page, so every section is present in frame), but the harness selectors need fixing before the next round. On mobile, full-page capture also duplicates the sticky header mid-scroll; that is a capture artifact, not a layout bug.
2 · The finding: a 47× overrun against the design contract

The design artifact is not silent on what this row should look like. The binding rule is V-12 / P0-1, stated in brain.html:3403 (frame f22, Active section): “ONE playbook row, TWO sheets — never a zone toggle… the row stays one because a founder reads ‘does this sound and look like me?’ as one question; the sheets stay two because the material behind it doesn’t share a shape.” Every rendered instance in the artifact agrees — :1605, :1767, :1938, :2283, :3175 all draw ~6–10 words per facet:

This is stronger than “too long”. V-12’s own rationale explicitly cites a “~4:1 length asymmetry” as the reason the material was put behind two doors in the first place. Production isn’t drifting from an under-specified design — it is violating a rule that was written because this content is long.
Artifact f13 — the specified row
Branding   (sound) Warm, direct, a little playful. · (look) Earthy neutrals, film-grain photos.

That is roughly six words per facet. Here is the same row in production:

Production — (sound), rendered verbatim into the row
Spiritual, gentle, introspective, and professional. The tone is inviting and focused on healing and self-discovery. Professional, reflective, and appreciative. The tone is elevated and community-focused, emphasizing empowerment and shared experiences. Mystical, artistic, and slightly cryptic. The tone is elevated and intentional, focusing on the spiritual or symbolic nature of the artwork. Spiritual, artistic, and therapeutic. The tone is ethereal, grounded, and intentional… [1,452 chars total]
FacetArtifact specProductionOverrunRepetition
(sound)~6 words192 words / 1,452 chars / 22 fragments~32דThe tone is” ×11 · “artistic” ×9 · “spiritual” ×7
(look)~6 words282 words / 1,868 chars / 29 fragments~47דThe aesthetic” ×6 · “earthy” ×6 · “bohemian” ×4

Two sentence-pairs appear verbatim twice inside the same block. The content is not merely long — it is one description per screenshot, concatenated, with no synthesis pass.

3 · Root cause — and why it only bites some founders

Three lines of production code explain the whole thing.

PlaybookPage.tsx:1371 — the voice row renders the column verbatim
const voiceLine = voiceInstructions || profile.tone?.trim() || '';
PlaybookPage.tsx:1378 — the look row branches, and this is the crux
const lookLine = hasStyleCard
  ? 'Colours, type, logo — from your site'      // short, artifact-shaped
  : profile.visual_tone?.trim() || '';          // raw 1,868-char dump
screenshotCorpus.ts:179,204 — how the column got that long
const merged = [currentCustomInstructions, ...dedupeNearIdenticalNotes(voiceNotes)]
  .filter(Boolean)
  .join('\n\n');

// …and the file's own comment at L120:
//   "This is NOT the real fix (an LLM synthesis pass …)"
The asymmetry is the story — and it is a hard structural fork, not a coincidence. _shared/style-harvest.ts:1-24 declares a BINDING scope wall on the style card: extraction is “from a founder’s website CSS + HTML”, with “NO design-system-from-a-screenshot” and “NO vision-as-primary-palette — the palette is 100% CSS-derived.” So an Instagram-only founder structurally cannot populate brand_style_card. The ternary always falls to the raw column. The short line isn’t a summariser — it is a placeholder only the website path can ever reach. Rounds 2 and 3 were both Instagram-only, which is why this surfaced now. Retreat and workshop hosts — the launch ICP — are disproportionately Instagram-first.

So the answer to “should it be bullet points?” is narrower than it looked. The design already says what the row should be, and it is not a paragraph or a bullet list — it is a one-line summary, with the full detail living in the (sound) and (look) sheets behind it. The build honours that on one path and ignores it on the other. The missing piece is a synthesis step, not a formatting choice.

  per-screenshot vision notes
        │
        ▼
  dedupeNearIdenticalNotes()          ← #2988 interim fix: collapses near-duplicates
        │
        ▼
  .join('\n\n')  ─────────────────►  brain_profile.custom_instructions / visual_tone
        │                                              │
        │                          ┌───────────────────┴───────────────────┐
        │                          ▼                                       ▼
        │              hasStyleCard === true                  hasStyleCard === false
        │              (website crawl ran)                    (Instagram-only)
        │                          │                                       │
        │                          ▼                                       ▼
        │              short canned line ✓                    raw column dumped ✗
        │
        └── MISSING: a synthesis pass that turns N notes into ONE summary line
                     + keeps the full text for the sheet behind the door
4 · “Cut off” is three different problems, not one

Worth separating, because the three need different fixes and only one is a genuine data loss.

What it looks likeWhat it actually isVerdict
“What you sell” shows 5, then view all 10 → All 10 offerings are stored. PLAYBOOK_LIST_PREVIEW_LIMIT caps the preview at 5 with a disclosure (PlaybookPage.tsx:739). But the disclosure leads nowhere complete — see the row below. Count disclosed, content not
Offering description / details visibility Corrected in Round 5 — narrower than first stated. PlaybookDepthSheet.tsx:107 defaults readOnly = false, and the /brain call sites (PlaybookPage.tsx:1673,1695) never pass it — so the signed-in founder does see both fields behind view all 10 →, as editable textareas. The gap is the read-only branch (BrainFocusPanel.tsx:166,199, readOnly={isGuest}): guests and shared-preview viewers see name + price + dates only. Separately, exportPlaybook.ts:145 still drops details and dates from the markdown export. Real, but guest + export only
Branding line ends in “…” The opposite of truncation — the field is over-full and CSS line-clamps it. Nothing is missing; too much was written. And the clamp is the only thing hiding it: Round 5 opened the (look) door and found HowYouLookSheet’s “THE VIBE” block rendering the same 1,868-char concatenation unclamped. The overflow follows you through the door — there is no synthesis anywhere in the look vertical, row or sheet. Symptom of §3 — and worse in the sheet
“Where & how you operate” is empty Bali appears at least twice in the Round 3 raw extraction — in the IG bio (“Art as expression of the soul ☉ Bali”) and in a vision description (“natural settings (Bali)”) — yet the field is empty. The mapper is not missing — see below. Open — two candidates
Do not build a location mapper — one already exists, end to end. The prompt asks for it (organize-content.ts:113, “location: city / region / country exactly as written”), the parser keeps it (organize-classify-output.ts:245), the mapper proposes it (organizeCleanToProposals.ts:156-157, pushBusiness('location', location)), and the page renders it (PlaybookPage.tsx:714-717). So an empty field is exactly one of two things: (a) the classify pass never extracted it — ☉ Bali is an emoji-decorated bio fragment and the prompt gives no example of that shape; or (b) the proposal was generated and the founder never tapped ✓ Use — this is a confirm-spine, nothing reaches brain_profile until confirmed, and an unconfirmed proposal is indistinguishable from a missed one after the fact. These are cheaply distinguishable: run one read and look at whether a location card appears in the composer before confirm. Appears → confirm-UX problem. Doesn’t → one added prompt example fixes it.

The second “Bali” is unrecoverable by design: it came from the vision visual_style field, which maps to the brand-look column. Nothing lifts a location out of an aesthetic description, and nothing should.

Three other extracted facts are genuinely never stored:

FactWhy it vanishesVerdict
linktr.ee/AmbreStudio organizeCleanToProposals.ts:75-78isRealUrl requires /^https?:\/\//i. Instagram displays bio links without the scheme, so the link fails the test and is silently dropped. Compounding: the screenshot path’s contact_info shape is email/phone/address only — no socials key at all, unlike the website path. Bug — two causes
Bilingual IT/EN Zero hits for language anywhere in src/types/brain.ts. Never extracted, nowhere to put it. No field exists
343 posts / 7,184 followers Actively excluded — _shared/brain-prompts.ts:359-360 instructs “do NOT add UI chrome (likes, timestamps, button labels)”, and follower counts read as chrome. Deliberate — worth re-confirming
Not a finding: missing prices. Every offering renders · — where a price would go. I checked the raw extraction before calling this a defect — this Instagram profile genuinely publishes no prices, so an empty price is honest, not lost.
5 · Defect watch
R4-01 · blocker
Branding row dumps the raw column on the Instagram-only path
Violates artifact f13 (Active, marked shipped) by ~47×. Fix: add a synthesis pass producing one summary line for the row, keeping full text for the sheet. See §3.
R4-02 · corrected by Round 5
Offering detail is invisible to guests, and absent from the export
This entry originally claimed the detail had “no read surface anywhere”. That was wrong — it was derived from the read-only branch without checking which branch /brain actually mounts. Round 5 verified the sheet mounts editable on the founder’s own page, so she does see both fields. The real gap: the guest / shared-preview read-only branch omits them, and the markdown export drops details + dates. Still worth fixing, but smaller than first filed.
R4-06
Instagram bio links are dropped by a scheme check
isRealUrl demands https://; IG renders bio links without it. Separately, the screenshot path’s contact_info has no socials slot at all, so even a well-formed link would have nowhere to land.
R4-07 · needs one experiment
Location extracted but not stored — cause not yet isolated
The full mapper path exists and is verified. Empty field is either a classify miss on the emoji-decorated bio fragment, or a proposal that was never confirmed. One read settles it — do not build a mapper.
R4-03
FAQ section holds prose, not question/answer pairs
“Customer questions & policies” renders a service description (“Medicine Drawing is a profound journey…”) rather than a Q&A. Corroborates the mis-categorisation half of #2989. The empty-FAQ / persona-generation path is still unexamined.
R4-04
“My Business” still renders as the business name
The #2988 fix correctly counts the placeholder as missing (the panel lists “your business name”, completion reads 50%). But the row still displays “My Business” as though it were real content. Counting and rendering disagree. Caveat: this row was written pre-fix, so this may be stale data rather than a live write — a fresh read would settle it.
R4-05 · working as intended
Honest placeholder on unbuilt sections
“Product listing copy” reads “Specified, not built yet — no generation exists for this section.” Correct behaviour — says what is true instead of faking content.
6 · What this round could not answer