---
status: reconciled-partial
coverage_depth: representative
last_reconciled: 2026-07-18
specs:
  - apps/oshun/bff/src/routes/domain-stubs-postgres.test.ts
source: WALKTHROUGH/results/external-dependencies/README.md
---

# Dependency result: Studio scene contract

- **Opened**: 2026-05-29 because Studio drafts had only path, session, kind, and
  flat state while scoring, voice mapping, policy review, and publication
  semantics were undecided.
- **Reconciled**: 2026-07-18 against the current Studio contract, persistence
  registry, generated Prisma model, migration, creation adapter, and live-DB
  test. This was a source reconciliation, not a fresh production walk.
- **Verdict**: **partial** — the original design dependency is closed in source:
  `StudioSceneSchema` encodes authoring score, per-persona voice mapping,
  policy-gated publication, and the linked Tara template decision. Creation now
  dual-writes a canonical draft, but no review/publish path populates the rich
  fields or proves the canonical table as read authority.
- **Primary spec**: `apps/oshun/bff/src/routes/domain-stubs-postgres.test.ts`.

## Result at a glance

| Evidence lane      | Current result                                                                 | Authority limit                                                          |
| ------------------ | ------------------------------------------------------------------------------ | ------------------------------------------------------------------------ |
| Contract design    | Score manifest, voice map, reviews, publication link, and lifecycle gates ship | Source policy; no editorial or persona-policy execution proof            |
| Persistence model  | Registry, Prisma model, migration, indexes, and tombstone fields ship          | Repository evidence, not a production rollout receipt                    |
| Creation write     | `studioScenes.add()` writes legacy authoring and canonical drafting rows       | Sequential queries; no atomicity or reconciliation mechanism             |
| Initial mapping    | Platform tenant `oshun`, authenticated author, kind/path/session are preserved | Score, voices, reviews, summary, and published template begin empty/null |
| Automated evidence | Live-DB test checks tenant, author, state mapping, kind, path, and session     | No Zod parse and no review/publication transitions                       |
| Read/publish path  | Owner listing still reads `goal3_stub_studio_scene`                            | No canonical review, policy-clear, publish, retire, or template readback |

## Evidence map

The canonical draft is real. The governance and publication lane is still a
contract-shaped promise rather than an exercised product path.

```mermaid
flowchart LR
    A[Create Studio scene] --> B[Legacy authoring row]
    B --> C[Canonical drafting row]
    C -. not connected .-> D[Authoring score and voices]
    D -. not connected .-> E[Policy review]
    E -. not connected .-> F[Published Tara template]
    C -. reads still legacy .-> G[Studio scene list]
    B -. no atomic rollback .-> H[Possible split write]
```

## Proven observations

### The previously open design choices are encoded

- `StudioSceneSchema` distinguishes drafting, review, policy-cleared, published,
  and retired states. It carries a manifest-backed score with voice, music, and
  silence ratios; a per-persona voice map; policy review entries; and a
  `publishedRitualTemplateId` link while keeping the authoring row live.
- Refinements require a score after drafting, an approved latest policy review
  at policy-clear, and both a template link and approved review at publication.
  They also constrain score ratios to approximately one.
- The contract accepts the platform `oshun` tenant while leaving room for future
  tenant sandboxes. The registry, generated model `v1_studio_studio_scene`, and
  migration `20260528024226_atelier_studio_metis_canonical_contracts` are
  present.

### Creation now writes a truthful draft projection

- `studioScenes.add()` writes legacy state `authoring` and canonical state
  `drafting`, preserves kind/path/session, fixes the canonical tenant to
  `oshun`, and uses the authenticated owner as author.
- Voice mapping and policy reviews start empty; score, summary, and published
  template start null. The adapter therefore does not manufacture review or
  publication evidence.
- The live-DB test creates one sit scene and reads its canonical peer, asserting
  tenant, contract id, state mapping, author, kind, path, and session index.

## Boundaries and gaps

- **A contract gate is not a publication gate.** No connected route runs the
  Lilith persona-policy adapter, appends an actor-bound review, or rejects a
  publish attempt that lacks current approval.
- **A template id field is not a publish operation.** This result does not copy
  a cured artifact into `v1_tara_ritual_template`, link both sides, or read the
  published result back.
- **A canonical row is not necessarily contract-valid.** The adapter-generated
  `studio-scene-…` id and author strings can violate UUID requirements, and the
  focused test never reconstructs and parses `StudioSceneSchema`.
- **A dual-write is not atomic.** The legacy and canonical inserts are separate
  statements with no transaction, outbox, or repair receipt.
- **A canonical write is not canonical read authority.** Studio listing remains
  on the legacy table, so later canonical lifecycle state would not
  automatically reach the current UI.
- **One platform tenant is not tenant-isolation proof.** The test verifies the
  `oshun` default; it does not exercise tenant authoring sandboxes or
  cross-tenant denial.

## Re-run evidence

Run the focused live-DB assertion with the repository Postgres test setup:

```bash
pnpm exec vitest run \
  apps/oshun/bff/src/routes/domain-stubs-postgres.test.ts \
  -t "studioScenes.add\(\) dual-writes"
```

A green result proves the initial canonical draft mapping. It must not be
reported as scoring, policy review, publication, tenant isolation, or canonical
read cutover.

## Source trail

- [External-dependency index](./README.md)
- [Studio contract](../../../libs/contracts/src/studio/index.ts)
- [Persistence registry](../../../libs/oshun/persistence/src/contract-persistence-registry.ts)
- [Generated Prisma schema](../../../libs/oshun/persistence/prisma/schema.prisma)
- [Canonical migration](../../../libs/oshun/persistence/prisma/migrations/20260528024226_atelier_studio_metis_canonical_contracts/migration.sql)
- [Postgres adapter](../../../apps/oshun/bff/src/routes/domain-stubs-postgres.ts)
- [Live-DB adapter test](../../../apps/oshun/bff/src/routes/domain-stubs-postgres.test.ts)

## Cross-references

- [Lilith Studio scene-publish journey](../../journeys/lilith-studio-tara-scene-publish.md)
- [Studio new-scene view](../../studio/01-scenes/new-scene.md)
- [Editorial review result](../editorial-review-approval.md)
- [Atelier scene contract result](./atelier-scene-contract.md)
- [External-dependency convention](./README.md)

## Open questions

- Which service owns score generation, voice selection, review receipts, and
  state transitions, and where does it enforce `StudioSceneSchema`?
- What transaction or saga creates the Tara template and links the Studio row
  without orphaning either artifact?
- How will current non-UUID scene and author identifiers migrate into
  contract-valid canonical objects?
- Will paired creation writes become transactional or outbox-backed, and how are
  historical split rows detected before read cutover?
- What browser and service tests prove reviewer permissions, stale-policy
  rejection, tenant isolation, publication readback, and retirement?
