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
//! Canonical token accounting — the rule that makes budget honesty checkable
//! (`SPEC.md` §B3, [ADR 0003](../../docs/adr/0003-canonical-token-accounting.md)).
//!
//! Budget honesty is CGP's flagship guarantee, but before this rule existed the
//! conformance suite could only verify *arithmetic*: it summed the costs a
//! provider declared and compared the total to the budget. A provider reporting
//! `token_cost: 1` on a ten-thousand-token frame satisfied that check perfectly
//! while destroying the host's actual budget. The one lie that mattered was the
//! one lie the suite could not catch.
//!
//! [`budget_tokens`] closes that hole by making cost a function of bytes both
//! sides observe:
//!
//! ```text
//! budget_tokens(content) = ceil(utf8_byte_length(content) / 4)
//! ```
//!
//! # This is an accounting unit, not a tokenizer
//!
//! A budget token is deliberately **not** a prediction of any model's
//! tokenizer. Its job is to make every provider's cost claims comparable and
//! verifiable, which no real tokenizer can do without being mandated in every
//! language an implementation might be written in.
//!
//! The approximation is honest about its direction. At roughly four bytes per
//! token it tracks English prose closely, and it **under-estimates** dense
//! source code (≈3–3.5 bytes/token) and CJK text (≈3 bytes/token). A host
//! therefore **MUST NOT** treat one budget token as one model token: it maps
//! its real model budget into budget tokens with a safety factor. See
//! [`SUGGESTED_HOST_SAFETY_FACTOR`].
//!
//! # Scope
//!
//! The count covers `ContextFrame::content` only — not `title`, not
//! `citation_label`, not provenance, and not the fences and labels a host wraps
//! around a frame. `content` is the one field the provider fully controls and
//! whose exact bytes both sides observe identically, so it is the only input on
//! which a byte-exact check can be built. The host's own rendering chrome is
//! the host's cost to budget.
/// Bytes per budget token. See the module docs for why this constant is an
/// accounting convention rather than an empirical tokenizer ratio.
pub const BYTES_PER_BUDGET_TOKEN: usize = 4;
/// The factor a host is advised to apply when converting a real model context
/// budget into budget tokens, compensating for the under-estimate on source
/// code and CJK text.
///
/// Advisory, not normative: a host that knows its corpus is English prose can
/// safely use less headroom, and one serving minified JSON may want more. It is
/// stated as a constant so the reference host's choice is inspectable rather
/// than buried in a literal.
pub const SUGGESTED_HOST_SAFETY_FACTOR: f32 = 1.35;
/// The canonical budget-token cost of a piece of frame content.
///
/// This is the value `ContextFrame::token_cost` **MUST** carry (`SPEC.md` §B3).
/// Exact equality is required — there is no tolerance band, because any band
/// wide enough to absorb genuine tokenizer disagreement is also wide enough to
/// hide meaningful under-reporting, which puts the suite back to guessing. A
/// provider cannot "disagree" with a byte count.
///
/// ```
/// use contextgraph_types::budget_tokens;
///
/// assert_eq!(budget_tokens(""), 0);
/// assert_eq!(budget_tokens("abcd"), 1);
/// assert_eq!(budget_tokens("abcde"), 2); // ceil, never floor
/// ```
/// Convert a real model context budget into budget tokens, applying `factor` as
/// headroom against the under-estimate documented on [`budget_tokens`].
///
/// A host asking for `model_tokens` worth of real context should request this
/// many budget tokens, so that honest providers filling the budget exactly do
/// not overflow the model window.