14 KiB
PROCESS.md
How work gets done on the Mechanical Compiler.
| Created | 2026-08-17 |
| Scope | All work on a Mechanical Compiler instance |
| Companions | ENVIRONMENT.md, STAGING-STATE.md, FAILURES.md, ROADMAP.md |
0. Why this document exists
The four companion documents describe what the environment is. None of them describes how work gets done in it — where files land, who runs what, how a change travels from a conversation into a running container.
Until now that gap was filled by restating the mechanics inside each work
order. That worked while the orders were written consecutively by one author.
It does not survive a handoff: an assistant reading ENVIRONMENT.md learns how
the host is built and nothing about how to operate on it.
Read this before your first command.
1. Who does what
Three parties, and confusing them is the most common way to waste a session.
| Party | Has | Does |
|---|---|---|
| Operator (CIVICVS) | A shell on srv-b and a file manager |
Runs every command. Uploads files. Decides. |
| Assistant | This conversation | Writes commands, reads output, writes code and documents |
| Architect | This conversation, in a different mode | Sets specification, accepts work, maintains the documents |
The constraint that shapes everything
The operator has a shell on srv-b and a browser-based file manager.
Nothing else.
No workstation git client. No direct container shell. No IDE. No ability to
scp. Every file arrives by upload to a folder on srv-b; every command runs
in that one shell.
An assistant that assumes otherwise produces instructions the operator cannot execute. This has already happened once.
What follows from it
- Files reach a container as: upload to
srv-b→pct pushor expand and copy →pct execto act on them. srv-bis the only place a human types. Containers are reached throughpct exec, never by SSH from elsewhere.- This is a legitimate deployment path, not a workaround. Do not design around a git client that does not exist.
2. Two modes of work, and they are not the same
Applying the wrong one is slow in one direction and dangerous in the other.
Infrastructure mode
For anything that changes the host, the containers, the network, or a service that other work depends on.
- One command group at a time
- Read-only before write
- Record a failure before correcting it, in
FAILURES.mdformat - Smallest corrective experiment — not the one that also fixes three adjacent worries
- Preserve a rollback copy before editing any configuration file
- Prove the negative: assert the forbidden path fails, not that the interface is gone
- Assert health after a host reboot, never before
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.
Development mode
For anything inside the repository: code, tests, documents, fixtures.
- Iterate freely. Edit, run the tests, edit again.
- No command-group ceremony. A test-fix-rerun loop is not a provisioning step.
- Failures during a normal red-green loop are not
FAILURES.mdentries. - Commit when something works, not when something is finished.
The distinction is reversibility. A wrong iptables rule can strand the
operator. A wrong line of Python fails a test and gets deleted. Ceremony
appropriate to the first is obstruction applied to the second.
Which mode am I in?
Ask: if this is wrong, what does it cost?
| Cost | Mode |
|---|---|
| A rebooted host, a lost shell, a broken service | Infrastructure |
| A red test | Development |
If genuinely unsure, use infrastructure mode. Being slow is recoverable.
3. Getting files into the environment
The path
assistant produces a tarball
-> operator downloads it
-> operator uploads it to /root/incoming on srv-b (file manager)
-> operator expands it on srv-b
-> pct push, or expand-then-copy, into CT 100
-> pct exec to act on it
REQ — /root/incoming on srv-b is the landing area. One directory,
always the same, so nothing has to be remembered between sessions.
REQ — Files landing in a container must end up owned by mechcomp.
pct push writes as root; fix ownership immediately afterwards. See F-008 —
repository operations run as the service user, and a root-owned file inside the
tree causes exactly that failure later.
REQ — An assistant delivering files states, in this order: what the archive contains, where it expands, what it overwrites, and how to verify it landed correctly. "Overwrites nothing" is a claim that must be checked, not assumed.
Delivering a whole tree
Prefer one tarball that expands over the existing tree. Individual file paths are error-prone to transcribe through a file manager.
Delivering a single small file
For anything that fits comfortably on screen, a heredoc in the srv-b shell is
faster than an upload, and leaves the content visible in the session transcript
where it can be checked.
4. The repository
Gitea is the source of truth. https://gitea.barternetwork.us/TheRON/mechanical-compiler
CT 100 holds a clone at /var/www/mechcomp, owned by mechcomp.
Two directions, both valid
Gitea → container. git pull inside CT 100, as mechcomp. Use this
whenever the change already exists in Gitea.
Upload → container → Gitea. Land the files, verify they work, then commit and push from inside CT 100. Use this when the assistant produced something new.
The second direction is the normal one for assistant-produced work, because the operator has no git client outside the environment.
REQ (F-008) — Every git command runs as mechcomp. Never as root, and
never add a root safe.directory exception — it would mask every future
instance of the same mistake.
What must be true before a push
- The oracle verifies:
python3 fixtures/strap-beam-8.0.0/make_fixtures.py --verify - The test suite runs, with a result the assistant has actually seen
git statusshows nothing unexpected — particularly notvenv/
Recording provenance
Artifacts are attributed to the commit that produced them, not to a timestamp or a file copy. When an artifact is generated, the commit SHA of the tree that produced it is part of its record. This is why the transport does not matter but the SHA does.
5. The development loop
Inside CT 100, as mechcomp, from /var/www/mechcomp:
make deps once, and after any requirements change
make test the loop
make verify-oracle before any commit that touches fixtures
The oracle is the gate
fixtures/strap-beam-8.0.0/ holds 123 frozen cases. It is the acceptance
criterion for the port, and it is not negotiable.
The ten rejected cases are part of the contract. A port that accepts them is wrong however good its numbers are elsewhere. Reproducing geometry is straightforward; keeping the constraint that made the geometry trustworthy is the actual work.
The oracle is never edited to make a test pass. If the port disagrees with it, the port is wrong until proven otherwise. If the oracle is genuinely wrong, that is a finding, it is recorded, and it is regenerated inside the pinned toolchain — never hand-edited.
Test discipline
A test must distinguish failure of the tool from failure of the thing under test (F-027). Every negative assertion first establishes that it could have observed the positive case. A test whose failure mode is indistinguishable from success manufactures confidence.
Prove a new harness by making it fail deliberately before trusting it green.
6. Work orders
A work order is an infrastructure-mode instruction set. Development work does not need one.
When to write one
- The work changes the host, containers, network, or a shared service
- The work has an acceptance criterion that can be stated in advance
- The work will be executed by someone other than the author
Required sections
| Section | Purpose |
|---|---|
| Scope | In and out. Explicit "do not touch" list. |
| Success criteria | Strict, testable, stated before the work |
| Known state | So the operator does not re-derive what is already recorded |
| Command groups | One at a time, read-only first |
| Acceptance | What must be true to close |
| Reporting | What comes back to the architect |
Executing one
- One group at a time. Paste output back before the next.
- Record a failure before correcting it.
- A defect in the work order is a finding, not something to work around silently. F-024 and F-028 are work-order defects, logged as such.
- "The problem is elsewhere and here is the evidence" is a complete outcome. Do not manufacture a local workaround for a remote problem.
7. When something goes wrong
Is it a FAILURES.md entry?
Yes if it is a surprise about the environment: something behaved differently from what the specification or a work order said, and a future automation writer would get it wrong the same way.
No if it is an ordinary development failure: a red test, a syntax error, a wrong algorithm. Those are the loop working.
Entry format
### F-nnn — one-line summary
Host or container. Phase.
**Observed:** verbatim where possible
**Cause:** proven, or explicitly "unproven"
**Correction:** the smallest change that fixed it
**Consequence:** what the specification or automation must do differently
An entry with no Consequence is either not understood or not worth recording.
"Unproven" is a respectable result. F-006, F-012 and F-022 are carried open and the log is better for it. Never invent a cause to close an entry, and never close one on a change that merely coincided with the symptom disappearing.
Escalating
Stop and ask the operator when:
- A decision is needed that is not the assistant's to make
- The work requires changing infrastructure outside this project
- A REQ in the specification cannot be satisfied
- The specification and observed reality disagree
The last one is not a blocker — reality wins, and the specification is corrected. But it is always worth saying out loud.
8. Session handoff
Sessions end abruptly. Assume the next assistant has these documents and nothing else.
Before a session ends
- Anything working is committed and pushed
- Anything learned is in
FAILURES.md - Anything changed on a host is in
STAGING-STATE.md - Any open decision is in
STAGING-STATE.mdsection 6
Starting a session
Read in this order:
PROCESS.md— this documentSTAGING-STATE.md— what is true right nowFAILURES.md— what has already gone wrongENVIRONMENT.md— the specificationROADMAP.md— where it is going
If writing provisioning automation, read FAILURES.md before the
specification. Every entry is something a script written from the specification
alone would have got wrong.
Authority when documents disagree
STAGING-STATE.md— factual, wins on what is trueFAILURES.md— evidence from contact with real hostsENVIRONMENT.md— the specification, corrected when proven wrongROADMAP.md— sequence
A permanent deviation is not a deviation. It is the specification. Promote it and delete the exception.
9. Instructions the operator can actually run
This section exists because it has already gone wrong.
REQ — One command group per message. Wait for output.
REQ — Commands run in the srv-b shell, or via pct exec from it. Nothing
assumes a tool the operator does not have.
REQ — A group is copy-pasteable as a block, with echo markers separating
sections so the output can be read back.
REQ — State what the expected output is. An operator who cannot tell success from failure cannot report usefully.
Do not deliver a numbered multi-stage procedure spanning several systems and expect it to be executed. It will not be, and the parts that are will not be separable in the output.
Do not assume the operator will improvise the missing step. If a command 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,
bastion access, TLS, reverse proxy, mail alerting, disk monitoring. See
STAGING-STATE.md.
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. 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.
From here the mode is development unless the work touches the host, the containers, or a shared service.