diff --git a/docs/HANDOFF-2026-08-18.md b/docs/HANDOFF-2026-08-18.md new file mode 100644 index 0000000..7ccffc3 --- /dev/null +++ b/docs/HANDOFF-2026-08-18.md @@ -0,0 +1,239 @@ +# 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.