# Coming from Terraform

> If you write Terraform, Pulumi, CloudFormation or Kubernetes manifests, you already think declaratively: describe the target, let an engine converge on it. Endoskeletal keeps that instinct and moves it up a level. You don't declare resources. You declare the organization that decides which resources exist, who may change them, what evidence they need, and what happens when that evidence runs out.

Canonical: https://endoskeletal.com/terraform/
Last updated: 2026-09-28

## The same need, twice

*main.tf*

```hcl
resource "aws_db_instance" "main" {
  engine                  = "postgres"
  instance_class          = "db.r6g.large"
  multi_az                = true
  backup_retention_period = 7
  storage_encrypted       = true
}

# Implicit: this vendor, this region, this size.
# Whoever holds credentials can apply a change.
# Why 7 days of backups? Who approved r6g?
# Is it still patched? The file doesn't say.
```

*meridian.esk (excerpt)*

```esk
requires capability Database {
  operation query(q : Entity) -> rows : Entity
  property  availability >= 99.95 % per month
  property  consistency  = "strong"
  property  rpo          <= 5 min
  property  rto          <= 60 min
  property  jurisdiction = "US"
  property  patched      = true
  property  cost         <= 14_000 USD per month
  for ApiAvailable, RecordsResident, NoUnpatchedProduction
}

norm OwnerBinds { power of Owner to bind | unbind _ about _   level collective }
```

The Terraform file fixes an implementation and leaves the reasons, the authority and the evidence outside. The Endoskeletal version fixes the reasons (each property traces with `for` to the intent or norm that needs it), states who may choose an implementation, and leaves the implementation open. Any provider offer whose evidenced properties meet the contract is a candidate; the one bound today is a fact in the log, not a line in the source.

## Concept map

|  | Terraform and friends | Endoskeletal |
| --- | --- | --- |
| You declare | Resources of named providers | Required capabilities with properties, plus who may bind them |
| Source of truth | State file: last applied attributes | Append-only log of every observation, decision and act; state is a projection |
| Plan / apply | Anyone with credentials; policy-as-code gates outside the model | `propose` (epistemic) → `decide` under a power → `bind` / `execute` authorized by that decision; each act checked for felicity |
| Drift | Diff between state and reality; fixed by re-apply | Evidence decays (`decays after 3 d`); provider statements start unknown; lifecycle claims (price change, deprecation, terms change) fire reconsideration |
| Unknown values | "Known after apply", only during planning | Status N or B on any claim, at any time, and every unknown needs an owner |
| Approvals | PR review, run tasks, a Slack thread | Norms: powers, quorums, cooling-off delays, deadlines, escalation, all recorded |
| Modules | Reusable HCL | Patterns that expand to kernel records, each carrying `expandedFrom` provenance |
| Lock file | Provider versions and checksums | `endoskel.lock`: packages pinned by content hash. Knowledge about providers ships separately, as claim bundles |
| Cost | Estimates bolted on | Cost is a property claim; budgets are prohibitions with freezes; a power's condition can require price × n ≤ limit |
| People, agents | Not modeled | Positions and parties. An LLM occupies a position and holds exactly the powers it grants |
| Reconciler | Converges to spec unconditionally | Rebinding is a decision under authority and can be refused by a non-tradeable norm even when it would converge |

## Where Terraform still fits

Below the specification is a boundary called *realization*. A realization binds an offered capability to a required one and carries its groundings: adapters, credential references, monitors, runbooks. A Terraform module is a perfectly good grounding. When the Operations controller scales Compute, the log records `authorize` under the `ScaleEnvelope` power, then `execute pv.Scale(n)` via the bound realization; the mechanism that runs might be `terraform apply`. Endoskeletal decides whether, when and on whose authority. Terraform does the doing.

> **Rule of thumb.**
>
> If it would appear in a design review, a policy document or an incident postmortem, it belongs in the specification. If it would appear in a provider's API reference, it belongs below the realization boundary.

## Three things IaC can't express

### "We don't know yet"

Meridian requires EU-resident inference. At founding no provider offered it. The frontier showed `InferenceEU` as UNSATISFIABLE from week 1; when a provider announced an EU offer (week 61) it became UNKNOWN because contract permissibility hadn't been established; a week later, with the terms reviewed, it was realized. Terraform has no state for "an offer exists but we don't yet know if we're allowed to use it this way".

### "You may, up to here"

An envelope is a power with a condition. The Operations controller may scale Compute to 40 units if price × units stays under 24,000 USD a month. Above that, its authorization misfires and a request routes to the OpsLead with a one-business-day deadline and escalation to the Owner. Terraform can only say "has credentials" or "doesn't".

### "Not even if it's cheaper"

Some rules can't be priced. `DataResidency` and `Privacy` are constitutional, `not tradeable` and `not defeasible`: no weighting can trade them off, no priority rule can suspend them, and a candidate realization that would breach one is inadmissible, however well it scores.
