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
//! `cache_salt`: which caller's namespace a request's cached prefixes
//! belong to.
//!
//! A prefix cache is shared state keyed by token ids. Without a salt,
//! one caller's prompt can be answered from another caller's cached
//! prefix, and the shared leading tokens are usually the system prompt
//! -- the part a caller most expects to be theirs. That is an
//! ISOLATION property, not a performance knob, which is why frink
//! refused the field by name rather than ignoring it.
//!
//! # Hashed, not stored
//!
//! The caller's string never reaches a cache. It is hashed to a `u64`
//! and only the hash is kept, so a heap dump of the cache does not
//! carry whatever the caller chose to namespace by -- which may be a
//! tenant id, an account, or something they considered secret.
//!
//! A hash collision would merge two namespaces, and `u64` from
//! `DefaultHasher` makes that vanishingly unlikely for the number of
//! distinct salts one server sees. It is written down rather than
//! ignored: the failure mode is two callers sharing a namespace, which
//! is the behaviour they had before the field existed.
//!
//! # Where it is NOT honoured
//!
//! The paged store's radix tree has no per-namespace scoping: it walks
//! one tree keyed by token ids, and its nodes hold block indices the
//! whole deployment shares. Adding a namespace there is a change to
//! the tree and its eviction, not a parameter, so a paged request that
//! names a salt is REFUSED BY NAME. Serving it would be the worst of
//! the three options: a caller who asked for isolation, told they got
//! it, and sharing anyway.
use ;
/// The namespace id for a caller's salt, or `None` for the shared one.
///
/// An EMPTY string is `None` rather than its own namespace: a caller
/// who sends `""` has named nothing, and giving them a private
/// namespace keyed on emptiness would silently stop them sharing with
/// themselves across requests.
pub