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
//! The dimensions availability is *derived from*, kept separate on purpose
//! (#206).
//!
//! Five independent questions decide whether a tenant may reach an upstream
//! target, and each has its own authority, its own lifetime, and its own repair:
//!
//! | Dimension | Authority | Repair |
//! | --- | --- | --- |
//! | [`CataloguePresence`] | the catalogue (#192/#146) | publish or restore the entry |
//! | [`Enablement`] | the tenant's own enablement (#205/#149) | enable it |
//! | [`Entitlement`] | the provider account behind a credential (#198/#145) | grant or rotate |
//! | [`PolicyDecision`] | the deployment's policy | change the policy |
//! | [`RuntimeHealth`] | this replica's own request outcomes | wait, or fix the upstream |
//!
//! Collapsing them into one tri-state would be smaller and wrong. "The operator
//! has not enabled this model", "your provider account is not entitled to it",
//! and "this replica's circuit for it is open" call for three different actions by
//! three different people, and only the third one heals by itself. They are also
//! *not* commutative with respect to durability: a runtime observation is
//! replica-local evidence with a lifetime of minutes, and a catalogue fact is
//! durable and fleet-wide. So the dimensions stay separate all the way to the
//! evaluator, which combines them under one documented precedence
//! ([`AvailabilityIndex::evaluate`]) and records *which* dimension decided.
//!
//! [`AvailabilityIndex::evaluate`]: super::AvailabilityIndex::evaluate
//!
//! Discovery is the sixth dimension and lives in [`discovery`](super::discovery),
//! because it is the only one with observations, expiry, and a last-known-good
//! history rather than a single current value.
/// Whether the catalogue carries the target at all.
///
/// A durable, fleet-wide fact: what the deployment's catalogue says exists. Not
/// an entitlement — a present entry says the deployment knows the model, not that
/// anyone may call it.
/// Whether the scope has been enabled for the target.
///
/// The tenant-facing switch (#205/#149), and the reason unknown or stale evidence
/// can be routable at all: a scope that has explicitly enabled a target has said
/// it accepts the risk of calling one whose discovery evidence is not definitive.
/// Whether the provider account behind the scope's credential may call the
/// target.
///
/// Decided upstream of the gateway and only *observed* here.
/// [`Self::Unknown`] is a first-class value rather than an optimistic default: a
/// credential that has never been exercised against a target says nothing about
/// entitlement, and treating silence as a grant is how a fleet learns about a
/// missing entitlement from a customer.
/// What the deployment's policy says about the pair.
///
/// [`Self::Indeterminate`] is what a policy engine that could not decide reports —
/// a rule referencing a fact this replica does not hold, for instance. It is
/// deliberately *not* a permit: an undecided policy leaves availability unknown,
/// and unknown is routable only under explicit enablement.
/// What this replica's own request outcomes last said about the target.
///
/// Replica-local by construction, exactly like the per-target circuit breaker it
/// is derived from (ADR 0008, [`CircuitBreaker`](gateway_core::CircuitBreaker)),
/// and it stays that way: runtime evidence contributes to a *verdict* and never
/// to a durable fact. Nothing here is written back to a catalogue, a discovery
/// observation, or a revision, so a single replica's bad afternoon cannot retire
/// a model for the fleet.