From a00ba354518f5e3ede951d8c98e6511446fd7df3 Mon Sep 17 00:00:00 2001 From: TheRON Date: Sun, 16 Aug 2026 12:00:42 -0400 Subject: [PATCH] Roadmap What the Mechanical Compiler is for, and the order in which it gets built. --- docs/ROADMAP.md | 237 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 237 insertions(+) create mode 100644 docs/ROADMAP.md diff --git a/docs/ROADMAP.md b/docs/ROADMAP.md new file mode 100644 index 0000000..2fded99 --- /dev/null +++ b/docs/ROADMAP.md @@ -0,0 +1,237 @@ +# 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.