tests: close F-034; bound the derived trio at 8 ULP of the oracle record

The oracle records six significant figures, so the last digit of an area near 200 mm2 is worth 0.001 mm2. Every measured disagreement between port and reference is one, two or three units in that place. SECTION_AREA_MM2, VOLUME_MM3 and MASS_G are now bounded at 8 ULP of the expected value. Everything that positions material keeps the declared 1e-4 mm and remains exact in all 123 cases.

Option 1 scope kept, derivation rejected on measurement. Max |dA|/P over the accepted set is 1.434e-05 mm, one seven-hundredth of the 0.01 mm criterion, so a perimeter x 0.01 bound would have run 1800 to 4500 times the worst real discrepancy and caught nothing. Perimeter also anti-correlates with the error.

Suite 468 passed, 0 failed. The 30 expected failures are resolved, not suppressed. Mutation tested before landing: worst case uses 37.5 percent of its bound, 12 ULP offsets and 1e-4 relative scalings are caught in all 113 cases, 1e-6 and 1e-5 correctly are not.

Adds docs/ACCEPTANCE.md as the specification. Adds F-036, the venv interpreter error, same class as F-035. Corrects the F-034 per-profile distribution to Three-Fin 10, Y 7, A Frame 6, Rectangle 5, T 1, Four-Fin 1, which sums to the stated 30.
This commit is contained in:
2026-08-23 08:19:18 -05:00
parent 52d00b588b
commit 6836ece4ff
4 changed files with 447 additions and 34 deletions
+77 -27
View File
@@ -6,7 +6,12 @@ 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 `b255ebb`.
Last updated 2026-08-22, closing F-034.
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
*previous* commit and section 3 drifted two commits behind without anyone
noticing. Date only, from here.
---
@@ -20,6 +25,11 @@ 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.
**The interpreter is `/var/www/mechcomp/venv/bin/python`, not `python3`.**
`Makefile` line 3 sets `PY ?= venv/bin/python`, and `make deps` installs
pytest, Shapely, numpy and `mechcomp` itself into that virtualenv. System
`python3` has none of them and fails at the first import (F-036).
**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).
@@ -130,10 +140,11 @@ terminate rather than recur.
### The port — COMPLETE
Gitea `main` at `114189c`. CT 100 clean and matching.
Gitea `main` at `52d00b5` before this commit. 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.
**Suite: 468 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.
| Module | Ported from | Contents |
|---|---|---|
@@ -155,28 +166,41 @@ red `make test` as a broken port — read §7 before doing anything about it.
## 4. What to do next
**Nothing is blocked. §7 is decided and awaiting implementation;
everything else is new capability.**
**Nothing is blocked. F-034 is closed and the suite is green; everything
below is new capability.**
**Immediate: the F-034 tolerance change — decided, not yet
implemented.** CIVICVS approved **option 1** (§7) on 20 AUG:
scale-aware bounds in `test_oracle.py` for `SECTION_AREA_MM2`,
`VOLUME_MM3` and `MASS_G`, derived from the 0.01 mm criterion and the
section perimeter. It was deferred deliberately — implementation,
mutation testing and a green suite are one piece of work, not a partial
landing. **Do not touch the oracle JSON** (§7).
**CIVICVS stated the goal on 22 AUG: he will not print anything that is not
fully configurable.** The compiler is a half-visual composer — the T encloses
poly pallet straps in a T, the Y takes a metal electrical conduit core at its
centre. That reorders what follows, because a fixed-profile STL is not a
deliverable he wants. Two consequences:
`FAILURES.md` still records F-034 as Open, which is correct until the
change lands. Its measurement rewrite is already done (commit
`b255ebb`) — do not redo it.
- **The bore is a declared interface**, with a diameter and a fit class,
specified by what goes through it. It is not a byproduct of the inside
walls. Conduit for the Y, not only rebar.
- **The catalogue front end is the product, not a convenience** that comes
after export. `ROADMAP.md` §4 orders it third; that ordering predates this
and should be read against it.
After that, the roadmap items — read `ROADMAP.md` before starting any:
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.
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.
- STL and STEP export. No CAD kernel is installed in CT 100 (§5).
- Nodes (non-prismatic) and panels (sheet). No representation exists for either.
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
is not what he asked for, and offering it again would be repeating a mistake
already made once.
---
## 5. Facts established by porting
@@ -214,9 +238,16 @@ 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.
Load-bearing, not cosmetic — and it is now the basis of the tolerance model.
Because the oracle holds six significant figures, the last recorded digit of
an area near 200 mm² is worth 0.001 mm², and the whole measured disagreement
between port and reference is one, two or three units in that place. See
`docs/ACCEPTANCE.md`.
Historical note, since it was the visible symptom for two sessions:
`VOLUME_MM3` ends in `_MM3`, so the old comparison judged it at the lengths
tolerance of 1e-4 against a magnitude near 20,000 — 5e-9 relative, demanded
of discretised geometry, by accident of key naming.
### Angles are degrees; the arbitrary constants are contract
@@ -289,7 +320,7 @@ module calls it through the module global, so patching the attribute works.
---
## 7. F-034 — measured, and the decision is ready
## 7. F-034 — measured, decided, closed
**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.
@@ -347,9 +378,25 @@ The change belongs in `test_oracle.py`, which is not hashed:
3. **Accept 30 known failures.** Honest but `make test` is never green and a real
regression hides among them.
**Decided 20 AUG: option 1**, scale-aware bounds for the three
discretisation-limited keys. The change goes in `test_oracle.py`, never
the oracle JSON. Not yet implemented — see §4.
**Closed 22 AUG.** Option 1's *scope* was kept — the three keys, the change in
`test_oracle.py`, the oracle JSON untouched — but its *derivation* was
rejected on measurement and replaced.
Measuring `|dA| / P`, the boundary displacement that would produce each area
discrepancy, gives a maximum of 1.434e-05 mm: one seven-hundredth of the
0.01 mm criterion. A `perimeter × 0.01` bound would have been 1.86 mm² at the
smallest section and 4.54 mm² at the largest, between 1,800 and 4,500 times
the worst real discrepancy, and would have caught nothing. Perimeter also
anti-correlates with the error — the largest discrepancy is at P = 209 mm and
the smallest at P = 454 mm — because the error is driven by how many corners
tip from 12 segments to 13, not by boundary length.
What replaced it: **eight units in the last place of the oracle's
six-significant-figure record**, for those three keys only. Worst case uses
37.5% of its bound, mutation-tested before landing. **`docs/ACCEPTANCE.md` is
the specification** — read it before touching any tolerance, and note E-4:
everything that positions material stays exact at 1e-4 mm and must never be
moved into that regime.
---
@@ -440,7 +487,8 @@ held to it. When in doubt, narrow.
| 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 | **Decided 20 AUG: option 1.** Implementation pending |
| 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 |
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
@@ -451,6 +499,8 @@ a design conversation, not a configuration change.
## 12. Commit log
```
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
7b3182c port: the 3x and 4x profile catalogues; build() now exists
af196a2 docs: one canonical handoff, rewritten in place; F-035