238 lines
10 KiB
Markdown
238 lines
10 KiB
Markdown
# ROADMAP.md
|
||
|
||
What the Mechanical Compiler is for, and the order in which it gets built.
|
||
|
||
| | |
|
||
|---|---|
|
||
| Updated | 2026-08-15 |
|
||
| Companions | `ENVIRONMENT.md`, `STAGING-STATE.md`, `FAILURES.md` |
|
||
|
||
---
|
||
|
||
## 1. Mission
|
||
|
||
**Build the capacity to construct real structures from reclaimed and
|
||
commodity materials, using whatever fabrication a person actually has.**
|
||
|
||
The reference case is a faceted timber shell: planar panels meeting along
|
||
straight fold lines, converging on nodes, sitting on a platform. Buildable
|
||
without a factory, from 3D printing, tabletop CNC, welding, cement casting, and
|
||
COTS stock — provided someone has worked out what the pieces are and how they
|
||
meet.
|
||
|
||
That last clause is the whole project. The Mechanical Compiler exists to make
|
||
the pieces computable, qualifiable, and reproducible by someone who was not
|
||
present when they were designed.
|
||
|
||
**Explicitly not in scope:** building codes, permitting, and jurisdictional
|
||
approval. Qualification and compliance are different animals. A qualification
|
||
says *this member is what it claims to be, made this way, from this stock*.
|
||
Compliance is a jurisdiction-specific argument someone else may build on top.
|
||
Plenty of legitimate contexts — agricultural, temporary, accessory, artistic —
|
||
never need the second thing.
|
||
|
||
The cheap hedge, taken deliberately: **record physical claims, never verdicts.**
|
||
Section modulus, moment of inertia, material provenance, process parameters.
|
||
Those cost nothing to capture, since the geometry layer computes most of them
|
||
anyway, and they are what any future argument would need. Recording a pass/fail
|
||
verdict would bake in a jurisdiction we do not want to be bound to.
|
||
|
||
Measure and attest. Never adjudicate.
|
||
|
||
---
|
||
|
||
## 2. Three artifact classes
|
||
|
||
Reading the reference structure back into components gives three kinds of
|
||
thing, only one of which currently exists.
|
||
|
||
### Members — prismatic, exists
|
||
|
||
Straight runs where panels meet along a fold line. Fixed cross-section, 10 to
|
||
100 feet, made from pallet-strap bundles in a printed enclosure.
|
||
|
||
This is the strap-beam work. Eleven profiles, locked at revision 8.0.0, frozen
|
||
as a 123-case fixture oracle.
|
||
|
||
Read as edge conditions rather than as shapes, the catalogue stops looking
|
||
arbitrary:
|
||
|
||
| Profile | Edge condition |
|
||
|---|---|
|
||
| T | panel-edge stiffener — flange takes the sheet, stem is the web |
|
||
| Y, Three-Fin | seams where three surfaces converge along a line |
|
||
| A Frame | a gable in section |
|
||
| Ring profiles | closed torsion boxes — perimeter, sill, deck edge |
|
||
|
||
The fins are not decoration. They are where the panel gets fastened.
|
||
|
||
### Nodes — non-prismatic, does not exist
|
||
|
||
Where fold lines converge. Look at the hipped ends of the reference structure:
|
||
four or five edges meeting at a vertex, at angles that differ at every corner.
|
||
|
||
Short, geometrically unique, almost certainly fully printed or cast. **Not a
|
||
strap beam, and will not come out of the current library.** No representation
|
||
exists yet.
|
||
|
||
### Panels — sheet, does not exist
|
||
|
||
The planar faces. CNC-cut from sheet goods. Every face in the reference
|
||
structure is planar, which is a hard constraint on the form and also exactly
|
||
what makes it buildable from sheet plus edge members.
|
||
|
||
Convenient technical note: planar polygon algebra, edge extraction and
|
||
unfolding are precisely what Shapely and CadQuery are good at. The toolchain
|
||
choice looks better after seeing the reference than before it.
|
||
|
||
**This is why interface contracts sit at the centre of the design.** A node
|
||
declares what member ends it accepts; a member declares what end it presents; a
|
||
panel declares its edges. Without that, three artifact classes are three
|
||
unrelated generators.
|
||
|
||
---
|
||
|
||
## 3. The gap that changes the backlog
|
||
|
||
If two panels meet at 137°, none of the eleven profiles gives you a member for
|
||
it.
|
||
|
||
`a_frame_leg_angle_deg` is the only dihedral-ish parameter anywhere, and the
|
||
crossbar geometry pins it to 20–53°. The Three-Fin's fins are locked at 120°
|
||
because they derive from a regular polygon. The library solves placement
|
||
against **webs** — the PLA between strap channels — but nothing solves
|
||
placement against **the angle between attachment faces**.
|
||
|
||
Closing this is an addition the architecture already supports:
|
||
`sb_member_on_edge` takes an arbitrary direction, `sb_fin_profile` takes N, and
|
||
the solver converges on measured quantities. A dihedral-parameterised family is
|
||
a new call into the same machinery, not a new machine.
|
||
|
||
**It moves ahead of the rebar-core bore variant in priority.**
|
||
|
||
---
|
||
|
||
## 4. Sequence
|
||
|
||
### Done
|
||
|
||
- **Rev 8.0.0 generators.** Six 3x profiles, five 4x profiles, shared N-generic
|
||
library. Every wall measures its declared minimum; symmetric profiles are
|
||
provably non-chiral; profile parameters are isolated from one another.
|
||
- **Fixture oracle frozen.** 123 cases, `ddd0f154…`, pinned to OpenSCAD 2021.01
|
||
and BOSL2 `92d697c`. The ten rejected cases are part of the contract.
|
||
- **Staging environment.** In progress — see `STAGING-STATE.md`.
|
||
|
||
### Next — the port
|
||
|
||
Port `sb-geom` to Shapely; `pytest -n auto` green against all 123 cases. A port
|
||
that accepts the ten rejections is wrong.
|
||
|
||
Why this rather than more OpenSCAD: exceptions can be caught. Roughly half the
|
||
defensive complexity in the current library exists because an OpenSCAD assert
|
||
is fatal and uncatchable — `sb_path_max_round()` exists solely because a radius
|
||
could not be probed and the failure caught. Testing becomes pytest in CI rather
|
||
than bash scraping echo lines. And SVG generated from Python can emit the
|
||
outline, each strap channel and the bore as separately classed paths, which is
|
||
what makes hover and layer toggling possible in the catalogue.
|
||
|
||
### Then, roughly in order
|
||
|
||
1. **Dihedral-parameterised members** — see §3.
|
||
2. **Rebar-core bore variant** — Utility One's 40-ft side member is three strap
|
||
chords around a rebar core. The bore stops being a byproduct of the inside
|
||
walls and becomes a declared interface with a diameter and a fit class.
|
||
3. **Catalogue front end** — the reason for the web application. Customizer is
|
||
too limiting; SVG plus JavaScript, driven by the same generators.
|
||
4. **Node connectors** — new artifact class, new representation.
|
||
5. **Panels and unfolding** — new artifact class.
|
||
6. **Interface contracts** — formalised once two classes exist to connect. Not
|
||
before; §6 of Part I is right that use cases precede interface
|
||
proliferation.
|
||
7. **Qualification and attestation** — physical claims bound to a generator
|
||
revision. `SB_REVISION` already exists for this.
|
||
8. **Production instance** — automation derived from the proven staging
|
||
procedure. See §5.
|
||
9. **YunoHost packaging** — see §6.
|
||
|
||
Higher polygon counts are **not** on this list. 4x is the end of the N-strap
|
||
family; hexagons and above compose from triangles and squares rather than
|
||
getting their own generators.
|
||
|
||
---
|
||
|
||
## 5. Staging to production
|
||
|
||
`srv-b` is standalone and will remain so. Promotion is export/restore, not
|
||
cluster migration.
|
||
|
||
The order is deliberate: **manual first, then automation derived from the
|
||
proven procedure.** `FAILURES.md` is the evidence for why. Three specification
|
||
assumptions were wrong in ways only contact with a host revealed, and scripts
|
||
written from the specification alone would have faithfully reproduced all
|
||
three — one of them producing a container that booted, looked healthy, and had
|
||
four broken services.
|
||
|
||
When production is provisioned, the automation is written from `FAILURES.md`
|
||
first and `ENVIRONMENT.md` second.
|
||
|
||
Production differs from staging in four known ways, recorded so they are not
|
||
invented under pressure:
|
||
|
||
| | Staging | Production |
|
||
|---|---|---|
|
||
| Certificate | local staging CA | Let's Encrypt, per-name, no wildcard |
|
||
| FQDN | `mechanical-compiler.dev.infra` | `mechanical-compiler.manufacturing.kane-il.us` |
|
||
| Proxmox firewall | disabled | must be revisited |
|
||
| Proxy location | CT 101 on the same host | undecided — **not on the WireGuard side**, since the current NAT is outbound-only |
|
||
|
||
Three variables change in `mechcomp.env`: `MECHCOMP_ENV`, `MECHCOMP_BIND`,
|
||
`MECHCOMP_BASE_URL`. Nothing else.
|
||
|
||
---
|
||
|
||
## 6. Distribution
|
||
|
||
**YunoHost and Docker are parallel targets, not sequential.** YunoHost apps
|
||
install natively — apt, venv, systemd, nginx — and the project does not want
|
||
Docker inside YunoHost. Neither blocks the other, and neither should be built
|
||
"in order to" reach the other.
|
||
|
||
On the catalog's weight criterion: it reads "resource-hungry **compared to
|
||
their features**" and is aimed at marginal apps. `fab-manager_ynh` is in the
|
||
catalog; `paperless-ngx_ynh` declares nine apt dependencies including
|
||
postgresql and redis. The useful comparison is those, not a hello-world.
|
||
|
||
On provenance: the project is LLM-generated under human direction, stated
|
||
plainly in the README and in any submission. The catalog policy is a **quality
|
||
bar with a disclosure requirement, not a ban** — it rejects generated packages
|
||
that do not follow `example_ynh`, citing verbose code, hallucinated helpers and
|
||
non-standard directory architectures, then explicitly permits AI use where the
|
||
maintainer is transparent and can explain every line.
|
||
|
||
Two consequences. The package is drafted against `example_ynh` and reviewed by
|
||
CIVICVS as his own work; anything he would not defend in a review thread does
|
||
not ship. And disclosure belongs in the README, not in the pitch — if
|
||
provenance becomes the pitch, the project gets judged on that axis instead of
|
||
on whether it makes distributed manufacturing capacity legible.
|
||
|
||
---
|
||
|
||
## 7. Standing principles
|
||
|
||
1. **Measure, do not assume.** Every wall thickness in rev 8 is a measured
|
||
value. Connectivity is necessary and never sufficient — revision 7 passed
|
||
cross-sections joined by 0.13 mm.
|
||
2. **Solve numerically against the real quantity.** Closed-form placement is
|
||
where the wrong-by-a-cosine errors came from.
|
||
3. **Structure before decoration.** Members butt through their neighbours;
|
||
fillets are applied on top of that overlap, never instead of it.
|
||
4. **Hash inputs, not outputs.** Mesh bytes are not reproducible across
|
||
toolchain versions. Hashing parameters plus generator revision keeps a
|
||
qualification valid across an upgrade that did not change the geometry.
|
||
5. **A permanent deviation is not a deviation — it is the specification.**
|
||
Promote it and delete the exception.
|
||
6. **Record the failure before correcting it.** Then apply the smallest
|
||
corrective change, not the one that also fixes three things you were
|
||
worried about.
|