HANDOFF.md rewritten in place, as it is meant to be. The port is complete,
so the document now describes that state rather than the work leading to it.
Most important change for whoever reads it next: the suite is 436 passed,
30 failed, and section 3 says plainly that the 30 are expected and a red
`make test` is not a broken port. Without that line the next assistant
spends its opening exchange rediscovering what is already known.
Also added: the 0.01 mm accuracy criterion as a settled decision; that
defaults are per-family and differ (ring_corner_radius_mm is 2.00 in 3x
and 1.25 in 4x); that check declaration order is the reporting order; that
params carries only a case's overrides; and pointers to PRECISION.md for
what the compiler does not do.
F-034 rewritten around measurement rather than estimate. The original Y
evidence is preserved verbatim -- it was specific and hard-won. What is
new:
- the same mechanism at 90 degree ring corners, where the expression is
exactly 12 rather than exactly 8. Rectangle: reference envelope 50
vertices, port 48.
- which side is noisy, which was previously unstated and turns out to
matter. Instrumented at %.17g the port prints half=45 raw=12 ceil=12
on every call. It lands on the integer deterministically; the
reference does not. A guard cannot make the port match noise it does
not have, so there is nothing left to try on this side.
- the scale: 30 of 113 accepted cases, 83 exact, worst relative error
2.24e-05, confined to SECTION_AREA_MM2 and its two derivatives.
- the physical magnitude: chord deviation is r*(1-cos 3.75deg), so
0.0027 mm at r=1.25 and 0.0043 mm at r=2.00. The two implementations
differ from each other by at most ~0.4 um. Two orders inside the
0.01 mm criterion.
- the constraint on any fix: the tolerance block is inside the hashed
oracle document, so the change belongs in test_oracle.py.
Status stays Open. The decision is CIVICVS's and has not been made.
464 lines
20 KiB
Markdown
464 lines
20 KiB
Markdown
# HANDOFF
|
||
|
||
**This document is rewritten in place each session. It is state, not a log.**
|
||
|
||
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-20 at commit `114189c`.
|
||
|
||
---
|
||
|
||
## 1. Invocation — read before typing anything
|
||
|
||
These are facts, not examples. Getting one wrong produces an error that looks
|
||
like a problem with the repository or the containers.
|
||
|
||
**`mechcomp` has `nologin` as its shell.** Use `runuser -u mechcomp -- <cmd>`,
|
||
which executes directly. **`su - mechcomp` cannot work** and fails with
|
||
`This account is currently not available` — a message that looks like a broken
|
||
account and is not. See F-035.
|
||
|
||
**All repository operations run as `mechcomp`, never root.** The clone is at
|
||
`/var/www/mechcomp` in CT 100. Never add a git `safe.directory` exception to work
|
||
around an ownership complaint; fix the ownership (F-008).
|
||
|
||
**`mechcomp`'s home *is* the working tree.** Anything writing to `$HOME` writes
|
||
into the repository. `.cache/`, `.local/` and `.ssh/` are in `.gitignore` for
|
||
that reason (F-029). Git identity is set `--local` for the same reason —
|
||
`--global` would write into the tree.
|
||
|
||
**`verify.sh` is mode `100644`.** Invoke it as `bash tools/reference-toolchain/verify.sh`,
|
||
never `./tools/...`.
|
||
|
||
**Gitea SSH is port 42022.** Remotes need
|
||
`ssh://git@host:42022/owner/repo.git`; the `git@host:path` shorthand cannot carry
|
||
a port. CT 100 pushes with deploy key `srv-b-ct100`.
|
||
|
||
**Deploy *tokens* in Gitea are account-level**, under user Settings. Repository
|
||
settings offer deploy *keys* only.
|
||
|
||
**Files reach CT 100 by upload, then `pct push`, then `chown`.** `pct push`
|
||
writes as root, so `pct exec 100 -- chown mechcomp:mechcomp <path>` immediately
|
||
after, every time.
|
||
|
||
**Every network command needs an explicit timeout** (F-030). One without hung the
|
||
operator's shell.
|
||
|
||
**Logs are in `journalctl`**, not `/var/log/`. Proxmox ships without `rsyslog`
|
||
(F-024).
|
||
|
||
**Long-running jobs go to `systemd-run --unit=<name> --collect`**, not `nohup` or
|
||
`setsid`. `pct exec` tears those down when it exits; systemd owns the job and the
|
||
output lands in the journal.
|
||
|
||
**Docker runs as root in CT 100 only.** `mechcomp` cannot reach the daemon. CT 101
|
||
has no `keyctl` and cannot run it at all.
|
||
|
||
**Assert the guest is running before interpreting any `pct exec` result** (F-027).
|
||
A command that fails because the container is stopped otherwise reads as a pass.
|
||
|
||
Useful canonical form:
|
||
|
||
```bash
|
||
if [ "$(pct status 100 | awk '{print $2}')" != "running" ]; then
|
||
echo "CT 100 NOT RUNNING - stop here."
|
||
else
|
||
pct exec 100 -- runuser -u mechcomp -- git -C /var/www/mechcomp status --short
|
||
fi
|
||
```
|
||
|
||
---
|
||
|
||
## 2. The operator's constraint
|
||
|
||
**CIVICVS has a shell on `srv-b` and a browser-based file manager. Nothing
|
||
else.**
|
||
|
||
No workstation git. No SSH into a container. No IDE. No `scp`. Files arrive by
|
||
upload to `/root/incoming` on `srv-b`; every command runs in that one shell.
|
||
`pct exec` from that shell reaches all three containers — that is the container
|
||
path, and it is not a limitation.
|
||
|
||
An assistant that assumes otherwise produces instructions the operator cannot
|
||
execute. This has happened repeatedly.
|
||
|
||
**Deliver code by upload, not by paste.** A sixty-line heredoc containing
|
||
em-dashes and nested code fences was mangled by the browser terminal. Everything
|
||
delivered since as a tarball — with a stated checksum, file list, and what it
|
||
overwrites — has worked without exception. State what the archive contains, where
|
||
it expands, and what it overwrites, every time.
|
||
|
||
When a delivery supersedes an earlier one, **ship every file in the set**, not
|
||
just the changed one, so the resulting state is unambiguous.
|
||
|
||
---
|
||
|
||
## 3. Where things stand
|
||
|
||
### Infrastructure — complete, do not revisit
|
||
|
||
`srv-b`, Proxmox VE 8.4.0, standalone.
|
||
|
||
| CT | Name | Address | Role |
|
||
|---|---|---|---|
|
||
| 100 | `mechcomp` | `10.20.0.10` | application, worker, Docker |
|
||
| 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 and cannot send mail.
|
||
|
||
`ct-baseline.sh` is read-only, runs any time, exits non-zero on divergence.
|
||
Installed at `/usr/local/sbin/`. Last run: 62 passed, 0 failed. **A property it
|
||
does not check is not part of the standard** — that is what makes conformance
|
||
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.
|
||
- 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.
|
||
- The `--full` toolchain gate's Docker root-ownership hazard is understood and
|
||
handled by mounting read-only. See §6.
|
||
- **Accuracy criterion: 0.01 mm over the entire set.** Set by CIVICVS on 20 AUG.
|
||
This is the standard the software is held to, and it is met with two orders of
|
||
margin on every dimensional quantity. See `docs/PRECISION.md`.
|
||
|
||
### The port — COMPLETE
|
||
|
||
Gitea `main` at `114189c`. CT 100 clean and matching.
|
||
|
||
**Suite: 436 passed, 30 failed. The 30 failures are expected.** Do not treat a
|
||
red `make test` as a broken port — read §7 before doing anything about it.
|
||
|
||
| 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/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 |
|
||
| `geom/report.py` | `sb-report.scad` | Checks-as-values, metrics, five universal checks, `ProfileRejected`, report formatting |
|
||
| `geom/core.py` | `sb-core.scad` | PROFILE record, failure representation, centred assembly |
|
||
| `geom/arrangements.py` | `sb-profiles.scad` | Ring, spoke and fin arrangements, all N-generic |
|
||
| `profiles/_common.py` | both generators | Assembly pipeline and the eight shared base checks |
|
||
| `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 |
|
||
|
||
`make deps` is complete in CT 100 and **must not be re-run**.
|
||
|
||
---
|
||
|
||
## 4. What to do next
|
||
|
||
**Nothing is blocked. Pick up §7 first if the operator wants it closed; otherwise
|
||
the port is done and the next work is new capability.**
|
||
|
||
Immediate, small, and already scoped:
|
||
|
||
1. **F-034 tolerance decision** (§7). Evidence is gathered; the decision is
|
||
CIVICVS's. Do not implement before he chooses.
|
||
2. **Rewrite F-034 in `FAILURES.md`** around the measurements below. The entry
|
||
still describes it as an unquantified hazard; it is now measured.
|
||
|
||
After that, the roadmap items — read `ROADMAP.md` before starting any:
|
||
|
||
- STL and STEP export. No CAD kernel is installed in CT 100 (§5).
|
||
- Dihedral parameterisation. If two panels meet at 137°, none of the eleven
|
||
profiles gives you a member for it. This is the highest-value gap.
|
||
- Nodes (non-prismatic) and panels (sheet). No representation exists for either.
|
||
|
||
---
|
||
|
||
## 5. Facts established by porting
|
||
|
||
### The public entry point is `mechcomp.profiles`, not `mechcomp.geom`
|
||
|
||
`conftest.py` does `importorskip("mechcomp.profiles")` and requires a `build`
|
||
attribute. `build(family, profile, params) -> Result` and `ProfileRejected` are
|
||
exported from `mechcomp.profiles`. Params use the OpenSCAD parameter names
|
||
unchanged.
|
||
|
||
**`params` carries only a case's overrides.** Everything else comes from the
|
||
family's declared defaults, which is why those defaults live in the port rather
|
||
than the test harness.
|
||
|
||
### Defaults are per-family, not shared
|
||
|
||
`ring_corner_radius_mm` is **2.00 in 3x** and **1.25 in 4x**. The two generators
|
||
declare their own parameter blocks and they are not identical. Do not assume a
|
||
value read from one file applies to the other. 4x also declares
|
||
`rectangle_aspect`, which 3x has no equivalent of, and its base-check list is
|
||
correspondingly one entry longer.
|
||
|
||
### Check order is the reporting order
|
||
|
||
The reference reports the **first** failing check, not an aggregate. Base checks
|
||
run before profile checks, and both run before any geometry is measured — a
|
||
builder that failed returns an empty profile, and `centred()` on an empty profile
|
||
has no members to measure.
|
||
|
||
### Report values are rounded to six significant figures
|
||
|
||
The oracle records what OpenSCAD's `echo` printed — C's `%g` at default
|
||
precision — not full-precision geometry. `echo_num()` does this; `echo_vec()`
|
||
handles vectors, which reach the oracle as strings like
|
||
`'[20.5209, 20.5209, 20.5209]'`.
|
||
|
||
Load-bearing, not cosmetic. `VOLUME_MM3` ends in `_MM3`, so `test_oracle.py`
|
||
compares it at the **lengths** tolerance of 1e-4, not the areas tolerance of
|
||
1e-3.
|
||
|
||
### Angles are degrees; the arbitrary constants are contract
|
||
|
||
OpenSCAD trigonometry is in degrees. The port keeps degrees throughout with
|
||
explicit `cos_d`/`sin_d`/`tan_d` so every expression matches its source line. The
|
||
44 solver iterations, the 0.999 and 0.98 scale factors, the 0.05/179.95 degree
|
||
cutoffs and the 1e9 sentinel are reproduced exactly. They produced the frozen
|
||
values.
|
||
|
||
### Environment
|
||
|
||
Shapely 2.1.2 on GEOS 3.13.1 — keep these in step, boolean results on
|
||
near-degenerate geometry can shift between GEOS releases. numpy 2.4.6. Shapely is
|
||
in `requirements-base.txt`, the 2D path's own dependency set.
|
||
|
||
**No CAD kernel is installed in CT 100.** `cadquery`, `OCP` and `build123d` are
|
||
all absent, though `requirements-cad.txt` says it is installed by default. That
|
||
is the strictest environment for developing the 2D path and will matter when STL
|
||
and STEP export begins.
|
||
|
||
### What is verified against the reference
|
||
|
||
**Every dimensional quantity is exact to 1e-4 mm across all 123 cases, with no
|
||
exceptions.** `ENVELOPE_X_MM`, `ENVELOPE_Y_MM`, `MIN_WALL_ACTUAL_MM`, and every
|
||
profile extra: `AF_*`, `FIN_*`, `SPOKE_*`, `RING_*`, `T_*`. Every count is exact.
|
||
|
||
**All ten rejections fire correctly**, including the bespoke A Frame and T paths,
|
||
which were written from the join primitives rather than from a shared
|
||
arrangement. That is strong evidence those two are structurally right.
|
||
|
||
Only `SECTION_AREA_MM2` and its two derivatives ever disagree. See §7.
|
||
|
||
---
|
||
|
||
## 6. Probing the reference directly
|
||
|
||
The pinned toolchain image is in CT 100 and OpenSCAD will echo whatever you ask
|
||
it. This settled F-034 in four exchanges and will settle any later disagreement
|
||
the same way. **Prefer it to reasoning.**
|
||
|
||
Mount the tree **read-only** and keep the probe on a separate writable mount —
|
||
Docker runs as root, and a read-write mount against a `mechcomp`-owned tree is
|
||
the F-033 hazard. A nested single-file mount inside a read-only mount fails with
|
||
`EXIT=125`; give the probe its own directory.
|
||
|
||
```bash
|
||
pct exec 100 -- bash -c 'mkdir -p /tmp/probe && cat > /tmp/probe/p.scad << "EOF"
|
||
include </repo/legacy/openscad/lib/sb-core.scad>
|
||
$fn = 48;
|
||
g = sb_geo(15.875, 0.508, 1, 0.25, 1.20, 1.20, 1.20, 1.20);
|
||
echo(str("PROBE=", sb_area([sb_sleeve_path(sb_member(0,0,0), g)])));
|
||
EOF
|
||
docker run --rm -v /var/www/mechcomp:/repo:ro -v /tmp/probe:/probe -w /probe \
|
||
mechcomp/reference-toolchain:8.0.0 \
|
||
openscad -o /tmp/o.stl --export-format=asciistl p.scad 2>&1 | grep -E "PROBE|ERROR"'
|
||
```
|
||
|
||
`EXIT=1` is normal — STL export fails on 2D geometry, the echoes still arrive.
|
||
|
||
**The oracle itself is stable.** The gate was run on 19 AUG: all 123 cases
|
||
regenerate byte-identically inside the pinned image, 113 accepted and 10
|
||
rejected, the only diff being `frozen` and the hash containing it.
|
||
`verify.sh --full`'s restore path was broken, is now fixed, and is **still
|
||
unexercised** (F-033).
|
||
|
||
**Instrumenting the port is equally cheap.** Monkeypatching
|
||
`mechcomp.geom.rounding._circlecorner` to print its half-angle and segment count
|
||
turned the F-034 diagnosis from inference into measurement in one command. The
|
||
module calls it through the module global, so patching the attribute works.
|
||
|
||
---
|
||
|
||
## 7. F-034 — measured, and the decision is ready
|
||
|
||
**The port is exact. The reference is noisy.** That is the opposite of what the
|
||
entry previously implied, and it changes what can be done about it.
|
||
|
||
`_circlecorner` computes `raw = (90 - angle)/180 * segs(r, None, fn)` and takes
|
||
`ceil(raw)`. At `$fn = 48` a 90° corner has half-angle 45, and `(90-45)/180*48`
|
||
is **exactly 12**. A ceiling on an exact integer is a knife edge.
|
||
|
||
Measured: the port prints `half=45 raw=12 ceil=12` at `%.17g` — landing dead on
|
||
the integer, every call, both families. The reference's arithmetic lands a hair
|
||
under 45° at some corners, pushing `raw` fractionally above 12 and the ceiling to
|
||
13. On Rectangle: **reference envelope 50 vertices, port 48** (`13+13+12+12`
|
||
against `12×4`).
|
||
|
||
**Do not try to fix this.** Rounding before the ceiling was tried and reverted —
|
||
it fixes Y exactly and breaks Three-Fin, because Three-Fin has the same asymmetry
|
||
and the oracle records it. There is nothing to correct on the port's side.
|
||
|
||
### Scale of the effect
|
||
|
||
30 of 113 accepted cases affected. 83 exact. Only three keys ever breach:
|
||
`SECTION_AREA_MM2` (29), `VOLUME_MM3` (30), `MASS_G` (22) — and volume is area
|
||
×100, mass is volume ×density/1000, so each case has **one** discrepancy reported
|
||
three times. **Worst relative error 2.24e-05.**
|
||
|
||
By profile: Three-Fin 9, Y 7, A Frame 5, Rectangle 5, T 1, Four-Fin 1. None on
|
||
Equilateral, General Triangle, Square, Diamond or Cross.
|
||
|
||
### Why the test fails when the geometry is fine
|
||
|
||
At `$fn = 48` a chord deviates from its true arc by `r(1 − cos 3.75°)` =
|
||
`r × 2.1413e-3`: **2.68 µm at r=1.25, 4.28 µm at r=2.00.** The port and the
|
||
reference differ from *each other* by at most ~0.4 µm. Against the 0.01 mm
|
||
criterion (§3) that is two orders of margin.
|
||
|
||
The tests fail because `VOLUME_MM3` is compared at 1e-4 **absolute** against a
|
||
magnitude near 20,000 — demanding 5e-9 relative agreement from discretised
|
||
geometry. `3x/Y/steel0.79` breaches on `VOLUME_MM3` alone while its area passes:
|
||
the same discrepancy, judged by two wildly different standards by accident of key
|
||
naming.
|
||
|
||
### The options, and the constraint
|
||
|
||
**Do not edit `tolerance` in the oracle JSON.** It is inside the hashed document;
|
||
`test_integrity_hash` covers everything but `fixtures_sha256`. Editing it breaks
|
||
that test by design.
|
||
|
||
The change belongs in `test_oracle.py`, which is not hashed:
|
||
|
||
1. **Scale-aware bounds for the three discretisation-limited keys**, derived from
|
||
the 0.01 mm criterion and the section perimeter. Most faithful to where the
|
||
error originates. Recommended.
|
||
2. **A relative floor** — pass if within absolute tolerance *or* ~1e-4 relative.
|
||
Simplest; loosens `SECTION_AREA_MM2` from 0.001 to ~0.02 mm².
|
||
3. **Accept 30 known failures.** Honest but `make test` is never green and a real
|
||
regression hides among them.
|
||
|
||
**CIVICVS decides.** The evidence is above; bring him the recommendation and
|
||
stop.
|
||
|
||
---
|
||
|
||
## 8. Method that has earned its keep
|
||
|
||
**Read the pinned source; do not recall it.** BOSL2 was fetched at
|
||
`92d697c2856de2fed93a33e858068589cefc2898` and read directly. Every function
|
||
examined had a detail that mattered and that recollection would have got subtly
|
||
wrong. The same applied to the generators: reading `sb-profiles.scad` before
|
||
writing `four_x.py` confirmed the call signatures rather than inferring them from
|
||
call sites.
|
||
|
||
**Check the invocation before concluding anything about state.** A `su` that
|
||
failed identically on two commands read as a repository problem and was an
|
||
invocation problem. That is the F-027 pattern and it cost a session's opening
|
||
exchange.
|
||
|
||
**Verify your own arithmetic before shipping it.** A claim in `PRECISION.md` that
|
||
a 50 mm radius needs `facets ≈ 460` was wrong — deviation falls with the *square*
|
||
of the segment angle, so the count grows with the square root of radius and the
|
||
answer is 158. A three-line script caught it.
|
||
|
||
**Mutation-test every suite before landing it.** Break the code deliberately and
|
||
confirm the tests notice. This found real gaps in five of six slices. It also
|
||
caught a malformed mutation of mine — cutting the cavities twice is idempotent.
|
||
**A surviving mutation is sometimes a bad mutation, not a test gap.**
|
||
|
||
**Read-only before write.** Every command group where the answer was not certain
|
||
established the facts first.
|
||
|
||
**One task, one command group, wait for output.** Not a menu of next steps. If
|
||
you find yourself writing "and also", delete it.
|
||
|
||
---
|
||
|
||
## 9. What the project is for
|
||
|
||
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 output must eventually be sealed manifolds and printable STL.** The 2D
|
||
section is where manifold validity is decided, not downstream in the CAD kernel —
|
||
`is_region_simple` is already a build-blocking check, and a self-touching outline
|
||
extrudes into something untessellatable.
|
||
|
||
**`docs/PRECISION.md` states what this compiler does not do**: no assembly layer,
|
||
no structural analysis of any kind, prismatic shapes only, no toolpaths. That
|
||
document is scope-locked to additive and subtractive manufacturing. **Requests to
|
||
widen it should be refused, not accommodated** — see its §10.
|
||
|
||
---
|
||
|
||
## 10. 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 it at face value; it is
|
||
accurate and it is not personal.
|
||
|
||
**He decides. Bring evidence and a recommendation, then stop.**
|
||
|
||
He has delegated all coding decisions — structure, algorithms, test design — and
|
||
does not want to be consulted on them. Still bring him scope, provenance, and
|
||
anything irreversible on the host. He runs every command, so nothing is
|
||
autonomous regardless.
|
||
|
||
When he says he does not understand something, the writing was unclear. Rewrite
|
||
it shorter; do not explain it again at greater length.
|
||
|
||
**He watches for scope creep and treats it as the primary risk** — "the greatest
|
||
enemy of software is not bugs, it's feature-creep". Documents and code are both
|
||
held to it. When in doubt, narrow.
|
||
|
||
---
|
||
|
||
## 11. 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 | Cross-project |
|
||
| 5 | Tolerance model for the three discretisation-limited keys — see §7 | CIVICVS, **ready to decide** |
|
||
|
||
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.
|
||
|
||
---
|
||
|
||
## 12. Commit log
|
||
|
||
```
|
||
114189c docs: PRECISION.md -- scope, guarantees and limits, for lay readers
|
||
7b3182c port: the 3x and 4x profile catalogues; build() now exists
|
||
af196a2 docs: one canonical handoff, rewritten in place; F-035
|
||
009fcce docs: handoff for the 19 AUG session
|
||
86a47c3 rounding: record F-034, arc segment counts tip on the last bit
|
||
8d79431 geom: port sb-core and sb-profiles, the N-generic arrangements
|
||
b101fe6 geom: port sb-report, validation and report formatting
|
||
ebf02d6 geom: port sb-join, the junction and envelope strategies
|
||
38ea024 geom: Shapely-backed region layer
|
||
545eee7 geom: port BOSL2 round_corners and path cleanup
|
||
dfd02a4 geom: port the pure-geometry half of sb-geom
|
||
b67cc12 verify.sh: reach the restore on the diff branch
|
||
1d3eed0 Handover push
|
||
6967eef Conformance updates.
|
||
c7e32d8 Seed repository: rev-8.0.0 reference, frozen oracle, toolchain, test harness
|
||
```
|