Skip to content

Commit ed4b062

Browse files
committed
docs(plan): §7 —— 四个缺口的实测回填,含两次「通过了但什么都没测到」
Records what each of the four items measured. Two of them first passed without testing anything: the tool-tier assertion read empty on a machine where the emulator was already installed, and the orphan test's first two drafts were signalled through `timeout` (which reaches the child either way) and then sized so that a 32-core host finished the build inside the window. Both are written down with the shape that fixed them. Gap 1's answer is recorded as an interface change rather than a note: the entry value fits in `arch_u64` and the STORAGE width was not askable, so `arch_pte_entry_bytes()` exists and the header's own claim was corrected. Gap 4's cause remains unestablished; §1.3 stands. The ninja work turned up a stronger fact than §1.5 had: twelve copies at one size with twelve different hashes, which is in-place patching, so an installed binary cannot be compared against a published checksum at all.
1 parent 9da7163 commit ed4b062

1 file changed

Lines changed: 94 additions & 0 deletions

File tree

.agents/docs/2026-09-04-four-gaps-after-the-ecosystem-batch.md

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -357,3 +357,97 @@ discovery.
357357
Everything except item 4 can start without further input. Item 4 is a
358358
compatibility decision about a published contract, and the recommendation in
359359
§4.2 is a recommendation rather than a conclusion.
360+
361+
---
362+
363+
## 7. Outcomes (2026-09-04, same day)
364+
365+
All four items were implemented, one pull request per repository. What follows
366+
records what was measured, including two places where a first attempt passed
367+
without testing anything.
368+
369+
| gap | delivered | where |
370+
|---|---|---|
371+
| 1 | openarch 0.9.0: ARMv7-A backend, `arch_pte_entry_bytes()` | openarch #9 |
372+
| 2 | `when = "run"` on both boards, with the pair asserted | riscv-virt-rt #5, aarch64-virt-rt #3 |
373+
| 3 | `mcpp run` reports the program's status | mcpp #555 |
374+
| 4 | mcpp kills its child; `MCPP_NINJA_DEBUG`; ninja pinned by checksum | mcpp #555, xim-pkgindex #756 |
375+
376+
### 7.1 Gap 1: the answer is "no, and here is the missing query"
377+
378+
The width question is settled. ARMv7-A's short-descriptor entry is 32 bits and
379+
FITS in the `arch_u64` the interface carries, so the carrier did not change —
380+
but nothing could ask how wide the storage is, and a kernel sizing a table from
381+
`sizeof(arch::pte)` builds one twice as large as the hardware walks. Nothing
382+
diagnoses that: the table is well formed, the entries are correct, and the
383+
machine reads the gaps.
384+
385+
`arch_pte_entry_bytes()` is the addition, implemented by all five backends. The
386+
header's own claim — "a page-table entry is 64 bits on every machine here" — was
387+
corrected rather than left standing.
388+
389+
Asserted twice, because one place cannot cover both halves: `tests/pte_encoding`
390+
compares the encoder against a descriptor written out from the architecture
391+
manual, and a CI job boots a program on qemu `-M virt -cpu cortex-a15` that
392+
reads the width back THROUGH THE ABI and exits 0 only if it is 4. Measured:
393+
`armv7a pte width 4, entry fits 32 bits`, exit 0.
394+
395+
`openarch:preemption` is withheld on this machine. The resumption address lives
396+
on the SVC stack rather than in a register, so a trap-time switch is well
397+
defined only if the resumed context was suspended the same way — a real design,
398+
and not one this backend has measured. Withholding it refuses a consumer by
399+
name at resolution, which is the mechanism Cortex-M already uses for
400+
`openarch:address-space`.
401+
402+
### 7.2 Gap 2: the criterion needed an isolated home
403+
404+
The tier itself was two lines. The assertion was not: on a machine where the
405+
emulator is already installed, `MCPP_NO_AUTO_INSTALL` has nothing to report, so
406+
BOTH halves read empty and the step passes without testing anything. Measured in
407+
exactly that state before the step was moved to an isolated `MCPP_HOME`.
408+
409+
With one, the pair is decisive and needs no download: a build names the emulator
410+
zero times, and a run refuses with `declared but not provisioned` naming
411+
`xim:qemu-riscv@9.2.4-1`. CI reports `ok build asks for no emulator, run asks
412+
for xim:qemu-riscv` on both boards.
413+
414+
### 7.3 Gap 3: three bands, and 2 stays where it is
415+
416+
`mcpp run` passes the child's status through. Spawn refusals move to 125-127,
417+
the band `env`, `timeout` and `nice` already use. mcpp's own refusals BEFORE a
418+
spawn — no binary target, no runner declared, a runner not on PATH — keep exit
419+
2, which is what every other mcpp command uses, so no existing script that
420+
tests for it changes meaning. Only the case where the program never ran moved.
421+
422+
`mcpp test` is unchanged at 0/1: it aggregates many programs and has no single
423+
status to pass through.
424+
425+
### 7.4 Gap 4: the fix, and what the test had to be to catch it
426+
427+
Fixing `run_exec` alone left the orphan in place, because a full build spawns
428+
ninja through `capture_exec`. The A/B caught it; reading the code had not.
429+
430+
THE TEST SIGNALS mcpp's PID ALONE. `timeout` and Ctrl-C both signal the process
431+
group and reached ninja even before the fix, so a test built on `timeout` passes
432+
either way — the first version of this test did exactly that. The second version
433+
used 200 parallel translation units and passed against a defective build because
434+
a 32-core host finished the batch inside the ten-second window. `--jobs 1` makes
435+
the window deterministic by construction. The final test FAILS against the
436+
released 2026.9.4.2, naming the orphan and its `(deleted)` working directory.
437+
438+
The spin's cause remains unestablished and §1.3 stands. `MCPP_NINJA_DEBUG`
439+
appends `-d explain` to both ninja launches so the next occurrence can be read
440+
rather than guessed at.
441+
442+
### 7.5 A finding the ninja work turned up
443+
444+
`xim:ninja@1.12.1` now carries a checksum. While computing it, a stronger fact
445+
than §1.5's appeared: this machine holds ninja binaries at THREE distinct sizes
446+
under that one version, and the twelve copies at 290152 bytes have twelve
447+
DIFFERENT SHA-256 values.
448+
449+
Same size and different content is the signature of in-place patching, which
450+
xlings does to installed binaries. So an installed ninja cannot be compared
451+
against a published checksum at all — only the downloaded archive can, which is
452+
what the checksum added here covers. A clean-home install was verified to fetch,
453+
verify and produce the 2202320-byte static binary the descriptor describes.

0 commit comments

Comments
 (0)