The fixture holds one value per dispatch input, distinct from its default, so
an input the retrigger drops shows up as a missing key. Adding the input
without adding it here made that check fail on its own absence.
Declared once and passed to the four chunks only; validation does not take it,
because a selection pin is checked against axes the row offers, not against
the run's own.
It was only pinnable per token, so there was no run-wide control and nothing
for the GitHub UI to show. Now a dropdown beside the tor one, and a run that
holds it says so in the title.
Reading a title back into its axes is the inverse of building one, and it kept
axes.py over the 500-line cap once the mesh axis landed. The names stay
importable from axes so no consumer moves.
auto rotates, enforced meshes every swarm row, disabled meshes none. No
exclusive: every swarm row can take the mesh, so there is nothing to drop.
A run that holds the axis outranks a per-token pin, because an operator who
asked for a whole sweep on one side means it.
Six commits, all Docker image version bumps for web-app-erpnext,
web-app-gitlab and web-app-matomo. No conflicts.
The MCP audit report needed no regeneration this time: the lint gate that
caught the stale baserow row twice is green as merged.
The controller is now a mesh member rather than staying off it behind a
gateway hop, and the two-phase seam falls between the two deploy passes the
round already had, so the second runs over the tunnel at no extra CI cost.
The gate and the axis are separated: whether a swarm deploy carries the mesh
is decided per run, and when it does the mesh is mandatory. Swarm and the mesh
are independent, so an off run omits the role entirely and proves swarm still
works with no mesh logic in the path.
The MTU is measured rather than declared. Criteria follow: three new ones for
the transport, two for the axis arms, one for the tooling, and the MTU one is
unchecked again because what it claimed has changed.
The round already had two passes. The first brings the mesh up over the
container connection; the inventory is then switched to the mesh addresses and
the second pass runs over the tunnel, so no extra round and no extra CI time.
A full deploy of every role over the mesh is a stronger proof than a narrow
bootstrap round would have been.
It runs the role like any member, but it drives the deploy rather than being
deployed to, so it keeps a local connection while the nodes keep the container
one.
Named rather than resolved from a group: the controller is not a swarm member
and has no role group, and inventing one would put a non-role name into
group_names where every service and placement lookup would special-case it.
Pins the two failure modes the design turns on: a host with no mesh address is
left reachable rather than stranded, and an address is only read from the host
that owns it, because the swarm reset mirrors one node's host_vars over every
other.
The first pass of a deploy reaches the hosts however it can, because no tunnel
exists yet and that pass is what creates one. Every pass after it connects
over the mesh, which is what makes the mesh load-bearing rather than merely
present: a broken tunnel then fails the deploy at the connection, and no role
can quietly fall back to the underlay it was supposed to stop using.
A separate step rather than a fact set during the play, because a play cannot
change the transport it is already running over. A host holding no address on
the mesh is left alone -- rewriting it would strand a host that was
reachable.
A consumer that admits mesh traffic needs every range a member can arrive
from, so a deployment carving its meshes from more than one pool extends this
rather than each consumer.
The blanket info-media nocheck claimed WireGuard has no consumer-facing
upstream, which is wrong: wireguard.com is the project's own site and the
README table renders it as the role's link.
A host presents the same identity on every plane it belongs to, so the hub no
longer carries two identities and the writer has one credential to keep in
step. A member already keyed by an earlier mesh keeps that key instead of
minting a second one.
The pool is declared once under NETWORK_* and referenced from the mesh file.
Ansible resolves that at play time; this writer runs before the play, so it
follows the one hop rather than duplicating the value.
wg-quick down on the interface Ansible is connected over kills the session
carrying the play, and the up that would restore it never runs. syncconf
applies new keys and peers to the live interface, so a rotated mesh converges
without dropping the connection that is rotating it.
Latent until now only because the deploy still runs over the underlay.
The install no longer skips when wg-quick happens to exist: the node image
stopped pre-baking it, so the role is what puts it there.
The tunnel and overlay MTUs are now measured with automtu against the hub's
underlay endpoint rather than hardcoded. Fixed values contradict the MTU
automtu already derives for the docker daemon, and the mesh addresses cannot
be probed because the interface those MTUs configure is not up yet.
Shipping wireguard-tools in the image meant the role's own install path was
never exercised, which is the thing the test exists to prove. The role now
provisions it.
Swarm and the mesh are independent: a production swarm can run in one isolated
physical environment, and the mesh exists to join clusters that are physically
separated. Declaring the service required made every swarm deploy pull the
mesh in, which is what the axis now decides per run.
With the axis off the role is left out of both inventories entirely rather
than deployed disabled, so that arm proves swarm works with no mesh logic
anywhere in the path.
SWARM_REQUIRED_SERVICES no longer force-keeps wireguard: with the axis off the
role is absent from the inventory, so there is no disabled-service conflict to
work around.
A fully pinned priority row now pins the mesh state too, and a priority row
with more combinations than the distro pool has members wraps the rotation
instead of holding one distribution per combination.
role&vpn / role&direct, and the same state read back off a pasted job title.
Own separator rather than more + words: + is the onion axis, and one
separator meaning two things could not be read back unambiguously.
Entries carry vpn, labels carry the glyph, and the artifact slug carries the
state so a meshed and a direct run of one row cannot collide on one artifact
name. Priority rows cover both states; compose never takes the axis.
A swarm deploy runs either over the mesh or straight over the underlay, and
both have to keep working: the mesh joins physically separated clusters, so a
single-site swarm has no use for it and must not depend on it.
Quarters on sweep // 4 so it flips in step with neither the mode rotation nor
the onion, and a row walks every mode/tor/vpn combination over eight sweeps.