diff --git a/docs/HANDOFF.md b/docs/HANDOFF.md index c7d75e8..c2ae8db 100644 --- a/docs/HANDOFF.md +++ b/docs/HANDOFF.md @@ -6,7 +6,7 @@ It is the only handoff you need to read. Dated handoffs in `docs/archive/` are historical and are not required reading — do not diff them against this to work out what is true. If something here is wrong, correct it here. -Last updated 2026-08-22, closing F-034. +Last updated 2026-09-11, after the composer went live behind the proxy. This line used to carry the commit hash of its own rewrite. It cannot: the hash is not known until the commit is made, so the value was always the @@ -15,6 +15,25 @@ noticing. Date only, from here. --- +## 0. Read these first, in this order + +This document is not the first thing to read, despite being the handoff. + +1. **`docs/PROCESS.md`** — how work is done here: who runs what, on which + machine, with which tools. **It constrains everything below.** Reading it + eleventh cost this session three sets of instructions the operator could + not execute. +2. **`docs/STAGING-STATE.md`** — what is true on the host right now. +3. **`docs/FAILURES.md`** — what has already gone wrong and why. +4. This document — where the code stands. +5. `docs/ACCEPTANCE.md`, `docs/STOCK.md`, `docs/PRECISION.md` — the + specifications the code is held to. + +When documents disagree, `STAGING-STATE.md` wins on facts about the host and +`FAILURES.md` wins on what was actually observed. This one is corrected. + +--- + ## 1. Invocation — read before typing anything These are facts, not examples. Getting one wrong produces an error that looks @@ -128,7 +147,17 @@ terminate rather than recur. **Settled decisions. Do not reopen any of these:** -- Webmin is the operator's only remote access. Questioning it wasted a session. +- **Webmin is the operator's only remote access.** He works from Webmin on + `wg-pk`, the WireGuard hub, and from there into the `srv-b` shell — not the + other way round. Questioning this wasted a session once and was questioned + again on 11 SEP, because the decision had been recorded without the fact it + rests on. The fact is above. Do not ask again. +- **`dev.infra` does not exist on the internet.** It is a hosts-file name on + `srv-b`, CT 100 and CT 101 only, and CT 101's leaf is signed by a local + staging CA. Never tell the operator to open a `dev.infra` URL or a + `10.20.0.x` address in a browser: `10.20.0.0/24` is a portless bridge with + LAN traffic dropped. The public name is `dev.mechcomp.kane-il.us` and it + needs `WORK-ORDER-004`. - Backup is deliberately postponed. Entry condition: `ct-baseline.sh` exits 0. Do not raise it again. - `4x` is the end of the N-strap family. @@ -140,15 +169,20 @@ terminate rather than recur. ### The port — COMPLETE -Gitea `main` at `52d00b5` before this commit. CT 100 clean and matching. +Gitea `main` at `a8081e1` before this commit. CT 100 clean and matching. -**Suite: 468 passed, 0 failed.** The 30 expected failures are gone, resolved +**Suite: 529 passed, 0 failed.** The 30 expected failures are gone, resolved rather than suppressed, by the tolerance model in `docs/ACCEPTANCE.md`. A red `make test` now means something is actually wrong. +**The composer is live.** `mechcomp.service` in CT 100 serves it on +`10.20.0.10:8770`, behind nginx on CT 101, proven `HTTPS 200` end to end. +`mechcomp-placeholder.service` is disabled and retained as the rollback. + | Module | Ported from | Contents | |---|---|---| -| `geom/primitives.py` | `sb-geom.scad` | Vectors, GEO and MEMBER, sleeve and cavity paths, exact polyline distance, corner-radius derivation, monotone solver | +| `geom/primitives.py` | `sb-geom.scad` | **Pure geometry only.** Vectors, degree trig, exact polyline distance, corner-radius derivation, monotone solver. **`Geo` and `Member` are NOT here** — an earlier version of this table said they were, and two modules were read on the strength of it | +| `geom/records.py` | `sb-geom.scad` | `Geo`, `Member`, `place`, `local_rect`, sleeve and cavity paths, reach. The other half of `sb-geom` | | `geom/rounding.py` | BOSL2 `92d697c2` | `round_corners`, `_circlecorner`, `arc`, `segs`, `deduplicate`, `path_merge_collinear`, `is_collinear` | | `geom/region.py` | BOSL2 regions | Shapely booleans, nesting-parity decomposition, area, simplicity, hull, mitred offset, cleaning | | `geom/join.py` | `sb-join.scad` | Butt joints, hull caps, fillets, derived bore, ring fit, section assembly | @@ -159,6 +193,10 @@ rather than suppressed, by the tolerance model in `docs/ACCEPTANCE.md`. A red | `profiles/four_x.py` | `strap-beam-4x.scad` | Five profiles, defaults, 4x base checks | | `profiles/three_x.py` | `strap-beam-3x.scad` | Six profiles, defaults, 3x base checks | | `profiles/__init__.py` | — | `build()`, `ProfileRejected`, family registry | +| `stock.py` | — | COTS stock descriptor: `RectStock`, `RoundStock`, `Fit`, `Provenance`. A leaf module — imports nothing from `mechcomp`. See `docs/STOCK.md` | +| `design_record.py` | — | What a model was made from, at full precision, sufficient to regenerate it. `input_id` and `build_id` | +| `svg.py` | — | Cross-section as SVG, separately classed layers for material, cavities and stock | +| `web/app.py` | — | The composer. Standard library HTTP server; binding from `/etc/mechcomp/mechcomp.env` | `make deps` is complete in CT 100 and **must not be re-run**. @@ -166,7 +204,7 @@ rather than suppressed, by the tolerance model in `docs/ACCEPTANCE.md`. A red ## 4. What to do next -**Nothing is blocked. F-034 is closed and the suite is green; everything +**Nothing is blocked. The composer is live and the suite is green; everything below is new capability.** **CIVICVS stated the goal on 22 AUG: he will not print anything that is not @@ -188,13 +226,27 @@ Roadmap items — read `ROADMAP.md` before starting any: profiles gives you a member for it. This is the highest-value gap and it blocks a catalogue that could otherwise not serve the reference structure. - Rebar- and conduit-core bore as a declared interface. See above. -- The catalogue front end. Nothing of it exists: no SVG emitter, and - `src/mechcomp/web/__init__.py` and `worker/__init__.py` are 33- and 36-byte - stubs. `STAGING-STATE.md` records deployment as blocked on application - code, which is still true. +- **Per-member stock.** This is what the conduit core actually needs. `Geo` is + global to a build, so every member is the same rectangular strap by + construction and the Y's centre cannot hold something of a different shape. + Moving stock from the build to the placement reaches into `join.py` and + `arrangements.py`, and it is the first change where the oracle's own + geometry is genuinely at risk rather than merely nearby. +- **The composer, deepened.** It exists and serves; it does not export + anything, persist anything, or show a bill of materials. `payload["defaults"]` + is sent to the browser and nothing reads it — dead weight, and it is what + made a verification grep lie on 11 SEP. - STL and STEP export. No CAD kernel is installed in CT 100 (§5). +- `mechcomp-worker.service`. `src/mechcomp/worker/` is still a 36-byte stub and + nothing needs a worker yet. - Nodes (non-prismatic) and panels (sheet). No representation exists for either. +**`WORK-ORDER-004` publishes the composer at `dev.mechcomp.kane-il.us`.** It is +infrastructure-mode work on `wg-pk`, which this project does not own, so it is +an escalation under `PROCESS.md` §7 and not something to drive with command +groups. The `srv-b` half needs no change; the single gate is `AllowedIPs` on the +hub's peer entry. **Until it closes, CIVICVS cannot see any of this work.** + Note for anyone tempted to shortcut a test print: the OpenSCAD reference in `legacy/` does export printable STL today — `sb_extrude_section` does a `linear_sweep` and `legacy/openscad/README.md` documents the invocation. That @@ -489,6 +541,7 @@ held to it. When in doubt, narrow. | 4 | Kane Fabric participant mail, send and receive | Cross-project | | 5 | ~~Tolerance model for the three discretisation-limited keys~~ | **Closed 22 AUG.** See §7 and `docs/ACCEPTANCE.md` | | 6 | Is the bore's fit class per-material, or one clearance for all inserts? | CIVICVS — raised by the conduit-core requirement, §4 | +| 7 | Public ingress at `dev.mechcomp.kane-il.us` | `WORK-ORDER-004`; CIVICVS executes on `wg-pk` | 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 @@ -499,6 +552,13 @@ a design conversation, not a configuration change. ## 12. Commit log ``` +a8081e1 state: the composer replaced the placeholder; open public ingress +14514b0 web: the composer, served behind the existing proxy chain +e921cac design record: every build emits one +d2827c2 design record: what a model was made from, sufficient to regenerate it +70787ea stock: records delegates to the descriptor, and the descriptor stops gating +f5651d3 stock: name the COTS descriptor; the strap becomes the first entry +6836ece tests: close F-034; bound the derived trio at 8 ULP of the oracle record 52d00b5 docs: HANDOFF header commit line moved to b255ebb b255ebb docs: F-034 rewritten from measurement; handoff updated 114189c docs: PRECISION.md -- scope, guarantees and limits, for lay readers