M5-2c2 stage b: retire the ORPHAN verb, leave the fields reserved - #91
Merged
Conversation
ORPHAN was the one place a request-supplied identity was stored into a slot verbatim -- a forged identity taken from an unauthorised caller, which is exactly what the guard must never trust for a real client. The map (PR #90) priced its removal: row 2 is reproduced six times out of six with a real dying STC, row 3 was never producible live at all, and row 4 was always four branches of which ORPHAN drove one. The verb is rejected rather than deleted outright, and the placement is the point. Deleting the staging test alone would have let FNORPH fall through to the ECHO default and be serviced as an ordinary ECHO, so the code is now rejected by name in the pre-claim chain, ahead of the slot claim. A retired verb therefore costs no slot and no in-flight count, and that is true by position rather than by argument -- which is also what narrows the stranding case #67 describes. The rejection writes the return code into the caller's block rather than leaving it in R15 alone. The existing bad-request path does the latter, which would have left the client reading whatever it had initialised the field to -- indistinguishable from the SVC never having run. pascb and pasid stay, renamed reserved, at their existing offsets. That is deliberate: they sit mid-struct with seven fields after them, two of which carry real requests, and nothing version-checks this block -- the router validates a layout-invariant eyecatcher, and the anchor version guards a different contract. Clients link separately from the runtime library and the runbook replaces only the latter, so a router-only deploy would hand a new client an old router reading these offsets silently. They can go when the block gains a version check or a round relinks every client with the router. Obligation #4 is discharged in substance for the identity half only. The rest of the probe scaffolding remains, so #4 is not met overall.
The verb is retired and the gates are green; this records them and the two questions the round is told to report rather than answer. TSTDEATH's four options are priced against the property that matters, which is not test count: an isolated Stage-0 probe going red names a mechanism, while a socket operation going red names nothing. One of the four turns out not to be possible as stated, for this round's own reason -- keeping the probe on NSFV with rows 1 and 2 needs a client whose address space really dies, and a batch client in an initiator reads LIVE forever. Row 1 alone is keepable, because the blocking ECHO already witnesses it with a real identity and never needed ORPHAN. Also states the cost of keeping the ORPHAN constant, which is not neutral: the header still names a verb that no longer works. Deleting or renaming it breaks the test's compile and would settle the TSTDEATH question as a side effect, which is the one thing this round must not do. The #67 narrowing and the STATS truncation issue are drafted here and deliberately not applied or filed.
A fifth TSTDEATH option: split the test by row rather than moving or retiring it -- row 1 stays on NSFV where it is already witnessed by the blocking ECHO, row 2's live proof lives on the NSFS side where the death rig exists, rows 3 and 4 stay host-pinned and documented as not producible. None of the first four keeps the probe named while splitting the rows, so it is genuinely a fifth. It carries the lowest isolation cost, and the reasoning holds up: the isolation being protected is a property of the probe rather than of the round, so proving each row where it is producible preserves it better than moving a whole test into a round where half its scenarios cannot run. Its real cost is that row 2's live proof stops being a test and becomes an operator-driven procedure with no deterministic batch form. It also differs from retiring the test by more than it appears: an incidental witness still fails when the guard breaks, but it does not name the mechanism, which is the property at stake. The ORPHAN constant keeps its name, and the reason is now at the declaration rather than only in the round's notes: a mechanical change must not settle an open design question as a side effect, so the constant is cleaned up together with the TSTDEATH decision and not before it. Comment-only -- no code, no layout, no constant value changed.
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.
M5-2c2 stage b — retire the
ORPHANverb, leave the fieldsImplements the decisions locked on the stage-a map (PR #90). Detail in
docs/measurements/m5-2c2/stage-b.md.Nothing is closed. Obligation #4 is discharged in substance for the identity half
only — the rest of the probe scaffolding is c3, after (e). #67 is narrowed, not closed.
The
TSTDEATHrestructuring is priced and left open.Anchor layout unmoved,
ANCVERNO3,NSFRQEfrozen, no field removed.The change
ORPHANstored a request-supplied identity into the slot verbatim — a forged identitytaken from an unauthorised caller, which is what the guard must never trust for a real
client. It is retired.
It is rejected, not just deleted, and the placement carries the argument. The staging
dispatch is a fall-through chain ending in ECHO, so deleting the test alone would have made
FNORPHbe serviced as an ordinary ECHO. It is now rejected by name, first in thepre-claim chain, so a retired verb costs no slot and no in-flight count — true by
position, not by argument. That is also what narrows #67.
The rejection writes the rc into the caller's block (
BADFUNC, mirroringBADANC)rather than reusing
BADREQ, which leaves it in R15 only.BADREQwould have left theclient reading its own initialised
-1— indistinguishable from "the SVC never ran".pascb/pasidstay asrsvd_pascb/rsvd_pasidat identical offsets: no layout change,so the client/router skew stage a identified cannot arise.
NSFV_REQ_ORPHANis kept, with the rule written at the declaration: a mechanical changemust not settle an open design question as a side effect. Deleting it breaks
tstdeath.c'scompile and would force the
TSTDEATHdecision; the constant is cleaned up with thatdecision, not before it.
Verified host-side (survives without a stand)
make test-host3342 PASS / 0 FAIL, unchanged.src/nsfreqx.candtest/tstreqx.careuntouched by this branch, so all four rows and all four
UNKNOWNbranches keep their hostcoverage. The retirement removes a live driver, not host coverage.
mainby comparing everyNSFV_OFF_ASSERTvalue andNSF_SIZE_ASSERT(NSFV_REQ, 64)— no field removed, no offset moved.tools/check-card-columns.shOK — after it caught one of my own cards at 72 bytesmid-edit, which is the documented failure mode found before the toolchain saw it.
as370 -a=listing:C R3,=A(FNORPH)→5930 64F8,BE BADFUNC→4780 64A4, base R6not dropped to 0, target matching
BADFUNCat0004A4.subsequence — macro expansion makes listing statement numbers non-1:1 with source lines).
check-card-columnsFAILED,as370 rc=8, and the statement check named both the overlong card and the
BE BADFUNCit ate.
XFERINstill endsB DOPOST; only comment text sits whereORPHINwas — no orphanedcode, no new fall-through.
Verified live (MVSCE)
TSTSVC/TSTMVCK/TSTUBUF/TSTXFWTSTRQXC/TSTRQXFTSTRQXMTSTDEATH's absence is stated, not quiet: the NSFV figure moves 484 → 412, exactlyits 72 assertions.
TSTMVCDstays excluded (#53).TSTRQXM's TSO arm fails by design(one-shot listener consumed by the batch run — verified to be exactly
CONNECT+ itsdependent
CLOSE).The rejection, from an unauthorised client —
TSTDEATHis that client, now FAIL CC 1("ran and failed", not the CC 20 "did not run" idiom):
rc = 4in the caller's block; slot FREE;inflight 0. No slot, no count — observed.Revert test, three states, one assertion moving:
TSTDEATHState 2 is rendered positively — the forged identities shown taking:
ASID=0020(afree ASID nothing owns),
ASCB=00FD0F20(the real ASCB +8),ASCB=00000000(row 4a).Zero dumps; both STCs start/stop clean;
SVC 239stolen and restored every cycle; noNSF054W; stand left with nothing running.Reported, not done
TSTDEATH: five options priced against the thing that actually matters — a Stage-0probe going red names a mechanism, a socket op going red names nothing. Option B turns
out not to be possible as stated, for this round's own reason (a batch client reads LIVE
forever). Option E — split by ROW rather than moving or retiring the test — carries the
lowest isolation cost, on the reasoning that isolation is a property of the probe, not of
the round; its real cost is that row 2's live proof stops being a test and becomes an
operator-driven procedure with no deterministic batch form. Decision left open.
NSFV_REQ_ORPHAN: kept with a retired-marker comment. Cost stated both ways — deletingor renaming it breaks
tstdeath.c's compile and would force theTSTDEATHdecision as aside effect, which this round is told not to pre-empt. The honest cost of keeping it is a
header that names a verb which no longer works.
issue stays open (
ECHO/XFERstill strand a slot each and hang the client), and thetitle drops the now-false
ORPHANclause while restoring the hang. Still OPEN.