ota Workspace Reference
June 27, 2026 · View on GitHub
This document describes the current ota.workspace.yaml contract accepted by the shipped workspace validator.
For machine-readable workspace contract publication, use
json-schemas/workspace-contract.json locally or
https://dist.ota.run/spec/json-schemas/latest/workspace-contract.json in CI, editors, and
other tooling.
Purpose
ota.workspace.yaml is the canonical workspace bootstrap contract.
It is separate from ota.yaml, which remains the canonical repo readiness contract.
Minimal contract
version: 1
workspace:
name: ota-dev
git_base: https://github.com/ota
repos:
web:
path: apps/web
source:
repo: web
Top-level fields
version: required, currently only1workspace: required workspace metadatarepos: required map of repo entriespolicies: optional workspace-local policy overlays and additive governance data
workspace
workspace:
name: ota-dev
description: Local multi-repo development workspace
policy: .ota/org-policy.yaml
Fields:
name: required, non-empty stringdescription: optional stringgit_base: optional clone base used byrepos.<name>.source.repopolicy: optional policy pack path or HTTP(S) URL resolved from the workspace root
repos
repos:
web:
path: apps/web
tasks:
prepare-dev:
task: build-sdk
source:
repo: web
api:
path: services/api
contract: services/api/ota.yaml
required: true
depends_on:
- web
source:
git: https://github.com/ota/api.git
ref: main
Fields:
path: required path to a repo directory, relative toota.workspace.yamlcontract: optional explicit repo contract path, relative toota.workspace.yamlworkflow: optional repo workflow selection used by workspace execution pathstasks: optional workspace-owned task bindings that map one shared workspace task name to a repo-local task namerequired: optional booleandepends_on: optional list of workspace repo namessource: optional acquisition source for repos that are not present yet
tasks fields:
tasks.<workspace_task>.task: required repo-local task nameota workspace run <workspace_task>should execute for this repo
source fields:
git: explicit clone URL or git-accepted clone sourcerepo: repo path or slug resolved againstworkspace.git_baseref: optional branch, tag, or ref to checkout after clone
Design intent:
repos.<name>.taskslets one workspace verb span repos that do not share the same local task name- this keeps cross-repo execution truth in the workspace contract instead of hiding it in shell wrappers or repo-specific readme steps
- ota still falls back to the literal task name when no workspace binding is declared for that repo
source.gitis the canonical acquisition fieldsource.repois shorthand for multiple repos sharing the sameworkspace.git_base- both are generic git concepts and work for GitHub, GitLab, Bitbucket, and internal git hosts
Current validation behavior:
- repo names must not be empty
- workspace must declare at least one repo
- repo
pathmust be non-empty - repo
pathmust exist and point to a directory unlesssourceis declared contractmust be non-empty when presenttasksbinding names must not be emptytasks.<workspace_task>.taskmust not be empty- if
contractis omitted, ota expects<repo path>/ota.yaml sourcemust declare exactly one ofgitorreposource.reporequiresworkspace.git_basedepends_onreferences must resolve to known workspace repos- workspace repo dependency cycles are rejected
- each present repo contract must load and pass repo-level validation
- when the repo is already present and its contract validates, each
tasksbinding target must resolve to a non-internal repo task - when the repo is already present and its contract validates, a workspace task binding must not
shadow a visible repo task of the same name with a different target task, because
ota workspace run <task>would become ambiguous
Current scope
The shipped workspace surface is intentionally narrow:
- workspace contract parsing
- workspace contract validation
- repo contract validation through the workspace contract
- workspace-level diagnosis as orchestration over repo-level
doctor - workspace-level prepare flow as orchestration over repo-level
up - acquisition of missing repos before workspace prepare
Current non-goals:
- workspace task orchestration beyond one shared workspace task name mapped repo-by-repo
- workspace-wide environment mutation
- hidden repo bootstrap behavior
- passing a repo URL directly on the CLI without a workspace contract
- GitHub API integration or non-git acquisition modes
ota workspace doctor
Current workspace diagnosis behavior:
- validates workspace structure first
- evaluates repos in dependency order
- can diagnose independent repos concurrently when
--jobsis greater than1 - preserves deterministic repo ordering in the final report
- diagnoses each referenced repo through its own
ota.yaml - reports missing-but-acquirable repos as not yet acquired instead of treating them as unreadable local paths
- preserves repo-level diagnosis semantics for required repos
- downgrades optional repo errors to warnings at the workspace layer
- rejects required repos that depend on optional repos
ota workspace doctor --jsonandota workspace check --jsonboth publish workspace roll-upverdict/agent_verdict, additive workspacesummary.primary_blocker, and per-repoprimary_blocker; additive blockercodeonly appears when the blocker came from explicit stable finding identity
This keeps workspace behavior as orchestration over repo readiness, not a parallel readiness system.
ota workspace tasks and ota workspace run
Current workspace task behavior:
ota workspace taskslists visible repo tasks in dependency order- it also lists workspace-owned task bindings when
repos.<name>.tasksmaps a shared workspace task name to a different local repo task ota workspace run <task>executes the same literal repo task name by default- when
repos.<name>.tasks.<task>.taskis declared,ota workspace run <task>resolves that repo-local task instead for that repo - workspace run receipts and JSON output keep the requested workspace task visible and also expose the resolved repo task when the binding differs
ota workspace up
Current workspace prepare behavior:
- validates workspace structure first
- acquires missing repos declared with
sourcebefore repo-level bootstrap - runs repo-level
upfor each referenced repo - can prepare independent repos concurrently when
--jobsis greater than1 - respects declared workspace repo dependency order
- blocks downstream repos when a dependency does not become ready
- aggregates repo-level status, phase, findings, and exit details
- captures repo child stdout and stderr per repo so the final report remains deterministic
- emits live repo progress on stderr in text mode so users can see execution moving without losing ordered final output
- optional repo failures do not fail the overall workspace status
--streamopts into raw live child process output instead of buffered per-repo output
Current execution policy:
- workspace repo execution defaults to sequential because
--jobsdefaults to1 - ota only parallelizes repos whose dependencies are already satisfied
- final reporting remains in deterministic repo order even when execution is concurrent
- required repos must not depend on optional repos, because required readiness cannot rest on optional guarantees
--streamis currently text-only and requires--jobs 1so raw child logs do not interleave
Current non-goals:
- cross-repo dependency scheduling
- passing a repo URL directly on the CLI without a workspace contract
- host or workstation provisioning
- a workspace-only bootstrap engine that bypasses repo contracts
- implicit pull, fetch, or update behavior for repos that already exist locally
- GitHub API integration or non-git acquisition modes
ota workspace refresh
Current workspace refresh behavior:
- validates workspace structure first
- refreshes repos that already exist locally and have a declared source
- leaves missing repos alone so
ota workspace upremains the bootstrap path - can refresh independent repos concurrently when
--jobsis greater than1 - respects declared workspace repo dependency order
- blocks downstream repos when a dependency does not become ready
- aggregates repo-level status, phase, findings, and exit details
- captures repo child stdout and stderr per repo so the final report remains deterministic
- emits live repo progress on stderr in text mode so users can see execution moving without losing ordered final output
- optional repo failures do not fail the overall workspace status
--streamopts into raw live child process output instead of buffered per-repo output--dry-runpreviews the refresh commands without changing repo state--forceforce-fetches and hard-resets refreshed repos to the declared source or--refoverride--pruneprunes stale remote-tracking refs during refresh--ref <branch|tag|sha>overrides the source ref used for refresh
Current execution policy:
- workspace repo execution defaults to sequential because
--jobsdefaults to1 - ota only parallelizes repos whose dependencies are already satisfied
- final reporting remains in deterministic repo order even when execution is concurrent
- required repos must not depend on optional repos, because required readiness cannot rest on optional guarantees
--streamis currently text-only and requires--jobs 1so raw child logs do not interleave
Current non-goals:
- cloning missing repos
ota workspace diff
Current workspace diff behavior:
- validates workspace structure first
- reads the current local git state for each acquired repo without mutating anything
- compares each repo against its declared source ref when present, or upstream branch when the source ref is not pinned
- reports
MATCHwhen the repo is clean and aligned,DIRTYwhen the worktree has local changes,DIFFERENTwhen commit counts differ,MISSINGwhen the repo is absent, andUNRESOLVEDwhen git state cannot be compared safely - can compare independent repos concurrently when
--jobsis greater than1 - never clones, fetches, resets, or writes repo state
- differences are surfaced in the report but do not fail the command
Current non-goals:
- refreshing or mutating repo state
- cloning missing repos automatically
- cross-repo dependency scheduling
- passing a repo URL directly on the CLI without a workspace contract
- host or workstation provisioning
- a workspace-only bootstrap engine that bypasses repo contracts
- implicit pull, fetch, or update behavior for repos that already exist locally
- GitHub API integration or non-git acquisition modes
ota workspace status
Current workspace status behavior:
- validates workspace structure first
- reads readiness and local git drift for each workspace repo without mutating anything
- reports readiness and drift together in one operational summary
- can compare independent repos concurrently when
--jobsis greater than1 - never clones, fetches, resets, or writes repo state
- readiness findings and drift findings are surfaced in the same report
--jsonreports the combined roll-up withmode: "status"
Current execution policy:
- workspace repo execution defaults to sequential because
--jobsdefaults to1 - ota only parallelizes repos whose dependencies are already satisfied
- final reporting remains in deterministic repo order even when execution is concurrent
- required repos must not depend on optional repos, because required readiness cannot rest on optional guarantees
Current non-goals:
- mutating repo state
- cloning missing repos automatically
- cross-repo dependency scheduling
- passing a repo URL directly on the CLI without a workspace contract
- host or workstation provisioning
- a workspace-only bootstrap engine that bypasses repo contracts
- GitHub API integration or non-git acquisition modes
ota workspace receipt
Read-only workspace receipts capture the current workspace state as an execution artifact.
Current behavior:
- validates workspace structure first
- reads readiness and local git drift for each workspace repo without mutating anything
- records the combined workspace state as a receipt with one step per repo
- can compare independent repos concurrently when
--jobsis greater than1 - never clones, fetches, resets, or writes repo state
--jsonreports the receipt roll-up withmode: "receipt"- the receipt records the same readiness, drift, and findings scan so CI or agents can archive it deterministically
Current non-goals:
- mutating repo state
- cloning missing repos automatically
- cross-repo dependency scheduling
- passing a repo URL directly on the CLI without a workspace contract
- host or workstation provisioning
- a workspace-only bootstrap engine that bypasses repo contracts
- GitHub API integration or non-git acquisition modes