V1 Web PWA · Surface walkthrough

Studio · Authoring

A per-surface walkthrough of the V1 Web PWA studio surface: layout, states, interactions, data, and cross-references.

walked
8sections4 minread

On this page

Context. surface studio · domain authoring · route /studio/authoring · auth signed-in + studio entitlement · source apps/oshun/web/src/app/studio/authoring/page.tsx

Last walked. 2026-05-29 automated runtime walk (Playwright headless) — render, /v1 data (2xx), console/page-errors, expected content, screenshot verified; live screen-reader, touch, offline, and telemetry-delivery checks pending a manual AT pass. Evidence: WALKTHROUGH/results/runtime-sweep-2026-05-29.md; body re-derived 2026-06-03 from current source (lane-console architecture)

Purpose#

Compose Oshun Studio artifacts with the structured-block editor, live source panel, preview-as-customer, evaluation harness, and AI-assist guardrails (§16.2). StudioAuthoringWorkspace is seeded — it loads a SEED_DOCUMENT (a "Morning Tara Practice" demo) and runs every client-side evaluator from @oshun/studio-authoring against it — and additionally embeds one live, real-backed AuthoringReadabilityLane wired to the Flesch readability scorer at /v1/admin/studio/readability. (This is the seeded exception to the studio lane pattern: there is no catalog fetch for the editor itself; only the readability lane talks to the BFF.)

Entry points#

  • Studio root (/studio) — discoverable as an authoring workspace
  • Review-approval-workflows, commenting-annotation-system, real-time-collaboration-substrate, asset-preview-pipeline, internationalization-localization — link here via quick actions
  • Direct URL / bookmark — yes

Layout regions#

page.tsx mounts <ShellLayout active="studio">, renders StudioAuthoringWorkspace, then a panel of 5 quickAction links. There is no Route Map panel on this route.

  • Header: document title <h1> (WorkspaceHeading, shows document.title)
    • a metadata line (templateId, locale) and an autosave/lamport strip
  • Readability Scoring lane (<section data-rd-lane>, <h2 data-rd-heading>): the only server-backed region — loads readability bands from /v1/admin/studio/readability, scores a pasted samples payload via /score
  • Two-column body (2fr 1fr):
    • Document blocks (data-studio-authoring-document-blocks): each block in document.blocks as an editable card, marked data-studio-authoring-block="<blockId>" + data-studio-authoring-block-kind="<kind>" (heading / paragraph / image / citation); paragraph/heading blocks are editable textareas
    • Right rail (aside): Sources (DEMO_SOURCE_SNIPPETS with per-snippet "Cite on para-2" buttons, data-studio-authoring-cite-snippet=<snippetId>), Preview parity (data-studio-authoring-preview-surface=<surface> chiplets + data-studio-authoring-preview-verdict), Evaluation harness (data-studio-authoring-evaluation-findings), Publish readiness (data-studio-authoring-publish-readiness), AI assist (data-studio-authoring-ai-instruction + data-studio-authoring-ai-verdict)

States#

  • Loading — server-rendered + client hydration
  • Readability lane loading / unauthorized / error / readydata-rd-loading, data-rd-unauthorized (admin scope 401/403), data-rd-error, then data-rd-bands + the score form
  • Initial seeded document — heading + 2 paragraphs + image; image has alt text; the second paragraph trips the cautionary "always" phrase
  • Findings populated — the second paragraph surfaces a tone-policy finding for "always"
  • Preview parity — at least one preview surface flags a missing caption track on the image block
  • Publish blockedreadiness.ok === false; missing list / unmet Isis gate ids (e.g. accessibility unmet when caption track is missing)
  • AI assist verdict — default instruction passes; adding banned phrases ("cure" / "eliminates anxiety") flips the verdict to blocked with a reason
  • Drag-to-cite — clicking "Cite on para-2" mutates document.blocks to add a citation block (via applyDragToCite)
  • Offline — editor is fully client-side; only the readability lane needs the network

Interactions#

Readability Scoring lane (live)#

  • Samples (JSON)textarea[data-rd-payload], aria-label="readability samples json" (e.g. { targetGrade, samples[{ sampleId, sentences, words, syllables }] })
  • Score readabilitybutton[data-rd-submit] (form data-rd-form submit) → POST /v1/admin/studio/readability/score; renders data-rd-result with data-rd-avg-ease / data-rd-avg-grade headline and data-rd-sample-row rows (data-rd-ease / data-rd-grade / data-rd-band)

Editor blocks (per block)#

  • Block card (data-studio-authoring-block="<blockId>", data-studio-authoring-block-kind="<kind>") — heading/paragraph render an editable textarea (onBlurhandleEdit); image shows URL + alt; citation shows source id + locator
  • Autosave — each edit runs acceptAutosave against in-page state and updates the lamport clock / autosave status string

Sources panel#

  • "Cite on para-2" (button[data-studio-authoring-cite-snippet=<id>]) — calls applyDragToCite('para-2', snippet); appends a citation block or reports "citation already present"

Preview parity / Evaluation / Publish readiness / AI assist#

  • Per-surface chiplet (data-studio-authoring-preview-surface) — selects the active surface; verdict shows ✓ ready or N parity issue(s)
  • Findings list (data-studio-authoring-evaluation-findings) — severity, kind, blockId, message
  • Publish readiness (data-studio-authoring-publish-readiness) — ✓ satisfied or "Blocked — missing: …" + unmet Isis gates
  • AI instruction textarea + verdictevaluateAiAssistGuardrails pass / blocked with reason + detail
  • 5 sibling links: Review and Approval Workflows, Commenting and Annotation System, Real-Time Collaboration Substrate, Asset Preview Pipeline, Internationalization & Localization

Data & contracts#

  • Reads (editor): in-page seeded SEED_DOCUMENT, DEMO_TONE_POLICY, DEMO_SOURCE_SNIPPETS, DEMO_BINDINGS
  • Reads (lane): GET /v1/admin/studio/readability (catalog: bands[])
  • Writes (lane): POST /v1/admin/studio/readability/score (returns { result: { samples[], summary } })
  • Writes (editor): none — acceptAutosave / applyDragToCite run against in-page state only
  • Realtime: none
  • Caching: readability lane uses client fetch on mount, cache: 'no-store'
  • Auth/role check: the readability lane is admin-scoped fail-closed (admin:* | admin:studio, 401/403) at the BFF; proxy studio gate on the route (signed-in + studio entitlement). Headers via buildBffAuthHeaders().
  • Library: @oshun/studio-authoringevaluateAuthoringWithPolicy, evaluateAllPreviewSurfaces, evaluatePublishReadiness, evaluateAiAssistGuardrails, acceptAutosave, applyDragToCite, citationDensityByBlock

Cross-references#

Open questions / known gaps#

  • The editor is seeded; only the readability lane is server-backed. Confirm the authoring-document persistence path once the workspace moves off SEED_DOCUMENT.
  • Document the autosave latency budget — acceptAutosave currently runs synchronously against in-page state.