> ## Documentation Index
> Fetch the complete documentation index at: https://sponson.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# ADR 0012: One flat plan with per-line environment filters; production is never inferred

> Architecture decision record 0012. Status: Accepted

Date: 2026-10-10

## Status

Accepted

## Context

A release touches several environments: preview resources per pull request, and production. The first design had a
top-level `environment:` key, one plan per environment. The candidates for describing several environments in one
file were:

| Option | Problem |
| - | - |
| a section per environment, shared lines through YAML anchors | anchors are hard to read and agents get them wrong |
| one file per environment | "one release, one plan" no longer holds |
| one flat list, each line optionally filtered by `environments:` | the same variable from two sources is two lines |
| one flat list with `when:` expressions | an expression language for a problem a list solves |

## Decision

A plan is one flat list of lines. A line with `environments: [...]` applies only in those environments; a line
without it applies in all. The environment is chosen when running: `--env <name>`, default `preview`. It is never
inferred from the branch name, so no path leads to production by accident.

A run requires a named approver (`--approved-by` or `SPONSON_APPROVED_BY`; blank is no name) whenever it can write
to production: when `--env production`, or when any active line writes to production whatever the run's environment.
Ops declare the latter through `writesEnvironment()` (for `vercel.env`, its `target`). Without an approver, `apply`
fails with `ENV_NOT_APPROVED` before any provider is called, and the receipt records `approvedBy`.

## Consequences

* One file describes the whole release and reads top to bottom without anchors or expressions.
* A reference from a line to a line that the filter removed is an error (`REF_FILTERED`) with a message saying which
  filter to change.
* Writing the same key for two environments takes two lines; that repetition is accepted.
* The approval rule lives in the open-source engine, so "an agent cannot approve itself" holds without any service.
  Who may pass `--approved-by` is left to the workflow (for example a GitHub environment with required reviewers).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.