<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>2026 on Deevnet Infrastructure Platform</title><link>https://deevnet.github.io/deevnet-docs/docs/changes/2026/</link><description>Recent content in 2026 on Deevnet Infrastructure Platform</description><generator>Hugo</generator><language>en-us</language><atom:link href="https://deevnet.github.io/deevnet-docs/docs/changes/2026/index.xml" rel="self" type="application/rss+xml"/><item><title>CHG-0002: Authority Transition Rework</title><link>https://deevnet.github.io/deevnet-docs/docs/changes/2026/0002-authority-transition-rework/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://deevnet.github.io/deevnet-docs/docs/changes/2026/0002-authority-transition-rework/</guid><description>&lt;h1 id="chg-0002-authority-transition-rework">
 CHG-0002: Authority Transition Rework
 &lt;a class="anchor" href="#chg-0002-authority-transition-rework">#&lt;/a>
&lt;/h1>
&lt;blockquote class="book-hint info">
 
**Retrospective change record.** This was rebuilt from the gap analysis written at the time,
which is kept below as captured, and from the commits that delivered the fixes. The analysis was
first published in the runbook as "Authority Transition Gap Analysis".

Host names follow ADR-0008. At the time the builder was `provisioner-ph01`, the sites were
`dvntm` and `dvnt`, and the site zones were `dvntm.deevnet.net` and `dvnt.deevnet.net`.

&lt;/blockquote>

&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>Date&lt;/strong>&lt;/td>
 &lt;td>2026-03-26&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Change type&lt;/strong>&lt;/td>
 &lt;td>Configuration&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Classification&lt;/strong>&lt;/td>
 &lt;td>Structural — playbook, role and inventory changes&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Status&lt;/strong>&lt;/td>
 &lt;td>Complete. Analysed and fixed on 2026-03-26.&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Site&lt;/strong>&lt;/td>
 &lt;td>mobile, and the builder&amp;rsquo;s multi-site design&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Systems&lt;/strong>&lt;/td>
 &lt;td>Builder &lt;code>dv00bld001p01&lt;/code>: the &lt;code>bootstrap&lt;/code> role and &lt;code>bootstrap-authoritative.yml&lt;/code> / &lt;code>core-authoritative.yml&lt;/code> in &lt;code>ansible-collection-deevnet.builder&lt;/code>; &lt;code>disable-&lt;/code> / &lt;code>enable-opnsense-services.yml&lt;/code> in &lt;code>ansible-collection-deevnet.net&lt;/code>; &lt;code>group_vars/bootstrap_nodes.yml&lt;/code>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Automation&lt;/strong>&lt;/td>
 &lt;td>Builder &lt;code>f5d38d6&lt;/code>, net &lt;code>d37a95f&lt;/code>, inventory &lt;code>9600744&lt;/code>, docs &lt;code>9e0b967&lt;/code>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Risk&lt;/strong>&lt;/td>
 &lt;td>Low to the running site. Nothing changes until an authority transition is run, and then the builder&amp;rsquo;s own IP swap is the risky step.&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Related changes&lt;/strong>&lt;/td>
 &lt;td>
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/changes/2026/0001-flat-network-to-vlans/">CHG-0001: Flat Network → VLANs&lt;/a>, which left these playbooks non-functional&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Related incidents&lt;/strong>&lt;/td>
 &lt;td>None&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Related runbooks&lt;/strong>&lt;/td>
 &lt;td>
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/runbook/building-recovery/authority-transition/">Authority Transition&lt;/a>; 
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/runbook/building-recovery/build-sequence/">Configure PXE&lt;/a> (&lt;code>make bootstrap-auth&lt;/code>); 
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/runbook/building-recovery/build-network/">Build Network&lt;/a> (&lt;code>make core-auth&lt;/code>)&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;hr>
&lt;h2 id="summary">
 Summary
 &lt;a class="anchor" href="#summary">#&lt;/a>
&lt;/h2>
&lt;p>The &lt;strong>authority transition&lt;/strong> is how the builder takes over DNS, DHCP and the gateway from the
core router to bootstrap a site (&lt;code>make bootstrap-auth&lt;/code>), and hands them back afterwards
(&lt;code>make core-auth&lt;/code>). The 
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/changes/2026/0001-flat-network-to-vlans/">VLAN migration&lt;/a>
moved the site onto the segmented 10-space, and nothing in it touched this procedure.&lt;/p></description></item><item><title>CHG-0003: Host Rename (ADR-0008)</title><link>https://deevnet.github.io/deevnet-docs/docs/changes/2026/0003-host-rename/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://deevnet.github.io/deevnet-docs/docs/changes/2026/0003-host-rename/</guid><description>&lt;h1 id="chg-0003-host-rename-adr-0008">
 CHG-0003: Host Rename (ADR-0008)
 &lt;a class="anchor" href="#chg-0003-host-rename-adr-0008">#&lt;/a>
&lt;/h1>
&lt;blockquote class="book-hint info">
 
**Retrospective change record.** This was rebuilt from the runbook page that tracked the rename
as it ran (marked done on 2026-09-08), and from the commits and pull requests across the seven
repos it touched. Times are local (UTC−4), from commit timestamps.

&lt;/blockquote>

&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>Date&lt;/strong>&lt;/td>
 &lt;td>2026-09-05&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Change type&lt;/strong>&lt;/td>
 &lt;td>Migration&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Classification&lt;/strong>&lt;/td>
 &lt;td>Disruptive&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Status&lt;/strong>&lt;/td>
 &lt;td>Complete. Executed 2026-09-05, 08:41–13:55; recorded done 2026-09-08. Four follow-ups open.&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Site&lt;/strong>&lt;/td>
 &lt;td>mobile; home received its site identity only, having no hosts&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Systems&lt;/strong>&lt;/td>
 &lt;td>Every host in the mobile inventory; DNS and DHCP on &lt;code>dv02cor002p01&lt;/code>; both Proxmox nodes; the site inventories and every repo that names a host, site or zone&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Automation&lt;/strong>&lt;/td>
 &lt;td>Pull requests across &lt;code>deevnet-docs&lt;/code>, &lt;code>ansible-inventory-deevnet&lt;/code>, the three collections, &lt;code>deevnet-image-factory&lt;/code>, &lt;code>deevnet-tenant-factory&lt;/code> and &lt;code>deevnet-tenant-tdemo&lt;/code> — see 
 &lt;a href="#procedure">Procedure&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Risk&lt;/strong>&lt;/td>
 &lt;td>High. The first live change was DNS and DHCP (phase 8), and a Proxmox node name has no supported rename (phase 13).&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Related changes&lt;/strong>&lt;/td>
 &lt;td>None&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Related incidents&lt;/strong>&lt;/td>
 &lt;td>None&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Related runbooks&lt;/strong>&lt;/td>
 &lt;td>
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/runbook/lifecycle/host-rename/">Renaming Hosts&lt;/a>; 
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/runbook/lifecycle/host-rename/pve-node-rename/">Rename a Proxmox Node&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;hr>
&lt;h2 id="summary">
 Summary
 &lt;a class="anchor" href="#summary">#&lt;/a>
&lt;/h2>
&lt;p>The migration that brought the estate onto the naming scheme in

 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/architecture/decisions/0008-host-naming-site-codes/">ADR-0008&lt;/a>: fixed-width hostnames
(&lt;code>dv02hyp001p01&lt;/code>), site codes, and the &lt;code>home&lt;/code> / &lt;code>mobile&lt;/code> DNS zones. The site inventories were
renamed with it, from &lt;code>dvnt/&lt;/code> and &lt;code>dvntm/&lt;/code> to &lt;code>home/&lt;/code> and &lt;code>mobile/&lt;/code>. The ADR was proposed on
2026-09-04 and accepted as the first step of the change.&lt;/p></description></item><item><title>CHG-0004: Omada Controller Upgrade</title><link>https://deevnet.github.io/deevnet-docs/docs/changes/2026/0004-omada-controller-upgrade/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://deevnet.github.io/deevnet-docs/docs/changes/2026/0004-omada-controller-upgrade/</guid><description>&lt;h1 id="chg-0004-omada-controller-upgrade">
 CHG-0004: Omada Controller Upgrade
 &lt;a class="anchor" href="#chg-0004-omada-controller-upgrade">#&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>Date&lt;/strong>&lt;/td>
 &lt;td>2026-09-10&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Change type&lt;/strong>&lt;/td>
 &lt;td>Upgrade&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Classification&lt;/strong>&lt;/td>
 &lt;td>Structural — a controller outage, but nothing on site depended on the controller&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Status&lt;/strong>&lt;/td>
 &lt;td>&lt;strong>Complete&lt;/strong> 2026-09-10. Re-scoped 2026-09-11: see 
 &lt;a href="#scope-change">Scope change&lt;/a>.&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Window&lt;/strong>&lt;/td>
 &lt;td>2026-09-10, 05:16–05:30 local&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Site&lt;/strong>&lt;/td>
 &lt;td>mobile&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Systems&lt;/strong>&lt;/td>
 &lt;td>Omada controller on &lt;code>dv00bld001p01&lt;/code>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Automation&lt;/strong>&lt;/td>
 &lt;td>Controller pinned by inventory #24 and builder #13; runbook in docs #30&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Risk&lt;/strong>&lt;/td>
 &lt;td>A newer controller&amp;rsquo;s database cannot be opened by an older one&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Related changes&lt;/strong>&lt;/td>
 &lt;td>
 &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) and 
 &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), both split out of this record&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Related incidents&lt;/strong>&lt;/td>
 &lt;td>None&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Related runbooks&lt;/strong>&lt;/td>
 &lt;td>
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/runbook/lifecycle/omada-controller-upgrade/">Omada Controller Upgrade&lt;/a>; 
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/runbook/recovery/omada-controller-recovery/">Omada Controller Recovery&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;hr>
&lt;h2 id="summary">
 Summary
 &lt;a class="anchor" href="#summary">#&lt;/a>
&lt;/h2>
&lt;p>The Omada controller ran 6.1. This change upgraded it in place to 6.3.0.45, the current
release, and staged 6.2.14.11 as a rehearsed fallback. The aim was to bring the controller current
before it is used to manage the site&amp;rsquo;s Omada devices. The switch&amp;rsquo;s current firmware recommends
controller 6.2.0.&lt;/p></description></item><item><title>CHG-0005: Wireless AP Firmware and Omada Adoption</title><link>https://deevnet.github.io/deevnet-docs/docs/changes/2026/0005-wireless-ap-firmware-and-adoption/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://deevnet.github.io/deevnet-docs/docs/changes/2026/0005-wireless-ap-firmware-and-adoption/</guid><description>&lt;h1 id="chg-0005-wireless-ap-firmware-and-omada-adoption">
 CHG-0005: Wireless AP Firmware and Omada Adoption
 &lt;a class="anchor" href="#chg-0005-wireless-ap-firmware-and-omada-adoption">#&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>Date&lt;/strong>&lt;/td>
 &lt;td>2026-09-15&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Change type&lt;/strong>&lt;/td>
 &lt;td>Migration — the AP moves from standalone to controller-managed&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Classification&lt;/strong>&lt;/td>
 &lt;td>Disruptive — wireless is down during each firmware hop and during adoption, and one hop cannot be undone&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Status&lt;/strong>&lt;/td>
 &lt;td>&lt;strong>Complete, 2026-09-15.&lt;/strong> The AP runs 1.3.11, is adopted and Connected, and serves the three controller-provisioned SSIDs; &lt;code>DVNTM&lt;/code> was verified on a client landing on 10.20.10.x. PPSK with per-key VLAN binding was &lt;strong>proven on the AP&lt;/strong> (phase 6) and then torn down, leaving &lt;code>DVNTM-IOT&lt;/code> for a follow-up that provisions per-device keys from inventory.&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Window&lt;/strong>&lt;/td>
 &lt;td>2026-09-15, one operator window. Operator on site at the AP; the AP was reached and adopted through the builder on VLAN 99, so no laptop on &lt;code>gi1/0/2&lt;/code> was needed.&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Site&lt;/strong>&lt;/td>
 &lt;td>mobile&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Systems&lt;/strong>&lt;/td>
 &lt;td>AP &lt;code>dv02wap001p01&lt;/code> (EAP650-Outdoor v1); the Omada controller, now a container in the network management VM &lt;code>dv02nms001v01&lt;/code> on &lt;code>dv02hyp001p01&lt;/code> (moved off &lt;code>dv00bld001p01&lt;/code>) (
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/architecture/decisions/0013-management-services-domain-vms/">ADR-0013&lt;/a>). &lt;strong>Not&lt;/strong> the access switch.&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Automation&lt;/strong>&lt;/td>
 &lt;td>Firmware mirrored by inventory #22. Networks, SSIDs and AP settings by &lt;code>ansible-collection-deevnet.net&lt;/code> &lt;code>playbooks/omada-wireless.yml&lt;/code>, through the documented Open API (
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/architecture/decisions/0009-network-device-config-ownership/">ADR-0009&lt;/a>).&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Risk&lt;/strong>&lt;/td>
 &lt;td>High. The AP&amp;rsquo;s 1.3.3 hop cannot be undone, and adoption replaces the AP&amp;rsquo;s own configuration with the controller&amp;rsquo;s.&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Related changes&lt;/strong>&lt;/td>
 &lt;td>
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/changes/2026/0001-flat-network-to-vlans/">CHG-0001&lt;/a> — the hand-set SSIDs this retires; 
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/changes/2026/0004-omada-controller-upgrade/">CHG-0004&lt;/a> — the controller upgrade this was split from; 
 &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, deliberately separate&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Related incidents&lt;/strong>&lt;/td>
 &lt;td>
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/incidents/2026/0002-controller-vm-network-hang/">INC-0002&lt;/a> — the controller VM was silent at the start of this window; Phase 0 recovered it before the change could run&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Related runbooks&lt;/strong>&lt;/td>
 &lt;td>
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/runbook/recovery/console-recovery/wireless-ap/">Wireless AP&lt;/a> (the reset-and-recover path); 
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/runbook/recovery/omada-controller-recovery/">Omada Controller Recovery&lt;/a>; 
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/runbook/network/important-urls/">Important URLs&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;hr>
&lt;h2 id="summary">
 Summary
 &lt;a class="anchor" href="#summary">#&lt;/a>
&lt;/h2>
&lt;p>The AP ran firmware 1.0.4, from April 2023. Omada could not push VLAN-tagged SSIDs to it, so

 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/changes/2026/0001-flat-network-to-vlans/">CHG-0001&lt;/a> left the four SSIDs configured by
hand in the AP&amp;rsquo;s own web UI — the one piece of the site&amp;rsquo;s network configuration that lived
nowhere but on the device.&lt;/p></description></item><item><title>CHG-0006: Access Switch Firmware Upgrade</title><link>https://deevnet.github.io/deevnet-docs/docs/changes/2026/0006-access-switch-firmware-upgrade/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://deevnet.github.io/deevnet-docs/docs/changes/2026/0006-access-switch-firmware-upgrade/</guid><description>&lt;h1 id="chg-0006-access-switch-firmware-upgrade">
 CHG-0006: Access Switch Firmware Upgrade
 &lt;a class="anchor" href="#chg-0006-access-switch-firmware-upgrade">#&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>Date&lt;/strong>&lt;/td>
 &lt;td>2026-09-16&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Change type&lt;/strong>&lt;/td>
 &lt;td>Upgrade&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Classification&lt;/strong>&lt;/td>
 &lt;td>Disruptive — the reboot drops every wired path on site&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Status&lt;/strong>&lt;/td>
 &lt;td>&lt;strong>Complete, 2026-09-16.&lt;/strong> The switch runs 1.20.24 from &lt;code>image1.bin&lt;/code>, with 1.20.1 kept in &lt;code>image2.bin&lt;/code> as the rollback. The configuration came through unchanged and matches inventory, and Ansible connects. STP is still disabled. LLDP came up enabled under the new default and was kept on deliberately; it is now declared in inventory.&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Window&lt;/strong>&lt;/td>
 &lt;td>2026-09-16, one operator window. The operator was on site and reached the builder through the travel router. The switch was down from 08:15:32 to 08:17:11 EDT, about 100 seconds.&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Site&lt;/strong>&lt;/td>
 &lt;td>mobile&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Systems&lt;/strong>&lt;/td>
 &lt;td>Access switch &lt;code>dv02acc001p01&lt;/code> (SG2218, hardware 1.20)&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Automation&lt;/strong>&lt;/td>
 &lt;td>Firmware mirrored by inventory #23; procedure in docs #29 and #70. LLDP declared by net #21 (&lt;code>switch_lldp&lt;/code>) and inventory #33.&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Risk&lt;/strong>&lt;/td>
 &lt;td>High. The switch reboot takes the builder, the controller and Ansible offline with everything else.&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Related changes&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> — this was its phase 2 until 2026-09-11&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Related incidents&lt;/strong>&lt;/td>
 &lt;td>None&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Related runbooks&lt;/strong>&lt;/td>
 &lt;td>
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/runbook/recovery/console-recovery/access-switch/#firmware-upgrade">Access Switch → Firmware upgrade&lt;/a>; 
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/runbook/network/operator-access/">Operator Access&lt;/a>; 
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/runbook/network/important-urls/">Important URLs&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;hr>
&lt;h2 id="summary">
 Summary
 &lt;a class="anchor" href="#summary">#&lt;/a>
&lt;/h2>
&lt;p>The access switch ran firmware 1.20.1, from January 2024. Current for its hardware is 1.20.24,
from May 2026: one hop, with no minimum prior version and nothing irreversible. This change is
the firmware only. The switch stays standalone, configured by &lt;code>switch_vlans&lt;/code>. Adopting it into
the controller is a later change under

 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/architecture/decisions/0009-network-device-config-ownership/">ADR-0009&lt;/a>.&lt;/p></description></item><item><title>CHG-0007: Core Router Zone Policy, First Application</title><link>https://deevnet.github.io/deevnet-docs/docs/changes/2026/0007-core-router-zone-policy/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://deevnet.github.io/deevnet-docs/docs/changes/2026/0007-core-router-zone-policy/</guid><description>&lt;h1 id="chg-0007-core-router-zone-policy-first-application">
 CHG-0007: Core Router Zone Policy, First Application
 &lt;a class="anchor" href="#chg-0007-core-router-zone-policy-first-application">#&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>Date&lt;/strong>&lt;/td>
 &lt;td>Not yet scheduled&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Change type&lt;/strong>&lt;/td>
 &lt;td>Configuration&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Classification&lt;/strong>&lt;/td>
 &lt;td>Disruptive — it changes what every segment on site can reach, the operator&amp;rsquo;s own path included&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Status&lt;/strong>&lt;/td>
 &lt;td>&lt;strong>Planned&lt;/strong>, after the &lt;code>opnsense_firewall&lt;/code> fixes and the mobile reachability targets (see 
 &lt;a href="#prerequisites">Prerequisites&lt;/a>). Pre-change state read on 2026-09-14 (see 
 &lt;a href="#pre-change-state-read-2026-09-14">Pre-change state&lt;/a>). Allow-all removal decided on 2026-09-14: Option A (see 
 &lt;a href="#decision-removing-the-allow-all-rules">Decision&lt;/a>).&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Window&lt;/strong>&lt;/td>
 &lt;td>To be scheduled, with the operator at the rack and the router&amp;rsquo;s console connected&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Site&lt;/strong>&lt;/td>
 &lt;td>mobile&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Systems&lt;/strong>&lt;/td>
 &lt;td>Core router &lt;code>dv02cor002p01&lt;/code> (OPNsense 26.7.3); control host &lt;code>dv00bld001p01&lt;/code>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Automation&lt;/strong>&lt;/td>
 &lt;td>&lt;code>ansible-collection-deevnet.net&lt;/code> role &lt;code>opnsense_firewall&lt;/code>, run by &lt;code>playbooks/migration/07-opnsense-firewall.yml&lt;/code> (&lt;code>make migration-opnsense-firewall&lt;/code>) against &lt;code>ansible-inventory-deevnet/mobile&lt;/code>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Risk&lt;/strong>&lt;/td>
 &lt;td>High. The policy has never been applied as a whole, and the last unguarded run of this role took the site down.&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Related changes&lt;/strong>&lt;/td>
 &lt;td>
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/changes/2026/0001-flat-network-to-vlans/">CHG-0001&lt;/a> — the segmentation that declared this policy&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Related incidents&lt;/strong>&lt;/td>
 &lt;td>
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/incidents/2026/0001-firewall-policy-deletion/">INC-0001&lt;/a> — its open items are this change&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Related decisions&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&lt;/a> — attachment by trust class depends on this policy; its 
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/architecture/decisions/0011-edge-devices-application-owned/#validation-2026-09-14">Validation&lt;/a> is where the pre-change state was first read&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Related runbooks&lt;/strong>&lt;/td>
 &lt;td>
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/runbook/change-management/#validation-checklist">Change Management&lt;/a>; 
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/runbook/recovery/console-recovery/core-router/">Console Recovery → Core Router&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;hr>
&lt;h2 id="summary">
 Summary
 &lt;a class="anchor" href="#summary">#&lt;/a>
&lt;/h2>
&lt;p>&lt;code>mobile/group_vars/all/firewall.yml&lt;/code> declares a default-deny zone policy: 18 inter-zone allows and
internet egress for 8 zones. 
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/incidents/2026/0001-firewall-policy-deletion/">INC-0001&lt;/a>
records that this policy &lt;em>&amp;ldquo;has still never been applied&amp;rdquo;&lt;/em>. The router is running whatever a config
backup of unknown vintage put back.&lt;/p></description></item><item><title>CHG-0008: Management Domain VMs, First Build</title><link>https://deevnet.github.io/deevnet-docs/docs/changes/2026/0008-domain-vms-build-out/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://deevnet.github.io/deevnet-docs/docs/changes/2026/0008-domain-vms-build-out/</guid><description>&lt;h1 id="chg-0008-management-domain-vms-first-build">
 CHG-0008: Management Domain VMs, First Build
 &lt;a class="anchor" href="#chg-0008-management-domain-vms-first-build">#&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>Date&lt;/strong>&lt;/td>
 &lt;td>2026-09-15&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Change type&lt;/strong>&lt;/td>
 &lt;td>Deployment · Decommission&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Classification&lt;/strong>&lt;/td>
 &lt;td>Structural. It replaces every VM on the management hypervisor except the provisioners, and re-applies the access switch&amp;rsquo;s trunks.&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Status&lt;/strong>&lt;/td>
 &lt;td>&lt;strong>Complete&lt;/strong>, 2026-09-16. Done on 2026-09-15: Steps 1–2 and 5–6; Step 7 for &lt;code>dv02nms001v01&lt;/code> and &lt;code>dv02sob001v01&lt;/code>, both rebooted after their first-boot upgrade; Step 8 for the Omada controller on &lt;code>dv02nms001v01&lt;/code>, with its firewall ports corrected at 22:05Z. Step 9&amp;rsquo;s manual floor is done: the wizard, a local Owner, the automation account and the Open API client. Step 10 stopped the Builder&amp;rsquo;s controller at 23:14Z, and Step 3 carried VLAN 25 to the management hypervisor&amp;rsquo;s port at 23:28Z with the operator at the rack. Step 4 made the hv01 bridge VLAN-aware at 23:38Z, and Step 7 finished at 00:07Z with the four Platform and IoT Backend VMs built, verified and rebooted. Step 8 finished at 00:17Z with MinIO and the Deevnet API on &lt;code>dv02prv001v01&lt;/code>. Every step is done; what is left is the follow-ups below. Steps 3–4 wait for someone at the rack, and the Platform and IoT Backend VMs in Steps 7–8 wait on those.&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Window&lt;/strong>&lt;/td>
 &lt;td>Started 2026-09-15 about 04:10Z, vault decrypted for each working window. Steps 3 and 4 need hands at the hardware. The SG2218 has no console port, so recovery is a laptop on &lt;code>gi1/0/2&lt;/code> or the reset button; &lt;code>dv02hyp001p01&lt;/code> needs its monitor and keyboard.&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Site&lt;/strong>&lt;/td>
 &lt;td>mobile&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Systems&lt;/strong>&lt;/td>
 &lt;td>Management hypervisor &lt;code>dv02hyp001p01&lt;/code>; six new VMs: &lt;code>dv02nms001v01&lt;/code>, &lt;code>dv02sob001v01&lt;/code>, &lt;code>dv02prv001v01&lt;/code>, &lt;code>dv02idn001v01&lt;/code>, &lt;code>dv02tob001v01&lt;/code>, &lt;code>dv02msg001v01&lt;/code>; retired: &lt;code>dv02tdn001v01&lt;/code>, &lt;code>dv02tst001v01&lt;/code>, &lt;code>dv02mqt001v01&lt;/code>; core router &lt;code>dv02cor002p01&lt;/code> (Unbound, Kea); access switch &lt;code>dv02acc001p01&lt;/code>; control host &lt;code>dv00bld001p01&lt;/code>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Automation&lt;/strong>&lt;/td>
 &lt;td>&lt;code>ansible-collection-deevnet.mgmt&lt;/code> (&lt;code>podman_service&lt;/code>, &lt;code>powerdns&lt;/code>, &lt;code>minio&lt;/code>, &lt;code>deevnet_api&lt;/code>, &lt;code>omada_controller&lt;/code>, &lt;code>proxmox_vm&lt;/code>, &lt;code>vm_identity&lt;/code>); &lt;code>ansible-collection-deevnet.net&lt;/code> (&lt;code>dns.yml&lt;/code>, &lt;code>dhcp.yml&lt;/code>, &lt;code>switch-vlans.yml&lt;/code>, &lt;code>proxmox-node-network.yml&lt;/code>); &lt;code>ansible-collection-deevnet.builder&lt;/code> (&lt;code>artifacts&lt;/code>); the new 
 &lt;a href="https://github.com/deevnet/deevnet-provisioning-api">&lt;code>deevnet-provisioning-api&lt;/code>&lt;/a> repository; all against &lt;code>ansible-inventory-deevnet/mobile&lt;/code>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Risk&lt;/strong>&lt;/td>
 &lt;td>Medium. The step most likely to go wrong is the switch trunk re-apply, which rewrites every trunk on the switch, including the ports the control host and the management hypervisor sit behind.&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Related decisions&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&lt;/a> — the domain VMs this builds, and §6&amp;rsquo;s fold-in of tenant DNS and state, which this record carries out; 
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/architecture/decisions/0012-iot-platform-api/">ADR-0012&lt;/a> — the API whose shell is deployed; 
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/architecture/decisions/0009-network-device-config-ownership/">ADR-0009&lt;/a> — the controller&amp;rsquo;s manual floor&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Related changes&lt;/strong>&lt;/td>
 &lt;td>
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/changes/2026/0005-wireless-ap-firmware-and-adoption/">CHG-0005&lt;/a> — waits for the network management VM this builds; 
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/changes/2026/0007-core-router-zone-policy/">CHG-0007&lt;/a> — the zone policy these VMs are placed to survive&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Related incidents&lt;/strong>&lt;/td>
 &lt;td>
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/incidents/2026/0001-firewall-policy-deletion/">INC-0001&lt;/a> — why the router record prune is previewed and gated&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Related runbooks&lt;/strong>&lt;/td>
 &lt;td>
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/runbook/building-recovery/vm-identity/">VM Identity&lt;/a>; 
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/runbook/recovery/console-recovery/access-switch/">Console Recovery → Access Switch&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;hr>
&lt;h2 id="summary">
 Summary
 &lt;a class="anchor" href="#summary">#&lt;/a>
&lt;/h2>
&lt;p>
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/architecture/decisions/0013-management-services-domain-vms/">ADR-0013&lt;/a> groups the
management hypervisor&amp;rsquo;s services into domain VMs, each on exactly one segment, with every function
a container. Today the hypervisor still runs the earlier one-service VMs: tenant DNS
(&lt;code>dv02tdn001v01&lt;/code>), the tenant state store (&lt;code>dv02tst001v01&lt;/code>) and an MQTT broker that never
answered (&lt;code>dv02mqt001v01&lt;/code>). The Omada controller runs on the Builder.&lt;/p></description></item><item><title>CHG-0009: Access Switch Omada Adoption</title><link>https://deevnet.github.io/deevnet-docs/docs/changes/2026/0009-access-switch-adoption/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://deevnet.github.io/deevnet-docs/docs/changes/2026/0009-access-switch-adoption/</guid><description>&lt;h1 id="chg-0009-access-switch-omada-adoption">
 CHG-0009: Access Switch Omada Adoption
 &lt;a class="anchor" href="#chg-0009-access-switch-omada-adoption">#&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>Date&lt;/strong>&lt;/td>
 &lt;td>Not yet scheduled&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Change type&lt;/strong>&lt;/td>
 &lt;td>Migration — the switch moves from standalone to controller-managed&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Classification&lt;/strong>&lt;/td>
 &lt;td>Disruptive — adoption rewrites port VLANs, and the uplink is expected to drop until they are re-applied&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Status&lt;/strong>&lt;/td>
 &lt;td>&lt;strong>Planned, on hold since 2026-09-16.&lt;/strong> Deprioritised behind the Deevnet API and the first working tenant; it is not on that path. The research below settles the route, so the work resumes from here without repeating it.&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Window&lt;/strong>&lt;/td>
 &lt;td>To be scheduled, with the operator on site and connected through the travel router (
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/runbook/network/operator-access/">Operator Access&lt;/a>)&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Site&lt;/strong>&lt;/td>
 &lt;td>mobile&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Systems&lt;/strong>&lt;/td>
 &lt;td>Access switch &lt;code>dv02acc001p01&lt;/code> (SG2218 hardware 1.20, firmware 1.20.24); the Omada controller (6.3.0.45) in &lt;code>dv02nms001v01&lt;/code>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Automation&lt;/strong>&lt;/td>
 &lt;td>To be written: &lt;code>ansible-collection-deevnet.net&lt;/code> &lt;code>playbooks/omada-switch.yml&lt;/code>, modelled on &lt;code>playbooks/omada-wireless.yml&lt;/code>. &lt;code>switch_vlans&lt;/code> becomes break-glass once the switch declares &lt;code>switch_management: omada&lt;/code>.&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Risk&lt;/strong>&lt;/td>
 &lt;td>High. Every path to the controller crosses this switch; if adoption does not keep the management VLAN, the controller loses the switch mid-provision and the way back is a factory reset.&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Related changes&lt;/strong>&lt;/td>
 &lt;td>
 &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, adopted the same way; 
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/changes/2026/0006-access-switch-firmware-upgrade/">CHG-0006&lt;/a> — the firmware this relies on&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Related incidents&lt;/strong>&lt;/td>
 &lt;td>None&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Related runbooks&lt;/strong>&lt;/td>
 &lt;td>
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/runbook/recovery/console-recovery/access-switch/">Access Switch&lt;/a> (the reset path, and the rollback); 
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/runbook/network/operator-access/">Operator Access&lt;/a>; 
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/runbook/network/important-urls/">Important URLs&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;hr>
&lt;h2 id="summary">
 Summary
 &lt;a class="anchor" href="#summary">#&lt;/a>
&lt;/h2>
&lt;p>The access switch is standalone. Its configuration is declared in inventory and applied over its
CLI by &lt;code>switch_vlans&lt;/code>.

 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/architecture/decisions/0009-network-device-config-ownership/">ADR-0009&lt;/a> decides that the
controller applies that inventory through its documented Open API instead, as it already does for
the AP since CHG-0005. This change adopts the switch and moves its port configuration to the
controller.&lt;/p></description></item><item><title>CHG-0010: Deploy the Deevnet API and Cut Tenants Over</title><link>https://deevnet.github.io/deevnet-docs/docs/changes/2026/0010-tenant-api-cutover/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://deevnet.github.io/deevnet-docs/docs/changes/2026/0010-tenant-api-cutover/</guid><description>&lt;h1 id="chg-0010-deploy-the-deevnet-api-and-cut-tenants-over">
 CHG-0010: Deploy the Deevnet API and Cut Tenants Over
 &lt;a class="anchor" href="#chg-0010-deploy-the-deevnet-api-and-cut-tenants-over">#&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>Date&lt;/strong>&lt;/td>
 &lt;td>2026-09-17&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Change type&lt;/strong>&lt;/td>
 &lt;td>Build-out and migration — OpenBao and the tenant API are deployed, and tenants stop being built from inventory&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Classification&lt;/strong>&lt;/td>
 &lt;td>Disruptive in one step only: the tenant DNS server restarts when its HTTP API is turned on. Everything else adds services or changes objects nothing depends on yet.&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Status&lt;/strong>&lt;/td>
 &lt;td>&lt;strong>Complete.&lt;/strong> All eleven steps are done. OpenBao, the PowerDNS API, the API and the egress agent are deployed; &lt;strong>tdemo and eds are both live and built entirely through the API&lt;/strong>; and the inventory tenant registry and the role tasks that read it are gone. One working-tree edit awaits &lt;code>make vault&lt;/code>: the two now-unread tenant secret dicts.&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Window&lt;/strong>&lt;/td>
 &lt;td>No operator on site needed: every step is a control-node run or an API call. The one restart affects tenant name resolution for seconds, and no tenant is live.&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Site&lt;/strong>&lt;/td>
 &lt;td>mobile&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Systems&lt;/strong>&lt;/td>
 &lt;td>&lt;code>dv02idn001v01&lt;/code> (OpenBao, tenant DNS), &lt;code>dv02prv001v01&lt;/code> (the API, its database, the state store), &lt;code>dv02hyp002p02&lt;/code> (the tenant hypervisor and exit node), &lt;code>dv02cor002p01&lt;/code> (the resolver&amp;rsquo;s delegations)&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Automation&lt;/strong>&lt;/td>
 &lt;td>&lt;code>deevnet.mgmt&lt;/code> &lt;code>openbao&lt;/code>, &lt;code>powerdns&lt;/code>, &lt;code>minio&lt;/code>, &lt;code>deevnet_api&lt;/code>; &lt;code>deevnet.net&lt;/code> &lt;code>tenant_egress_agent&lt;/code>; &lt;code>deevnet-provisioning-api&lt;/code> &lt;strong>v0.2.4&lt;/strong> (v0.2.0 as planned, then four defects the run and the rebuild found); &lt;code>terraform-provider-deevnet&lt;/code> v0.1.0; the tenant repositories &lt;code>deevnet-tenant-tdemo&lt;/code> and &lt;code>eds&lt;/code>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Risk&lt;/strong>&lt;/td>
 &lt;td>Medium. OpenBao becomes a service everything else needs to start, and its seal key is the root of the whole arrangement. The API gains write access to tenant DNS, the resolver, the state store and the tenant hypervisor.&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Related decisions&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&lt;/a> — what the API builds and what a tenant holds; 
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/architecture/decisions/0016-substrate-secrets-openbao/">ADR-0016&lt;/a> — where the credentials live; 
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/architecture/decisions/0012-iot-platform-api/">ADR-0012&lt;/a> §5 and §9; 
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/architecture/decisions/0014-tenant-state-durability/">ADR-0014&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Related changes&lt;/strong>&lt;/td>
 &lt;td>
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/changes/2026/0008-domain-vms-build-out/">CHG-0008&lt;/a> — built the VMs this deploys into, and created eds&amp;rsquo;s zones, key and state credential; 
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/changes/2026/0007-core-router-zone-policy/">CHG-0007&lt;/a> — the zone policy this adds two rules to, still unapplied&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Related runbooks&lt;/strong>&lt;/td>
 &lt;td>
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/runbook/tenant-provisioning/">Provisioning a Tenant&lt;/a> — replaced by this change&amp;rsquo;s step 9&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;hr>
&lt;h2 id="summary">
 Summary
 &lt;a class="anchor" href="#summary">#&lt;/a>
&lt;/h2>
&lt;p>ADR-0015 moves everything about a tenant behind the Deevnet API, and ADR-0016 puts the credentials
that needs into OpenBao. This change deploys both and cuts the two tenants over.&lt;/p></description></item><item><title>CHG-0011: Tenant Workloads Get a Resolver</title><link>https://deevnet.github.io/deevnet-docs/docs/changes/2026/0011-tenant-workload-resolver/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://deevnet.github.io/deevnet-docs/docs/changes/2026/0011-tenant-workload-resolver/</guid><description>&lt;h1 id="chg-0011-tenant-workloads-get-a-resolver">
 CHG-0011: Tenant Workloads Get a Resolver
 &lt;a class="anchor" href="#chg-0011-tenant-workloads-get-a-resolver">#&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>Date&lt;/strong>&lt;/td>
 &lt;td>2026-09-17&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Change type&lt;/strong>&lt;/td>
 &lt;td>Configuration · Deployment&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Classification&lt;/strong>&lt;/td>
 &lt;td>Structural&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Status&lt;/strong>&lt;/td>
 &lt;td>&lt;strong>Complete.&lt;/strong> All three steps are done and verified. Step 3 was run as a full destroy-and-rebuild at the operator&amp;rsquo;s request, which proved the fix on the create path as well as the repair path.&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Window&lt;/strong>&lt;/td>
 &lt;td>Started 2026-09-17; Steps 1–2 ran 2026-09-17/18&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Site&lt;/strong>&lt;/td>
 &lt;td>mobile&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Systems&lt;/strong>&lt;/td>
 &lt;td>&lt;code>dv02prv001v01&lt;/code> (the Deevnet API); tenant workloads 2040 &lt;code>tdemo-app&lt;/code> and 2080 &lt;code>eds-services&lt;/code> on &lt;code>dv02hyp002p02&lt;/code>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Automation&lt;/strong>&lt;/td>
 &lt;td>&lt;code>deevnet.mgmt&lt;/code> &lt;code>playbooks/site.yml --limit deevnet_api&lt;/code>, against &lt;code>ansible-inventory-deevnet/mobile&lt;/code>; then &lt;code>terraform apply&lt;/code> in each tenant repo&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Risk&lt;/strong>&lt;/td>
 &lt;td>Medium — both tenant workloads are replaced, so anything on their disks is lost. Today both are empty.&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Related changes&lt;/strong>&lt;/td>
 &lt;td>
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/changes/2026/0010-tenant-api-cutover/">CHG-0010&lt;/a> introduced the defect&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Related incidents&lt;/strong>&lt;/td>
 &lt;td>None&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Related runbooks&lt;/strong>&lt;/td>
 &lt;td>
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/architecture/decisions/0004-tenant-dns-publication/">Tenant DNS&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;hr>
&lt;h2 id="summary">
 Summary
 &lt;a class="anchor" href="#summary">#&lt;/a>
&lt;/h2>
&lt;p>Every tenant workload the Deevnet API has ever built was handed an &lt;strong>authoritative&lt;/strong> DNS server
as its resolver. &lt;code>dv02idn001v01&lt;/code> (10.20.25.21) runs PowerDNS authoritative: it answers the tenant
zones it is master for and returns REFUSED for everything else. A workload pointed at it can
resolve its own tenant&amp;rsquo;s names and nothing else — not a public name, not a substrate name, not
even &lt;code>api.mobile.deevnet.net&lt;/code>, the Deevnet API the tenant is meant to talk to.&lt;/p></description></item><item><title>CHG-0012: Operator Access to Tenant Workloads</title><link>https://deevnet.github.io/deevnet-docs/docs/changes/2026/0012-operator-access-to-tenants/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://deevnet.github.io/deevnet-docs/docs/changes/2026/0012-operator-access-to-tenants/</guid><description>&lt;h1 id="chg-0012-operator-access-to-tenant-workloads">
 CHG-0012: Operator Access to Tenant Workloads
 &lt;a class="anchor" href="#chg-0012-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>Date&lt;/strong>&lt;/td>
 &lt;td>2026-09-18&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Change type&lt;/strong>&lt;/td>
 &lt;td>Configuration&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Classification&lt;/strong>&lt;/td>
 &lt;td>Structural&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Status&lt;/strong>&lt;/td>
 &lt;td>&lt;strong>Complete.&lt;/strong> The route is applied and verified from both operator zones.&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Window&lt;/strong>&lt;/td>
 &lt;td>2026-09-18&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Site&lt;/strong>&lt;/td>
 &lt;td>mobile&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Systems&lt;/strong>&lt;/td>
 &lt;td>&lt;code>dv02cor002p01&lt;/code> (core router, static route and zone policy); &lt;code>ansible-inventory-deevnet&lt;/code> firewall policy&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Automation&lt;/strong>&lt;/td>
 &lt;td>&lt;code>deevnet.net&lt;/code> role &lt;code>opnsense_routes&lt;/code>, run by &lt;code>playbooks/routes.yml&lt;/code> against &lt;code>ansible-inventory-deevnet/mobile&lt;/code>. The zone-policy rules are inventory, applied by &lt;code>opnsense_firewall&lt;/code> when 
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/changes/2026/0007-core-router-zone-policy/">CHG-0007&lt;/a> runs.&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Risk&lt;/strong>&lt;/td>
 &lt;td>Low — it adds reachability and removes none. The one thing most likely to go wrong is the route being written to the wrong gateway, which fails closed.&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Related changes&lt;/strong>&lt;/td>
 &lt;td>
 &lt;a href="https://deevnet.github.io/deevnet-docs/deevnet-docs/docs/changes/2026/0007-core-router-zone-policy/">CHG-0007&lt;/a>, which must not undo it&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Related incidents&lt;/strong>&lt;/td>
 &lt;td>None&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Related runbooks&lt;/strong>&lt;/td>
 &lt;td>None&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;hr>
&lt;h2 id="summary">
 Summary
 &lt;a class="anchor" href="#summary">#&lt;/a>
&lt;/h2>
&lt;p>A tenant workload cannot be reached from anywhere today. Building, checking or debugging one means
the hypervisor console, or &lt;code>ip vrf exec&lt;/code> from the exit node as root — the most privileged access the
substrate has, used for ordinary work.&lt;/p></description></item></channel></rss>