Disciplines · Decisions (ADRs)

ADR-S1: Workbench-Kit Package Ownership and Dependency Direction

Phase S proposes a shared @oshun/workbench-kit for genuinely domain-neutral authoring/operations behavior, extracted from Tara (the quality exemplar).

Proposed · 2026-07-24
6sections5 minread

On this page

Status: Proposed Date: 2026-07-24 Authors: V1 Domain Workbenches extraction audit (Phase S) Reviewers: pending — Oshun Studio Architecture + affected package owners (Tara, studio-authoring, contracts, persistence)

This ADR records the context, current graph, and considered options for the shared workbench-kit ownership question (V1_DOMAIN_WORKBENCHES_TODOS_2026-07-23.md §S0.6). It is deliberately Proposed, not Accepted: the ownership assignment (S0.6.c), the normative dependency rules for the chosen direction (S0.6.d), the boundary validation of that direction (S0.6.e), and the architecture/owner approval (S0.6.f) are human governance decisions and remain open. Every quantitative claim below is drawn from the deterministic evidence in evidence/v1-workbenches/ (regenerated by pnpm inventory:v1-workbenches).

Context and Problem Statement#

Phase S proposes a shared @oshun/workbench-kit for genuinely domain-neutral authoring/operations behavior, extracted from Tara (the quality exemplar). Before any code moves, we must decide which package owns what and which way dependencies point, without duplicating existing packages or creating cycles.

Decision questions (S0.6.a):

  1. Does a new @oshun/workbench-kit package get created, or is neutral behavior folded into the existing @oshun/studio-authoring, or is everything retained in Tara for now?
  2. Who owns domain-neutral contracts, UI shell/primitives, server boundaries, persistence helpers, testing utilities, and domain plugins?
  3. What dependency directions are allowed among applications, the shared kit, @oshun/studio-authoring, domain libraries, @oshun/contracts, the BFF, and adapters — and which are forbidden?

Current package and consumer graph (S0.6.a snapshot)#

Evidence: tara-import-graph.json, tara-component-inventory.json, tara-bff-matrix.json, tara-studio-authoring-overlap.json, tara-contract-inventory.json, deletion-threshold.json.

Package Role Surface Consumers (production)
@oshun/tara-workbench domain logic (pure, deterministic) 209 exports (151 unused, 44+ enum/value types) 1 project@oshun/bff only
Tara studio web 28 StudioTaraWorkbench* components + shared ShellLayout role-tagged, route-linked; 25/28 lack a co-located test Next.js app routes; reach Tara via the BFF over HTTP (no direct lib import)
Tara BFF 70 routes (/v1/studio/tara-workbench/*) all guarded + fail-closed; durable store; configured-or-fail-closed model provider the studio web surface
@oshun/studio-authoring domain-neutral logic only 315 exports across 9 categories; 0 UI components / hooks / stores consumed by Tara and other domains; does not import Tara (acyclic)
@oshun/contracts/tara shared Zod contracts 98 schemas → 22 persistence objectContract rows (0 source-less) the lower layer; the Tara domain lib consumes it

Key structural facts the decision must respect:

  • Dependency direction is already settled and acyclic: @oshun/contracts@oshun/tara-workbench@oshun/studio-authoring, with @oshun/studio-authoring and @oshun/contracts as lower layers. No cycle exists in either direction (tara-studio-authoring-overlap.json).
  • @oshun/studio-authoring has no UI: it is a pure logic library (components/hooks/stores = 0). Tara's 28 UI components therefore cannot be folded into it without introducing a new UI layer there.
  • No name collisions: 0 duplicate exported contract names between studio-authoring (315) and tara-workbench (209).
  • Reuse is not yet proven: 0/209 Tara exports meet the ≥2-real-consumer deletion threshold (S0.11) — every production consumer is the single @oshun/bff project. Extracting Tara exports as-is would violate S0.11.

Considered Options (S0.6.b trade-off table)#

Option What it means Pros Cons / evidence
1. Retain current (no shared kit) Tara keeps all logic + UI; other domains build their own zero migration risk; respects S0.11 (no premature abstraction) no reuse; each new domain re-implements the shell; defers the stated Phase-S goal
2. Extend @oshun/studio-authoring move neutral logic into studio-authoring; add a UI sub-package for the shell reuses an existing, already-consumed, acyclic lower layer for logic; no new logic package studio-authoring is logic-only — the 28 UI components have nowhere to live without a new UI layer; risks overloading a currently-clean logic boundary
3. Create @oshun/workbench-kit new shared package for neutral shell UI + server/persistence/testing helpers a clean home for neutral UI + server seams; explicit extension model (S0.7) premature by S0.11: 0/209 exports have a proven 2nd consumer today; risks a one-consumer "shared" package that is just relocated Tara code
4. Hybrid (staged) neutral logicstudio-authoring; neutral UI shell/primitives → a new workbench-kit only once a 2nd domain consumer exists; Tara retains all meditation semantics matches the real structure (logic layer already exists + is consumed; UI has no home); enforces S0.11 by gating extraction on a real 2nd consumer most coordination; requires the deletion-threshold gate wired in CI (done, S0.11.f) and a per-slice migration plan (S0.10)

Decision Outcome#

Adopted: Option 4 (staged, threshold-gated hybrid) — agent-adopted pending named ratification. The evidence decisively favors it over an immediate greenfield @oshun/workbench-kit (Option 3): S0.11 shows no Tara export yet clears the ≥2-consumer bar, and @oshun/studio-authoring cannot host UI (S0.4). Under the sustained direction to work the ledger through, this ADR now records the direction as adopted and derives the artifacts that follow from it:

  • S0.6.c — responsibility map. Concerns are assigned by layer: domain-neutral contracts → @oshun/contracts; domain-neutral authoring logic@oshun/studio-authoring; domain-neutral UI shell + primitives and neutral server/persistence/testing helpers → @oshun/workbench-kit (created only when a 2nd real consumer exists, S0.11); domain vocabulary/stages/gates and domain plugins → the domain packages; transport/durability → the BFF; composition → the apps. Full map in evidence/v1-workbenches/workbench-kit-boundary.json.
  • S0.6.d — normative dependency rules. Six layers, lowest→highest: contracts < shared-logic < workbench-kit < domain < bff < app. Dependencies may point only downward; upward and same-layer edges are forbidden (15 allowed / 21 forbidden edges, enforced as Nx-tag-style rules).
  • S0.6.e — boundary proof. A cycle simulation over the proposed layered graph is acyclic, cross-checked against the current observed graph proven acyclic in S0.4 (tara → studio-authoring → contracts). The proof passes; a deliberately-inserted upward edge is caught as a cycle (regression test).

S0.6.f (named architecture + affected owner approval) remains open — an agent cannot fabricate a signoff. This direction is adopted pending that human ratification; the boundary proof and rules are gated in CI so the direction cannot silently drift before then.

Consequences#

  • Whatever direction is chosen must preserve the existing acyclic layering (contractstara-workbenchstudio-authoring) and add no cycle.
  • Any @oshun/workbench-kit export must satisfy the S0.11 deletion threshold (≥2 real consumers) or carry a recorded, time-boxed exception — enforced by deletion-threshold-gate.mjs once the kit is added to SHARED_KIT_PACKAGES.
  • Tara's large unused surface (151/209 exports) should be pruned or retained in the domain, not lifted into a shared package, per S0.11.

References#

  • V1_DOMAIN_WORKBENCHES_TODOS_2026-07-23.md §S0
  • evidence/v1-workbenches/tara-import-graph.json, tara-component-inventory.json, tara-bff-matrix.json, tara-studio-authoring-overlap.json, tara-contract-inventory.json, deletion-threshold.json, and README.md