# HANDOFF — 2026-08-18 For the assistant taking over. Read this, then the documents it points to. --- ## 1. Read these first, in this order All in `mechanical-compiler/docs/` at commit `6967eef5`. | # | File | Why | |---|---|---| | 1 | `PROCESS.md` | How work is done here. Read before issuing any command. | | 2 | `STAGING-STATE.md` | What is true on `srv-b` right now | | 3 | `FAILURES.md` | What has already gone wrong. 32 entries. | | 4 | `ENVIRONMENT.md` | The specification, revision 5.3 | | 5 | `ROADMAP.md` | Where the project is going, and 16 standing principles | If you are writing provisioning automation, read `FAILURES.md` **before** the specification. Every entry is something a script written from the specification alone would have got wrong. **Authority when documents disagree:** `STAGING-STATE.md` wins on facts. `FAILURES.md` is evidence. `ENVIRONMENT.md` is corrected when proven wrong. --- ## 2. The operator's constraint **CIVICVS has a shell on `srv-b` and a browser-based file manager. Nothing else.** No workstation git client. No direct container shell. No IDE. No `scp`. Files arrive by upload to `/root/incoming` on `srv-b`; every command runs in that one shell. Everything below follows from this. An assistant that assumes otherwise produces instructions the operator cannot execute — which has happened more than once, including to me. --- ## 3. How I failed the operator, so you can avoid it This section matters more than the status. Four specific failures, all mine. ### Multiple instructions in one message The single most repeated complaint, and the one that ended the session. **One task. One command group. Wait for output.** Not "here are three things you could do next." Not a numbered procedure spanning several systems. Not a task with two optional extras attached. If you find yourself writing "and also" or offering a choice of next steps, delete it. Ask which one, or pick one and do it. ### Referring to things the operator cannot see I wrote `cd /path/to/srv-b-host` for a repository that exists only in Gitea, uploaded through a web form. There was no path. The operator was right to object that if I did not know it, he had no reason to. **Never write a placeholder path.** If you do not know where something is, ask — as one question, on its own. ### Raising things that do not matter I flagged a file mode bit in Gitea that could not be fixed from the web interface, was not worth a clone, and did not affect anything. It cost a full exchange of confusion. **If a finding is not actionable and not important, do not raise it.** The operator's attention is the scarce resource. ### Asserting from a proxy observation I stated that CT 100 and CT 101 had no mail agent, based on inspecting Postfix configuration **on the host**. I then "standardised" CT 102 against that belief. The first run of `ct-baseline.sh` showed both containers had mail agents. See F-031. **Check the thing, not something adjacent to it.** --- ## 4. Where things stand ### Infrastructure — complete `srv-b`, Proxmox VE 8.4.0, standalone. Three containers, all conforming. | CT | Name | Address | Role | |---|---|---|---| | 100 | `mechcomp` | `10.20.0.10` | application, worker | | 101 | `mcproxy` | `10.20.0.11` | reverse proxy, TLS | | 102 | `kane-fabric` | `10.20.0.12` | **separate project** | All on `vmbr1`, a portless service bridge. `srv-b` is router and bastion: internet → WireGuard → `srv-b` → containers. Containers cannot reach the home LAN. Containers cannot send mail — only `srv-b` does, and only its own alerts. Working and proven: TLS termination with `X-Forwarded-Proto` reaching the backend, mail delivered end to end, `smartd` monitoring four drives with alerts received, SMTP egress blocked, host-reboot persistence. ### Conformance `ct-baseline.sh` — read-only, run any time, exits non-zero on divergence. Installed at `/usr/local/sbin/ct-baseline.sh`. Canonical copy in `TheRON/srv-b-host`. **A property not checked by it is not part of the standard.** That is what makes conformance terminate rather than recur. Last run: 62 passed, 0 failed. ### Repository — seeded `mechanical-compiler` at `6967eef5`. CT 100 has a working clone at `/var/www/mechcomp`, owned by `mechcomp`, pushing over SSH with deploy key `srv-b-ct100`. **Gitea SSH is on port 42022.** Dependencies installed. Oracle verifies in-container. `3 passed, 236 skipped`. ### Backup — deliberately not done Not an oversight. The operator's reasoning, which is correct: a backup of an unverified configuration restores the confusion along with the data. A backup taken before 2026-08-18 would have preserved two containers that queue mail forever. **Entry condition: `ct-baseline.sh` exits 0.** Do not raise this again until there is something worth preserving. The documents are in Gitea; nothing else currently exists whose loss would cost more than an afternoon. --- ## 5. The next work item **Port `sb-geom` to Shapely.** Get `pytest -n auto` green against the 123 frozen cases in `fixtures/strap-beam-8.0.0/`. This is development mode, not infrastructure mode — see `PROCESS.md` §2. Do not apply command-group ceremony to a test-fix-rerun loop. `tests/test_oracle.py` already specifies the API. It was written before the port, deliberately, so the interface follows from what must be verified: ```python build(family, profile, params) -> Result # Result.report -> dict of SB_* keys ProfileRejected # str() names the parameter and the limit ``` **The ten rejected cases are part of the contract.** A port that accepts them is wrong however good its numbers are elsewhere. The harness was proven by adversarial stub: a `build()` that rejects everything passes all 10 rejection tests and fails all 226 acceptance tests. An untried gate that should be run first: ``` make toolchain ./tools/reference-toolchain/verify.sh --full ``` That regenerates all 123 cases inside the pinned image and diffs against the committed oracle. Slow — single-threaded solvers on 2010 Westmere cores. Expect a one-line difference in the `frozen` date; anything else means drift. --- ## 6. Open questions, none blocking | # | Question | Owner | |---|---|---| | 1 | Should `wg-pk` narrow `mynetworks` from `10.110.0.0/22` to explicit hosts? | CIVICVS, estate decision (F-025) | | 2 | Backup strategy — USB, IPFS, optical? | CIVICVS | | 3 | Where is the 3+ TB USB disk attached? | CIVICVS | | 4 | Kane Fabric participant mail — send and receive, unsolved | Cross-project | Question 4 is real and unaddressed. Containers do not send mail by standard, and nothing can reach `vmbr1` from outside, so receiving has no path at all. It needs a design conversation, not a configuration change. --- ## 7. Things that will bite you - **Gitea SSH is port 42022.** Remotes need `ssh://git@host:42022/owner/repo.git` — the `git@host:path` shorthand cannot carry a port. - **Deploy tokens in Gitea are account-level**, under user Settings. Repository settings offer deploy **keys** only. I got this wrong twice. - **The service user's home is the install directory**, so anything writing to `$HOME` writes into the working tree. `.cache/`, `.local/`, `.ssh/` are all in `.gitignore` for that reason (F-029). - **Every network command needs an explicit timeout.** One without hung the operator's shell (F-030). - **`journalctl`, not `/var/log/mail.log`.** Proxmox ships without `rsyslog` (F-024). - **Assert health after a *host* reboot**, not a guest reboot. Different machinery (F-026). - **A test must distinguish tool failure from the condition it tests.** A `pct exec` that fails because the container is stopped will otherwise read as a pass (F-027). --- ## 8. What the project is for Not required to do the next work item, but it is why any of this exists. Build the capacity to construct real structures — the reference case is a faceted timber shell — from reclaimed and commodity materials, using whatever fabrication is to hand. The compiler makes the pieces computable, qualifiable, and reproducible by someone who was not present when they were designed. **Codes and permitting are out of scope, deliberately.** The project records physical claims, never verdicts. Measure and attest; never adjudicate. Three artifact classes: **members** (prismatic, exist — the eleven profiles), **nodes** (non-prismatic, no representation yet), **panels** (sheet, none yet). The gap that moves next in priority is dihedral parameterisation: if two panels meet at 137°, none of the eleven profiles gives you a member for it. --- ## 9. Working with this operator He is precise, keeps excellent records, and will tell you directly when you are wrong — including when you are being unhelpful. Take that at face value; it is accurate and it is not personal. He decides. Bring evidence and a recommendation, then stop. Do not re-litigate settled decisions. Webmin is installed on every node and is his only remote access to `srv-b`; I wasted his time questioning it. Backup is postponed for good reasons. `4x` is the end of the N-strap family. When he says he does not understand something, the writing was unclear. Rewrite it shorter, do not explain it again at greater length.