Files
hq/02-DECISIONS/0032-a-scenario-is-an-isolated-address-space.md
T
jschoubben a253afe020 Scenario lifecycle, and how two scenarios coexist
ADR 0032: a scenario is a closed address space. Every segment materialises
as its own isolated link belonging to one instance, so two scenarios raised
from the same declaration hold the same addresses and never meet. The
declaration keeps its literal addresses and they mean what they say —
allocating from a pool would have made them a fiction, so a scenario
reproducing a specific topology would stop reproducing it.

The constraint that follows shapes everything: the lab never reaches into a
scenario over IP. It talks to machines through the virtualisation layer's
own channel. If it reached them by address, the workstation would need a
route into each scenario, and two carrying the same prefix would give it
two routes to one destination — failing not with an error but by one
scenario's traffic arriving in another.

That also makes reachability an honest question. Can this machine reach
that one is asked from INSIDE, by executing on the first, rather than
probed from a workstation that is not on the network and whose opinion
would be a different question with a misleadingly similar answer.

The lifecycle itself: six verbs, of which raise and destroy are enough to
be useful and the rest are what make repetition cheap. Raising is
convergent rather than incremental, because a lab behaving differently
from the thing it tests teaches the wrong habit.

A failed raise leaves the wreckage standing. Tearing down on failure
destroys the only evidence, which is backwards — a scenario that failed to
raise is more interesting than one that succeeded.

Snapshots are whole-scenario. Per-machine would be cheaper and wrong: the
mesh keeps state spanning nodes, so restoring one machine while its peers
move on produces a mesh that has never existed, and faults found there
would be artefacts of the lab.

Closes the declaration's open question about running several scenarios at
once.
2026-08-23 23:53:00 +02:00

3.8 KiB

status, date, deciders, reconstructed
status date deciders reconstructed
accepted 2026-08-23 jochen false

32. A scenario is an isolated address space, and the lab never reaches into it over IP

Context

A scenario declares literal addresses — the declaration is full of them, and it has to be, because reproducing published but behind NAT means saying which address the world sees.

That raises a question the declaration left open: two scenarios at once. Several agents working means several scenarios, and the lab design already calls that a requirement. But two scenarios built from the same declaration want the same addresses, and there are only three documentation ranges in existence.

Considered options

  1. Allocate addresses from a pool at raise time, rewriting the declaration's literals. Rejected. It makes the addresses in a declaration a fiction, so a scenario reproducing a specific topology no longer reproduces it; it breaks the RFC-range validation, since allocated addresses would have to come from somewhere real; and the numbers a person reads in the file stop being the numbers they will see in a capture.
  2. One scenario at a time. Rejected — it is the requirement, not an inconvenience. A gate an agent has to queue for is a gate that gets bypassed.
  3. Give each scenario its own network stack, so the addresses do not collide. Chosen.

Decision

A scenario is a closed address space. Every segment materialises as its own isolated link, belonging to one scenario instance. Two scenarios raised from the same declaration hold the same addresses and never meet, because nothing joins their links.

The declaration therefore keeps its literal addresses, and they mean exactly what they say.

The consequence that constrains everything else: the lab never reaches into a scenario over IP. It talks to a machine through the virtualisation layer's own channel — the same way one executes a command in a container without the container being routable.

That is not a preference. If the lab reached machines by address, the workstation running it would need a route into each scenario, and two scenarios carrying the same prefix would give it two routes to the same destination. Concurrency would be impossible, and it would fail in the worst available way: not with an error, but by one scenario's traffic arriving in another.

Consequences

  • Scenarios are concurrent by construction, with no allocation, no bookkeeping and no limit beyond the machine's capacity.
  • The three documentation ranges stop being a scarce resource. Every scenario may use all of them, because no two scenarios share a link.
  • The lab cannot use IP to check anything, which is more of a constraint than it first appears: "can this machine reach that one" has to be asked from inside the scenario, by executing on a machine, rather than probed from outside. That is the honest way to ask it anyway — reachability from the workstation is not the question.
  • A scenario is a unit that can be paused, snapshotted and destroyed whole, because nothing outside holds a reference into it.
  • The lab needs a scenario instance identity distinct from the scenario name in the declaration: the declaration is a kind, and several instances of one kind may exist.
  • The workstation is not on the scenario's network, so it is not a node in it. Anything a developer wants to reach — a web interface, a database — needs an explicit, deliberate forward out of the scenario, which is a feature rather than a gap: nothing leaks by default.

References

  • ADR 0031 — the declaration whose literal addresses this preserves.
  • ADR 0029 — the lifecycle jobs this shapes.