Conformance updates.

This commit is contained in:
2026-08-18 10:33:26 -04:00
parent c7e32d8e07
commit 6967eef59c
5 changed files with 319 additions and 15 deletions
+49 -2
View File
@@ -4,9 +4,9 @@ Specification for a Mechanical Compiler instance.
| | |
|---|---|
| Revision | 5.2 (2026-08-17) |
| Revision | 5.3 (2026-08-18) |
| Supersedes | Revisions 1 through 4 |
| Basis | Revision 4, reconciled against the proven staging build, then work orders 002 and 003 |
| Basis | Revision 4, reconciled against the proven staging build, work orders 002 and 003, and container standardisation |
| Scope | **Host-agnostic.** Applies to any instance. |
| Instance state | `STAGING-STATE.md`, and later `PRODUCTION-STATE.md` |
| Failure evidence | `FAILURES.md` |
@@ -769,6 +769,44 @@ wrong form reported a pass against containers that were not running.
---
## 14a. Conformance
**REQ** — An instance carries an executable **baseline check**: read-only,
runnable at any time, exiting non-zero when any container diverges from the
standard.
**REQ** — **A property not checked by it is not part of the standard.** This is
what makes conformance terminate. Without it, divergence is discovered one
property at a time whenever something behaves oddly, and the process never
finishes because nothing states what "the same" means. A property that must be
uniform belongs in the check, not in an operator's memory.
**REQ (F-031)** — The check must examine **the thing being standardised**. An
assertion derived from a related observation is not a check. Postfix
configuration on the host says what the host does; it says nothing about the
containers, and a standard asserted that way was wrong on two of three.
**REQ** — Each failure names the failure-log entry that established the
requirement, so the reason survives the person who found it.
**REQ (F-032)** — Host-level requirements belong to the host, not to whichever
project discovered them first. Where several projects share a host, the check
is host-level and covers every container regardless of owner. Two projects on
this host independently rediscovered the same two defects before this was done.
### Mail
**REQ** — **Containers do not originate mail.** Only the host does, and only its
own operational alerts. A container with a mail agent installed but SMTP egress
blocked is worse than either alone: it queues indefinitely and delivers nothing,
while appearing configured.
Application mail — participant notification and similar — is a separate design
problem with its own delivery and inbound requirements. It is not solved by
leaving a partially configured agent in a container.
---
## 15. Acceptance gates
**REQ** — Five independent gates. Revision 4 ran them as one list, which meant
@@ -812,6 +850,15 @@ active. Reference toolchain image reproduces `ddd0f154…`. Scaffolding removed.
Undefined pending a strategy decision.
**REQ** — **Conformance is a precondition, not a companion.** Backup work does
not begin until the baseline check (§14a) exits zero, and the check forms part
of restore verification.
A backup of an unverified configuration does not preserve a system; it
preserves a state of confusion, and a restore returns that state faithfully.
This was not hypothetical: a backup taken before 2026-08-18 would have restored
two containers that queue mail forever (F-031).
### Gate 5 — Production automation
Idempotent scripts derived from a proven manual procedure. Firewall posture
+99 -1
View File
@@ -6,7 +6,7 @@ Compiler environment.
| | |
|---|---|
| Scope | All instances. Staging entries are marked `srv-b`. |
| Updated | 2026-08-17, after work order 003 |
| Updated | 2026-08-18, after repository seeding and container standardisation |
| Method | `PROCESS.md` section 7 |
| Rule | Append only. Never edit an entry except to add a `Resolution` line. |
| Numbering | Sequential, never reused. See §0 on the renumbering. |
@@ -634,6 +634,100 @@ device class.
---
### F-029 — pip cache written into the repository working tree
CT 100. Repository seeding.
**Observed:** `git add -A` staged 465 files where 28 were expected. The extra
437 were `.cache/` — pip's download cache.
**Cause:** **Proven.** The service user's home is the install directory, so
`$HOME/.cache` **is** `/var/www/mechcomp/.cache`. `make deps` wrote there.
**Correction:** `.cache/`, `.local/`, `.ssh/`, `.gitconfig` and `.lesshst`
added to `.gitignore`; the cache unstaged before committing.
**Consequence:** Setting the service user's home to `install_dir` is correct
and matches YunoHost convention, but it means **any tool writing to `$HOME`
writes into the working tree**. `.gitignore` must anticipate that from the
first commit.
Method note: reading the staged list by eye showed nothing wrong. Counting it
and grouping by top-level directory found the problem immediately. **Verify by
counting, not by scanning** — a long correct-looking list is exactly where an
extra 437 files hide.
---
### F-030 — a network command in a work order could hang indefinitely
`srv-b`. Repository seeding.
**Observed:** An SSH authentication test was issued with neither
`ConnectTimeout` nor `BatchMode`. Gitea's SSH is on port 42022, so the attempt
on 22 hung and the operator had to interrupt it.
**Cause:** **Proven.** Missing timeout options, and an incorrect assumption
about the port.
**Correction:** Re-issued with `-o ConnectTimeout=10 -o BatchMode=yes -p 42022`,
after a `timeout`-wrapped reachability probe that could not hang.
**Consequence:** **Every network command in a work order carries an explicit
timeout.** A command that can hang strands the session, and the operator cannot
tell a hang from slow progress. Reachability is probed with `timeout` before any
client is invoked.
Also recorded, having been got wrong twice: Gitea **deploy tokens** are
account-level under user Settings, not repository settings. Repository-scoped
credentials are **deploy keys**. SSH here is on **42022**, so remotes need
`ssh://git@host:42022/owner/repo.git` — the `git@host:path` shorthand cannot
carry a port.
---
### F-031 — a standard was asserted from a check that never examined the thing
CT 100, CT 101, CT 102. Container standardisation.
**Observed:** The architect stated that CT 100 and CT 101 had no mail agent, and
standardised CT 102 by purging Postfix to match. The first run of
`ct-baseline.sh` reported a mail agent installed on **both** CT 100 and CT 101.
CT 102 — the container just "corrected" — was the only one conforming.
**Cause:** **Proven.** The earlier assertion came from inspecting Postfix
configuration and `/etc/aliases` **on `srv-b`**, during work order 002. That
established what the host does. It said nothing about the containers, and the
containers were never examined.
**Correction:** Postfix purged from CT 100 and CT 101. Queues were checked first
and both were empty, so nothing was lost. Re-run: 62 passed, 0 failed.
**Consequence:** **A standard asserted from a proxy observation is not a
standard.** The check must examine the thing being standardised. This is the
same class as F-027 — a result that cannot distinguish the case it claims to
test — but reached through inference rather than through shell semantics.
It is also the justification for `ct-baseline.sh` existing. Divergence had been
discovered by asking, one property at a time, whenever something behaved oddly.
That does not terminate: every check finds a new difference because nothing
states what "the same" means. The script is that statement, and it disagreed
with the architect on its first run.
---
### F-032 — the same host defects were discovered independently by two projects
`srv-b`. Cross-project.
**Observed:** Kane Fabric's `INFRASTRUCTURE_BASELINE.md`, written independently,
records `nesting=1,keyctl=1` against `226/NAMESPACE` systemd failures, and that
minimal Debian CTs lack a generated `en_US.UTF-8`. These are F-003 and F-004,
found again on the same host, in different words, at a different time.
**Cause:** **Proven.** Both are properties of the Proxmox/Debian 12 host, not of
either application. Neither project's documentation was visible to the other.
**Correction:** None required — both projects reached the correct conclusion.
**Consequence:** **Host-level requirements belong to the host, not to whichever
project discovered them first.** `ct-baseline.sh` encodes them once and checks
every container on `srv-b` regardless of owner, so the third project does not
have to discover them a third time.
Note that `keyctl=1` is required **only where Docker runs**. CT 101 was proven
to work with `nesting=1` alone (F-003). Kane Fabric's baseline currently
specifies both; if CT 102 runs no containers, `keyctl` can be dropped.
---
## Open, not closed
| # | Status |
@@ -649,5 +743,9 @@ device class.
| F-026 | **Corrected** 2026-08-17. Reboot persistence proven. |
| F-027 | **Corrected** 2026-08-17. Applies retroactively to F-018's proofs. |
| F-028 | **Corrected** 2026-08-17. |
| F-029 | **Corrected** 2026-08-18. |
| F-030 | **Corrected** 2026-08-18. |
| F-031 | **Corrected** 2026-08-18. Root cause of `ct-baseline.sh`. |
| F-032 | **Closed** 2026-08-18. No correction required; encoded in `ct-baseline.sh`. |
Everything else is closed with a proven cause and a proven correction.
+28
View File
@@ -356,6 +356,28 @@ needs a directory to exist, create it in the same group.
---
## 9a. The baseline check
`ct-baseline.sh` is the executable definition of the container standard on this
host. Read-only, runnable at any time, exits non-zero on divergence.
Run it:
- before starting work on a container;
- after any change to a container or to host firewall rules;
- after any host reboot;
- before considering backup work (see `ENVIRONMENT.md` §15 gate 4).
**A property not checked by it is not part of the standard.** If something
should be uniform across containers, add it to the script. If it should not,
leave it out and stop worrying about the difference. That is the whole point:
it converts an endless comparison into a pass or a fail.
It covers containers belonging to more than one project, and encodes host
requirements neither project owns alone. Treat it as host property.
---
## 10. Current mode
**Infrastructure: complete and accepted.** Host, containers, network isolation,
@@ -366,6 +388,12 @@ bastion access, TLS, reverse proxy, mail alerting, disk monitoring. See
more than an afternoon; the documents are in Gitea. This changes when
`artifacts/` stops being empty.
**Repository seeded** at `c7e32d8`: reference implementation, frozen oracle,
pinned toolchain, test harness. Dependencies installed in CT 100, oracle
verified in-container, `3 passed, 236 skipped`.
**Container baseline established.** All three containers on `srv-b` conform.
**Development: starting.** First work item is the Shapely port —
`pytest -n auto` green against the 123 frozen cases.
+35 -1
View File
@@ -4,7 +4,7 @@ What the Mechanical Compiler is for, and the order in which it gets built.
| | |
|---|---|
| Updated | 2026-08-17 |
| Updated | 2026-08-18 |
| Companions | `PROCESS.md`, `ENVIRONMENT.md`, `STAGING-STATE.md`, `FAILURES.md` |
---
@@ -133,6 +133,11 @@ a new call into the same machinery, not a new machine.
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 at `c7e32d8`. Dependencies installed, oracle
verified in-container, `3 passed, 236 skipped`.
- **Container baseline established, 2026-08-18.** All three containers on
`srv-b` conform, asserted by an executable check rather than by inspection.
### Next — the port
@@ -172,6 +177,24 @@ getting their own generators.
---
## 4a. Parallel project
**Kane Fabric** — a separate project on the same host, and the platform on
which SASE, HOA Diagnostics, the Mechanical Compiler and other SASE-consuming
projects are implemented.
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
@@ -264,3 +287,14 @@ on whether it makes distributed manufacturing capacity legible.
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.
+108 -11
View File
@@ -4,7 +4,7 @@ Live state of the Mechanical Compiler staging instance on `srv-b`.
| | |
|---|---|
| Updated | 2026-08-17, after work order 003 (monitoring, SMTP egress) |
| Updated | 2026-08-18, after repository seeding and container standardisation |
| Instance | Staging / development |
| Specification | `ENVIRONMENT.md` revision 5 |
| Failure log | `FAILURES.md` |
@@ -329,7 +329,10 @@ work. None is a defect.
the four members, so drive age is a known quantity rather than an
assumption. `smartctl -d cciss,N -A /dev/sda`. Read-only, one command.
- [ ] **Backup infrastructure, entirely.** Postponed 2026-08-16 because the
strategy may change: `vzdump` job, archive sizing, retention, free-space
strategy may change, and reaffirmed 2026-08-18 on stronger grounds: a
backup of an unverified configuration restores the confusion along with
the data. **Entry condition: `ct-baseline.sh` exits 0.** Scope when
resumed: `vzdump` job, archive sizing, retention, free-space
guard, host-side pull, `mechcomp-backup`, backup alerting, gold media,
3+ TB redundancy.
@@ -348,6 +351,91 @@ hold the only instance with no monitoring, no alerting and no backup.
---
## 3b. Container baseline
**`ct-baseline.sh` is the definition of "standard configuration" on this host.**
It changes nothing, runs any time, and exits 0 only when every container
conforms.
```
last run 2026-08-18
result 62 passed, 0 failed, 3 informational
scope srv-b, CT 100, CT 101, CT 102
```
**A property not checked by that script is not part of the standard.** That is
what makes it terminate. Divergence used to be discovered by asking, one
property at a time, whenever something behaved oddly — which never finishes,
because nothing stated what "the same" meant. If a property should be uniform,
it belongs in the script rather than in someone's memory.
What it asserts, per container: `onboot`, unprivileged, `nesting=1`, a single
interface on the service bridge, systemd `running` with zero failed units, one
interface stanza, Debian 12, timezone, **generated** locale, `curl`,
`ca-certificates`, `openssh-server`, sshd active, admin account with
`authorized_keys` at `0600`, **no mail agent**, SMTP egress blocked, LAN
gateway unreachable. Host-level: systemd health, both firewall rules, `smartd`
device count, bastion key.
Each failure cites the failure entry that established the requirement, so the
reason survives the person.
### The mail standard
**Containers do not send mail.** Only `srv-b` does, and only its own alerts,
through `[10.110.0.1]:25`. A container with a mail agent installed but SMTP
egress blocked is the worst case: it queues forever and delivers nothing.
CT 100 and CT 101 were in exactly that state until 2026-08-18 (F-031).
### Ownership
The script checks containers belonging to two projects and encodes host
requirements neither owns alone (F-032). It is **host-level**, not Mechanical
Compiler property. Suggested home: `/usr/local/sbin/ct-baseline.sh` on `srv-b`,
with the canonical copy outside this repository.
### Relationship to backup
**Conformance is a precondition for backup, not a companion to it.** A backup
taken before 2026-08-18 would have preserved two containers that queue mail
forever, and a restore would have faithfully returned them to that state.
Backing up an unverified configuration does not preserve a system; it preserves
a state of confusion. The entry condition for backup work is `ct-baseline.sh`
exiting 0 — and it becomes part of restore verification.
---
## 3a. Parallel project on this host
**Kane Fabric** is a separate project sharing `srv-b`. It is where SASE, HOA
Diagnostics, the Mechanical Compiler and other SASE-consuming projects are
implemented.
| | |
|---|---|
| Repository | `github.com/git64bit/Kane-Fabric` |
| Container | CT 102 `kane-fabric` |
| Address | `10.20.0.12/24` on `vmbr1`, gateway `10.20.0.1` |
| Ownership | Separate project. Not Mechanical Compiler infrastructure. |
| Baseline | Conforms as of 2026-08-18, verified by `ct-baseline.sh` |
Recorded here for two operational reasons only.
**It shares the service network.** CT 102 sits on `vmbr1` alongside CT 100 and
CT 101, so host-level rules scoped to `10.20.0.0/24` apply to it. In particular
it **inherits the SMTP egress block** (F-025) — if Kane Fabric ever needs to
send mail, that will present as a Postfix failure with a non-obvious cause.
**Host resources are shared, not pooled.** Neither project consumes or
repurposes the other's containers. Any integration is through an explicit
contract, not through co-location on `srv-b`.
No interface between the two projects exists today, and none is assumed.
---
## 4. Access model
Confirmed: no workstation access from the home LAN is required.
@@ -374,25 +462,31 @@ entire address space.
Repository state:
```
HEAD e85c4f4e5bab9a4f032230c99aa6784ace4c80e2
top level .git LICENSE README.md venv
git status ?? venv/
absent requirements-base.txt, requirements-cad.txt, service units
HEAD c7e32d8e0772d89d1117bab7ff08d61e5b2a497e
top level .gitignore LICENSE Makefile README.md docs/ fixtures/ legacy/
pyproject.toml requirements-*.txt src/ tests/ tools/ venv/
remote ssh://git@gitea.barternetwork.us:42022/TheRON/mechanical-compiler.git
deploy key srv-b-ct100, read/write
venv Python 3.11.2, shapely 2.1.2, cadquery 2.8.0, mechcomp editable
tests 3 passed, 236 skipped
oracle ddd0f154... verified in-container
absent the Shapely port itself
```
None of the following can be honestly completed, and none may be fabricated by
provisioning:
- [ ] Dependency install from committed manifests
- [x] ~~Dependency install from committed manifests~~ — done 2026-08-18
- [ ] `mechcomp.service`, `mechcomp-worker.service`
- [ ] Reference toolchain image `mechcomp/reference-toolchain:8.0.0`
- [ ] Fixture reproduction against `ddd0f154...`
- [ ] Application-runtime acceptance
- [ ] Replacing the placeholder with the real service
**Architect decision:** `venv/` belongs in `.gitignore` — it is a legitimate
artifact inside `install_dir` per YunoHost convention, it simply should not be
tracked. Applied with the first application commit.
**Applied 2026-08-18:** `venv/` is in `.gitignore`, along with `.cache/`,
`.local/`, `.ssh/`, `.gitconfig` and `.lesshst` — the service user's home is
`install_dir`, so anything writing to `$HOME` writes into the working tree
(F-029).
The Shapely port gates all of the above.
@@ -425,4 +519,7 @@ All three need CIVICVS.
| Why did delivery fail downstream? | `mx1` relay trust. Proven and corrected (F-023). |
| Where does Postfix log on this host? | journald. No `rsyslog`, no `/var/log/mail.log` (F-024). |
| Should container SMTP egress be blocked? | Yes. Implemented and reboot-proven (F-025 project-local half). |
| Do the containers autostart? | Yes, `onboot: 1` on both, proven by host reboot (F-026). |
| Do the containers autostart? | Yes, `onboot: 1` on all three, proven by host reboot (F-026). |
| How do files reach a container? | Upload to `/root/incoming` on `srv-b`, then `pct push` / `pct exec`. See `PROCESS.md`. |
| How does CT 100 push to Gitea? | Deploy key `srv-b-ct100`, SSH on port **42022**, read/write. |
| Do containers send mail? | **No.** Only `srv-b` does. See section 3b. |