lab: complete Step 6 — VerifyingSlotProvider, IDiagSink, scenario pump#23
Merged
Merged
Conversation
Implements the Milestone 1 payoff step per the lab README: - Ports/IDiagSink: the RT-safe sticky-counter seam (increment-only, no logging, no allocation); Lab/StickyCounterSink as its fixed-array relaxed-atomic implementation for tests and the future dext dump. - Lab/VerifyingSlotProvider: decorator over any IAmdtpTxSlotProvider asserting P1-P4 on every PublishSlot — cadence window (6000/8000) and N,D,D,D run shape, DBC continuity (no-data carries unchanged), CIP bit-exactness re-parsed from the published wire image (Q0/Q1 fields, 8-byte no-data, byteCount vs frames*dbs), and gapless frame tiling. Observer not gate: packets always forward; violations resync so one fault counts once. Structural constants are asserted, stream constants (SID, frames-per-data) are learned from the wire — the verifier shares no code with the packetizer it judges. - Step 6 seams (additive only, no behavior change): controller BindLabSlotProvider() to interpose Verifying(Fake) between engine and ring, and PayloadCounters()/PayloadWriterCounters() accessors to read the writer's miss buckets from scenarios. - Tests/VerifyingSlotProviderTests: instrument self-tests — a hand-rolled golden driver (independent of AmdtpTxPacketizer) plus one corruption case per violation kind, each proving the targeted counter fires exactly once with no cross-talk. - Tests/VerifierScenarioTests: the scenario pump (controller -> engine -> Verifying(Fake)) — regular 512-frame soak past 1e6 cycles with zero violations, irregular frame counts, skipped callback (silence in structurally valid packets, never corruption), sample-time jumps landing in framesWithoutPacket/framesOutsidePacket, and stream restart. Suite: 17440 checks, 0 failures (was 8341). Dext target still compiles. Milestone 1 exit criteria are now executable checks. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
mrmidi
added a commit
that referenced
this pull request
Jun 12, 2026
lab: complete Step 6 — VerifyingSlotProvider, IDiagSink, scenario pump
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.
What
Step 6 of Milestone 1, per the lab README: the
VerifyingSlotProviderinvariant decorator, theIDiagSinkport behind it, and the scenario pump. The Milestone 1 exit criteria are now executable checks — and they pass:Verifying(Fake)on the regular 512-frame schedule: zero invariant violationsframesWithoutPacket/framesOutsidePacketSuite: 17,440 checks, 0 failures (was 8,341). Dext target still compiles.
The instrument
Lab/VerifyingSlotProviderwraps anyIAmdtpTxSlotProviderand asserts P1–P4 on everyPublishSlot:firstAudioFrame/framesInPacket), zero frames on no-dataDesign points (documented in the source):
Ports::IDiagSinkmirroring, no logging anywhere. Ready to run inside the lab dext at Milestone 3, and to wrap the real DMA ring at ASFW bring-up.Self-tests
An asserting instrument that never fires is worse than none, so every violation kind has a corruption case proving it fires exactly once with no cross-talk (DBC jump on data, DBC advance on no-data, short/padded byte counts, wrong FDF, wrong DBS field, frame-tiling gap, frames-on-no-data, double no-data, index gap, unacquired publish, 5999/8000 window).
Seams touched (additive only, no behavior change)
VirtualAudioDeviceController::BindLabSlotProvider()— interposesVerifying(Fake)between engine and ring (the seam theAudioIOPathcomment anticipated for the Step 6 pump)DiceTxStreamEngine::PayloadWriterCounters()/ controllerPayloadCounters()— read-only access to the writer's miss buckets so scenarios can assert the expected signaturesNothing else in
Protocols/was modified. README untouched — happy to tick the Step 6 / M1-exit boxes there too if you'd like it in this PR, or leave that to you.Verification
🤖 Generated with Claude Code