1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
// SHIP-TWO-001 — `apr-cli-operations-v1` algorithm-level PARTIAL
// discharge for FALSIFY-OPS-007.
//
// Contract: `contracts/apr-cli-operations-v1.yaml`.
// Spec: `docs/specifications/aprender-train/ship-two-models-spec.md`.
//
// ## What FALSIFY-OPS-007 says
//
// rule: Token count bounded by input length
// prediction: No input produces more than 4x tokens (BPE worst case)
// test: Encode adversarial strings (single-byte tokens), verify
// count <= 4 * len
// if_fails: Token explosion — unbounded memory usage
//
// ## What this file proves NOW (`PARTIAL_ALGORITHM_LEVEL`)
//
// Decision rule: given (`input_byte_len`, `token_count`), Pass iff:
//
// input_byte_len > 0 AND
// token_count <= AC_OPS_007_MAX_RATIO (4) * input_byte_len
//
// Linear-bound verdict via `checked_mul` to prevent overflow at
// adversarial input sizes near `u64::MAX`. Inclusive `<=` matches
// the contract's `<= 4 * len` test wording.
/// Maximum tokens-per-input-byte ratio for BPE worst case.
///
/// Per contract: BPE byte-level fallback emits at most ~4 tokens
/// per input byte in the worst case (UTF-8 4-byte sequences split
/// into 4 byte-fallback tokens). 4× cap is the published BPE
/// worst-case bound.
///
/// Drift to 8× would mask token-explosion bugs (unbounded merge
/// expansion); drift to 2× would over-tighten and reject
/// pathological-but-valid CJK / emoji inputs.
pub const AC_OPS_007_MAX_RATIO: u64 = 4;
/// Binary verdict for `FALSIFY-OPS-007`.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Ops007Verdict {
/// `input_byte_len > 0` AND `token_count <= 4 * input_byte_len`.
Pass,
/// One or more of:
/// - `input_byte_len == 0` (caller error — empty input).
/// - `token_count > 4 * input_byte_len` (token explosion).
/// - Multiplication overflow on `4 * input_byte_len`.
Fail,
}
/// Pure verdict function for `FALSIFY-OPS-007`.
///
/// Inputs:
/// - `input_byte_len`: length of the input string in bytes (UTF-8).
/// - `token_count`: number of tokens produced by tokenizing the
/// input.
///
/// Pass iff:
/// 1. `input_byte_len > 0`,
/// 2. `token_count <= input_byte_len.checked_mul(4)` (overflow → Fail).
///
/// Otherwise `Fail`.
///
/// # Examples
///
/// 100-byte input → 50 tokens (well within 4× cap) — `Pass`:
/// ```
/// use aprender::format::ops_007::{
/// verdict_from_token_count_bound, Ops007Verdict,
/// };
/// let v = verdict_from_token_count_bound(100, 50);
/// assert_eq!(v, Ops007Verdict::Pass);
/// ```
///
/// 100-byte input → 401 tokens (exceeds 4× cap = 400) — `Fail`:
/// ```
/// use aprender::format::ops_007::{
/// verdict_from_token_count_bound, Ops007Verdict,
/// };
/// let v = verdict_from_token_count_bound(100, 401);
/// assert_eq!(v, Ops007Verdict::Fail);
/// ```
#[must_use]
pub fn verdict_from_token_count_bound(
input_byte_len: u64,
token_count: u64,
) -> Ops007Verdict {
if input_byte_len == 0 {
return Ops007Verdict::Fail;
}
let max_tokens = match input_byte_len.checked_mul(AC_OPS_007_MAX_RATIO) {
Some(v) => v,
None => return Ops007Verdict::Fail,
};
if token_count <= max_tokens {
Ops007Verdict::Pass
} else {
Ops007Verdict::Fail
}
}
#[cfg(test)]
mod tests {
use super::*;
// -------------------------------------------------------------------------
// Section 1: Provenance pin — 4× ratio.
// -------------------------------------------------------------------------
#[test]
fn provenance_max_ratio_is_4() {
assert_eq!(AC_OPS_007_MAX_RATIO, 4);
}
// -------------------------------------------------------------------------
// Section 2: Pass band — typical compression ratios.
// -------------------------------------------------------------------------
#[test]
fn pass_typical_compression_ratio() {
// BPE typically compresses ~3:1 on English text — 100 bytes → ~30 tokens.
let v = verdict_from_token_count_bound(100, 30);
assert_eq!(v, Ops007Verdict::Pass);
}
#[test]
fn pass_at_exact_4x_cap() {
// Worst case: every byte → 4 tokens.
let v = verdict_from_token_count_bound(100, 400);
assert_eq!(v, Ops007Verdict::Pass);
}
#[test]
fn pass_one_byte_one_token() {
let v = verdict_from_token_count_bound(1, 1);
assert_eq!(v, Ops007Verdict::Pass);
}
#[test]
fn pass_realistic_apr_run_input() {
// 50-byte prompt → 12 tokens (typical English compression).
let v = verdict_from_token_count_bound(50, 12);
assert_eq!(v, Ops007Verdict::Pass);
}
#[test]
fn pass_huge_clean_input() {
let v = verdict_from_token_count_bound(1_000_000, 100_000);
assert_eq!(v, Ops007Verdict::Pass);
}
// -------------------------------------------------------------------------
// Section 3: Fail band — token explosion.
// -------------------------------------------------------------------------
#[test]
fn fail_just_above_4x_cap() {
let v = verdict_from_token_count_bound(100, 401);
assert_eq!(
v,
Ops007Verdict::Fail,
"+1 token over cap must Fail"
);
}
#[test]
fn fail_5x_token_explosion() {
let v = verdict_from_token_count_bound(100, 500);
assert_eq!(v, Ops007Verdict::Fail);
}
#[test]
fn fail_10x_token_explosion() {
let v = verdict_from_token_count_bound(100, 1_000);
assert_eq!(v, Ops007Verdict::Fail);
}
#[test]
fn fail_unbounded_memory_attack() {
// Adversarial input: 10-byte string produces 100k tokens.
let v = verdict_from_token_count_bound(10, 100_000);
assert_eq!(
v,
Ops007Verdict::Fail,
"DoS-class token explosion must Fail"
);
}
// -------------------------------------------------------------------------
// Section 4: Fail band — empty input (caller error).
// -------------------------------------------------------------------------
#[test]
fn fail_zero_input_zero_tokens() {
// Empty input is degenerate — refuse.
let v = verdict_from_token_count_bound(0, 0);
assert_eq!(
v,
Ops007Verdict::Fail,
"zero-byte input must Fail (vacuous Pass refused)"
);
}
#[test]
fn fail_zero_input_with_tokens() {
// Counter corruption: 0 bytes but 5 tokens.
let v = verdict_from_token_count_bound(0, 5);
assert_eq!(v, Ops007Verdict::Fail);
}
// -------------------------------------------------------------------------
// Section 5: Overflow protection — checked_mul on input * 4.
// -------------------------------------------------------------------------
#[test]
fn fail_input_times_4_overflow() {
// input * 4 overflows u64.
let huge = u64::MAX / 2 + 1;
let v = verdict_from_token_count_bound(huge, 0);
// tokens=0 ≤ overflow → Fail (overflow triggers Fail).
assert_eq!(
v,
Ops007Verdict::Fail,
"input * 4 overflow must Fail (not silently wrap)"
);
}
#[test]
fn fail_input_max_overflow_with_tokens() {
let v = verdict_from_token_count_bound(u64::MAX, 100);
assert_eq!(v, Ops007Verdict::Fail);
}
// -------------------------------------------------------------------------
// Section 6: Boundary sweep — token-count sweep around 4× cap.
// -------------------------------------------------------------------------
#[test]
fn token_count_sweep_at_fixed_input_100() {
let input_len = 100_u64;
let probes: Vec<(u64, Ops007Verdict)> = vec![
(0, Ops007Verdict::Pass),
(1, Ops007Verdict::Pass),
(50, Ops007Verdict::Pass),
(100, Ops007Verdict::Pass),
(300, Ops007Verdict::Pass),
(399, Ops007Verdict::Pass),
(400, Ops007Verdict::Pass), // exact cap (inclusive)
(401, Ops007Verdict::Fail), // just above cap
(1_000, Ops007Verdict::Fail),
(u64::MAX, Ops007Verdict::Fail),
];
for (tokens, expected) in probes {
let v = verdict_from_token_count_bound(input_len, tokens);
assert_eq!(
v, expected,
"input=100 tokens={tokens} expected {expected:?}"
);
}
}
// -------------------------------------------------------------------------
// Section 7: Realistic — UTF-8 byte-fallback worst-case scenarios.
// -------------------------------------------------------------------------
#[test]
fn pass_4_byte_emoji_at_4_tokens() {
// Single emoji is 4 UTF-8 bytes → up to 4 byte-fallback tokens.
let v = verdict_from_token_count_bound(4, 4);
assert_eq!(v, Ops007Verdict::Pass);
}
#[test]
fn pass_3_byte_cjk_at_3_tokens() {
// CJK char is 3 UTF-8 bytes → up to 3 byte-fallback tokens.
let v = verdict_from_token_count_bound(3, 3);
assert_eq!(v, Ops007Verdict::Pass);
}
#[test]
fn fail_adversarial_token_explosion() {
// Realistic regression: tokenizer produces 5+ tokens per
// input byte due to broken merge table.
let v = verdict_from_token_count_bound(1_000, 5_001);
assert_eq!(
v,
Ops007Verdict::Fail,
"5+ tokens per byte must Fail (DoS class)"
);
}
}