feat(network): guard-band-aware 802.1Qbv GCL splitting (REQ-TSN-SYNTH-QBV-GUARDBAND-001)#309
Merged
Conversation
…-QBV-GUARDBAND-001) synthesize_gcl_split_guarded makes the window-splitting GCL synthesizer DEPLOYMENT-SOUND: it charges the IEEE 802.1Q §8.6.8.4 transmission-overrun guard band that the guard-free synthesize_gcl_split ignores. Each class's usable open window is sized by the same validated single-window search (the guard does not change the service a class receives — open w, latency cycle/K − w — only the packing budget Σwᵢ + N·g ≤ cycle/K), then an explicit trailing closed guard window of g is emitted after every class window so the deployed GateSchedule physically carries the guards a switch enforces. The guard-band rate-loss cliff (guards grow as N·K·g while the latency benefit shrinks as 1/K) is enforced automatically: when no split fits, the oracle returns the structured GuardOversubscribed rather than a silently rate-starved, unsound GCL. Model soundness is pinned NON-CIRCULARLY by a K=1 anchor test: "emit a (D−g)-open window + trailing g guard" is proven algebraically identical to the independently-derived tas_residual_service_with_sync_error at ε = g (open D−g, latency C−D+g, rate R·(D−g)/C from two different premises). g rounds UP to a whole ns (sound direction); g = 0 reproduces synthesize_gcl_split byte-for-byte. No new dependency (existing tsn.rs + curves.rs). Library API — like the whole synthesize_gcl* family it is not yet wired into a CLI/AADL→Qbv consumer; this REQ makes no end-to-end pipeline claim. Tests: 8 new (K=1 model anchor, g=0 degeneracy, feasible-split-with-guards, sub-ns round-up, the GuardOversubscribed cliff with required_ps assertion, exact-fit boundary, never-coarser-than-unguarded, input validation). 156 lib tests pass; clippy -D clean; nightly fmt clean; mutation 39 caught / 1 unviable / 1 missed (the defensive self-cert deadline arm — equivalent mutant matching shipped synthesize_gcl / synthesize_gcl_split precedent). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Rivet verification gate✅ 20/20 passed
Filter: Failed artifacts(none) Updated automatically by |
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
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
synthesize_gcl_split_guarded— the deployment-sound window-splitting 802.1Qbv GCL synthesizer. It charges the IEEE 802.1Q §8.6.8.4 transmission-overrun guard band that the guard-freesynthesize_gcl_split(v0.21) ignores, so the synthesizer's "meets deadline" claim becomes a real-hardware claim and the emittedGateSchedulephysically carries the guards a switch enforces.How it stays sound
open w,latency cycle/K − w), only the budgetΣwᵢ + N·g ≤ cycle/K. So the per-roundsynthesize_gclis reused unchanged.guard_band_k1_equals_sync_error_at_eps_gpins the construction: for a single window, "emit a(D−g)-open window + trailinggguard" yields a service curve byte-identical to the independently-derivedtas_residual_service_with_sync_erroratε = g(open D−g,latency C−D+g,rate R·(D−g)/C) — two derivations from different premises agreeing.N·K·gwhile the latency benefit shrinks as1/K; when no split fits, the oracle returns the structuredGuardOversubscribed, never a silently rate-starved GCL.grounds up to a whole ns (sound direction);g = 0reproducessynthesize_gcl_splitbyte-for-byte; the full guarded schedule self-certifies throughtas_residual_service+delay_boundbefore return.Scope
Library API. Like the whole
synthesize_gcl*family it is not yet wired into a CLI / AADL→Qbv consumer — this REQ makes no end-to-end pipeline claim; the "deployable" claim is about the GCL it produces. Consumer wiring is separate future work.Traceability
REQ-TSN-SYNTH-QBV-GUARDBAND-001→implementedTEST-TSN-GUARDBAND(satisfies) — 8 unit testsVerification
spar-networklib tests pass; clippy-D warningsclean; nightly fmt clean.cargo-mutants, guarded fn + error path): 39 caught / 1 unviable / 1 missed. The 1 missed is the defensive self-cert deadline arm — an equivalent mutant the budget invariant guarantees never trips, matching the identical surviving mutant in the shippedsynthesize_gcl/synthesize_gcl_split(precedent: unreachable defensive error arms).🤖 Generated with Claude Code