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, showsdocument.title)- a metadata line (
templateId,locale) and an autosave/lamport strip
- a metadata line (
- 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 indocument.blocksas an editable card, markeddata-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_SNIPPETSwith 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)
- Document blocks (
States#
- Loading — server-rendered + client hydration
- Readability lane loading / unauthorized / error / ready —
data-rd-loading,data-rd-unauthorized(admin scope 401/403),data-rd-error, thendata-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 blocked —
readiness.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.blocksto add a citation block (viaapplyDragToCite) - 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 readability —
button[data-rd-submit](formdata-rd-formsubmit) →POST /v1/admin/studio/readability/score; rendersdata-rd-resultwithdata-rd-avg-ease/data-rd-avg-gradeheadline anddata-rd-sample-rowrows (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 (onBlur→handleEdit); image shows URL + alt; citation shows source id + locator - Autosave — each edit runs
acceptAutosaveagainst in-page state and updates the lamport clock / autosave status string
Sources panel#
- "Cite on para-2" (
button[data-studio-authoring-cite-snippet=<id>]) — callsapplyDragToCite('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 + verdict —
evaluateAiAssistGuardrailspass / blocked with reason + detail
Footer quick actions#
- 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/applyDragToCiterun against in-page state only - Realtime: none
- Caching: readability lane uses client
fetchon mount,cache: 'no-store' - Auth/role check: the readability lane is admin-scoped fail-closed
(
admin:*|admin:studio, 401/403) at the BFF; proxystudiogate on the route (signed-in + studio entitlement). Headers viabuildBffAuthHeaders(). - Library:
@oshun/studio-authoring—evaluateAuthoringWithPolicy,evaluateAllPreviewSurfaces,evaluatePublishReadiness,evaluateAiAssistGuardrails,acceptAutosave,applyDragToCite,citationDensityByBlock
Cross-references#
- Parent:
../studio-overview.md - Sibling:
studio-compose.md,../collaboration/studio-review-approval-workflows.md,../collaboration/studio-commenting-annotation-system.md - Source:
apps/oshun/web/src/components/studio/StudioAuthoringWorkspace.tsx
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 —
acceptAutosavecurrently runs synchronously against in-page state.