Oshun Platform · Features

The Tara Content Workbench

A focused page within the Oshun Platform Features documentation. The full map and every sibling page live in the Features hub.

4sections5 minread

On this page

Tara is Oshun V1's meditation-content domain — the guided sits, courses, and collections a customer browses under /domains/tara. The Tara Content Workbench is the studio surface where that content is made: a structured creation-and-curation pipeline that carries an idea from a one-line spark, through premise, outline, and script, past a battery of safety and grounding gates, into a human approval ladder, and finally across a validated publishing bridge into the real apps/tara/content tree. It is the Tara-specific companion to the general Creator Roles and the Authoring Workspace; where that page describes the shared studio-authoring foundation, this one describes the domain pipeline built on top of it. The hub for the feature set is ../features.md.

What ships, honestly#

The substance is real, non-stub, domain-specific code in one library: libs/oshun/tara-workbench (package @oshun/tara-workbench), a pure-ESM source library backed by a known-value test suite (every gate, the overlay compiler, the state machine, and the manifest builder are tested against specific known-correct values, not shape assertions). Its modules are the pipeline:

text
state-machine       gates              grounding            invitational-language
steering-overlay    manifest           bundle               program-schedule
seasonal-registry   review-ladder      script-blocks        decision-records
gate-registry       category-registry  provider

The stage ladder is a real state machine. state-machine.ts models the nine maturity stages — spark → premise → outline → script-draft → grounded → in-review → approved → recorded → published — and every transition is guarded by recomputed evidence, never a stored flag. A concept cannot enter grounded while a blocker claim needs a citation, nor while the grounding gate last ran against a stale revision; it cannot enter in-review without all three of the language, duration, and grounding gates passing (an unavailable gate is treated as not passing); and it flips to published only on a bundle in the verified state, a transcript gate, and produced audio. Illegal transitions throw with the exact blockers named.

The gate battery is five real evaluators, one of them an honest seam. gates.ts, invitational-language.ts, and grounding.ts implement:

  • invitational-language — a directive-language linter ported from the V3 work: it flags coercive phrasing (must, empty your mind, you will feel) as blocking and softer cues (close your eyes) as warnings, whole-word only, and offers trauma-sensitive alternatives.
  • duration-coherence — compiles the script's timed segments and compares the total against the premise's duration target within a tolerance that is the larger of a 1.5% ratio and a 10-second floor.
  • grounding — applies a severity floor per claim kind (health-benefit and contraindication claims are always blockers; tradition attributions are major), distinguishes clinical-grade sources, and fails a publish while any blocker claim is unsourced.
  • transcript-captions — passes only when both accessibility assets exist and are non-empty.
  • audio-qa — an honest fail-loud seam: with no audio-analysis backend bound it reports unavailable with its reason, never a fabricated pass.

Program steering is tighten-only, by construction. steering-overlay.ts composes a program's overlay onto the global creative direction: tenets and banned topics union, quality bars raise only, and an overlay that requests more autonomy than the category floor throws AutonomyLooseningError rather than loosening the guardrail. The property holds across every pair of autonomy levels.

The publishing bridge is schema-mapped and content-addressed. manifest.ts builds a meditation/course/collection manifest whose output is validated against the real checked-in apps/tara/content/schemas/*.schema.json — builder-vs-tree drift fails the suite — and bundle.ts assembles the manifest plus its referenced assets into a content-addressed bundle (each asset carried with a real sha256), refusing missing, orphan, duplicate, empty, or path-traversing assets. The importer (tools/tara-content, @oshun/tara-content) re-validates the bundle and writes it into a git branch under apps/tara/content; a golden round-trip test proves builder → importer → schema-valid tree end to end, byte-faithfully.

The BFF exposes it fail-closed. apps/oshun/bff/src/routes/tara-workbench.ts mounts the pipeline under /v1/studio/tara-workbench/* — sparks, concepts, dossiers, sources, claims, programs, the Tara-scoped agents view, the publishing bundles, the published catalog, the editorial calendar, and a hub overview aggregate. Access is gated by studio scope resolved into the §3 creator-role permission matrix, and every integration that is not configured in a given deployment refuses with 503 not_configured naming its seam — the durable store, the model provider (script assist, divergence, claim extraction), the TTS voice-contract lock, the asset store, and the content tree — rather than serving fabricated data.

The web surface is the workbench itself. Under apps/oshun/web/src/app/studio/tara-workbench/ ship the hub (a live pipeline snapshot, queues, and a 30-day editorial calendar), the ideation inbox (keyboard-first triage), the concept board and dossier, the draft-review approval ladder, the grounding-source registry, programs and steering, the Tara-scoped autonomy console, the publishing bridge UI, the published catalog with curation editors, and the editorial calendar. Every panel drives its affordances from the server's resolved capabilities and renders an honest message on each failure state rather than an empty-but-cheerful dashboard.

What is a seam, not a gap#

Three things are honest fail-loud seams rather than missing work, and the UI says so: audio-qa reports unavailable without an analysis backend; the model-provider routes (script/assist, diverge, claims/extract) return 503 not_configured without an LLM key bound; and the TTS-narration publish path refuses fail-closed without a valid voice-scope lock. These represent real-but-absent integrations, not stubbed successes.

Cross-references and tests#

The domain library's known-value suite and the BFF contract suite (every not_configured seam and both tighten-only rejections) back the claims above, and the golden round-trip test in tools/tara-content guards the publishing bridge. The build ledger and per-phase provenance live in TARA_CONTENT_WORKBENCH_TODOS_2026-07-19.md, with the design decisions in V1/TARA_CONTENT_WORKBENCH_DESIGN_2026-07-19.md.