FABRIC.md §25.7.1: second review pass findings, awaiting rulings

Full re-read of the document as it stood after the first review's corrections,
looking for what would break a lower-capability model working the punch list.
Nothing in this commit fixes anything -- it records fourteen findings for triage.

The one that gates coding: GAP-A1. §16.4's inference "same tick ordinal → same
hash" is unsound, because the hash covers execution_heat, which is co-written by
the instruction stream and the tick stream, and a hardware timer makes the
interleaving of those two streams wall-clock-dependent. Firing on tick count
fixes the engine's schedule, not the composition. Blast radius: item 0.8 is
ambiguous between two different kernels, 0.10's double-boot check fails by
construction under one of them, and 2.1's corrected acceptance is still
unachievable. Recommended resolution recorded (virtual tick as a pure function
of the execution stream; hardware heartbeat as instrument and wake source only)
but explicitly not decided.

Also: three unverified prerequisites (DTB reachability for 0.3/0.6, FP-register
save vs compile flags for 0.2/0.5, EL-dependence of the vector path vs 0.4's
scope), seven punch-item defects (0.1 self-contradiction on block ranges,
0.2/0.5 unsatisfiable acceptance, 0.3's missing STIE and re-arm, §23.4 #4 not
being a schedulable item, 1.11's informal deferral, 0.10's stale control
framing, the hardcoded model attribution), and three amendment inconsistencies
(stale K-denominator language in §17.3/§17.5/§17.6d, §19.6 #1-#2 unmarked as
resolved, §20.3's stale LEANING).

Triage order is stated in the section: A1 first, B1/B2 are ten-minute reads,
C and D mechanical after that. C1-C3 minimum before any coding model starts.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Robert Allan James
2026-08-03 11:21:15 -04:00
co-authored by Claude Fable 5
parent 32f87d9e59
commit e8f8b098ed
+110
View File
@@ -2212,3 +2212,113 @@ so.*
- `src/*.c.bak` files are tracked in git at the `src/` top level.
- The `bump-z` / `bump-y` targets in the hosted `Makefile` reference version macros that do
not exist in the generated `include/version.h`.
### 25.7.1 Second review pass — 2026-08-03, pre-coding. Awaiting rulings.
*A full re-read of this document as it stood after the first review's corrections, looking
for what would break a lower-capability model working the punch list. Nothing here has been
fixed. GAP-A1 needs a ruling before item 0.8 is coded; the rest are queued for triage.*
#### GAP-A1 — §16.4's central inference is unsound. NEEDS RULING BEFORE PHASE 0 CODING.
§16.4 claims: *"same input → same tick ordinal → same reap and inference events → same
hash."* The last arrow is invalid. The hash covers `execution_heat`, which is co-written by
**two streams** — word executions (increments) and engine ticks (decay). Once ticks come
from a hardware timer, *where tick N lands relative to the instruction stream* is
wall-clock-dependent: under TCG, run A takes tick 42 after word #1000, run B after word
#1017. Decay interleaves differently, heat trajectories diverge, hashes differ. Firing on
tick count fixes the engine's *schedule*; the hash measures the *composition* of the two
streams, and that is not fixed.
Blast radius:
- **Item 0.8 is ambiguous between two different kernels.** Reading (i): the bottom half
services only TIME-TRUST bookkeeping — safe, parity holds, but "compudynamics on the
tick" did not actually happen. Reading (ii): the bottom half drives the engine/decay from
the hardware tick — parity breaks *by construction*, not by implementation error.
- **Item 0.10's double-boot dict-hash check** then fails under reading (ii), and no
implementation effort can fix it.
- **Item 2.1's corrected acceptance** (identical fleet heat *sum* across runs) is *still*
unachievable under a hardware tick: touch amounts scale with elapsed ticks between fixed
execution points, elapsed ticks vary run to run, so truncation losses vary, so the sum
varies. The first review's amendment did not go far enough.
- **The tempting split does not survive either.** "Hash-covered state on execution ticks,
TTLs on hardware ticks" fails because TTL expiry has side effects on the instruction
stream — a message expiring versus being delivered changes what runs, which corrupts heat
downstream. §17.1's "one tick" instinct was right; it picked the wrong clock.
**Recommended resolution (not decided):** the engine's tick is a **virtual tick — a pure
function of the execution stream**, which is exactly what exists today and why parity holds
today. The hardware heartbeat becomes: the TIME-TRUST instrument (now real on three ISAs
instead of one), the idle wake source, and the driver of nothing that feeds patron state.
Scripted/parity runs stay bit-identical; interactive idling pumps virtual ticks from the
REPL poll loop so TTLs still expire in real time, in a context where parity was never
claimed. Phase 0's timer work remains fully justified as instrument and substrate. Under
this ruling §16.4, §17.1, §18.4 and items 0.8, 0.10, 2.1 all need rewording. The
alternative — re-baselining the parity claim itself — touches the patent support material
and is not recommended.
#### GAP-B — unverified prerequisites (each is a short read; none has been done)
- **B1 — Device tree reachability.** Items 0.3 and 0.6 instruct "read from the device tree"
(0.6 forbids alternatives). Whether the loader captures the DTB from the EFI
configuration table into `BootInfo` is unverified. If it does not, 0.3 and 0.6 silently
require loader plumbing that has no punch item. Read `uefi_loader.c` / `BootInfo` first.
- **B2 — FP/SIMD in the ISR path.** Items 0.2 and 0.5 save integer state only. If the
kernel is not built with `-mgeneral-regs-only` (aarch64) / soft-float (riscv64), a C
interrupt handler may clobber FP registers the interrupted mainline was using. One grep
of `Makefile.starkernel` settles it; the items should carry the check.
- **B3 — 0.4's EL detection does not govern the vector path.** 0.4 refuses to hardcode the
EL for timer registers, but 0.5 hardcodes `ELR_EL1`/`SPSR_EL1`/`eret`, and today's
`isr.S` installs `VBAR_EL1`. If EDK2 leaves the kernel at EL2, exceptions vector through
`VBAR_EL2` and 0.5's entire edit targets a table that is never consulted. EL
determination must govern VBAR, the saved-state register forms, *and* the timer set.
#### GAP-C — defects in punch items a literal implementer will hit
- **C1 — Item 0.1 contradicts itself.** Body says remove "blocks 20502059"; Refs says
block 2050 *survives*. The delete set is 20512056 + 20582059; 2050 is edited (banner
call kept, handshake/broadcast calls removed). A literal reading deletes the banner.
- **C2 — Items 0.2 and 0.5 have unsatisfiable acceptance.** Both require having "taken and
returned from at least one trap/IRQ," but at 0.2 no timer is armed (0.3) and at 0.5 there
is no GIC (0.6) and no armed timer (0.7). No interrupt source exists at those stages.
Fix: 0.2/0.5 accept on "boots unchanged, no regression"; the took-and-returned evidence
moves to 0.3/0.7.
- **C3 — Item 0.3 lost the two silent-failure modes.** The SBI timer is one-shot: a missed
re-arm stops the heartbeat forever with no error. `sie.STIE` is also unmentioned. 0.7
says "re-armed each tick"; 0.3 must too.
- **C4 — §23.4 #4 blocks item 3.1 but is not a punch item.** The continuation-cell
encoding gates 3.1 by 3.1's own text, but rule 1 walks numbered items and nothing ever
schedules it. It should become item 1.12.
- **C5 — Item 1.11's deferral is not a formal prerequisite.** It says "do not settle
speculatively" but states no blocker, so rule 1 would schedule it. Add "(blocked on
4.3)."
- **C6 — Item 0.10 misc.** "amd64 output unchanged" treats amd64 as a control, but 0.8
changes amd64's engine plumbing by design — stale framing. "TIME-TRUST and variance
sane" is soft; sharpen to trust near `Q48_ONE`, variance small relative to the new
`expected_delta`.
- **C7 — The commit template hardcodes "Claude Opus 5."** Whichever model implements will
either violate the template or misattribute. Genericize.
#### GAP-D — inconsistencies left by the layered amendments
- **D1 — Three passages still argue from the K-justification the first review removed.**
§17.3 ("wastes the bounded capacity that gives K a fixed denominator"), §17.5's sizing
argument (same phrase), and §17.6(d) — the worst, since it cites §2 for a claim §2 now
explicitly disavows ("Without an inescapable bound, K is bookkeeping — §2 says this in as
many words").
- **D2 — §19.6 #1 and #2 read as open but are resolved** (#1 by §23.1 with the residue in
§23.4 #4; #2 by §24.3). §17.4 got strike-through treatment; §19.6 did not.
- **D3 — §20.3 still says "LEANING nested"** one section before §21 decides it. One
forward pointer fixes it.
#### What held up under this pass
The patron taxonomy, behaviours-not-kinds dispatch, the three quantities, the two-valued
cell union, the nested-elastic-quota layout, the identity/mass invariant, Hera's
pin-and-panic, and §25.0's rules themselves. None of them moved.
**Triage order when this is picked up:** rule on A1 first — it decides what item 0.8 even
means. B1/B2 are ten-minute reads. C and D are mechanical once A1 is ruled. Nothing should
go to a coding model before C1, C2 and C3 are fixed at minimum — those are the ones it
will hit in its first hour.