Reference

Writes and Caching

Where ota may write, where it must stay read-only, and how caches stay safe.

referenceautomation buildersintermediatestable2026-05-30

When to use this page

Use this page when you need to know what ota may change on disk and what it must leave alone.

Mutations must stay explicit, and cache state should never outrank filesystem truth, so read-only review stays trustworthy.

  • map each command to whether it reads or writes before you rely on its output
  • use review-first commands and move to explicit write modes only after checking the preview
  • repo contract changes use source-bound candidates and explicit candidate application; they do not use merge or rewrite shortcuts
  • workspace merge applies eligible additive changes, while workspace rewrite is destructive and requires explicit confirmation
  • policy-aware diagnosis stays read-only
  • hidden mutation paths are not allowed

How writes work

ota should only write when the command explicitly says it can.

If the command is read-only, it should stay read-only even when it has enough information to suggest a change.

  • repo detect and workspace detect are review-by-default; repo mutation flows through reviewed candidates, while workspace mutation retains its separate write/merge/rewrite model
  • ota detect --candidate-out .ota/candidates/detect.json publishes a canonical create-new source-bound review artifact from one immutable source snapshot without modifying ota.yaml; it retains every selected evidence tuple, binds subjects as structured path segments, reconciles indexed fields and schema-default command posture, omits semantically equivalent existing truth, marks real disagreements as conflicts, and requires an inventory content identity for every source. Linux and macOS publication combines atomic no-replace rename with a retained no-follow directory handle; other platforms refuse rather than weakening alias or create-new protection. JSON reports artifact publication through candidate_published and candidate_publication, separately from the always-false contract written field. It is not an application or agent-safety authority
  • ota contract apply-candidate .ota/candidates/detect.json re-derives one reviewed candidate against current source and contract truth. Default --write only creates a previously absent ota.yaml through the shared evaluator's validated contract. To update a tracked existing contract, use the explicit --write --carrier git: Ota requires a non-detached checkout where ota.yaml matches HEAD in both index and worktree, scrubs caller Git routing state, disables configured Git helpers, commits only ota.yaml with expected-HEAD compare-and-swap, verifies the worktree, and reports the branch and commit identities. It never pushes, rebases, amends, or changes unrelated paths. Candidate identity and kind are validated first, so review-only kinds return their stable refusal before writer admission; writable candidates on unsupported platforms return candidate_write_unsupported_platform before repository locking, Git invocation, or mutation. A matching second application is a semantic no-op.
  • ota contract upgrade --candidate-out .ota/candidates/upgrade.json publishes a schema-v2 lossless migration review artifact without changing ota.yaml. The first registered migration converts legacy flat toolchain fulfillment into the structured fulfillment.mode spelling and binds source bytes, implementation, unchanged semantics, resulting content, and replacement operations. JSON reports durable, not_published, or durability_uncertain candidate publication independently from contract mutation. After review, ota contract apply-candidate ... --write --carrier git can commit the exact upgrade; ordinary --write remains create-new-only.
  • ota contract effect-refusal-candidate --archive ARCHIVE --canary-id ID --candidate-out PATH turns one verified private workflow explicit typed denial into an archive-bound, unknown canary proposal. It freezes and rechecks one regular no-follow contract snapshot, re-derives current workflow, effect, attachment, migration-plan, and realization truth, and creates no application projection. apply-candidate returns platform-stable candidate_read_only before writer admission. Published and exact-existing no-op results both expose one versioned reconciliation identity and its archive/contract/effect/attachment/realization inputs. It cannot infer a new effect definition, policy, grant, provider authority, or execution approval.
  • ota detect --write is a temporary create-new-only alias that derives the versioned conservative first-contract profile and publishes through the same evaluator as apply-candidate; successful JSON exposes write_candidate.identity, schema_version, and profile for that exact applied candidate
  • source-bound candidates keep exact CI verifier lanes separate when job identity distinguishes them. Repository-relative GitHub Actions working directories become structured command cwd truth; dynamic or noncanonical directories are not promoted. Named multiline verification steps retain their full ordered body as unresolved review input rather than selecting one line. CI closure evidence can retain observed runner platform, Cargo toolchain, service, and environment requirement names. CI remains non-authoritative review evidence: those observations do not enter the contract projection or make a task agent-safe
  • detected task names, wrappers, opaque shell scripts, and CI snippets do not authorize agent-safe execution. V11.22 emits no inferred agent-safe proposal; review and declare safe_for_agent in the contract until the planned typed effect/realization evaluator can prove a future affirmative rule
  • repo-level --merge, --apply, --apply-all, --rewrite, and --yes are removed parser tombstones; they fail with detect_legacy_mutation_removed before repository access
  • ota workspace detect follows the same pattern with --write, --merge, and --rewrite
  • init commands are explicit scaffold paths and may only write when you choose that mode

Writable commands

  • ota detect --write
  • ota contract apply-candidate CANDIDATE --write (missing contract only)
  • ota contract apply-candidate CANDIDATE --write --carrier git
  • ota detect --candidate-out PATH (candidate artifact only; it does not write a contract)
  • ota contract upgrade --candidate-out PATH (upgrade candidate artifact only; it does not write a contract)
  • ota workspace detect --write
  • ota workspace detect --merge
  • ota workspace detect --rewrite --yes
  • ota init
  • ota workspace init

Read-only commands

  • default ota detect/ota workspace detect behavior is read-only unless a write mode is selected
  • ota contract apply-candidate CANDIDATE re-derives a candidate for review; default --write creates only a previously absent contract, while --write --carrier git is the explicit existing-contract update path
  • ota contract upgrade --candidate-out PATH is read-only; its reviewed candidate can be applied only with the explicit Git carrier
  • ota detect --contract is text-only and does not write
  • doctor and policy review do not mutate contracts
  • check does not mutate contracts
  • workspace doctor and workspace check stay read-only
  • policy-aware diagnosis stays read-only

How caching works

Caching is only an implementation detail for repeated reads.

It exists to avoid re-parsing and re-scanning when nothing meaningful changed.

  • repo cache entries are keyed by normalized file path and content hash
  • workspace cache entries use the same path+hash strategy for ota.workspace.yaml
  • changed file contents invalidate cache keys on next read
  • cache is for performance only and does not alter command semantics
  • if the filesystem changes, ota must trust the filesystem over any cached copy

How to use it

  • use review-only commands when you want to inspect first
  • for repo contracts, publish a candidate with ota detect --candidate-out PATH, review it, then use ota contract apply-candidate PATH --write for a missing contract or add --carrier git for an existing tracked contract
  • for workspace contracts only, use ota workspace detect --merge --dry-run before additive writes or ota workspace detect --rewrite --dry-run before destructive replacement
  • use doctor when you want to inspect readiness without writing
  • use detect --dry-run when you want a safe preview of what would change
  • use the Agent boundary section in detect/init preview to understand whether ota has contract-owned or affirmatively classified safe-task truth, a partial boundary, or intentionally omitted agent because no approved safe task was established
  • treat external structured AGENTS.md / CLAUDE.md content as boundary corroboration only: it cannot create runnable task truth or agent-safe authorization; ota-generated agent docs and broader prose stay out of detect evidence
  • do not use removed repo-level merge or rewrite flags; they refuse with detect_legacy_mutation_removed

Why it matters

  • preview a contract change before writing it
  • keep detect --dry-run review-only
  • know that init writes only when asked
  • avoid stale contract state
  • trust that a cached parse never wins over the current file on disk

What this is not

  • not a background sync engine
  • not a persistent hidden state machine
  • not a general-purpose cache policy surface
  • not a replacement for the contract or filesystem truth
  • not a place where stale state can outrank what is on disk