<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Decisions on Deevnet Infrastructure Platform</title><link>https://deevnet.github.io/deevnet-docs/docs/architecture/decisions/</link><description>Recent content in Decisions on Deevnet Infrastructure Platform</description><generator>Hugo</generator><language>en-us</language><atom:link href="https://deevnet.github.io/deevnet-docs/docs/architecture/decisions/index.xml" rel="self" type="application/rss+xml"/><item><title>ADR-0001: Tenant Network Fabric</title><link>https://deevnet.github.io/deevnet-docs/docs/architecture/decisions/0001-tenant-network-fabric/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://deevnet.github.io/deevnet-docs/docs/architecture/decisions/0001-tenant-network-fabric/</guid><description>&lt;h1 id="adr-0001-tenant-network-fabric">
 ADR-0001: Tenant Network Fabric
 &lt;a class="anchor" href="#adr-0001-tenant-network-fabric">#&lt;/a>
&lt;/h1>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>&lt;/th>
 &lt;th>&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>&lt;strong>Status&lt;/strong>&lt;/td>
 &lt;td>Accepted&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Date&lt;/strong>&lt;/td>
 &lt;td>2026-08-30&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Scope&lt;/strong>&lt;/td>
 &lt;td>Tenant networking on the tenant hypervisor; relationship to the core router and management hypervisor&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Supersedes&lt;/strong>&lt;/td>
 &lt;td>The Option A tenant-networking model previously described in &lt;code>architecture/tenant/networking.md&lt;/code> (core-router-owned per-tenant VLANs)&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;hr>
&lt;h2 id="context">
 Context
 &lt;a class="anchor" href="#context">#&lt;/a>
&lt;/h2>
&lt;p>We are ready to begin hosting &lt;strong>tenants&lt;/strong> — isolated application workloads — on the tenant
hypervisor. A tenant needs a network: an address space, a gateway, routing, isolation from
other tenants, and a controlled path to the outside world.&lt;/p></description></item><item><title>ADR-0002: Tenant Fabric Numbering</title><link>https://deevnet.github.io/deevnet-docs/docs/architecture/decisions/0002-tenant-fabric-numbering/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://deevnet.github.io/deevnet-docs/docs/architecture/decisions/0002-tenant-fabric-numbering/</guid><description>&lt;h1 id="adr-0002-tenant-fabric-numbering">
 ADR-0002: Tenant Fabric Numbering
 &lt;a class="anchor" href="#adr-0002-tenant-fabric-numbering">#&lt;/a>
&lt;/h1>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>&lt;/th>
 &lt;th>&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>&lt;strong>Status&lt;/strong>&lt;/td>
 &lt;td>Accepted&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Date&lt;/strong>&lt;/td>
 &lt;td>2026-08-30&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Scope&lt;/strong>&lt;/td>
 &lt;td>Address and identifier allocation for the tenant fabric and the tenants on it&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Depends on&lt;/strong>&lt;/td>
 &lt;td>
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/architecture/decisions/0001-tenant-network-fabric/">ADR-0001: Tenant Network Fabric&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;hr>
&lt;h2 id="context">
 Context
 &lt;a class="anchor" href="#context">#&lt;/a>
&lt;/h2>
&lt;p>ADR-0001 made &lt;strong>globally-unique numbering&lt;/strong> its first build requirement: allocate VNIs, VRF
identifiers, and tenant subnets &lt;em>as if they already share one fabric&lt;/em>, so that gaining a member
is additive rather than a renumbering. It did not say what that scheme is. The Tenant Platform
roadmap carried it as an open thread.&lt;/p></description></item><item><title>ADR-0003: Tenant Egress on a Single-Member Fabric</title><link>https://deevnet.github.io/deevnet-docs/docs/architecture/decisions/0003-tenant-egress-single-member-fabric/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://deevnet.github.io/deevnet-docs/docs/architecture/decisions/0003-tenant-egress-single-member-fabric/</guid><description>&lt;h1 id="adr-0003-tenant-egress-on-a-single-member-fabric">
 ADR-0003: Tenant Egress on a Single-Member Fabric
 &lt;a class="anchor" href="#adr-0003-tenant-egress-on-a-single-member-fabric">#&lt;/a>
&lt;/h1>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>&lt;/th>
 &lt;th>&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>&lt;strong>Status&lt;/strong>&lt;/td>
 &lt;td>&lt;strong>Accepted&lt;/strong>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Date&lt;/strong>&lt;/td>
 &lt;td>2026-09-01&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Scope&lt;/strong>&lt;/td>
 &lt;td>How tenant workloads reach the perimeter, and why they must reach it rather than route around it&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Depends on&lt;/strong>&lt;/td>
 &lt;td>
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/architecture/decisions/0001-tenant-network-fabric/">ADR-0001: Tenant Network Fabric&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;hr>
&lt;h2 id="context">
 Context
 &lt;a class="anchor" href="#context">#&lt;/a>
&lt;/h2>
&lt;p>
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/architecture/decisions/0001-tenant-network-fabric/">ADR-0001&lt;/a> chose a self-contained
EVPN/VXLAN fabric per tenant hypervisor, realized today as a &lt;strong>single-member fabric&lt;/strong> on hv02 and
designed to expand by adding members. Seam 1 of that record defines north-south egress: aggregate
tenant traffic leaves the fabric on a transit VLAN, and the core router is a perimeter that never
learns tenant address space.&lt;/p></description></item><item><title>ADR-0004: Tenant DNS Publication</title><link>https://deevnet.github.io/deevnet-docs/docs/architecture/decisions/0004-tenant-dns-publication/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://deevnet.github.io/deevnet-docs/docs/architecture/decisions/0004-tenant-dns-publication/</guid><description>&lt;h1 id="adr-0004-tenant-dns-publication">
 ADR-0004: Tenant DNS Publication
 &lt;a class="anchor" href="#adr-0004-tenant-dns-publication">#&lt;/a>
&lt;/h1>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>&lt;/th>
 &lt;th>&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>&lt;strong>Status&lt;/strong>&lt;/td>
 &lt;td>Accepted&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Date&lt;/strong>&lt;/td>
 &lt;td>2026-09-01&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Scope&lt;/strong>&lt;/td>
 &lt;td>How a tenant&amp;rsquo;s own DNS records reach the resolver substrate clients use&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Depends on&lt;/strong>&lt;/td>
 &lt;td>
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/architecture/decisions/0001-tenant-network-fabric/">ADR-0001: Tenant Network Fabric&lt;/a>, 
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/architecture/decisions/0002-tenant-fabric-numbering/">ADR-0002: Tenant Fabric Numbering&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Extended by&lt;/strong>&lt;/td>
 &lt;td>
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/architecture/decisions/0005-tenant-zone-apex-ownership/">ADR-0005: Tenant Zone Apex Ownership&lt;/a> — the zone apex, which §4 does not assign&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Extended by&lt;/strong>&lt;/td>
 &lt;td>
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/architecture/decisions/0006-tenant-code-boundary/">ADR-0006: Tenant Code Boundary&lt;/a> — where the tenant&amp;rsquo;s code lives, which §5 does not say&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Extended by&lt;/strong>&lt;/td>
 &lt;td>
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/architecture/decisions/0010-tenants-consume-platform-services/">ADR-0010: Tenants Consume Platform Services&lt;/a> — §5&amp;rsquo;s line as a rule for every platform service, not only DNS &lt;em>(Proposed)&lt;/em>&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;hr>
&lt;h2 id="context">
 Context
 &lt;a class="anchor" href="#context">#&lt;/a>
&lt;/h2>
&lt;p>Seam 2 of 
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/architecture/decisions/0001-tenant-network-fabric/">ADR-0001&lt;/a> splits addressing
from naming: IPAM belongs to the fabric, while DNS is &lt;strong>tenant-owned but published to the substrate
zone&lt;/strong>. With 
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/architecture/decisions/0003-tenant-egress-single-member-fabric/">ADR-0003&lt;/a>
closing egress, this is the last part of the tenant contract still undecided.&lt;/p></description></item><item><title>ADR-0005: Tenant Zone Apex Ownership</title><link>https://deevnet.github.io/deevnet-docs/docs/architecture/decisions/0005-tenant-zone-apex-ownership/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://deevnet.github.io/deevnet-docs/docs/architecture/decisions/0005-tenant-zone-apex-ownership/</guid><description>&lt;h1 id="adr-0005-tenant-zone-apex-ownership">
 ADR-0005: Tenant Zone Apex Ownership
 &lt;a class="anchor" href="#adr-0005-tenant-zone-apex-ownership">#&lt;/a>
&lt;/h1>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>&lt;/th>
 &lt;th>&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>&lt;strong>Status&lt;/strong>&lt;/td>
 &lt;td>Accepted&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Date&lt;/strong>&lt;/td>
 &lt;td>2026-09-03&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Scope&lt;/strong>&lt;/td>
 &lt;td>Who owns the SOA and apex NS records inside a delegated tenant zone&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Extends&lt;/strong>&lt;/td>
 &lt;td>
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/architecture/decisions/0004-tenant-dns-publication/">ADR-0004: Tenant DNS Publication&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;hr>
&lt;h2 id="context">
 Context
 &lt;a class="anchor" href="#context">#&lt;/a>
&lt;/h2>
&lt;p>
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/architecture/decisions/0004-tenant-dns-publication/">ADR-0004&lt;/a> drew a clean line: the
substrate creates the zone and issues the TSIG key, and the tenant writes the records inside it.
&lt;em>Substrate provides the machine; tenants provide the content.&lt;/em>&lt;/p>
&lt;p>Building it exposed a category the line does not cover. A zone&amp;rsquo;s &lt;strong>apex&lt;/strong> — its SOA, and the NS
records naming the servers authoritative for it — is made of records, which puts it on the tenant
side of that table. But it is created by &lt;code>pdnsutil create-zone&lt;/code>, which is a substrate act, and it
describes the zone&amp;rsquo;s own existence rather than anything the tenant runs. It is neither the machine
nor the content.&lt;/p></description></item><item><title>ADR-0006: Tenant Code Boundary</title><link>https://deevnet.github.io/deevnet-docs/docs/architecture/decisions/0006-tenant-code-boundary/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://deevnet.github.io/deevnet-docs/docs/architecture/decisions/0006-tenant-code-boundary/</guid><description>&lt;h1 id="adr-0006-tenant-code-boundary">
 ADR-0006: Tenant Code Boundary
 &lt;a class="anchor" href="#adr-0006-tenant-code-boundary">#&lt;/a>
&lt;/h1>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>&lt;/th>
 &lt;th>&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>&lt;strong>Status&lt;/strong>&lt;/td>
 &lt;td>Accepted&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Date&lt;/strong>&lt;/td>
 &lt;td>2026-09-03&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Scope&lt;/strong>&lt;/td>
 &lt;td>Where a tenant&amp;rsquo;s code lives, and what it needs from the substrate to stand alone&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Depends on&lt;/strong>&lt;/td>
 &lt;td>
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/architecture/decisions/0001-tenant-network-fabric/">ADR-0001: Tenant Network Fabric&lt;/a>, 
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/architecture/decisions/0002-tenant-fabric-numbering/">ADR-0002: Tenant Fabric Numbering&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Extends&lt;/strong>&lt;/td>
 &lt;td>
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/architecture/decisions/0004-tenant-dns-publication/">ADR-0004: Tenant DNS Publication&lt;/a> §5&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;hr>
&lt;h2 id="context">
 Context
 &lt;a class="anchor" href="#context">#&lt;/a>
&lt;/h2>
&lt;p>
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/architecture/decisions/0004-tenant-dns-publication/">ADR-0004&lt;/a> §5 drew a line that has held
up well: &lt;strong>onboarding may touch substrate; the recurring lifecycle may not.&lt;/strong> Adding a record,
rebuilding, destroying — those are &lt;code>terraform apply&lt;/code> and nothing else.&lt;/p></description></item><item><title>ADR-0007: Terraform State Custody</title><link>https://deevnet.github.io/deevnet-docs/docs/architecture/decisions/0007-terraform-state-custody/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://deevnet.github.io/deevnet-docs/docs/architecture/decisions/0007-terraform-state-custody/</guid><description>&lt;h1 id="adr-0007-terraform-state-custody">
 ADR-0007: Terraform State Custody
 &lt;a class="anchor" href="#adr-0007-terraform-state-custody">#&lt;/a>
&lt;/h1>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>&lt;/th>
 &lt;th>&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>&lt;strong>Status&lt;/strong>&lt;/td>
 &lt;td>Accepted&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Date&lt;/strong>&lt;/td>
 &lt;td>2026-09-03&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Scope&lt;/strong>&lt;/td>
 &lt;td>Where Terraform state lives, who may read it, and what protects it&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Depends on&lt;/strong>&lt;/td>
 &lt;td>
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/architecture/decisions/0006-tenant-code-boundary/">ADR-0006: Tenant Code Boundary&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Extended by&lt;/strong>&lt;/td>
 &lt;td>
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/architecture/decisions/0014-tenant-state-durability/">ADR-0014: Tenant State Durability&lt;/a> — how the store&amp;rsquo;s contents survive losing their host, once state holds device secrets &lt;em>(Proposed)&lt;/em>&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;hr>
&lt;h2 id="context">
 Context
 &lt;a class="anchor" href="#context">#&lt;/a>
&lt;/h2>
&lt;p>State custody was never decided. &lt;code>architecture/tenant/building.md&lt;/code> offered three bullets —&lt;/p>
&lt;blockquote>
&lt;p>Tenant Terraform state should be:&lt;/p>
&lt;ul>
&lt;li>Stored in version control (for small deployments)&lt;/li>
&lt;li>Or in remote backend (for team access)&lt;/li>
&lt;li>Never edited manually&lt;/li>
&lt;/ul>
&lt;/blockquote>
&lt;p>— which is a menu, not a decision, and it is contradicted on its own page by a &lt;code>terraform_remote_state&lt;/code>
example. Both state files have been committed to git on the strength of the first bullet.&lt;/p></description></item><item><title>ADR-0008: Host Naming and Site Codes</title><link>https://deevnet.github.io/deevnet-docs/docs/architecture/decisions/0008-host-naming-site-codes/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://deevnet.github.io/deevnet-docs/docs/architecture/decisions/0008-host-naming-site-codes/</guid><description>&lt;h1 id="adr-0008-host-naming-and-site-codes">
 ADR-0008: Host Naming and Site Codes
 &lt;a class="anchor" href="#adr-0008-host-naming-and-site-codes">#&lt;/a>
&lt;/h1>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>&lt;/th>
 &lt;th>&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>&lt;strong>Status&lt;/strong>&lt;/td>
 &lt;td>Accepted&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Date&lt;/strong>&lt;/td>
 &lt;td>2026-09-04&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Accepted&lt;/strong>&lt;/td>
 &lt;td>2026-09-05&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Scope&lt;/strong>&lt;/td>
 &lt;td>How a host is named, and how a site is identified in that name and in DNS&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Related&lt;/strong>&lt;/td>
 &lt;td>
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/architecture/decisions/0002-tenant-fabric-numbering/">ADR-0002: Tenant Fabric Numbering&lt;/a> — the site octet this record&amp;rsquo;s site codes sit alongside&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;hr>
&lt;h2 id="context">
 Context
 &lt;a class="anchor" href="#context">#&lt;/a>
&lt;/h2>
&lt;p>Only the mobile site has hosts. Its names — &lt;code>hv01&lt;/code>, &lt;code>core-rt01&lt;/code>, &lt;code>provisioner-ph01&lt;/code> — are scoped to
their site by inventory boundary alone, and the home site&amp;rsquo;s shell would reuse every one of them.&lt;/p></description></item><item><title>ADR-0009: Network Device Configuration Is Inventory-Owned and Controller-Applied</title><link>https://deevnet.github.io/deevnet-docs/docs/architecture/decisions/0009-network-device-config-ownership/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://deevnet.github.io/deevnet-docs/docs/architecture/decisions/0009-network-device-config-ownership/</guid><description>&lt;h1 id="adr-0009-network-device-configuration-is-inventory-owned-and-controller-applied">
 ADR-0009: Network Device Configuration Is Inventory-Owned and Controller-Applied
 &lt;a class="anchor" href="#adr-0009-network-device-configuration-is-inventory-owned-and-controller-applied">#&lt;/a>
&lt;/h1>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>&lt;/th>
 &lt;th>&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>&lt;strong>Status&lt;/strong>&lt;/td>
 &lt;td>Accepted&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Date&lt;/strong>&lt;/td>
 &lt;td>2026-09-10&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Accepted&lt;/strong>&lt;/td>
 &lt;td>2026-09-10&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Scope&lt;/strong>&lt;/td>
 &lt;td>Who owns, and who applies, the configuration of controller-managed network devices — the access switch and the AP — and how automation talks to the Omada controller&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Extended by&lt;/strong>&lt;/td>
 &lt;td>
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/architecture/decisions/0013-management-services-domain-vms/">ADR-0013: Management-Hypervisor Services Run as Containers on Domain VMs&lt;/a> — where the controller runs (a container in the network management VM, &lt;code>nms&lt;/code>), and the order a rebuild uses it in&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Related&lt;/strong>&lt;/td>
 &lt;td>
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/changes/2026/0004-omada-controller-upgrade/">CHG-0004&lt;/a> — brings the controller current; 
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/changes/2026/0005-wireless-ap-firmware-and-adoption/">CHG-0005&lt;/a> — the AP, the first device adopted under this record; 
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/changes/2026/0006-access-switch-firmware-upgrade/">CHG-0006&lt;/a> — the switch&amp;rsquo;s firmware; 
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/incidents/2026/0001-firewall-policy-deletion/">INC-0001&lt;/a> — the guards any reconciling role now carries&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;hr>
&lt;h2 id="context">
 Context
 &lt;a class="anchor" href="#context">#&lt;/a>
&lt;/h2>
&lt;p>The mobile site&amp;rsquo;s network devices are configured three different ways today:&lt;/p></description></item><item><title>ADR-0010: Tenants Consume Platform Services</title><link>https://deevnet.github.io/deevnet-docs/docs/architecture/decisions/0010-tenants-consume-platform-services/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://deevnet.github.io/deevnet-docs/docs/architecture/decisions/0010-tenants-consume-platform-services/</guid><description>&lt;h1 id="adr-0010-tenants-consume-platform-services-they-are-not-woven-into-the-substrate">
 ADR-0010: Tenants Consume Platform Services; They Are Not Woven Into the Substrate
 &lt;a class="anchor" href="#adr-0010-tenants-consume-platform-services-they-are-not-woven-into-the-substrate">#&lt;/a>
&lt;/h1>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>&lt;/th>
 &lt;th>&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>&lt;strong>Status&lt;/strong>&lt;/td>
 &lt;td>Proposed&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Date&lt;/strong>&lt;/td>
 &lt;td>2026-09-13&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Scope&lt;/strong>&lt;/td>
 &lt;td>What makes a substrate-run service safe for a tenant to depend on, and where issuing a tenant something ends and becoming part of it begins&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Extends&lt;/strong>&lt;/td>
 &lt;td>
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/architecture/decisions/0004-tenant-dns-publication/">ADR-0004: Tenant DNS Publication&lt;/a> §5, which drew the onboarding-versus-recurring line for DNS only&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Extended by&lt;/strong>&lt;/td>
 &lt;td>
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/architecture/decisions/0012-iot-platform-api/">ADR-0012: IoT Platform Services Through a Deevnet API and Terraform Provider&lt;/a> — how §3 is met when the backing service can&amp;rsquo;t confine a tenant itself &lt;em>(Proposed)&lt;/em>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Related&lt;/strong>&lt;/td>
 &lt;td>
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/architecture/decisions/0006-tenant-code-boundary/">ADR-0006: Tenant Code Boundary&lt;/a>, 
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/architecture/decisions/0007-terraform-state-custody/">ADR-0007: Terraform State Custody&lt;/a>, 
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/architecture/decisions/0011-edge-devices-application-owned/">ADR-0011: Edge Devices Are Application-Owned and Platform-Attached&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;hr>
&lt;h2 id="context">
 Context
 &lt;a class="anchor" href="#context">#&lt;/a>
&lt;/h2>
&lt;p>Three records have drawn the same line, each for one thing, and none of them says it is a rule:&lt;/p></description></item><item><title>ADR-0011: Edge Devices Are Application-Owned and Platform-Attached</title><link>https://deevnet.github.io/deevnet-docs/docs/architecture/decisions/0011-edge-devices-application-owned/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://deevnet.github.io/deevnet-docs/docs/architecture/decisions/0011-edge-devices-application-owned/</guid><description>&lt;h1 id="adr-0011-edge-devices-are-application-owned-and-platform-attached">
 ADR-0011: Edge Devices Are Application-Owned and Platform-Attached
 &lt;a class="anchor" href="#adr-0011-edge-devices-are-application-owned-and-platform-attached">#&lt;/a>
&lt;/h1>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>&lt;/th>
 &lt;th>&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>&lt;strong>Status&lt;/strong>&lt;/td>
 &lt;td>Accepted&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Accepted&lt;/strong>&lt;/td>
 &lt;td>2026-09-15, once its four open questions were answered. Questions 1–3 were settled by the operator on 2026-09-15 (
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/changes/2026/0008-domain-vms-build-out/">CHG-0008&lt;/a> Step 9&amp;rsquo;s controller work made the platform side real); question 4 was settled on 2026-09-14.&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Date&lt;/strong>&lt;/td>
 &lt;td>2026-09-13&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Validated&lt;/strong>&lt;/td>
 &lt;td>2026-09-14, read-only, before acceptance. See 
 &lt;a href="#validation-2026-09-14">Validation&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Scope&lt;/strong>&lt;/td>
 &lt;td>Who owns a physical device an application uses, what the platform knows about it, which network it joins, and how it reaches the services it needs&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Depends on&lt;/strong>&lt;/td>
 &lt;td>
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/architecture/decisions/0010-tenants-consume-platform-services/">ADR-0010: Tenants Consume Platform Services&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Related&lt;/strong>&lt;/td>
 &lt;td>
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/architecture/decisions/0001-tenant-network-fabric/">ADR-0001: Tenant Network Fabric&lt;/a>, 
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/architecture/decisions/0003-tenant-egress-single-member-fabric/">ADR-0003: Tenant Egress on a Single-Member Fabric&lt;/a>, 
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/architecture/decisions/0009-network-device-config-ownership/">ADR-0009: Network Device Configuration Is Inventory-Owned and Controller-Applied&lt;/a>, 
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/architecture/decisions/0012-iot-platform-api/">ADR-0012: IoT Platform Services Through a Deevnet API and Terraform Provider&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;hr>
&lt;h2 id="context">
 Context
 &lt;a class="anchor" href="#context">#&lt;/a>
&lt;/h2>
&lt;p>Physical microcontrollers have been treated as substrate IoT devices. The treatment conflated
concerns that answer to different owners:&lt;/p></description></item><item><title>ADR-0012: IoT Platform Services Through a Deevnet API and Terraform Provider</title><link>https://deevnet.github.io/deevnet-docs/docs/architecture/decisions/0012-iot-platform-api/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://deevnet.github.io/deevnet-docs/docs/architecture/decisions/0012-iot-platform-api/</guid><description>&lt;h1 id="adr-0012-iot-platform-services-through-a-deevnet-api-and-terraform-provider">
 ADR-0012: IoT Platform Services Through a Deevnet API and Terraform Provider
 &lt;a class="anchor" href="#adr-0012-iot-platform-services-through-a-deevnet-api-and-terraform-provider">#&lt;/a>
&lt;/h1>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>&lt;/th>
 &lt;th>&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>&lt;strong>Status&lt;/strong>&lt;/td>
 &lt;td>Accepted&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Accepted&lt;/strong>&lt;/td>
 &lt;td>2026-09-18, at the close of 
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/changes/2026/0013-tenant-wifi-ppsk-keys/">CHG-0013&lt;/a> — when the Wi-Fi half had been built, deployed and proven on the AP, not when it was written. The broker half (§8) and the device registry (§3) are decided but not built.&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Date&lt;/strong>&lt;/td>
 &lt;td>2026-09-14&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Reviewed&lt;/strong>&lt;/td>
 &lt;td>2026-09-14. Four of the original open questions were decided in review: the broker (§8), secrets after a rebuild (§4, §5), provider distribution (§7) and credential delivery (§9). The sources are quoted in each section. Revised the same day: the API is provisioning-only, and the broker authenticates from its own auth database (§8). Open questions 2, 5 and 6 were then answered: where the API, its database, the broker&amp;rsquo;s auth database and the Omada controller run (§7, 
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/architecture/decisions/0013-management-services-domain-vms/">ADR-0013&lt;/a>). Revised 2026-09-16: tenant workloads get broker accounts too (§3), and topic confinement is decided (§10, Open question 4). Revised 2026-09-18 by 
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/changes/2026/0013-tenant-wifi-ppsk-keys/">CHG-0013&lt;/a>, which built the Wi-Fi half: a key is per tenant per trust class rather than per device (§3), v1 ships on &lt;code>DVNTM-IOT&lt;/code> only (§3), the drift report names profiles rather than counting keys (§6), and &lt;code>DVNTM-IOT&lt;/code> turned out to be a creation rather than a migration (Consequences).&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Scope&lt;/strong>&lt;/td>
 &lt;td>How a tenant reaches an IoT platform service whose own interface can&amp;rsquo;t confine it to its scope, and what the substrate builds so it can&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Extends&lt;/strong>&lt;/td>
 &lt;td>
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/architecture/decisions/0010-tenants-consume-platform-services/">ADR-0010: Tenants Consume Platform Services&lt;/a> §1 and §3, which require a scoped service but don&amp;rsquo;t say how one is built when the backing software can&amp;rsquo;t scope itself&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Answers, in part&lt;/strong>&lt;/td>
 &lt;td>
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/architecture/decisions/0011-edge-devices-application-owned/">ADR-0011: Edge Devices Are Application-Owned and Platform-Attached&lt;/a> open questions 1 (scoped registration) and 3 (Wi-Fi keys — answered per tenant per trust class, not per device; §3)&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Related&lt;/strong>&lt;/td>
 &lt;td>
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/architecture/decisions/0004-tenant-dns-publication/">ADR-0004: Tenant DNS Publication&lt;/a>, 
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/architecture/decisions/0006-tenant-code-boundary/">ADR-0006: Tenant Code Boundary&lt;/a>, 
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/architecture/decisions/0007-terraform-state-custody/">ADR-0007: Terraform State Custody&lt;/a>, 
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/architecture/decisions/0009-network-device-config-ownership/">ADR-0009: Network Device Configuration Is Inventory-Owned and Controller-Applied&lt;/a>, 
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/architecture/decisions/0013-management-services-domain-vms/">ADR-0013: Management-Hypervisor Services Run as Containers on Domain VMs&lt;/a>, 
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/architecture/decisions/0014-tenant-state-durability/">ADR-0014: Tenant State Durability&lt;/a> (§4 and §5 depend on it)&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;hr>
&lt;h2 id="context">
 Context
 &lt;a class="anchor" href="#context">#&lt;/a>
&lt;/h2>
&lt;h3 id="the-rule-has-no-mechanism-for-iot">
 The rule has no mechanism for IoT
 &lt;a class="anchor" href="#the-rule-has-no-mechanism-for-iot">#&lt;/a>
&lt;/h3>
&lt;p>ADR-0010 set the test for a platform service: &lt;em>does this recurring tenant action need a substrate
commit?&lt;/em> For IoT, two actions fail it today:&lt;/p></description></item><item><title>ADR-0013: Management-Hypervisor Services Run as Containers on Domain VMs</title><link>https://deevnet.github.io/deevnet-docs/docs/architecture/decisions/0013-management-services-domain-vms/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://deevnet.github.io/deevnet-docs/docs/architecture/decisions/0013-management-services-domain-vms/</guid><description>&lt;h1 id="adr-0013-management-hypervisor-services-run-as-containers-on-domain-vms">
 ADR-0013: Management-Hypervisor Services Run as Containers on Domain VMs
 &lt;a class="anchor" href="#adr-0013-management-hypervisor-services-run-as-containers-on-domain-vms">#&lt;/a>
&lt;/h1>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>&lt;/th>
 &lt;th>&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>&lt;strong>Status&lt;/strong>&lt;/td>
 &lt;td>Accepted&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Accepted&lt;/strong>&lt;/td>
 &lt;td>2026-09-16, once 
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/changes/2026/0008-domain-vms-build-out/">CHG-0008&lt;/a> built all six domain VMs and moved the controller, tenant DNS and the tenant state store onto them&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Date&lt;/strong>&lt;/td>
 &lt;td>2026-09-14&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Scope&lt;/strong>&lt;/td>
 &lt;td>How services on the management hypervisor are grouped into VMs and named, where the site&amp;rsquo;s Omada controller officially runs, and the order a rebuild uses them in&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Extends&lt;/strong>&lt;/td>
 &lt;td>
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/architecture/decisions/0009-network-device-config-ownership/">ADR-0009: Network Device Configuration Is Inventory-Owned and Controller-Applied&lt;/a>, which decided that the controller is the actuator for switch and AP configuration, but not where it runs&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Extended by&lt;/strong>&lt;/td>
 &lt;td>
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/architecture/decisions/0014-tenant-state-durability/">ADR-0014: Tenant State Durability&lt;/a> — the provisioning VM holds both the state store and the API&amp;rsquo;s database, so their data needs a data disk and a copy on separate hardware &lt;em>(Proposed)&lt;/em>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Related&lt;/strong>&lt;/td>
 &lt;td>
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/architecture/decisions/0004-tenant-dns-publication/">ADR-0004: Tenant DNS Publication&lt;/a>, 
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/architecture/decisions/0008-host-naming-site-codes/">ADR-0008: Host Naming and Site Codes&lt;/a>, 
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/architecture/decisions/0012-iot-platform-api/">ADR-0012: IoT Platform Services Through a Deevnet API and Terraform Provider&lt;/a> (its Open questions 2, 5 and 6), 
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/changes/2026/0005-wireless-ap-firmware-and-adoption/">CHG-0005&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;hr>
&lt;h2 id="context">
 Context
 &lt;a class="anchor" href="#context">#&lt;/a>
&lt;/h2>
&lt;h3 id="one-vm-per-function-is-where-things-were-heading">
 One VM per function is where things were heading
 &lt;a class="anchor" href="#one-vm-per-function-is-where-things-were-heading">#&lt;/a>
&lt;/h3>
&lt;p>The management hypervisor, &lt;code>dv02hyp001p01&lt;/code>, runs one VM per service today:&lt;/p></description></item><item><title>ADR-0014: Tenant State Durability</title><link>https://deevnet.github.io/deevnet-docs/docs/architecture/decisions/0014-tenant-state-durability/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://deevnet.github.io/deevnet-docs/docs/architecture/decisions/0014-tenant-state-durability/</guid><description>&lt;h1 id="adr-0014-tenant-state-is-kept-data-copied-away-from-what-it-restores">
 ADR-0014: Tenant State Is Kept Data, Copied Away From What It Restores
 &lt;a class="anchor" href="#adr-0014-tenant-state-is-kept-data-copied-away-from-what-it-restores">#&lt;/a>
&lt;/h1>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>&lt;/th>
 &lt;th>&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>&lt;strong>Status&lt;/strong>&lt;/td>
 &lt;td>Proposed&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Date&lt;/strong>&lt;/td>
 &lt;td>2026-09-16&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Scope&lt;/strong>&lt;/td>
 &lt;td>How the tenant state store&amp;rsquo;s contents survive losing the host, disk or hypervisor they live on, and how that copy is kept apart from the platform API&amp;rsquo;s database, which the state restores&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Extends&lt;/strong>&lt;/td>
 &lt;td>
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/architecture/decisions/0007-terraform-state-custody/">ADR-0007: Terraform State Custody&lt;/a>, which offered the store and recorded its durability as &lt;em>&amp;ldquo;the weakest part of the decision&amp;rdquo;&lt;/em>; 
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/architecture/decisions/0013-management-services-domain-vms/">ADR-0013: Management-Hypervisor Services Run as Containers on Domain VMs&lt;/a>, whose §1 and §6 put the store and the API&amp;rsquo;s database in one VM&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Related&lt;/strong>&lt;/td>
 &lt;td>
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/architecture/decisions/0010-tenants-consume-platform-services/">ADR-0010: Tenants Consume Platform Services&lt;/a> §4, 
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/architecture/decisions/0012-iot-platform-api/">ADR-0012: IoT Platform Services Through a Deevnet API and Terraform Provider&lt;/a> §4 and §5, 
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/architecture/substrate/storage/">Substrate Storage&lt;/a>, 
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/architecture/limits/">Limits&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;hr>
&lt;h2 id="context">
 Context
 &lt;a class="anchor" href="#context">#&lt;/a>
&lt;/h2>
&lt;h3 id="adr-0007-sized-state-loss-as-a-rebuild">
 ADR-0007 sized state loss as a rebuild
 &lt;a class="anchor" href="#adr-0007-sized-state-loss-as-a-rebuild">#&lt;/a>
&lt;/h3>
&lt;p>When the store was offered, losing state was cheap, and ADR-0007 said exactly how cheap:&lt;/p></description></item><item><title>ADR-0015: Tenants Are Built Through the Deevnet API</title><link>https://deevnet.github.io/deevnet-docs/docs/architecture/decisions/0015-tenant-onboarding-through-api/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://deevnet.github.io/deevnet-docs/docs/architecture/decisions/0015-tenant-onboarding-through-api/</guid><description>&lt;h1 id="adr-0015-tenants-are-built-through-the-deevnet-api">
 ADR-0015: Tenants Are Built Through the Deevnet API
 &lt;a class="anchor" href="#adr-0015-tenants-are-built-through-the-deevnet-api">#&lt;/a>
&lt;/h1>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>&lt;/th>
 &lt;th>&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>&lt;strong>Status&lt;/strong>&lt;/td>
 &lt;td>Proposed&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Date&lt;/strong>&lt;/td>
 &lt;td>2026-09-17&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Revised&lt;/strong>&lt;/td>
 &lt;td>2026-09-17, before review. First written as onboarding only; widened so that everything that builds a tenant (its network, workloads and DNS records) is behind the API and tenants hold no substrate credential (§11–§14). Admission by enrollment token (§10). Secrets handling moved to 
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/architecture/decisions/0016-substrate-secrets-openbao/">ADR-0016&lt;/a>.&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Scope&lt;/strong>&lt;/td>
 &lt;td>Who allocates a tenant&amp;rsquo;s index, who builds a tenant&amp;rsquo;s network, workloads and names, what a tenant holds, and where the record of tenants lives&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Extends&lt;/strong>&lt;/td>
 &lt;td>
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/architecture/decisions/0012-iot-platform-api/">ADR-0012: IoT Platform Services Through a Deevnet API and Terraform Provider&lt;/a>, whose API and provider become the way every tenant is created, not only the way it registers devices&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Supersedes, in part&lt;/strong>&lt;/td>
 &lt;td>
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/architecture/decisions/0002-tenant-fabric-numbering/">ADR-0002: Tenant Fabric Numbering&lt;/a>, where it says allocation is recorded in &lt;code>TENANTS.md&lt;/code> (the numbering itself stands); 
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/architecture/decisions/0006-tenant-code-boundary/">ADR-0006: Tenant Code Boundary&lt;/a> §1 (the module consumed by tag), §2 (the attachment rendered into the repository) and §3 (the reference implementation that cannot be applied). A tenant still lives in its own repository.&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Related&lt;/strong>&lt;/td>
 &lt;td>
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/architecture/decisions/0003-tenant-egress-single-member-fabric/">ADR-0003: Tenant Egress on a Single-Member Fabric&lt;/a>, 
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/architecture/decisions/0004-tenant-dns-publication/">ADR-0004: Tenant DNS Publication&lt;/a>, 
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/architecture/decisions/0005-tenant-zone-apex-ownership/">ADR-0005: Tenant Zone Apex Ownership&lt;/a>, 
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/architecture/decisions/0007-terraform-state-custody/">ADR-0007: Terraform State Custody&lt;/a>, 
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/architecture/decisions/0010-tenants-consume-platform-services/">ADR-0010: Tenants Consume Platform Services&lt;/a>, 
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/architecture/decisions/0014-tenant-state-durability/">ADR-0014: Tenant State Durability&lt;/a>, 
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/architecture/decisions/0016-substrate-secrets-openbao/">ADR-0016: Substrate Secrets in OpenBao&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;hr>
&lt;h2 id="context">
 Context
 &lt;a class="anchor" href="#context">#&lt;/a>
&lt;/h2>
&lt;h3 id="onboarding-today-is-a-substrate-commit-and-five-automation-runs">
 Onboarding today is a substrate commit and five automation runs
 &lt;a class="anchor" href="#onboarding-today-is-a-substrate-commit-and-five-automation-runs">#&lt;/a>
&lt;/h3>
&lt;p>A tenant is created in two halves. The substrate half runs once:&lt;/p></description></item><item><title>ADR-0016: Substrate Secrets in OpenBao</title><link>https://deevnet.github.io/deevnet-docs/docs/architecture/decisions/0016-substrate-secrets-openbao/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://deevnet.github.io/deevnet-docs/docs/architecture/decisions/0016-substrate-secrets-openbao/</guid><description>&lt;h1 id="adr-0016-the-substrate-keeps-its-runtime-secrets-in-openbao">
 ADR-0016: The Substrate Keeps Its Runtime Secrets in OpenBao
 &lt;a class="anchor" href="#adr-0016-the-substrate-keeps-its-runtime-secrets-in-openbao">#&lt;/a>
&lt;/h1>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>&lt;/th>
 &lt;th>&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>&lt;strong>Status&lt;/strong>&lt;/td>
 &lt;td>Proposed&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Date&lt;/strong>&lt;/td>
 &lt;td>2026-09-17&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Scope&lt;/strong>&lt;/td>
 &lt;td>Where the credentials substrate services use at runtime are kept, how tenant secrets are protected at rest and in transit, and where the internal certificate authority lives&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Extends&lt;/strong>&lt;/td>
 &lt;td>
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/architecture/decisions/0015-tenant-onboarding-through-api/">ADR-0015: Tenants Are Built Through the Deevnet API&lt;/a>, whose API holds credentials for PowerDNS, the core router, the state store and the tenant hypervisor, and stores tenant secrets&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Related&lt;/strong>&lt;/td>
 &lt;td>
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/architecture/decisions/0012-iot-platform-api/">ADR-0012: IoT Platform Services Through a Deevnet API and Terraform Provider&lt;/a> §9 (credential delivery), 
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/architecture/decisions/0013-management-services-domain-vms/">ADR-0013: Management-Hypervisor Services Run as Containers on Domain VMs&lt;/a>, 
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/architecture/decisions/0014-tenant-state-durability/">ADR-0014: Tenant State Durability&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;hr>
&lt;h2 id="context">
 Context
 &lt;a class="anchor" href="#context">#&lt;/a>
&lt;/h2>
&lt;h3 id="how-the-apis-credentials-are-handled-in-adr-0015s-first-slice">
 How the API&amp;rsquo;s credentials are handled in ADR-0015&amp;rsquo;s first slice
 &lt;a class="anchor" href="#how-the-apis-credentials-are-handled-in-adr-0015s-first-slice">#&lt;/a>
&lt;/h3>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>Credential&lt;/th>
 &lt;th>Kept in&lt;/th>
 &lt;th>Reaches the API as&lt;/th>
 &lt;th>Can do&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>Operator token, database password&lt;/td>
 &lt;td>inventory vault&lt;/td>
 &lt;td>a root-only env file, then container environment&lt;/td>
 &lt;td>the whole API; its database&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>PowerDNS HTTP API key&lt;/td>
 &lt;td>inventory vault; also in &lt;code>pdns.conf&lt;/code> on the DNS host&lt;/td>
 &lt;td>the same env file&lt;/td>
 &lt;td>every zone and key on the server&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Core router API key&lt;/td>
 &lt;td>the router automation user&amp;rsquo;s vault entry&lt;/td>
 &lt;td>the same env file&lt;/td>
 &lt;td>everything that user may do on the router&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>State-store admin&lt;/td>
 &lt;td>inventory vault&lt;/td>
 &lt;td>the same env file&lt;/td>
 &lt;td>user and policy administration&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Proxmox token&lt;/td>
 &lt;td>inventory vault&lt;/td>
 &lt;td>the same env file&lt;/td>
 &lt;td>what ADR-0015 grants it on the tenant hypervisor&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>And for what is handed to tenants:&lt;/p></description></item><item><title>ADR-0017: How Tenant Code Reaches a Tenant Workload</title><link>https://deevnet.github.io/deevnet-docs/docs/architecture/decisions/0017-tenant-code-delivery/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://deevnet.github.io/deevnet-docs/docs/architecture/decisions/0017-tenant-code-delivery/</guid><description>&lt;h1 id="adr-0017-how-tenant-code-reaches-a-tenant-workload">
 ADR-0017: How Tenant Code Reaches a Tenant Workload
 &lt;a class="anchor" href="#adr-0017-how-tenant-code-reaches-a-tenant-workload">#&lt;/a>
&lt;/h1>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>&lt;/th>
 &lt;th>&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>&lt;strong>Status&lt;/strong>&lt;/td>
 &lt;td>Proposed&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Date&lt;/strong>&lt;/td>
 &lt;td>2026-09-18&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Revised&lt;/strong>&lt;/td>
 &lt;td>2026-09-18, twice, before review. First written as a single choice between delivery mechanisms, with tenant-authored cloud-init user-data recommended; that draft argued the wrong layer. Rewritten to separate the &lt;strong>tenant-facing contract&lt;/strong> (§1, settled) from the &lt;strong>substrate-side mechanism&lt;/strong> (§2, open). Then revised again once both halves of the leading mechanism were tested rather than assumed, adding the measured SMBIOS limit and &lt;strong>§3, the fetch rule that keeps ADR-0012 provisioning-only&lt;/strong>.&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Scope&lt;/strong>&lt;/td>
 &lt;td>How a tenant&amp;rsquo;s own application code and configuration arrive on a tenant workload, and how they are kept current — not what the code is, and not how the workload itself is built&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Extends&lt;/strong>&lt;/td>
 &lt;td>
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/architecture/decisions/0010-tenants-consume-platform-services/">ADR-0010: Tenants Consume Platform Services&lt;/a>, which says tenants own their code but does not say how it is delivered; 
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/architecture/decisions/0015-tenant-onboarding-through-api/">ADR-0015: Tenants Are Built Through the Deevnet API&lt;/a>, which builds the empty workload this decision fills&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Related&lt;/strong>&lt;/td>
 &lt;td>
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/architecture/decisions/0001-tenant-network-fabric/">ADR-0001: Tenant Network Fabric&lt;/a>, 
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/architecture/decisions/0003-tenant-egress-single-member-fabric/">ADR-0003: Tenant Egress on a Single-Member Fabric&lt;/a>, 
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/architecture/decisions/0011-edge-devices-application-owned/">ADR-0011: Edge Devices Are Application-Owned&lt;/a>, 
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/architecture/decisions/0012-iot-platform-api/">ADR-0012: IoT Platform Services Through a Deevnet API and Terraform Provider&lt;/a>, 
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/architecture/decisions/0016-substrate-secrets-openbao/">ADR-0016: Substrate Secrets in OpenBao&lt;/a>, 
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/architecture/decisions/0018-operator-access-to-tenants/">ADR-0018: Operator Access to Tenant Workloads&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;hr>
&lt;h2 id="context">
 Context
 &lt;a class="anchor" href="#context">#&lt;/a>
&lt;/h2>
&lt;h3 id="the-substrate-can-build-a-workload-but-cannot-fill-one">
 The substrate can build a workload but cannot fill one
 &lt;a class="anchor" href="#the-substrate-can-build-a-workload-but-cannot-fill-one">#&lt;/a>
&lt;/h3>
&lt;p>
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/architecture/decisions/0015-tenant-onboarding-through-api/">ADR-0015&lt;/a> made tenant building
complete: a tenant declares &lt;code>deevnet_workload&lt;/code> and gets a running Fedora VM with an address, a
name, DNS and egress. What arrives is an &lt;strong>empty machine&lt;/strong>. Nothing in the substrate puts an
application on it, and nothing says how a tenant should.&lt;/p></description></item><item><title>ADR-0018: Operator Access to Tenant Workloads</title><link>https://deevnet.github.io/deevnet-docs/docs/architecture/decisions/0018-operator-access-to-tenants/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://deevnet.github.io/deevnet-docs/docs/architecture/decisions/0018-operator-access-to-tenants/</guid><description>&lt;h1 id="adr-0018-operator-access-to-tenant-workloads">
 ADR-0018: Operator Access to Tenant Workloads
 &lt;a class="anchor" href="#adr-0018-operator-access-to-tenant-workloads">#&lt;/a>
&lt;/h1>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>&lt;/th>
 &lt;th>&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>&lt;strong>Status&lt;/strong>&lt;/td>
 &lt;td>Proposed&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Date&lt;/strong>&lt;/td>
 &lt;td>2026-09-18&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Scope&lt;/strong>&lt;/td>
 &lt;td>Whether the substrate&amp;rsquo;s operator networks may reach tenant workloads, and what that does to the &amp;ldquo;no inbound path&amp;rdquo; property other records rely on&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Supersedes, in part&lt;/strong>&lt;/td>
 &lt;td>
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/architecture/decisions/0001-tenant-network-fabric/">ADR-0001: Tenant Network Fabric&lt;/a> and 
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/architecture/decisions/0002-tenant-fabric-numbering/">ADR-0002: Tenant Fabric Numbering&lt;/a>, where each says the core router &lt;strong>never learns tenant address space&lt;/strong>. It now learns one aggregate route. Everything else in both records stands, including SNAT at the exit node and per-tenant isolation inside the fabric.&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Related&lt;/strong>&lt;/td>
 &lt;td>
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/architecture/decisions/0003-tenant-egress-single-member-fabric/">ADR-0003: Tenant Egress on a Single-Member Fabric&lt;/a>, 
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/architecture/decisions/0010-tenants-consume-platform-services/">ADR-0010: Tenants Consume Platform Services&lt;/a>, 
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/architecture/decisions/0011-edge-devices-application-owned/">ADR-0011: Edge Devices Are Application-Owned&lt;/a>, 
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/architecture/decisions/0012-iot-platform-api/">ADR-0012: IoT Platform Services Through a Deevnet API and Terraform Provider&lt;/a>, 
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/architecture/decisions/0017-tenant-code-delivery/">ADR-0017: How Tenant Code Reaches a Tenant Workload&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;hr>
&lt;h2 id="context">
 Context
 &lt;a class="anchor" href="#context">#&lt;/a>
&lt;/h2>
&lt;h3 id="the-property-and-who-relies-on-it">
 The property, and who relies on it
 &lt;a class="anchor" href="#the-property-and-who-relies-on-it">#&lt;/a>
&lt;/h3>
&lt;p>Six records state some form of &amp;ldquo;a tenant has no inbound path&amp;rdquo;. They do not all mean the same thing,
and the difference matters:&lt;/p></description></item></channel></rss>