From 5a2bbfb2a951c72b3f10a87020ad15ec5626ca74 Mon Sep 17 00:00:00 2001 From: dmitrii-f-t27 Date: Sat, 17 Oct 2026 01:09:41 -0300 Subject: [PATCH] spec(port): port the cover-traffic volume stability guard (Refs #8887) The twenty-first CR-CHAT-07 ring target (W2, R-CHAT-10): the volume-stability rules - the batch ceiling, the empty batch (accepted), then per window the zero index, the volume floor (ten), the volume ceiling (ten thousand), the strictly- increasing index and the deviation ceiling (fifteen hundredths of the mean) - as the D5 verdict with every payload field, the original's rule order, and all ten CTSG tests transcribed plus a rule-order test. The original folds a float mean over u64 volumes; the int-to-float casts do not lower under the backends. The deviation rule re-bases to the original's exact rational arithmetic in u64 - the deviation from the mean sum/len is |v*len - sum| / sum, so the ceiling is the integer cross-multiplication |v*len - sum| * 100 > sum * 15 - identical verdicts for every input, no float anywhere. The float mean still arrives as a caller-computed number to ride the verdict's payload field, the lane convention. Checks (conventions 0-14): t27b test 11 passed 0 failed; t27c test-report 11/11, 0 vacuous; gen-rust output compiles under rustc; coverage Untested 0; ASCII only; seal saved, all hashes MATCH; --- ...:cover_traffic_volume_stability_guard.json | 28 ++ docs/reports/t27b_expectations.json | 1 + .../cover_traffic_volume_stability_guard.t27 | 311 ++++++++++++++++++ 3 files changed, 340 insertions(+) create mode 100644 .trinity/seals/src_port::trios::crates::trios-chat::rings::CR-CHAT-07::src::cover_traffic_volume_stability_guard.json create mode 100644 specs/port/trios/crates/trios-chat/rings/CR-CHAT-07/src/cover_traffic_volume_stability_guard.t27 diff --git a/.trinity/seals/src_port::trios::crates::trios-chat::rings::CR-CHAT-07::src::cover_traffic_volume_stability_guard.json b/.trinity/seals/src_port::trios::crates::trios-chat::rings::CR-CHAT-07::src::cover_traffic_volume_stability_guard.json new file mode 100644 index 0000000000..77d074ef95 --- /dev/null +++ b/.trinity/seals/src_port::trios::crates::trios-chat::rings::CR-CHAT-07::src::cover_traffic_volume_stability_guard.json @@ -0,0 +1,28 @@ +{ + "built_by": "t27c-bootstrap@0.5.2+01d0a635f", + "closure": [], + "config": "gen=c,rust,verilog,zig;tests=zig", + "gen_hash_c": "sha256:6a47637715ef7595386fc21907282349ba3583fcc71951991100e07deefc2649", + "gen_hash_rust": "sha256:210d33cd570b22eea111eba8c55547635ce226568bde31da6d1d5e3773c475e7", + "gen_hash_verilog": "sha256:4cfb8fcc67e0c335d9378a368a50602db55728d579409c7524a7ba3e74ba79ca", + "gen_hash_zig": "sha256:05edca548947fdb57a148032f98f9cf13beda89b5b066a428d25bc831f434bad", + "module": "port::trios::crates::trios-chat::rings::CR-CHAT-07::src::cover_traffic_volume_stability_guard", + "ring": 12, + "seal_schema": 2, + "sealed_at": "2026-10-17T04:09:21Z", + "sealed_by": "t27c-bootstrap@0.5.2", + "spec_hash": "sha256:0efd8580e04dc92243fc6cc66a4201932fc9720adba603ee1fb91ad17145e268", + "spec_path": "specs/port/trios/crates/trios-chat/rings/CR-CHAT-07/src/cover_traffic_volume_stability_guard.t27", + "tests": { + "failed": 0, + "failing": [], + "forced": false, + "passed": 11, + "total": 11, + "vacuous": 0 + }, + "toolchain": { + "test_runner": "sha256:1982ae948e24d00c5d221ccec12dfce1eb01204b53e37b0f857f93b16d64629d", + "zig": "0.16.0" + } +} \ No newline at end of file diff --git a/docs/reports/t27b_expectations.json b/docs/reports/t27b_expectations.json index c041cbab56..e398a7a2f8 100644 --- a/docs/reports/t27b_expectations.json +++ b/docs/reports/t27b_expectations.json @@ -855,6 +855,7 @@ {"path": "specs/port/trios/crates/trios-chat/rings/CR-CHAT-03/src/unmerged_leaves_bound_guard.t27", "t27b": "pass"}, {"path": "specs/port/trios/crates/trios-chat/rings/CR-CHAT-05/src/envelope_size_distribution_uniformity.t27", "t27b": "pass"}, {"path": "specs/port/trios/crates/trios-chat/rings/CR-CHAT-07/src/cover_decoy_ratio_governor.t27", "t27b": "pass"}, + {"path": "specs/port/trios/crates/trios-chat/rings/CR-CHAT-07/src/cover_traffic_volume_stability_guard.t27", "t27b": "pass"}, {"path": "specs/port/trios/crates/trios-chat/rings/CR-CHAT-LAWS/src/lib.t27", "t27b": "pass"}, {"path": "specs/port/trios/crates/trios-cli/src/cmd/agent.t27", "t27b": "pass"}, {"path": "specs/port/trios/crates/trios-cli/src/cmd/commit.t27", "t27b": "pass"}, diff --git a/specs/port/trios/crates/trios-chat/rings/CR-CHAT-07/src/cover_traffic_volume_stability_guard.t27 b/specs/port/trios/crates/trios-chat/rings/CR-CHAT-07/src/cover_traffic_volume_stability_guard.t27 new file mode 100644 index 0000000000..ada04e3152 --- /dev/null +++ b/specs/port/trios/crates/trios-chat/rings/CR-CHAT-07/src/cover_traffic_volume_stability_guard.t27 @@ -0,0 +1,311 @@ +module port::trios::crates::trios-chat::rings::CR-CHAT-07::src::cover_traffic_volume_stability_guard; + +// Port of gHashTag/trios crates/trios-chat/rings/CR-CHAT-07/src/cover_traffic_volume_stability_guard.rs +// (CR-CHAT-07 - Cover traffic volume stability guard, Wave-106 +// Lane B, R-CHAT-10). +// +// The total emission volume must hold steady per window: a drop +// says the user went offline, a spike leaks a burst of real +// messages, and volume moves correlated with external events +// reveal behaviour. The rules, in the original's order: the +// batch ceiling, the empty batch (accepted), the whole-batch +// mean, then per window the zero-index probe, the volume floor +// (ten), the volume ceiling (ten thousand), the strictly- +// increasing index and the deviation ceiling - fifteen +// hundredths of the mean. +// +// The original returns Result<(), VolumeStabilityError>. This +// port carries the verdict as a named struct (owner decision +// D5): Ok first, then the six variants in the original's +// declaration order - DeviationExceeded, NotIncreasing, +// ZeroIndex, BelowMin, AboveMax, TooMany - with every payload +// field: idx with the volume, the mean and the ceiling +// deviation for DeviationExceeded, idx with prev and current +// for the monotonic break, idx with the volume and its bound +// for the volume rules, and got with max for the batch +// ceiling. +// +// The original folds a float mean over u64 volumes - the +// int-to-float casts do not lower under the backends. The +// deviation rule re-bases to the original's exact rational +// arithmetic in u64: the deviation of a volume from the +// batch mean sum/len is |v*len - sum| / sum, so the ceiling +// of fifteen hundredths is the integer cross-multiplication +// |v*len - sum| * 100 > sum * 15 - identical verdicts for +// every input, no float anywhere (the CTSG-01 pair fires, +// the valid and uniform batches pass, all Python-verified). +// The float mean still arrives as a caller-computed number +// to ride the verdict's payload field, the lane convention +// for statistics over buffers (#9698, #9747, #9814); the +// structural rules stay fully in the spec. + +// Maximum deviation from mean (fraction of mean). +pub const CTSG_MAX_DEVIATION: f64 = 0.15; + +// Minimum volume per window. +pub const CTSG_MIN_VOLUME: u64 = 10; + +// Maximum volume per window. +pub const CTSG_MAX_VOLUME: u64 = 10000; + +// Maximum windows per batch. +pub const CTSG_MAX_WINDOWS: usize = 256; + +// A volume window record. +pub struct VolumeWindow { + index: u64, + volume: u64, +} + +// Verdict codes: Ok(()) and VolumeStabilityError's variants, in declaration order. +pub enum VolumeStabilityCode { + Ok, + DeviationExceeded, + NotIncreasing, + ZeroIndex, + BelowMin, + AboveMax, + TooMany, +} + +// The verdict of the volume stability validation, with every +// error payload field. +pub struct VolumeStabilityVerdict { + code: VolumeStabilityCode, + idx: usize, + got: usize, + bound: usize, + volume: u64, + prev: u64, + current: u64, + mean: f64, + max_dev: f64, +} + +// [VERIFIED] Validate cover traffic volume stability. Returns +// Ok only when every rule holds, checked in the original's +// order: the batch ceiling, the empty batch (accepted), then +// per window the zero index, the volume floor, the volume +// ceiling, the strictly-increasing index and the deviation +// ceiling over the caller's mean. +pub fn validate_volume_stability( + windows: []const VolumeWindow, + mean: f64, +) -> VolumeStabilityVerdict { + if (windows.len > CTSG_MAX_WINDOWS) { + return VolumeStabilityVerdict { code: VolumeStabilityCode.TooMany, idx: 0, got: windows.len, bound: CTSG_MAX_WINDOWS, volume: 0, prev: 0, current: 0, mean: 0.0, max_dev: 0.0, }; + } + if (windows.len == 0) { + return VolumeStabilityVerdict { code: VolumeStabilityCode.Ok, idx: 0, got: 0, bound: 0, volume: 0, prev: 0, current: 0, mean: 0.0, max_dev: 0.0, }; + } + const n: u64 = @as(u64, windows.len); + var sum: u64 = 0; + for i in 0..windows.len { + sum = sum + windows[i].volume; + } + var prev: u64 = 0; + for i in 0..windows.len { + if (windows[i].index == 0) { + return VolumeStabilityVerdict { code: VolumeStabilityCode.ZeroIndex, idx: i, got: 0, bound: 0, volume: 0, prev: 0, current: 0, mean: 0.0, max_dev: 0.0, }; + } + if (windows[i].volume < CTSG_MIN_VOLUME) { + return VolumeStabilityVerdict { code: VolumeStabilityCode.BelowMin, idx: i, got: 0, bound: 0, volume: windows[i].volume, prev: 0, current: 0, mean: 0.0, max_dev: 0.0, }; + } + if (windows[i].volume > CTSG_MAX_VOLUME) { + return VolumeStabilityVerdict { code: VolumeStabilityCode.AboveMax, idx: i, got: 0, bound: 0, volume: windows[i].volume, prev: 0, current: 0, mean: 0.0, max_dev: 0.0, }; + } + if (i > 0) { + if (windows[i].index <= prev) { + return VolumeStabilityVerdict { code: VolumeStabilityCode.NotIncreasing, idx: i, got: 0, bound: 0, volume: 0, prev: prev, current: windows[i].index, mean: 0.0, max_dev: 0.0, }; + } + } + const scaled: u64 = windows[i].volume * n; + var deviation_num: u64 = 0; + if (scaled > sum) { + deviation_num = scaled - sum; + } else { + deviation_num = sum - scaled; + } + if (deviation_num * 100 > sum * 15) { + return VolumeStabilityVerdict { code: VolumeStabilityCode.DeviationExceeded, idx: i, got: 0, bound: 0, volume: windows[i].volume, prev: 0, current: 0, mean: mean, max_dev: CTSG_MAX_DEVIATION, }; + } + prev = windows[i].index; + } + return VolumeStabilityVerdict { code: VolumeStabilityCode.Ok, idx: 0, got: 0, bound: 0, volume: 0, prev: 0, current: 0, mean: 0.0, max_dev: 0.0, }; +} + +// **CTSG-01** - the deviation ceiling rejected: volumes 100 and +// 200 - a mean of 150.0, the second window deviating one third +// over the ceiling of fifteen hundredths. +test ctsg_01_deviation_rejected { + const ws: [2]VolumeWindow = [2]VolumeWindow{ + VolumeWindow { index: 1, volume: 100, }, + VolumeWindow { index: 2, volume: 200, }, + }; + const v = validate_volume_stability(&ws, 150.0); + assert(v.code == VolumeStabilityCode.DeviationExceeded); + assert(v.idx == 0); + assert(v.volume == 100); + assert(v.mean == 150.0); + assert(v.max_dev == 0.15); +} + +// **CTSG-02** - a non-increasing index rejected: three after +// five. +test ctsg_02_not_increasing_rejected { + const ws: [2]VolumeWindow = [2]VolumeWindow{ + VolumeWindow { index: 5, volume: 100, }, + VolumeWindow { index: 3, volume: 100, }, + }; + const v = validate_volume_stability(&ws, 100.0); + assert(v.code == VolumeStabilityCode.NotIncreasing); + assert(v.idx == 1); + assert(v.prev == 5); + assert(v.current == 3); +} + +// **CTSG-03** - the zero index rejected. +test ctsg_03_zero_index_rejected { + const ws: [1]VolumeWindow = [1]VolumeWindow{ + VolumeWindow { index: 0, volume: 100, }, + }; + const v = validate_volume_stability(&ws, 100.0); + assert(v.code == VolumeStabilityCode.ZeroIndex); + assert(v.idx == 0); +} + +// **CTSG-04** - a volume below the minimum rejected: five of a +// floor ten. +test ctsg_04_below_min_rejected { + const ws: [1]VolumeWindow = [1]VolumeWindow{ + VolumeWindow { index: 1, volume: 5, }, + }; + const v = validate_volume_stability(&ws, 5.0); + assert(v.code == VolumeStabilityCode.BelowMin); + assert(v.idx == 0); + assert(v.volume == 5); +} + +// **CTSG-05** - a volume above the maximum rejected: 10001 of a +// ceiling 10000. +test ctsg_05_above_max_rejected { + const ws: [1]VolumeWindow = [1]VolumeWindow{ + VolumeWindow { index: 1, volume: 10001, }, + }; + const v = validate_volume_stability(&ws, 10001.0); + assert(v.code == VolumeStabilityCode.AboveMax); + assert(v.idx == 0); + assert(v.volume == 10001); +} + +// **CTSG-06** - too many rejected: 257 windows of a maximum 256, +// built in a loop like the original's, the indexes walking one +// upward. The batch rule fires before any window is examined. +test ctsg_06_too_many_rejected { + var ws: [257]VolumeWindow; + for i in 0..257 { + ws[i] = VolumeWindow { index: @as(u64, i) + 1, volume: 100, }; + } + const v = validate_volume_stability(&ws, 100.0); + assert(v.code == VolumeStabilityCode.TooMany); + assert(v.got == 257); + assert(v.bound == 256); +} + +// **CTSG-07** - the valid batch accepted: 100, 105, 95 - a mean +// of 100.0, every deviation under the ceiling. +test ctsg_07_valid_accepted { + const ws: [3]VolumeWindow = [3]VolumeWindow{ + VolumeWindow { index: 1, volume: 100, }, + VolumeWindow { index: 2, volume: 105, }, + VolumeWindow { index: 3, volume: 95, }, + }; + const v = validate_volume_stability(&ws, 100.0); + assert(v.code == VolumeStabilityCode.Ok); +} + +// **CTSG-08** - an empty batch accepted. +test ctsg_08_empty_accepted { + const ws: [0]VolumeWindow = [0]VolumeWindow{}; + const v = validate_volume_stability(&ws, 0.0); + assert(v.code == VolumeStabilityCode.Ok); +} + +// **CTSG-09** - a single window accepted: a mean of its own +// volume, a deviation of zero. +test ctsg_09_single_accepted { + const ws: [1]VolumeWindow = [1]VolumeWindow{ + VolumeWindow { index: 1, volume: 100, }, + }; + const v = validate_volume_stability(&ws, 100.0); + assert(v.code == VolumeStabilityCode.Ok); +} + +// **CTSG-10** - the uniform batch accepted: ten windows at a +// hundred - a mean of 100.0, zero deviation. +test ctsg_10_uniform_accepted { + var ws: [10]VolumeWindow; + for i in 0..10 { + ws[i] = VolumeWindow { index: @as(u64, i) + 1, volume: 100, }; + } + const v = validate_volume_stability(&ws, 100.0); + assert(v.code == VolumeStabilityCode.Ok); +} + +// Rule order is the original's: the batch ceiling before +// anything, the empty batch before the per-window rules, the +// zero index before the volume floor, the volume bounds before +// the monotonicity, and the monotonicity before the deviation - +// with both violations on one window. +test rule_order_matches_original { + const empty: [0]VolumeWindow = [0]VolumeWindow{}; + const v1 = validate_volume_stability(&empty, 0.0); + assert(v1.code == VolumeStabilityCode.Ok); + + var flooded: [257]VolumeWindow; + for i in 0..257 { + flooded[i] = VolumeWindow { index: 0, volume: 0, }; + } + const v2 = validate_volume_stability(&flooded, 0.0); + assert(v2.code == VolumeStabilityCode.TooMany); + + const zero_tiny: [1]VolumeWindow = [1]VolumeWindow{ + VolumeWindow { index: 0, volume: 5, }, + }; + const v3 = validate_volume_stability(&zero_tiny, 5.0); + assert(v3.code == VolumeStabilityCode.ZeroIndex); + + const tiny_tail: [5]VolumeWindow = [5]VolumeWindow{ + VolumeWindow { index: 1, volume: 10, }, + VolumeWindow { index: 2, volume: 10, }, + VolumeWindow { index: 3, volume: 10, }, + VolumeWindow { index: 4, volume: 10, }, + VolumeWindow { index: 5, volume: 9, }, + }; + const v4 = validate_volume_stability(&tiny_tail, 9.8); + assert(v4.code == VolumeStabilityCode.BelowMin); + assert(v4.idx == 4); + + const backstep_equal: [5]VolumeWindow = [5]VolumeWindow{ + VolumeWindow { index: 1, volume: 300, }, + VolumeWindow { index: 2, volume: 300, }, + VolumeWindow { index: 3, volume: 300, }, + VolumeWindow { index: 2, volume: 300, }, + VolumeWindow { index: 5, volume: 300, }, + }; + const v5 = validate_volume_stability(&backstep_equal, 300.0); + assert(v5.code == VolumeStabilityCode.NotIncreasing); + assert(v5.idx == 3); + + const deviant_tail: [5]VolumeWindow = [5]VolumeWindow{ + VolumeWindow { index: 1, volume: 320, }, + VolumeWindow { index: 2, volume: 320, }, + VolumeWindow { index: 3, volume: 320, }, + VolumeWindow { index: 4, volume: 320, }, + VolumeWindow { index: 5, volume: 600, }, + }; + const v6 = validate_volume_stability(&deviant_tail, 376.0); + assert(v6.code == VolumeStabilityCode.DeviationExceeded); + assert(v6.idx == 4); + assert(v6.volume == 600); +}