PROCESS: write down the delivery chain, and stop transcribing derivable state

New section 3a records the whole path from an assistant producing something to it existing in Gitea. It has been explained conversationally to every new assistant for months and was written in no document, which is the reason it is now here. Section 0 claims this document describes how work gets done; the part it did not describe was how work actually arrives.

3a covers: nothing but the operator writes, because the assistant reads Gitea read-only and the operator is the only party with write access anywhere in the chain. Three command groups rather than one, because section 4 requires a suite result the assistant has actually seen before a commit exists. The shell-free idioms - make -C, git -C, runuser - because pct exec runs no shell. Commit messages parsed by the host shell before pct sees them, so repeated -m flags and no dollar sign, backtick or exclamation mark. Which failures are passes, because an operator who cannot tell success from failure cannot report usefully.

3a also records the amendment rule: do not ship a rewritten file to change a few passages of a large one. Ship an anchored script that validates every anchor matches exactly once and writes nothing if any does not. This commit was made that way. A rewrite regenerates the document from the assistant reading of it and a transcription error is silent - the same hazard as rewriting HANDOFF.md in place, one level down.

Section 4: the oracle check and git status are one check, not two (F-033). And the two interpreters are deliberate - verify-oracle runs python3 because make_fixtures.py imports nothing outside the standard library, test runs venv/bin/python because the suite imports mechcomp, Shapely and pytest. Neither is a mistake to be tidied into consistency.

Section 8: the reading order was missing HANDOFF.md for three weeks while HANDOFF section 0 carried a different order missing ENVIRONMENT.md. Two lists, neither complete, each looking authoritative. Both now name DIVERGENCES.md. The authority ladder gains the rule underneath it: a document that describes something yields to the thing it describes, a document that prescribes something does not. That dissolves the apparent contradiction with deploy/README.md, which is correct to claim the repository wins for the files it owns.

Section 8 also qualifies promote-the-deviation. It applies to facts about a host, not to a requirement the code has not met. A REQ is never lowered to match what was built; the gap is recorded in DIVERGENCES.md and the correction is owed by the code. A specification that agrees with whatever exists specifies nothing.

Section 10 described 18 AUG: repository at its seed commit, port not started, 3 passed and 236 skipped. It now states that it no longer records a commit, a version or a test count, because git rev-parse, git describe and make test report those and every attempt to hold them current in prose went stale.

Suite 643 passed, oracle intact at 113 accepted and 10 rejected. Documentation only.
This commit is contained in:
2026-09-13 15:17:28 -05:00
parent 3ccec9ab40
commit 15e90fd8cf
+126 -14
View File
@@ -81,7 +81,7 @@ This is deliberate ceremony. Each step is irreversible or expensive to undo,
and the failure log is a deliverable in its own right — it is the primary input
to the eventual production automation.
Work orders 001 through 003 were all infrastructure mode.
Work orders 001 through 004 were all infrastructure mode.
### Development mode
@@ -164,6 +164,77 @@ where it can be checked.
---
## 3a. The delivery chain, end to end
The whole path from an assistant producing something to it existing in Gitea.
It has been explained conversationally to every new assistant for months and was
written in no document until now, which is the reason this section exists.
**Nothing but the operator writes.** The assistant reads Gitea over MCP, which
is read-only, and builds files in its own sandbox. The operator is the only party
with write access anywhere in the chain. That is deliberate, and it is section 1
restated: the operator executes, and the assistant never assumes a command
succeeded.
### The steps
```
assistant builds the artifact in its sandbox
-> states sha256, size, contents, where it lands, what it overwrites
-> operator downloads it and uploads to /root/incoming on srv-b
-> assistant gives ONE command group
-> operator pastes it into the srv-b shell, pastes output back
-> repeat until landed, verified, pushed
```
### Three groups, not one
**REQ** — landing, verification and commit are separate command groups, because
section 4 requires a suite result the assistant *has actually seen* before a
commit exists. A single group that lands and commits cannot satisfy that.
| Group | Does | Ends when |
|---|---|---|
| 1 | `pct push` or expand-and-copy, fix ownership, confirm checksum, `git status` | the file is in place and owned by `mechcomp` |
| 2 | `make verify-oracle`, `make test` | the assistant has read a real result |
| 3 | `git add`, `git commit`, `git push`, verify | `git status -sb` shows no ahead marker |
### Idioms that need no shell
`pct exec` runs no shell (section 9). These forms avoid needing one:
- `make -C /var/www/mechcomp test` — never `cd ... && make test`
- `git -C /var/www/mechcomp status` — never `cd ... && git status`
- `runuser -u mechcomp -- <cmd>` — never `su`
**REQ** — a commit message is parsed by the **host** shell before `pct` sees it.
Use repeated `-m` flags, and no dollar sign, backtick or exclamation mark
anywhere in the text. A heredoc does not survive `pct exec`.
### State which failures are passes
**REQ** — an instruction set says what the expected output is, including where
an **error is the correct result**. The group-1 check that a target does not yet
exist fails with `No such file or directory` when the delivery is correct; an
operator who reads that as a fault stops a working delivery. An operator who
cannot tell success from failure cannot report usefully (section 9).
### Amending a large document
**REQ** — do not ship a rewritten file to change a few passages of a large one.
Ship an anchored replacement script that validates every anchor matches exactly
once and writes nothing if any does not.
A rewrite regenerates the whole document from the assistant's reading of it, and
a transcription error is silent. `FAILURES.md` is 52 kB of correct prose whose
value depends on never being rewritten, and the same hazard applies to any
document large enough that nobody will diff it carefully.
This is the `HANDOFF.md` problem one level down: a document **replaced** rather
than **amended** loses content, and nothing reports what left.
---
## 4. The repository
**Gitea is the source of truth.** `https://gitea.barternetwork.us/TheRON/mechanical-compiler`
@@ -191,6 +262,21 @@ instance of the same mistake.
- The test suite runs, with a result the assistant has actually seen
- `git status` shows nothing unexpected — particularly not `venv/`
**The first and third are one check, not two (F-033).** `--verify` recomputes the
hash from the document it reads and compares it against the value stored inside
that same document, so a wholly regenerated oracle is self-consistent and passes.
It proves internal integrity, never identity with the committed bytes. Only
`git status` can tell you *which* oracle is present. Dropping either as redundant
removes the only check that catches a substituted oracle.
**The two interpreters are deliberate, and the Makefile is right.**
`make verify-oracle` runs `python3` because `make_fixtures.py` imports nothing
outside the standard library — that is what makes the oracle check trustworthy on
any machine at any time, and it must not be made to depend on a deployment.
`make test` runs `venv/bin/python` because the suite imports `mechcomp`, Shapely
and pytest, none of which system `python3` has (F-036). Neither is a mistake to
be tidied into consistency.
### Recording provenance
Artifacts are attributed to the **commit that produced them**, not to a
@@ -330,8 +416,15 @@ Read in this order:
1. **`PROCESS.md`** — this document
2. **`STAGING-STATE.md`** — what is true right now
3. **`FAILURES.md`** — what has already gone wrong
4. **`ENVIRONMENT.md`** — the specification
5. `ROADMAP.md` — where it is going
4. **`HANDOFF.md`** — where the last session left off
5. **`DIVERGENCES.md`** — what is required and not met
6. **`ENVIRONMENT.md`** — the specification
7. `ROADMAP.md` — where it is going
`HANDOFF.md` was created after this list was written and was missing from it for
three weeks, while its own section 0 carried a different list missing
`ENVIRONMENT.md`. Two reading orders, neither complete, each looking
authoritative. **If you add a document, add it here.**
If writing provisioning automation, read `FAILURES.md` **before** the
specification. Every entry is something a script written from the specification
@@ -341,12 +434,25 @@ alone would have got wrong.
1. `STAGING-STATE.md` — factual, wins on what is true
2. `FAILURES.md` — evidence from contact with real hosts
3. `ENVIRONMENT.md` — the specification, corrected when proven wrong
4. `ROADMAP.md` — sequence
3. `DIVERGENCES.md` — where a requirement stands and is not met
4. `ENVIRONMENT.md` — the specification, corrected when proven wrong
5. `ROADMAP.md` — sequence
**The rule underneath the list:** a document that *describes* something yields to
the thing it describes; a document that *prescribes* something does not.
`STAGING-STATE.md` describes a host, so the host wins. `deploy/README.md`
prescribes a host configuration, so it does not — and it says so itself. Both are
correct, and the apparent contradiction dissolves once the two kinds are named.
**A permanent deviation is not a deviation. It is the specification.** Promote
it and delete the exception.
**That applies to facts about a host, not to requirements 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. Promoting a divergence
would make every document true by construction and worthless — a specification
that agrees with whatever exists specifies nothing.
---
## 9. Instructions the operator can actually run
@@ -405,22 +511,28 @@ requirements neither project owns alone. Treat it as host property.
## 10. Current mode
**Infrastructure: complete and accepted.** Host, containers, network isolation,
bastion access, TLS, reverse proxy, mail alerting, disk monitoring. See
`STAGING-STATE.md`.
**Infrastructure: complete and accepted**, and now includes public ingress —
`WORK-ORDER-004-public-ingress.md`, closed 2026-09-11. See `STAGING-STATE.md`
for what is true on the host, and `DIVERGENCES.md` for where the running instance
and the specification disagree.
**Backup: deliberately postponed.** Nothing exists yet whose loss would cost
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, and not re-run since the host last changed.**
See DIV-006.
**Container baseline established.** All three containers on `srv-b` conform.
**Development: the Shapely port is complete.** The compiler builds cross
sections, reports them, renders SVG, exports STL, and serves a composer over
HTTP. `ROADMAP.md` section 4 carries what comes next.
**Development: starting.** First work item is the Shapely port —
`pytest -n auto` green against the 123 frozen cases.
**This section no longer records a commit, a version or a test count.** Those are
reported by `git rev-parse HEAD`, `git describe --tags` and `make test`, and
every previous attempt to hold them current in prose went stale — the last one
claimed the repository was still at its seed commit while the work it described
had been finished for three weeks. A document states what no command can report:
a decision, a constraint, a reason, a hazard.
From here the mode is **development** unless the work touches the host, the
containers, or a shared service.