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
// SPDX-License-Identifier: MIT OR Apache-2.0
// SPDX-FileCopyrightText: 2025-2026 ObzenFlow Contributors
// https://obzenflow.dev
//! FLOWIP-115d: the fail-fast ingress admission vocabulary.
//!
//! Per-attempt facts, the admission decision, the observed outcome, and the
//! refusal-reason labels. Ingress is not source polling and not FLOWIP-115e
//! backpressure; it admits, rejects (rate-limited), or sheds (edge overload) a
//! submission attempt without ever waiting for a token while holding a listener
//! request.
use ;
use Duration;
/// Monotonic, per-hosted-ingress submission-attempt sequence (FLOWIP-115d).
///
/// One sequence per external submission attempt: a single `POST {base}/events`
/// or a single `POST {base}/batch` consumes one sequence for the whole request.
/// It is attempt context and the v1 cross-journal audit merge key, never part of
/// the protected-unit key. Because it is assigned at admission time and carried
/// on the accepted row, source-journal position may differ from sequence order
/// under concurrency; auditors merge by the carried sequence value, not position.
;
/// Distinguishes a rate-limit refusal from a hosted-ingress edge shed.
///
/// `RateLimited` is the rate-limiter middleware's token-bucket decision (maps to
/// `429`). `EdgeShed` is a hosted-ingress admission outcome owned by infra before
/// source data exists (maps to `503`); it is not FLOWIP-115e backpressure.
/// Why a hosted-ingress edge shed an attempt. `BufferFull` is edge-shed because
/// the source input channel could not reserve capacity; it is not FLOWIP-115e
/// backpressure, which is runtime-owned downstream credit at output commit.
/// The reason an ingress submission attempt was refused, recorded on the durable
/// `IngressRefusal` system-journal fact (FLOWIP-115d). Telemetry projects the
/// per-`(ingress_key, reason)` refusal count from these facts, so the labels are
/// stable and the metric is replay-faithful (`state = fold(facts)`).
///
/// `RateLimited` is the limiter's token-bucket decision (429). `NotReady`,
/// `BufferFull`, `ChannelClosed`, and `ListenerOverloaded` are hosted-edge shed
/// outcomes (503). `Validation` is a per-event input-validation rejection; it is
/// journalled (unlike the other protocol 4xx rejects, which the bucketed
/// HTTP-surface metrics already cover) because a partially accepted batch returns
/// `200`, so its per-event validation rejections are otherwise invisible.
/// Per-attempt facts handed to the ingress boundary for one external submission.
///
/// The boundary instance is already bound to one protected unit (the linked
/// source stage plus hosted target), so identity is implicit; this carries only
/// the request-scoped facts an admission charge or proof row needs.
/// The fail-fast admission decision from the ingress boundary (FLOWIP-115d).
///
/// 115D HTTP ingress never waits for a token while holding a listener request: a
/// token exhaustion is a `Reject`, never a wait.
/// What infra observed after acting on the admission decision and enqueue.
///
/// Admitted policies observe this in reverse order (the forward-admission,
/// fail-fast ingress chain). It never represents downstream source handling or
/// later handler results.