Files
soleprint/berth/STALE.md
2026-09-14 03:57:00 -03:00

105 lines
6.6 KiB
Markdown

# 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.