Contract Authoring · Lesson 03 of 04

Effects, identities, services, and environments

Declare what a task writes, reads from the network, or depends on externally so Ota can reason about its safety and reproducibility.

LearnContract AuthoringIntermediate9 min read1.6.26+2026-08-24

Learning objectives

  • Add an effects block to a task
  • Declare an external service dependency
  • Explain why environment variables must be declared, not inferred

Prerequisites

Effects make material behavior reviewable. Requirements describe what execution needs; effects describe what it may change or contact. Environment declarations name required inputs without turning ota.yaml into a secret store.

Name writes, network, and external state

Use writes for durable repository paths, network with a network_kind for connectivity posture, adapter_state for provider-managed local state, and external_state for out-of-repository mutation such as database, hosted-service, or container-engine state.

Contract excerpt: service-backed integration task
tasks:  integration:    command:      exe: cargo      args: [nextest, run, --test, integration]    requires_services: [postgres]    requirements:      env: [DATABASE_URL]    effects:      network: true      network_kind: integration_test      external_state: [database]

Secrets remain externally supplied

The contract should declare required variable names and supported env sources, never secret values. Local shells and CI providers can supply values today. Ota scopes declared values to execution and redacts declared secrets from public evidence where supported; provider-backed remote secret injection remains a bounded adapter concern.

Canonical terminology

effectsnetworkservicesenvironment

Evidence boundary for this lesson

Establishes

  • The worked examples establish the lesson's canonical Ota distinctions for its stated scope.

Does not establish

  • Reading the lesson does not validate a repository, execute its tasks, or establish organizational acceptance.

Knowledge check

Why should ota.yaml declare a secret name but not its value?

The contract declares the requirement and scope. The local shell, CI provider, or supported adapter supplies the value so repository truth does not become secret storage.

Relevant specifications