M5-2d0: establish what (d) still contains - #96
Open
mgrossmann wants to merge 1 commit into
Open
Conversation
(d) had never run -- the #64 investigation landed between c0 and c1, the order was resequenced around it, and afterwards no memo named it as next. It surfaced when (e)'s stage a went to write the exit gate's isolation sentence and found the property is not in the code. This is the survey, not the work: no code, no live run, four questions answered from source against criteria fixed in advance. The ubuf/ulen obligation SPLITS. The cross-address-space security half is closed: every store into caller storage derived from ubuf is one of exactly three MOVEOUT sites, all inside the borrowed-key SPKA window, and the length is clamped to 2048 in both directions with every loop guard signed, so a negative ulen is a no-op rather than a hazard. The caller-side robustness half stays open and is reclassified -- nothing validates ubuf/ulen against the caller's real buffer extent, so an over-declared ulen overruns the caller's OWN storage, which is not a 17.3 concern and should stop being carried as one. Exhaustiveness needed two searches and neither alone establishes it. A search for stores with an R8 base structurally cannot find a store through a register loaded FROM the caller's block, which is exactly how ubuf is written; the second search returns exactly one instruction, MOVEOUT's own EX target. The first attempt at that search silently returned empty because the pattern could not match the length form 0(1,R4), so it was re-run with MVCPIEC as a positive control -- an empty result and a broken pattern are otherwise identical. The guard-arithmetic obligation closes with evidence: four extracted functions, both STCs calling them with no hand-written copy, and all four classifier rows, the reap predicate and the two-helper consistency pinned in test/tstreqx.c. Recorded there because a reader will get it backwards later: c2 stage c removed a live DRIVER, not host coverage. #67 is unreachable during (e). TSTRQXC stages only QUERY, SLOT and RQE at both revisions and never ECHO or XFER, and QUERY/UNSTAGE/SLOT dispatch before the claim loop and return BR R14 -- so they claim no slot and cannot move COLLISIONS or EXHAUSTED. Decision 3's stated reason did not apply; reported, not proposed as a change. d2 is small in code -- the reap is pure C via __cas, so no assembler, no layout move, no re-run-every-gate, and b3's fourth-state problem is about a CLAIMED slot and does not apply. But it carries one decision nobody has taken: force-reap flips `drained`, which takes nsfsx_stop's else branch and unloads the router under a possibly-parked client. The 2026-08-22 ruling was about the slot, not the module. Gathered for d1: there are THREE descriptor resolution points, not one -- req_socket, sel_scan (which a req_socket-only check would miss entirely), and soc_complete's internal one.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Docs-only. No code, no live run. A survey:
docs/measurements/m5-2d0/survey.md.(d) had never run — the #64 investigation landed between c0 and c1, the order was
resequenced around it, and afterwards no memo named it as next. It surfaced when (e)'s
stage a went to write the exit gate's isolation sentence and found the property is not
in the code.
Four questions, each answered from source against a criterion fixed in advance. This is
the evidence base d1 rests on, which is why it is its own PR rather than part of d1's diff.
Q1 —
ubuf/ulenvalidation: the answer SPLITSfrom
ubufis one of exactly threeBAL R15,MOVEOUTsites (asm/nsfvsvc.asm:845,:961,:971), all insideMOVEOUT's borrowed-keySPKAwindow (:1036-1041), so astore the caller could not itself make faults instead of corrupting. Length is
clamped to
XFCHUNK2048 in both directions and every loop guard is signed (LTR/BNP),so a negative
ulendegenerates to a no-op.ubuf/ulenagainst the caller's actual buffer extent, so an over-declared
ulenoverruns thecaller's own storage — inside its own address space, which is not a §17.3 concern
and should stop being carried as one.
NSFV_REQblock are a different destination,not derived from
ubuf, and stay open (ADR-0041 category 3). Count re-confirmed exact.Exhaustiveness needed TWO searches, and neither alone establishes it. A search for
stores with an
R8base structurally cannot find a store through a register loadedfrom the caller's block — which is exactly how
ubufis written. The second search(any store through R4/R5) returns exactly one instruction:
MOVEOUT's ownEXtarget.The first attempt at it silently returned empty because the pattern could not match the
length form
0(1,R4); it was re-run withMVCPIECas a positive control, since anempty result and a broken pattern are otherwise identical.
Q2 — guard arithmetic: CLOSED with evidence
Four extracted functions in
src/nsfreqx.c; both STCs (nsfsx.c,nsfv.c) call them,with no hand-written copy anywhere; all four classifier rows, the reap predicate and the
two-helper consistency pinned in
test/tstreqx.c.Recorded because a reader will get it backwards later: c2 stage c removed a live
DRIVER, not host coverage.
Q3 — #67 is unreachable during (e)
TSTRQXCstages onlyQUERY,SLOTandRQEat both revisions, neverECHOorXFER. AndQUERY/UNSTAGE/SLOTdispatch before the claim loop (:390-395vsCLAIMLP :445) and returnBR R14— they claim no slot, never publish, never park, andthe contention counters live only in the claim path. So no (e) role can move
EXHAUSTEDor
COLLISIONSthrough a probe verb.Decision 3's stated reason did not apply. Reported as the kickoff asks; not proposed
as a change.
Q4 — d2 is small in code, with one decision nobody has taken
The reap is pure C (
nsfsx_reapvia__cas): no assembler, no layout move, noANCVERNObump, no re-run-every-gate. b3's fourth-state problem is about a CLAIMEDslot and does not apply — an UNKNOWN slot at shutdown is
PENDINGorHELD, both alreadyin
reap_ok's published states.But force-reap flips
drained, which takesnsfsx_stop'selsebranch andunloads the router under a possibly-parked client — which that branch's own comment
calls "STRICTLY WORSE than leaking both". The 2026-08-22 ruling was about the slot; it
never ruled on the module. The escape-hatch condition (d2 has grown into an
investigation) is not met.
§5 gathered for d1
THREE descriptor resolution points, not one:
req_socket(src/nsfreq.c:547),sel_scan(src/nsfsel.c:83) — which areq_socket-only check would miss entirely —and
soc_complete's internal one (src/nsfsoc.c:273), where a check would be wrong.Plus the inherited-child behaviour, where the caller identity arrives, and the Phase-1
zero-identity enforcement point.
Verification
make test-host3414 PASS / 0 FAIL, unchanged — a no-regression check only, sincethis change contains no code. Diff is one added file.