6.6 KiB
berth — withdrawn assumptions
Everything in this file is no longer true.
It exists so the live docs stay short and so a withdrawn assumption cannot quietly return:
each entry carries a check, and ctrl/selftest.sh runs every one of them. A retraction
that is only prose is a retraction nobody re-reads.
Kept rather than deleted for the reason the docgen thread already wrote down — a requirement that disappears without explanation comes back.
For agents
- Do not restate these in a plan, a README or a comment. One line pointing here is enough.
- Ids are stable. Cite
✖ B3; do not re-explain it. - When you withdraw an assumption, move it here — quoted claim, where it came from, what superseded it and why, what changed in the code, and a check that proves it is gone.
- Only withdrawn things belong here. A warning that is still actionable is a live rule, however historical it sounds, and stays where it is.
✖ B1 — "Pulumi is the source in spr, and Terraform must match the config."
(INDEX §5, carried from 35.3) Withdrawn 2026-09-12. berth uses OpenTofu and only
OpenTofu. The rule assumed open source and industry standard pull apart — Terraform
being BUSL, Pulumi being the open alternative. OpenTofu is both: the standard language, plain
Terraform-compatible HCL, under MPL-2.0. Swappability was never bought by keeping two
renderings; it is bought by estate/*.json being the artifact — a rendering you can
produce, not one you must maintain.
Gone from: ctrl/versions.env (no PULUMI_VERSION), ctrl/estate.sh (plan runs one
executor), ctrl/lib/config.sh (PULUMI_STACK → TOFU_WORKSPACE), ctrl/check.sh
(toolchain list).
Deliberately kept: README.md and estate/mcrn.json both record that ppl/infra/ was
written and never applied — "no ~/.pulumi, no venv, no stack state". That is a historical
fact about the estate, not a live dependency.
Check: no pulumi in ctrl/ or Makefile.
✖ B2 — "ctlptl's rejection is the precedent for the seam belongs in a script, not a tool."
(INDEX §5, berth/README.md) Withdrawn 2026-09-12. ctlptl was reinstated — pinned in
rig/ctrl/versions.env at v0.9.4 — and had been removed for the wrong reason. The rule may
still hold; it now has to stand on its own reasoning rather than that example.
Gone from: README.md — the argument is stated directly, with no borrowed evidence.
Check: ctlptl appears nowhere in berth.
✖ B3 — "wg show is safe; wg showconf is not." (my own note, 2026-09-12) Incomplete,
and the gap is the dangerous one. There are three forms, and wg show <if> dump puts the
private key in field 1 of the first line. Stated as a two-way distinction, the dump form
reads as safe.
Now: wg show plain is safe; dump and showconf are not. ctrl/vpn.sh capture refuses
the latter two by shape, rather than parsing around them.
Check: vpn.sh names all three forms, and capture rejects both unsafe ones.
✖ B4 — "A roaming peer must set PersistentKeepalive on its own entry."
(ctrl/vpn.sh, first draft) Wrong side, and wrong in the direction that looks fine:
PersistentKeepalive is set per-peer in a config, so the roaming machine sets it on the entry
for the peer it dials. The original check would have warned on a correctly configured
overlay.
Now: checked once per overlay — if anything roams, some peer entry must carry a keepalive.
Check: the invariant is not keyed on the roaming peer's own keepalive field.
✖ B5 — "The Makefile's pass-through block goes near the top, with the other variables."
(Makefile, inherited from rig's layout) Withdrawn 2026-09-12. When a subcommand names a
real target, make has two recipes for it and the last definition wins — so with the block
first, make host ports ran ctrl/host.sh ports and ctrl/ports.sh ports, the second
failing because ports is not one of its verbs. Same for make host services, make vpn check, make vpn show estate.
Now: the $(eval $(ARGS):;@:) block is last in the file, so the no-op wins and the
word is swallowed — which is what an argument is. Make's "overriding recipe" warning is the
swallow working.
Check: every colliding invocation dispatches to exactly one script.
✖ B6 — "A base64 key in the description can be caught by its shape."
(ctrl/vpn.sh check, first draft) WireGuard public keys are also 44-char base64 and
legitimately live in the estate, so shape alone proves nothing and would flag correct data.
Now: two assertions instead — no field named priv*, and no base64 key outside a
public_key field.
Check: the estate's public keys do not trip the secret check.
✖ B7 — "network.wireguard is where the overlay is described." (estate/mcrn.json)
Superseded 2026-09-12: WireGuard is berth's network layer, not one service's transport, so it
is a top-level vpn block with named overlays and peers. ctrl/check.sh and
ctrl/registry.sh were repointed.
Gone from: the estate schema — a wireguard_moved tombstone marks the old key.
Check: nothing reads network.wireguard.*.
✖ B8 — "berth and rig are related through their first uses." (early framing) Withdrawn:
rig and berth are peers — neither depends on the other. They match on shape (dispatch,
config layering, key names) and consistency is verified by recomputation, never by
dependency. A shared library would put something outside rig/ on rig's path.
Check: berth imports nothing from rig; ports.sh recomputes the port formula and agrees
with rig's golden values.
✖ B9 — "langfuse.mcrn.ar is an exception that cannot be generated."
(estate/mcrn.json, raw: true) Withdrawn 2026-09-14. It was filed as the one route a
template could not express — a static upstream{} to a WireGuard address, with no resolver
and no set $var. It was not an exception; it was the first instance of the general case.
Those three properties are not three decisions, they are one: this service is reached by
address on the overlay, not by name on the docker network. Naming that decision —
placement — makes the file renderable.
Gone from: estate/mcrn.json — lng and langfuse were two entries for one socket
and are now one service with placement: local, peer: nrft, and a local_host for the
name it answers to locally. raw is dropped.
Check: the generated vhost matches the hand-written one, normalised for comments and
whitespace — proof against a live route rather than an assertion.