Oshun Platform · Reference & analysis

Tara Content Workbench — Design

companion TODOS is covered by the phase(s) named in its "Covered by" column; no row is rejected.

12sections15 minread2tables

On this page

Date: 2026-07-19. Status: ratified (2026-07-19, under the operator's directive to execute the companion TODOS; P0.1). Companion task ledger: /TARA_CONTENT_WORKBENCH_TODOS_2026-07-19.md.

Ratification note (P0.1, 2026-07-19)#

Benchmark dispositions: every row of the SOTA capability benchmark in the companion TODOS is covered by the phase(s) named in its "Covered by" column; no row is rejected. Two rows carry scope notes rather than rejections: real-time multiplayer boards remain a non-goal (§2) — capture, triage, and review are single-writer with three-way merge at launch — and the audio QA gate ships as an honest fail-loud seam (P7.4) until an audio pipeline exists.

Amendments recorded at ratification (investigated 2026-07-19):

  • A1 (resolves DR-3 / P0.2). V1 studio/editorial durability lives in libs/oshun/persistence: a generated Prisma schema (prisma/schema.prisma, "do not edit by hand") produced by scripts/generate-contract-persistence-schema.ts from Zod contracts registered in src/contract-persistence-registry.ts — which already registers Tara consumer models (objectContract('tara', 'RitualTemplate', …) etc.) and taxonomy enums (ThemeTaxonomy, ContextTag, LineageTaxonomy). BFF admin stores follow in-memory + durable-backed-* snapshot patterns over AdminStoreSnapshot. Decision: no libs/oshun/tara-workbench/prisma. Workbench entities are defined as Zod contracts in libs/contracts/src/tara/ (a workbench-scoped module), registered as first-class objectContract rows (queryable — required for the claims/sources graph), and the schema is regenerated. The Prisma client is constructed by the caller via createV1PrismaClient(connectionString) (fail-loud on empty; dev DB oshun_dev per root .env). Existing ThemeTaxonomy/ContextTag enums are reused for M4 theme vocabulary rather than duplicated.
  • A2 (resolves the P0.4 provider seam). The workbench uses the same conventions as the plane's shipped synthesizer (creative-autonomy/src/ideation/llm-synthesizer.ts): functions accept LLMProviderInterface | null from @oshun/ai, run through runStructuredOutput from @oshun/ai/agent-loop (schema-validated, retrying, fail-loud), and fence all untrusted material with @oshun/prompt-trust (definePromptAuthorityField, renderTrustPrompt). TaraWorkbenchModelProvider (diverge, extractClaims, assistScript — defined in P1) is a thin façade over that stack; a null provider yields a typed not_configured refusal, never canned output.
  • A3 (P0.5). Threat & safety review appended as §10.
  • P0.3 verification: @oshun/creative-autonomy root exports everything the workbench imports (composeBrief, deriveCandidateIdeas, IdeaSynthesizer, createStructuredIdeaSynthesizer, applySteeringUpdate, CreativeDirection, SteeringUpdate, ThemeWeight, IdeaScoreWeights, and — via export * from './types'ContentCategorySpec, AutonomyLevel). No deep paths, no export changes needed.

1. Problem statement#

Tara (the V1 meditation/mindfulness product) has no human-facing creation and curation workspace. A 2026-07-19 full-surface sweep found:

  • Authoring is file-editing in git. The source of truth for all Tara content is the apps/tara/content/ file tree (meditations/, courses/, teachers/, sounds/, collections/, validated by apps/tara/content/schemas/*.schema.json). No UI exists over it. The Tara API exposes no authoring routes; the Tara web app is consumer-only.
  • The autonomous pipeline is real but headless for Tara. The creative autonomy plane (libs/oshun/creative-autonomy, bound in apps/oshun/bff/src/agentic/autonomy-route.ts, produced through apps/oshun/content-service) already generates Tara content — category tara.seasonal-ritual in V1_AUTONOMY_LAUNCH_CATEGORIES (autonomy-route.ts:128) — with judges, budgets, gates, and provenance. Humans meet it only at the generic /operator/autonomy console.
  • Ideation and concept development have no human surface. Ideation exists solely as the agent-internal creative-autonomy/src/ideation step. The Hathor/Yemaya audit (HATHOR_YEMAYA_IDEATION_SOTA_TODOS_2026-07-17.md, G1) states the platform-wide gap: nothing owns capture → divergence → selection → development → promotion.
  • Knowledge grounding is backend-only or fixture-fed. Sophia grounded answers with citation trails exist (apps/oshun/bff/src/sophia/), and a claim/source/needs-citation domain model exists in libs/v3/tara-studio/src/lineage-grounding.ts — but the only Tara-facing grounding UI (TaraAiPersonaSponsorPanel, TaraLineageGroundingPanel in apps/oshun/admin) mounts on hardcoded fixtures, and the one authoring-shaped editor (LilithAsanaEditor, 1,076 lines) makes zero network calls and persists nothing.
  • Programs and themes are code, not content. ContentCategorySpec rows are hardcoded in the BFF; the only live "higher structure" lever is the global CreativeDirection steering document (creative-autonomy/src/steering/steering.ts:43-59).

The result: draft review and agent ops are strong; everything upstream of a draft (ideas, concepts, grounding, programs) and downstream of approval (publishing into the content tree) has no workspace.

2. Goals#

Build the Tara Content Workbench: a single Oshun-Studio surface where a small editorial team and the autonomy plane co-produce Tara content, covering:

  1. Ideation — capture, divergence, selection, and promotion of sparks into concepts, human-led and agent-assisted.
  2. Concept development — a dossier per concept with a maturity ladder from premise to publishable script.
  3. Knowledge grounding — first-class sources (contemplative traditions, philosophy, neuroscience/clinical evidence), claim extraction, citation trails, and needs-citation publish gating, wired live to Sophia.
  4. Draft review — the existing approval/comment/QA machinery composed into one pipeline view, including Tara-specific linters.
  5. Agent orchestration — a Tara-scoped autonomy view: briefs launched from concepts, steering scoped by program, provenance back-linked to dossiers.
  6. Higher structures — programs, seasons, arcs, themes, and contexts as editable entities that scope steering and the content calendar.
  7. Publishing — a validated bridge from approved drafts to the apps/tara/content file tree.

Non-goals#

  • Not a V3 surface. The yoga-tenant governance logic in libs/v3/tara-studio (persona sponsorship, TTS voice consent, class scheduling) stays V3-owned; we port domain shapes (lineage grounding, invitational-language linting) into V1, we do not move the tenant.
  • Not a replacement for /operator/autonomy or admin governance panels. The workbench embeds Tara-scoped views; kill switches, gold sets, and champion/challenger stay in AgenticOperationsPanel.
  • Not a new consumer surface. apps/tara/web/mobile remain untouched except for consuming newly published content.
  • Not real-time multiplayer editing at launch. Autosave and three-way merge from @oshun/studio-authoring suffice; CRDT/presence remains the platform-level effort documented in features/authoring-workspace-and-roles.md.

3. Users and roles#

Roles reuse the creator-roles module of libs/oshun/studio-authoring (role matrix, contributor model) — no parallel RBAC. Workbench personas:

Persona Primary modules Authority
Editorial lead Programs, calendar, review approve/publish, steering edits, gates
Contemplative editor Concepts, grounding, drafts author/edit, resolve claims, request cites
Subject reviewer Grounding, review verdicts on tradition/neuroscience claims
Agent operator Agent console, budgets run cycles, veto, rollback (existing role)
Teacher (external) Assigned dossiers, table read comment, record, no publish

4. Placement and decision records#

DR-1 — UI home: apps/oshun/web under /studio/tara-workbench. Follows the proven interactive-workbench pattern of /studio/concordia-workbench (nested routes over a case spine). The V1 features doc positions Oshun Studio as "a first-class product surface rather than an afterthought buried in the admin shell" — the workbench is a creator surface, not admin governance. Admin keeps governance; operator keeps fleet ops.

Route spine:

text
/studio/tara-workbench                      — hub: pipeline overview, calendar, queues
/studio/tara-workbench/inbox                — spark capture inbox
/studio/tara-workbench/concepts            — concept board (kanban by maturity)
/studio/tara-workbench/concepts/[conceptId]         — dossier home
/studio/tara-workbench/concepts/[conceptId]/develop — outline/script editor
/studio/tara-workbench/concepts/[conceptId]/grounding — claims & citations
/studio/tara-workbench/concepts/[conceptId]/review    — approvals & comments
/studio/tara-workbench/concepts/[conceptId]/history   — versions & decisions
/studio/tara-workbench/sources              — source registry (traditions, papers)
/studio/tara-workbench/programs             — programs/seasons/themes
/studio/tara-workbench/programs/[programId] — program detail + steering overlay
/studio/tara-workbench/agents               — Tara-scoped autonomy view
/studio/tara-workbench/publishing           — manifest builder & export queue

DR-2 — Domain logic: new libs/oshun/tara-workbench. TypeScript, Vitest, pure functions with injected clocks, following @oshun/studio-authoring conventions (which it depends on for blocks, lifecycle, roles, templates). It also imports steering/brief types from @oshun/creative-autonomy. It does not live in libs/tara/*: that tree is the app-store-safe consumer vertical; authoring tooling is Oshun-side. Nothing in libs/tara may depend on the workbench.

DR-3 — Persistence: Zod contracts registered into libs/oshun/persistence (RESOLVED — see amendment A1 in the ratification note). Entities in §6 are defined as Zod contracts in libs/contracts/src/tara/ and registered as first-class objectContract rows in libs/oshun/persistence/src/contract-persistence-registry.ts; the Prisma schema is generated (never hand-edited) and the client is constructed via createV1PrismaClient (dev DB oshun_dev). The domain library itself stays pure; stores live at the BFF boundary, mirroring how @oshun/studio-authoring splits logic from durability.

DR-4 — Publish path: git stays the source of truth. The consumer app is offline-first and builds from the validated apps/tara/content tree; we do not introduce a parallel CMS database of record. The workbench emits a publish bundle: content files laid out exactly as the tree expects, validated against apps/tara/content/schemas/*.schema.json, with assets staged in MinIO. A repo tool (tools/tara-content/) imports a bundle into a git branch; merge remains a human/CI step at launch. The autonomy plane's ContentPublisher seam adopts the same bundle format so agent-produced and human-produced content publish identically. No silent writes to main.

DR-5 — Grounding is server-side and fail-loud. Claims and sources persist in the workbench DB; grounding checks call the Sophia BFF services (grounding-service.ts, answer-composer.ts citation contract: one claim per passage traced to one citation). The claim/source/severity/ needs-citation shapes are ported (adapted, attributed) from libs/v3/tara-studio/src/lineage-grounding.ts. If Sophia or the model provider is unconfigured, grounding checks return not_configured and the publish gate blocks — nothing fabricates support.

DR-6 — Categories and programs become data. A tara.* category registry backed by DB rows merged over the code defaults in V1_AUTONOMY_LAUNCH_CATEGORIES (code rows are the floor; DB may add or tighten, never loosen defaultAutonomy — same tighten-only rule as steering autonomyOverrides). Programs are workbench entities that carry a steering overlay (tenets, theme weights, banned topics additions) compiled into the brief at composeBrief time; the global CreativeDirection document remains the single durable steering root and overlays merge tighten-only.

5. Module designs#

M1 — Ideation studio (/inbox, part of /concepts)#

Frictionless capture: a zero-form spark inbox (title optional, body, source-link paste, tag) reachable from the hub and the command palette. Sparks are triaged to: archive, merge into an existing concept, or promote to a concept. Divergence support on any spark or concept: generate N structured variations via the plane's existing IdeaSynthesizer/ deriveCandidateIdeas (best-of-N with idea scoring on timeliness/novelty/audienceValue/strategicFit/feasibility), each rendered as a card with its score vector, never auto-committed. Selection uses the existing idea-score weights, plus a human pick that records a decision record (why chosen / why killed) on the concept. Fail-loud: no model provider ⇒ divergence buttons render disabled with a not_configured notice; manual capture always works.

M2 — Concept dossiers and the development ladder#

A concept is the workbench spine (analog of Concordia's case). Maturity ladder, enforced as a state machine (reusing editorial-lifecycle conventions from @oshun/studio-authoring):

text
spark → premise → outline → script-draft → grounded → in-review →
approved → recorded → published   (+ killed, parked at any stage)

The dossier home shows: premise (structured logline: audience, intent, practice form, duration target, experience level per the meditation schema), the maturity checklist for its stage, linked program/themes, grounding status, agent-run links, decision log, and version history (versioning module three-way merge for concurrent edits). The develop tab hosts the outline/script editor built on authoring-blocks + StudioAuthoringWorkspace patterns — structured blocks for guidance scripts: intro, settling, breath cue, body scan, silence interval (duration-typed), bell cue, closing — so scripts compile deterministically into timed segments (the shape TTS and human recording both consume). Live readability scoring reuses POST /v1/admin/studio/readability.

M3 — Knowledge grounding and cross-referencing#

Source registry (/sources): first-class sources with typed kinds — contemplative-tradition (lineage, canonical text, teacher attribution), philosophy, neuroscience-clinical (with evidence tier: meta-analysis, RCT, cohort/observational, theoretical), expert-opinion. Fields: authority score, rights/licensing note, locale, and stable IDs cited everywhere else. Bulk import path for citations Sophia already resolves.

Claims: any factual/attributional statement in a script or concept — "this practice derives from Theravāda ānāpānasati", "slow breathing activates parasympathetic response" — is extracted (manual selection at launch; Sophia-assisted extraction behind the same provider seam) into a claim with kind, severity (info/major/blocker), and a citation trail. Health/medical-adjacent claims default to blocker severity until sourced to a clinical-tier source. Contraindication and safety notes (trauma-sensitive language, seizure/breathwork cautions) are claim kinds with mandatory sourcing.

Gating: needs-citation claims at blocker severity block the grounded → in-review transition and the publish manifest. The gate is evidence-based (counts recomputed server-side), not a checkbox.

Cross-referencing: sources ↔ claims ↔ concepts ↔ published items form a queryable graph; a source page lists every concept citing it (blast radius when a source is retracted or re-scored).

M4 — Programs, themes, contexts#

Programs (/programs): named higher structures — seasonal arcs ("Rains Retreat 2026"), course spines, thematic series — with: theme set (weighted, feeding emphasizeThemes), context brief (free text included in agent briefs verbatim, like steering tenets), target cadence, linked category rows (tara.seasonal-ritual etc.), and calendar placement. Program steering overlays compile into briefs (DR-6). The category registry editor lives here (title, cost units, maxPerCycle, autonomy — tighten-only vs. code floor). Themes are shared vocabulary rows so ideation cards, concepts, and programs cross-filter by theme.

M5 — Draft review pipeline#

One review tab per concept composing existing, already-live machinery rather than rebuilding it: stage-gated approval workflows with quorum and required roles (/v1/admin/studio/approval-workflow + /evaluate), threaded comments (/v1/admin/studio/comment-threads), and the editorial lifecycle states from @oshun/studio-authoring. Tara-specific QA gates added as evaluators: invitational-language linter (ported from libs/v3/tara-studio/src/invitational-language-linter.ts to the V1 lib), grounding gate (M3), duration/segment coherence (script segment sum vs. durationSeconds metadata), transcript/caption presence, and audio QA placeholders that fail loud until the audio pipeline lands. Verdicts and gate evidence persist on the dossier.

M6 — Agent orchestration (Tara view)#

/agents embeds the autonomy plane scoped to tara.* categories via the existing /v1/agentic/autonomy API (no forked control plane): run/queue/ budget/gate/provenance tabs filtered to Tara, steering panel showing the composed direction (global + program overlay) that the next brief will receive, and brief-from-concept: promote a dossier (premise, themes, grounding constraints, banned topics) into a category brief so agents develop human-selected concepts, not just self-ideated ones. Every agent-produced draft back-links to its concept; approvals in the workbench drive the same queue actions (approve/reject/request-tweak/veto/rollback) as the operator console.

M7 — Publishing bridge#

/publishing renders the manifest builder: map an approved dossier to the target schema (meditation.schema.json fields incl. category, contentType, durationSeconds, experienceLevel, isPremium, audio/thumbnail/transcript/ captions paths, relatedMeditations, series), validate server-side against the JSON schemas, assemble the publish bundle (DR-4), and stage assets. TTS narration goes through the existing Tara TTS voice contract/consent surfaces (/studio/tara/tts-voice-contract, tts-voice-consent) — a bundle containing TTS audio without a valid voice-scope lock is refused. Export queue shows bundle → branch → merged state; "published" flips only on evidence (the item resolvable in the content tree / consumer API), not on export.

M8 — Calendar and planning#

The hub calendar extends the editorial calendar (ContentCalendarPanel / BFF editorial workspace) with workbench entities: program cadences, seasonal/ritual dates driving tara.seasonal-ritual scheduling, dossier due dates by maturity stage, and agent-cycle placements. Read-write (the current panel is read-only): scheduling a slot creates/updates the dossier target date and, for agent-assigned slots, seeds the cycle plan.

M9 — Catalog and curation#

A catalog view over the published tree (parsed server-side from apps/tara/content) for curation acts that today mean hand-editing JSON: collections membership, relatedMeditations linking, featured flags, series ordering — each producing a publish bundle (DR-4) rather than direct writes, so curation follows the same validated path as creation.

6. Data model (Prisma sketch)#

text
Spark        id, body, title?, tags[], sourceUrl?, capturedBy, status(triage)
Concept      id, slug, stage, premise{audience,intent,form,durationTarget,level},
             programId?, themeIds[], killedReason?, createdBy, timestamps
ConceptRevision  conceptId, version, blocksJson, authorId, mergeBaseVersion?
DecisionRecord   conceptId, kind(chosen|killed|pivot), rationale, actorId, at
Source       id, kind, title, tradition?/evidenceTier?, authorityScore,
             rightsNote?, locale?, externalRefs[]
Claim        id, conceptId, kind, text, severity, status(supported|needs-citation),
             sophiaNote?, revisionAnchor
CitationLink claimId, sourceId, locator?, addedBy, at
Program      id, name, contextBrief, cadence, themeWeights[], categoryIds[],
             steeringOverlayJson, calendarJson
Theme        id, label, description?
CategoryRow  categoryId, title, estimatedCostUnits, maxPerCycle,
             autonomyLevel(tighten-only vs code floor), active
AgentRunLink conceptId, runId, artifactId?, queueItemId?, direction(from|to)
ReviewGateResult  conceptId, gateId, verdict, evidenceJson, at
PublishBundle id, conceptId?, curationBatch?, manifestJson, validation{ok,errors},
             assetRefs[], state(draft|exported|branched|merged|verified), at

Review threads and approval-workflow state stay in their existing studio stores (referenced by id), not duplicated here.

7. API surface (BFF)#

New router apps/oshun/bff/src/routes/tara-workbench.ts under /v1/studio/tara-workbench/*, thin over the domain lib + stores, same auth/RBAC middleware as other studio routes:

text
POST/GET    /sparks                       capture, triage, list
POST        /sparks/:id/promote           spark → concept
GET/POST    /concepts /concepts/:id       dossier CRUD + stage transitions
POST        /concepts/:id/diverge         N variations (provider-gated)
POST        /concepts/:id/revisions       autosave/merge (studio-authoring)
GET/POST    /sources /sources/:id         registry CRUD, re-score
POST        /concepts/:id/claims          extract/add claims
POST        /claims/:id/citations         attach citation
POST        /concepts/:id/grounding/check Sophia grounding run (fail-loud)
GET/POST    /programs /programs/:id       programs + steering overlays
GET/PATCH   /categories                   tara.* registry (tighten-only)
POST        /concepts/:id/brief           brief-from-concept → autonomy plane
GET         /agents/overview              tara-scoped plane snapshot (proxy)
POST        /concepts/:id/gates/run       QA gate battery
POST        /publish/bundles              build+validate manifest
GET         /publish/bundles/:id          state incl. verified-in-tree
GET         /catalog                      parsed content tree
POST        /catalog/curation             curation batch → bundle

Every mutation is durable before acknowledgement (the autonomy plane's persist-hook discipline), audit-logged with actor id.

8. Fail-loud seams (Zero-Tolerance compliance)#

Seam Unconfigured behavior
LLM provider (diverge, claim-extract, script-assist) not_configured; UI disables the action with the reason; manual paths remain
Sophia grounding check returns not_configured; grounded-stage gate blocks
TTS pipeline recording tasks show unavailable; bundle refuses TTS audio without voice-scope lock
Content-tree access catalog/publish verify against the real tree or error; never assume merged
Autonomy plane agents tab renders plane-unavailable state; no fabricated snapshots

No Math.random() scores, no hardcoded verdicts, no optimistic "published" states. Gate results always carry recomputed evidence.

9. Testing and verification#

  • Domain lib: Vitest with known-value tests (e.g., a script whose segment durations sum to 612s against durationSeconds: 600 fails the coherence gate with a 12s delta; a blocker claim with zero citations blocks grounded; overlay merge proves tighten-only autonomy).
  • BFF routes: contract tests per route incl. not_configured paths.
  • Schema fidelity: round-trip tests — manifest builder output validates against the real apps/tara/content/schemas/*.schema.json, and a golden bundle imports cleanly via tools/tara-content.
  • UI: Playwright e2e per module (narrow scope while iterating), plus Claude-in-Chrome visual/functional verification before any TODO checkbox flips (repo standard).
  • End-to-end proof: one full journey — spark → concept → grounded → approved → bundle → branch → verified in tree — exercised against the dev stack before launch sign-off.

10. Threat & safety review (P0.5)#

  • Prompt injection via authored content. Spark bodies, source titles, claim text, and pasted references are untrusted input that flows into LLM prompts (divergence, claim extraction, script assist). All such material is fenced with @oshun/prompt-trust authority fields (amendment A2); model proposals pass admission checks (registered category, no banned topic) exactly as admitSynthesizedIdeas does in the plane — the model expands the idea space, never the evidence. Sophia notes rendered in the UI are display-only and never re-enter prompts unfenced.
  • Health-claim liability. Meditation content routinely brushes clinical territory (breathwork contraindications, trauma responses, seizure risk). Mitigation is structural: health/medical-adjacent claim kinds carry a blocker severity floor that cannot be lowered in the UI, require clinical-tier sources, and block both the grounded transition and the publish manifest until sourced (M3, P1.7, P5.8). No workbench surface renders an unsourced health claim as supported.
  • Teacher attribution & consent. Content attributed to a teacher requires their registry entry; TTS narration requires a valid voice-scope lock from the existing tts-voice-contract surfaces before a bundle is accepted (M7, P9.7). Agent-produced drafts carry AI attribution end-to-end (accepted assist blocks record attribution, P4.7).
  • Tradition rights & cultural respect. contemplative-tradition sources carry a rights/licensing note and attribution fields; the invitational-language linter and program tone presets encode trauma-sensitive, non-appropriative language checks as data-driven gates (P1.6, P6.6). Sacred/closed-practice material flagged at the source level surfaces as a review-gate warning, not silently published.
  • Authority boundaries. Steering overlays and the category registry are tighten-only by construction (DR-6); no workbench path can raise autonomy or lower a quality bar beyond the code floor. Every mutation is audit-logged with actor id (§7).

11. Rollout#

Phased per the TODOS: foundation (lib + schema + BFF) → ideation/dossiers → grounding → programs/steering → review gates → agent view → publishing → calendar/catalog → hub polish + IA registration → e2e + launch review. Each phase lands with its tests and Chrome verification; fixture panels in admin are either wired live or explicitly labeled V3-demo as part of the final phase (no silently misleading surfaces left behind).