ENVIRONMENT 5.4: add the DIVERGENCE marker, and record five unmet requirements

The marker vocabulary had six entries - REQ, PREF, PROVEN, ASSUMED, DEFERRED, INSTANCE. They could say how strong a requirement was and where it came from. None could say it was not being met. That gap is why five unmet REQs in this document went unrecorded for weeks: there was no notation to write them in, so nobody wrote them.

DIVERGENCE is added as the seventh, with the rule attached. A REQ that stops being met does not become a PREF and is not rewritten to describe what was built. It stands, the gap is recorded, the correction is owed by the thing. A specification that agrees with whatever exists specifies nothing. No requirement in this revision was lowered.

DIV-001 at section 14 item 11: the AGPL section 13 source link is a numbered constraint the application code will follow, and it is not met on a public deployment. DIV-002 at section 9 twice and section 8.3: the FastAPI control plane, the worker unit and the SQLite queue do not exist, and five declared dependencies are imported by nothing. DIV-003 at sections 1.3 and 5.2: the instance is publicly reachable against three REQs. DIV-004 at section 11: eight declared keys are read by nothing.

Section 11 also gains MECHCOMP_MAX_EXPORT_MM, read by the code since cdde394 and declared nowhere. That is the divergence running the other way and the harder one to notice, because a missing key looks like nothing at all.

Section 5.2 records that the divergence may be a misfiling rather than a violation. WORK-ORDER-004 section 3 says dev abbreviates Mechanical Compiler Developers, that the name is production, and that it appears on printed material. If that reading holds, 5.2 never applied to this instance and 5.3 does. Written as a decision, not a correction.

Section 1.1 gets a note that it was right about CadQuery all along. DIV-005 was opened against this paragraph rather than against HANDOFF section 5, which had it backwards for three weeks.

Section 15 gate 3 now states its status: dependencies, toolchain image and scaffolding all met, worker unit not met, gate does not pass. Section 19 records the port complete since 20 AUG, retained because the rejected cases being part of the contract is why the oracle means anything.

STAGING-STATE specification reference updated from revision 5 to 5.4.

Applied by anchored patcher. The first attempt failed on one anchor - the env block comment column was 35, not 39 - and nothing was written, including the thirteen correct patches. Suite 643 passed, oracle intact. Documentation only.
This commit is contained in:
2026-09-14 04:26:44 -05:00
parent bc291822e1
commit eb537768ef
2 changed files with 92 additions and 6 deletions
+91 -5
View File
@@ -4,9 +4,9 @@ Specification for a Mechanical Compiler instance.
| | |
|---|---|
| Revision | 5.3 (2026-08-18) |
| Revision | 5.4 (2026-09-13) |
| Supersedes | Revisions 1 through 4 |
| Basis | Revision 4, reconciled against the proven staging build, work orders 002 and 003, and container standardisation |
| Basis | Revision 5.3, reconciled against the running instance during the documentation audit of 2026-09-13. Divergences recorded; no requirement lowered. |
| Scope | **Host-agnostic.** Applies to any instance. |
| Instance state | `STAGING-STATE.md`, and later `PRODUCTION-STATE.md` |
| Failure evidence | `FAILURES.md` |
@@ -44,6 +44,18 @@ disagreed with it. Everything specific to `srv-b` has been removed.
| **ASSUMED** | Decided without confirmation. Listed in §16. |
| **DEFERRED** | Deliberately postponed. Not a defect, not a gap. |
| **INSTANCE** | A value supplied per instance, not fixed here. |
| **DIVERGENCE** | The requirement stands and is **not currently met**. Cites its entry in `DIVERGENCES.md`. |
**DIVERGENCE is never a reason to lower a requirement.** A REQ that stops being
met does not become a PREF, and it is not rewritten to describe what was built.
It stands, the gap is recorded, and the correction is owed by the thing rather
than by this document. A specification that agrees with whatever exists
specifies nothing.
Added 2026-09-13. Its absence is why five unmet requirements in this document
went unrecorded for weeks — there was no notation to write them in, so nobody
wrote them. The six markers above could say how strong a requirement was and
where it came from, and none could say it was not being met.
### Provisioning method
@@ -83,6 +95,11 @@ defence against YunoHost's "resource-hungry" criterion; that was overcalibrated.
The criterion reads "compared to their features" and is aimed at marginal apps.
The boundary stays; the apology is gone.
**Verified 2026-09-13** — `cadquery` and `OCP` both import in CT 100. This
document was correct; `HANDOFF.md` §5 had said the opposite for three weeks, and
DIV-005 was opened against this paragraph rather than against that one. Closed,
and recorded there as having been written backwards.
### 1.2 YunoHost and Docker are parallel targets, not sequential
YunoHost apps install natively — apt, venv, systemd, nginx — and the project
@@ -98,6 +115,10 @@ directly would never exercise the `X-Forwarded-Proto` path.
Staging is not publicly reachable and does not use the public FQDN. That forces
the promotion path to be exercised rather than assumed.
**DIVERGENCE (DIV-003)** — the `srv-b` instance has been publicly reachable at
`dev.mechcomp.kane-il.us` since 2026-09-11. The requirement stands and the
instance does not meet it. §5.2 carries the same divergence with its reasoning.
### 1.4 Directory layout mirrors YunoHost conventions
`install_dir`, `data_dir`, a dedicated system user, a port treated as data. The
@@ -307,6 +328,19 @@ hyphenated FQDN cannot serve as the token.
publicly-trusted certificate: it consumes rate limit against a name production
needs clean, and puts a development host on the internet.
**DIVERGENCE (DIV-003)** — all three are unmet on `srv-b` as of 2026-09-11.
Public `A` and `AAAA` records exist and a Let's Encrypt certificate terminates on
the hub. The reasoning above is a live claim nobody has rebutted, and half of it
is already visible: that certificate expires 2026-12-10 and **no renewal has
been observed to succeed for this name**.
Whether this instance is still *non-production* is itself unsettled.
`WORK-ORDER-004` §3 records that `dev` abbreviates *Mechanical Compiler
Developers*, that the name is production, and that it appears on printed
material. If that reading holds, §5.2 never applied to it and §5.3 does — which
would make this a misfiled instance rather than a violated requirement. That is
a decision, not a correction.
**PROVEN** — A locally generated CA is sufficient and is the fallback whenever a
site CA has no discoverable issuance path. The point of the TLS step is
exercising termination and header forwarding, not the trust chain. Replacing the
@@ -508,6 +542,12 @@ use `--break-system-packages`.
| `requirements-base.txt` | shapely, fastapi, uvicorn, pydantic, sqlalchemy, jinja2, pytest, pytest-xdist |
| `requirements-cad.txt` | cadquery / build123d |
**DIVERGENCE (DIV-002)** — `fastapi`, `uvicorn`, `pydantic`, `sqlalchemy` and
`jinja2` are installed on every instance and imported by nothing in the composer.
They describe the architecture §9 specifies and nobody built. The manifest is
not wrong about what it installs; it is a faithful description of an unbuilt
design.
CI runs the suite twice — with both, then with base alone — and the second run
must pass. That is the mechanism keeping §1.1 honest.
@@ -522,6 +562,17 @@ must pass. That is the mechanism keeping §1.1 honest.
| `mechcomp.service` | FastAPI/uvicorn. Serves the catalogue, accepts jobs, returns cached artifacts. **Never runs geometry.** |
| `mechcomp-worker.service` | Consumes the queue, runs generators, writes artifacts. |
**DIVERGENCE (DIV-002)** — neither unit exists as specified. `mechcomp.service`
runs a standard-library `http.server` and builds geometry synchronously in the
request thread, so the control plane *does* run geometry.
`mechcomp-worker.service` does not exist; `src/mechcomp/worker/` is a 36-byte
stub.
The requirement stands. §1.1 reason 1 calls this separation a requirement
**regardless of distribution**, and reason 2 gives its purpose: a slow import
must never land in the request path for a page that only draws a cross-section.
Geometry itself now does, on a world-reachable service with no authentication.
**REQ** — Both:
```ini
@@ -556,6 +607,9 @@ container.
RabbitMQ. A table with a status column and a claim query is correct at this
scale and adds no services to either packaging target.
**DIVERGENCE (DIV-002)** — no queue and no database exist. Nothing has ever
written to `MECHCOMP_DATA_DIR`.
**REQ (F-019)** — **Anything a proof depends on must be supervised.** This
includes temporary scaffolding. A placeholder backend used to prove the proxy
chain before the application exists is a systemd unit, obviously named and
@@ -607,6 +661,7 @@ MECHCOMP_ENV= # staging | production
MECHCOMP_BIND= # single address — see below
MECHCOMP_PORT=
MECHCOMP_BASE_URL=
MECHCOMP_MAX_EXPORT_MM= # bound on the exported sweep length
MECHCOMP_DATA_DIR=/var/lib/mechcomp
MECHCOMP_LOG_LEVEL=info
MECHCOMP_DB_URL=sqlite:////var/lib/mechcomp/db/mechcomp.sqlite3
@@ -616,6 +671,21 @@ MECHCOMP_ARTIFACT_RETENTION_DAYS=30
MECHCOMP_SECRET_KEY= # generated on first provision, never committed
```
**DIVERGENCE (DIV-004)** — the application reads four of these: `MECHCOMP_BIND`,
`MECHCOMP_PORT`, `MECHCOMP_MAX_EXPORT_MM` and `MECHCOMP_BASE_URL`. The other
eight are read by nothing. Most belong to the architecture DIV-002 records as
unbuilt, so this is largely the same divergence seen from the configuration
side.
`MECHCOMP_MAX_EXPORT_MM` was added to this list on 2026-09-13. It had been read
by the code since `cdde394` and declared nowhere — the divergence running the
other way, and the harder one to notice, because a missing key looks like
nothing at all.
`MECHCOMP_SECRET_KEY` deserves its own note: a secret that nothing reads is
protecting nothing, and its presence implies a session or signing mechanism that
does not exist.
**REQ** — `MECHCOMP_BIND` is a **single address**. Loopback is not additionally
bound.
@@ -742,6 +812,10 @@ committed; an example with empty values is.
10. The test suite passes with `requirements-cad.txt` uninstalled.
11. AGPL-3.0 §13 requires network users be offered the source. The web tier
carries a visible source link to the repository. A licence obligation.
**DIVERGENCE (DIV-001) — not met.** The served page carries no such link,
and the deployment has been public since 2026-09-11. This is the only unmet
requirement in this document whose consequence falls outside the project,
and the smallest to correct.
### 14.1 Test validity
@@ -846,6 +920,12 @@ the containers have no reason to originate mail. Not gated on gate 1.
Dependencies installed from committed manifests. Real service and worker units
active. Reference toolchain image reproduces `ddd0f154…`. Scaffolding removed.
**Status 2026-09-13 — the gate does not pass.** Dependencies: met. Toolchain
image: met, present in CT 100 and the oracle reproduced inside it on
2026-08-19. Scaffolding: met, `mechcomp-placeholder.service` retired 2026-09-11
with the unit file left on disk disabled as the rollback path.
**Worker unit: not met (DIV-002).**
### Gate 4 — Backup
Undefined pending a strategy decision.
@@ -913,6 +993,12 @@ The useful comparison for acceptable weight is `paperless-ngx_ynh` or
## 19. First application work item
Port `sb-geom` to Shapely; `pytest -n auto` green against the 123 frozen cases in
`strap-beam-fixtures-8.0.0.json`. The ten rejected cases are part of the
contract: a port that accepts them is wrong.
**Complete 2026-08-20.** `sb-geom` is ported to Shapely and the suite is green
against the 123 frozen cases in `strap-beam-fixtures-8.0.0.json`. The ten
rejected cases are part of the contract: a port that accepts them is wrong, and
this one does not.
Retained rather than deleted because the framing outlived the task — the
rejected cases being part of the contract is the reason the oracle means
anything at all. What comes next is in `ROADMAP.md` §4, not here; an environment
specification should not carry a work queue.
+1 -1
View File
@@ -6,7 +6,7 @@ Live state of the Mechanical Compiler staging instance on `srv-b`.
|---|---|
| Updated | 2026-09-13, after the documentation audit |
| Instance | Staging / development |
| Specification | `ENVIRONMENT.md` revision 5 |
| Specification | `ENVIRONMENT.md` revision 5.4 |
| Failure log | `FAILURES.md` |
| Process | `PROCESS.md` — **read first** |
| Method | Manual, one command group at a time |