Files
TheRON 0c220f449b ROADMAP: section 7 is binding. PRECISION: prismatic-only is a limit
ROADMAP opened by saying nothing in it is a promise. Section 7 holds eighteen standing principles cited by number as settled law from commit messages and from other documents - 4 governs what is hashed, 13 defines what a standard is, 17 governs what may write to a record, 18 governs how a contribution is admitted. A reader taking the header at its word would conclude Principle 17 is optional. The disclaimer now says what it always meant: it covers section 4 sequence and section 5 assumptions, not section 7.

Principle 5 gets the same qualification PROCESS section 8 got. A permanent deviation is the specification is right about facts on a host and would be licence to lower a REQ if read without limit.

PRECISION section 10 requires every section 7 entry to say whether it is a limit that work may lift or a boundary that was chosen. The prismatic-only entry said neither, which is the single most consequential ambiguity in the document. It is a limit, and the reason is now recorded: the oracle is a two-dimensional oracle with a scalar length multiplier - every recorded value is a property of the cross-section except LENGTH_MM, VOLUME_MM3 and MASS_G, and volume equals rounded section area times length to within 3.6e-12 across all 113 accepted cases. Lift it carelessly and that relation stops holding; nothing fails, it just stops meaning what it means. Anything keeping each station two-dimensional preserves it.

Also in PRECISION: STL export landed and is no longer planned. An absent export format is a limit; the refusal to emit toolpaths is a boundary.

ROADMAP section 4a corrected to match STAGING-STATE section 3a: nothing here is implemented on Kane Fabric, and SASE was used and never defined. The port is recorded done. The seed commit and test count are removed as derivable.

IDENTITY-CONTRACT: the rewrap owed from a76879f.

Applied by anchored patcher. Suite 643 passed, oracle intact. Documentation only.
2026-09-14 04:45:04 -05:00

354 lines
17 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# ROADMAP.md
What the Mechanical Compiler is for.
**This document records intent, not commitment.** It is a reference for what the
project aims at and why; it does not schedule work and nothing here is a promise
that something will be built. `HANDOFF.md` §4 holds the actual order. Where the
two disagree, §4 wins on sequence and this document wins on purpose.
**§7 is the exception, and it is binding.** The eighteen standing principles are
cited by number as settled law from commit messages and from other documents —
Principle 4 governs what is hashed, 13 defines what a standard is, 17 governs
what may write to a record, 18 governs how a contribution is admitted. A reader
taking the paragraph above at its word would conclude Principle 17 is optional.
It is not. The disclaimer covers §4's sequence and §5's assumptions; it has never
covered §7, and said so nowhere until 2026-09-13.
§§1, 2, 3 and 7 are the durable parts and are still correct. §4's sequence and
§5's production assumptions had both drifted since 18 AUG. The documentation
audit of 2026-09-13 corrected what was factually wrong here and in the companion
documents; questions that remain genuinely open are in `HANDOFF.md` §11, and
requirements that stand and are not met are in `DIVERGENCES.md`.
| | |
|---|---|
| Updated | 2026-09-13 |
| Companions | `PROCESS.md`, `ENVIRONMENT.md`, `STAGING-STATE.md`, `FAILURES.md`, `DIVERGENCES.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 infrastructure accepted, 2026-08-16.** Host, both containers,
network isolation, bastion access, TLS trust, reverse proxy and the
application filesystem foundation are proven on `srv-b`. Mail alerting and
explicit disk monitoring are deferred; backup strategy is postponed by
operator decision; application deployment remains blocked on application
code. See `STAGING-STATE.md`.
- **Mail alerting accepted, 2026-08-17.** Delivered end to end and received
twice.
- **Disk monitoring accepted, 2026-08-17.** Four P410i members explicitly
monitored, four test alerts received, serial numbers recorded, reboot-proven.
- **Container SMTP egress blocked, 2026-08-17.** The project-local half of F-025
is corrected; the estate question about `wg-pk` client trust remains open.
- **Repository seeded, 2026-08-18.** Reference implementation, frozen oracle,
pinned toolchain and test harness. Dependencies installed and the oracle
verified in-container. The commit and the test count are not recorded here —
`git log` and `make test` report them, and the figures that used to sit on
this line described the repository for two days.
- **Container baseline established, 2026-08-18.** All three containers on
`srv-b` conform, asserted by an executable check rather than by inspection.
### The port — done, 2026-08-20
`sb-geom` is ported to Shapely and the suite is green against all 123 cases. A
port that accepted the ten rejections would have been wrong; this one does not.
The reasoning below is kept because it explains a choice that is now
load-bearing rather than prospective.
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.
---
## 4a. Parallel project
**Kane Fabric** — a separate project on the same host. Each project has its own
FQDN and its own container; they share the service bridge, the WireGuard hub and
the proxy.
An earlier version of this paragraph called Kane Fabric the platform on which
SASE, HOA Diagnostics, the Mechanical Compiler and other SASE-consuming projects
are implemented. Nothing here is implemented on Kane Fabric, and `SASE` was used
without being defined anywhere in this repository. Corrected 2026-09-13 on the
operator's statement of the topology.
It is recorded here so its existence is known, not because it creates work.
Kane Fabric owns geographic state; the Mechanical Compiler owns member
geometry, qualification and workflow state. Both sets of documents describe a
future interface between them; **neither defines it, and that is deliberate.**
Part I §6 holds that use cases precede interface proliferation, and no use case
crosses the boundary yet.
The contract becomes real work when a compiled member first needs to be sited
somewhere. It will be cheaper to define then, against a concrete artifact.
---
## 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. **This governs facts about a host, not a
requirement the code has not met.** A REQ is never lowered to match what was
built: it stands, the gap is recorded in `DIVERGENCES.md`, and the correction
is owed by the code. A specification that agrees with whatever exists
specifies nothing.
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.
7. **Prove the negative.** Isolation is asserted by showing the forbidden path
fails, never by showing the interface is gone (F-018). Health is asserted
after a reboot, never before (F-021).
8. **Handoff is not delivery.** An upstream acceptance code proves the message
left, not that it arrived (F-023). The same distinction applies wherever a
subsystem reports success on behalf of something downstream.
9. **Record what a change grants, not only what it repairs.** A trust rule
added to fix one rejection may authorise far more than the case that
prompted it (F-025).
10. **Shared infrastructure is not ours to reconfigure.** An instance may
configure its own client side; changes further down the chain are escalated
with evidence.
11. **A test must distinguish tool failure from the condition it tests.** One
whose failure mode is indistinguishable from success manufactures
confidence (F-027). Every negative assertion first establishes that it could
have observed the positive case.
12. **A component surviving its own restart is not proven to survive the
host's.** Different machinery; assert against the one that matters (F-026).
13. **A standard must be executable.** If conformance cannot be asserted by
running something, it is not a standard but a recollection, and it will
drift. A property not checked is not part of the standard (F-031).
14. **Check the thing, not something related to it.** An assertion inferred
from an adjacent observation is not evidence, however reasonable the
inference (F-031).
15. **Verify by counting, not by scanning.** A long, correct-looking list is
exactly where an unexpected 437 files hide (F-029).
16. **Conformance precedes backup.** Backing up an unverified configuration
preserves the confusion along with the data, and a restore returns it
faithfully.
17. **Nothing approximate may write to anything reproducible.** Principle 4
governs what is hashed; this governs what may reach the thing being hashed.
A search index, a documentation system or a language model may read design
records freely and may suggest anything to a person. None of them may
originate a parameter that lands in a record. The failure is silent and
compounding: if suggestions become records and records become the corpus,
the corpus teaches itself its own guesses, and every record is still
perfectly correct about what it was built from. A suggestion is an input to
a person, never an input to a build — and where one informed a build, the
record's `note` field says so, being already excluded from both hashes.
18. **A contribution is admitted by the oracle, not parsed by the compiler.**
The path from a new profile to the catalogue runs: author it in whatever
notation suits you, freeze its cases inside the pinned toolchain, port it,
and admit it when the oracle passes byte-identically. This has happened
twice, with both `.scad` generators. The consequence is that no second
geometry engine is ever kept in step with the first, and `legacy/` holds the
reference tier rather than superseded code. When someone asks for another
input format, the answer is that notation never runs in production — only
the kernel does.