docs(net): N5 accepted - Opus review PASS; loss gate strengthened per review

The review verified all three FAIL conditions absent (zero DROP_PCT=0
cost proven from code AND the decorator-absent baseline logs; the gate
fails explicitly on zero drops and zero recovery; teardown ordering
intact and ACE-safe) and reconciled the loss-ledger arithmetic packet by
packet. This acceptance folds in its two MEDIUM strengthenings: the
recovery assertion is now a per-direction conjunction (a one-direction
regression can no longer hide behind the other counter) and the three
keystream-health invariants (cksum-fail, sanity-drop, uncached-nak) are
asserted zero, turning the gate from "something recovered" into "loss
happened, both directions recovered, and the cipher ledger converged".
The unrecoverable-tail caveat now names the EnterWorldBody single-shot
alongside logoff/Disconnect and records ACE's gapped 1/s NAK trigger as
the mechanism. Script parse-validated; N6's gate run exercises it live.
N5 SHA 4e290f00 and its revert line recorded in the ledger.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Erik 2026-07-29 16:40:55 +02:00
parent 6077ce4d23
commit 3899ebe0fd
2 changed files with 36 additions and 9 deletions

View file

@ -16,11 +16,15 @@
# structurally blind to the #260 bug class. This gate removes that blindness
# permanently.
#
# Caveat recorded in the campaign doc: ACE's NAK is arrival-driven (a quiet
# client is never NAKed -- campaign section 3 row 1), so a drop landing on the final
# single-shot logoff request or transport Disconnect (~DropPct probability
# each) is unrecoverable by design and fails the teardown checks. Rerun with
# a different -Seed if that tail case is hit; do not widen the teardown
# Caveat recorded in the campaign doc: ACE's NAK trigger is arrival-driven
# AND gapped -- it fires only when a packet arrives at least TWO past the
# expected sequence, rate-limited to 1/s (NetworkSession.cs:351-363; a quiet
# client is never NAKed, campaign section 3 row 1). Three single-shot C2S
# messages are therefore unrecoverable if their datagram drops and the
# client goes quiet afterwards (~DropPct probability each): the
# EnterWorldBody send in EnterWorld (the route stalls before the world),
# the final logoff request, and the transport Disconnect. Rerun with a
# different -Seed if such a tail case is hit; do not widen the teardown
# tolerances.
[CmdletBinding()]
@ -383,10 +387,33 @@ function Invoke-Session(
$resends = [long]$netFinal.Counters.resends
$nakOut = [long]$netFinal.Counters.'nak-out'
$nakIn = [long]$netFinal.Counters.'nak-in'
if (($resends -eq 0) -and ($nakOut -eq 0) -and ($nakIn -eq 0)) {
# N5-review strengthening: a bidirectional run must show recovery
# in BOTH directions (a disjunction would let a one-direction
# regression hide behind the other's counter). C2S recovery is
# witnessed by ACE's NAKs reaching us (nak-in) or our resends;
# S2C recovery by our NAK emission (nak-out).
if (($resends -eq 0) -and ($nakIn -eq 0)) {
$failures.Add((
"${Label}: loss gate observed ZERO recovery activity " +
"(resends=0, nak-out=0, nak-in=0) -- the decorator never dropped, the gate proves nothing"))
"${Label}: no C2S recovery observed " +
"(resends=0, nak-in=0) -- outbound loss never healed or never happened"))
}
if ($nakOut -eq 0) {
$failures.Add((
"${Label}: no S2C recovery observed " +
"(nak-out=0) -- inbound loss never healed or never happened"))
}
# N5-review strengthening: the keystream-health invariants that
# catch #260's second bug class (cipher misalignment after loss).
# A converged run has all three at zero; any other value means
# the transport recovered messages while quietly corrupting or
# leaking sequencing state.
foreach ($invariant in @('cksum-fail', 'sanity-drop', 'uncached-nak')) {
$value = [long]$netFinal.Counters.$invariant
if ($value -ne 0) {
$failures.Add((
"${Label}: keystream-health invariant violated " +
"($invariant=$value, expected 0)"))
}
}
}
if ($null -ne $netLoss -and ($netLoss.DroppedOut + $netLoss.DroppedIn) -eq 0) {