Plan and reconcile

How desired Git state and the managed EVE lab are brought together. The conceptual model is on Architecture. This page is the operation: what each call writes, how a plan is classified, and how to_eve applies it.

YAML (topology.yml, configs/, selectors) is complete desired state. The agent does not take a second policy from EVE, the VSIX, or MCP.

Picture

     desired (Git)                         runtime (EVE)
  topology.yml, configs/                managed lab objects
            \                                 /
             \         eve-iac-agent         /
              \                           /
          validate  →  plan  →  reconcile
You asked for Agent does
validate Desired YAML vs live catalog. Invalid never reaches plan.
plan Same diff as reconcile. GET/read only. Returns classifications + plan_identity.
reconcile to_eve Apply Local onto EVE, fail-closed, then progressive.
reconcile from_eve Apply reproducible live fields onto Git. Zero EVE writes.

Two passes on to_eve are normal:

  1. Live-safe (eve-iac reconcile ./lab) — applies live_applicable or does nothing if any row is unsupported.
  2. Disruptive (eve-iac --yes reconcile ./lab --plan-identity <P>) — remaining requires_stop only. --yes does not invent identity.

What each operation writes

Operation Writes Git? Writes EVE?
validate no no
plan no no (GET/read only)
deploy sidecars creates managed lab
reconcile to_eve sidecars live-safe now; remaining stop after confirm + matching plan identity
reconcile from_eve yes (CLI commit_pulled) no mutating writes
destroy no deletes managed lab
inspect no observation only

Directions: to_eve / from_eve. First-time lab: Deploy. Later edits: Reconcile, not Deploy.

How the agent decides (to_eve)

One path. The executor does not re-decide IOL vs QEMU vs config wipe.

Validate (desired + live catalog; provenance-independent)
  → Fill managed template options from YAML presence (existing lab, to_eve)
  → Diff (one stored projection of that filled lab vs the lab EVE stored)
  → Typing (every persistent YAML leaf → one contract Attribute)
  → Exact Lookup (object, attribute, change, family, state)
  → Classified PlanAction (authorization + ordered obligations)
  → Executor (those obligations only, in Cell order)

plan and reconcile share that diff. The re-plan after a confirmed stop runs it again. The PUT sends the filled value, including a numeric default and an authorized empty string. Creating a lab that does not exist yet stays the first deploy, without that fill.

Step Owns
Validate Coherence of desired YAML against the live template/image catalog. Import must emit YAML that passes the same validate, or report incompatibility.
Fill On an existing lab, to_eve turns an omitted managed option into the template default. An explicit value, including the default and an allowed empty string, stays.
Typing Exhaustive mapping of persistent leaves onto one Attribute vocabulary. version is schema metadata, not a Key. Config selector (none / omit / named set) is independent of the config blob.
Lookup Product truth for to_eve only. Miss = internal contract error, not unsupported. A registered unsupported cell has empty obligations.
Executor Runs remaining obligations in the Cell’s declared order. The scheduler orders actions, never reorders a Cell.

from_eve is repository sync. It does not execute those obligations. Consoles, exec/wait/run, and live link quality/suspend are Interaction as Code — outside this matrix. Ordinary reconcile does not replay presentation.

VSIX / MCP / CLI have no local policy tables. They present classification, stop_nodes, and obligations from the agent. EVE never returns a Cell.

Family on Lookup: desired template on create/update, observed template on delete. State is absent | stopped | running | n/a.

Plan

Dry-run of the same semantic diff as reconcile. Omitted direction is to_eve. Copy plan_identity if you later confirm remaining requires_stop work. Never use plan as proof of running NOS configuration.

Top-level applicable is a summary of immediate full convergence. Do not gate reconcile on it. Read classification / status instead (converged | partial | pending_stop | failed).

Deploy

Create the managed lab the first time. Existing lab without replace → 409 lab_exists. replace is stop/wipe/delete then recreate and needs confirmation. Later edits use Reconcile, not Deploy.

Classifications

Class Meaning What reconcile does
live_applicable Safe to apply on current runtime Apply now (if the plan has no unsupported)
requires_stop Reachable after an exact-node stop Wait for confirm=true and matching plan_identity
unsupported Unreachable in-place transition Zero EVE mutations for the whole plan. Change the YAML. The plan stays inspectable.

requires_stop is not unsupported. Stop consent is not “apply anyway.”

Reconcile to_eve

Desired → managed runtime.

  1. Validate, then plan (typing → exact Lookup).
  2. If any action is unsupported, stop here: no POST/PUT/DELETE, no live-safe work, no stop. Fix desired state and plan again.
  3. Otherwise apply live_applicable work. Config blob upload, selector put, and wipe wait until the node exists and its binding is refreshed. Selector create is not a node create. A named configset YAML adds is created even when it has no files. A named configset YAML removes is deleted after selectors move off it. default stays the built-in store.
  4. Remaining requires_stop needs confirm=true and a matching plan_identity. That is “apply this examined plan”, not a generic “are you sure?”. Mismatch or omitted identity while stop work remains → 409 plan_stale, zero StopNode.
  5. On match: stop the exact logical keys, re-plan, merge continuation by ActionKey (object + logical id + attribute + change + optional subresource — not “same object”), then run the remaining obligation suffix in Cell order. Restore prior running state when start is still in that suffix.

confirm=false / omitted confirm still applies live-safe work only when the plan has no unsupported actions and returns remaining plan_identity. Declining stop does not roll back live-safe work already applied from that plan. No automatic wipe/redeploy of the whole lab.

The response executed list and text report what this call sent. effect is applied, failed, skipped, or pending_stop. operations is the plan that was examined, not that log. The IDE Reconcile output prints text.

Reconcile from_eve

Runtime → Local files. Zero EVE POST/PUT/DELETE. Confirm does not authorize stop. Not Import. No contract obligations; presentation may be rewritten locally from the live snapshot.

from_eve reads startup-config blobs already stored on the lab. It does not read NOS memory. Copy the running configuration into an existing set first (export-config / Export running config / exportProjectConfig), then pull. That export does not write topology.yml or configs/**.

prune

to_eve only: delete extra live objects. Requires --yes / IDE confirm / MCP confirm=true. Invalid with from_eve (a vanished live object is delete-local, not prune). If remaining work is requires_stop, still pass --plan-identity.

Destructive actions

Destroy, wipe, replace, prune, and classified stops are explicit. Omitted wipe on destroy still means wipe nodes on the agent; --no-wipe sends wipe=false.

Presentation is restored after full IMPORT deploy/recreate only. Ordinary to_eve reconcile does not replay visuals.