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
//! §Fase 33.z.k (v1.28.0) — Wire-format adapter framework.
//!
//! Closed-catalog dispatcher for SSE wire-format dialects. Three
//! dialects ship as first-class adapters per Q3 ratification:
//!
//! - **axon**: W3C named events (`event: axon.token` /
//! `event: axon.complete` / `event: axon.tool_call` /
//! `event: axon.error`). D6 backwards-compat baseline.
//! - **openai**: `data: {"choices": [{"delta": {"content": "..."}}]}`
//! frames terminated by `data: [DONE]`. Matches OpenAI Chat
//! Completions API streaming wire (OpenAI Reference Docs §Chat /
//! Create chat completion / Streaming).
//! - **anthropic**: `event: content_block_delta` /
//! `event: message_stop`. Matches Anthropic Messages API
//! streaming wire (Anthropic API Reference §Messages / Streaming).
//!
//! # Architecture
//!
//! The producer drives a translation loop:
//!
//! ```text
//! for event in flow_execution_event_stream {
//! for wire_event in adapter.translate(&event) {
//! tx.send(Ok(wire_event)).await?;
//! }
//! }
//! for terminator in adapter.flush_terminator() {
//! tx.send(Ok(terminator)).await?;
//! }
//! ```
//!
//! Each adapter is **stateful** — it tracks per-request state (event
//! ID counter, current step index for content_block boundaries,
//! per-dialect tool-call indices, etc.). A fresh adapter is
//! constructed per request via `select_adapter(dialect, trace_id)`.
//!
//! # D-letter coverage
//!
//! - **D3 semantic equivalence**: every dialect emits the SAME
//! per-token content + step-name + arrival ordering. Only framing
//! differs.
//! - **D4 algebraic-policy preservation**: each adapter exposes a
//! dedicated path for `enforcement_summary` / `runtime_warnings` /
//! `step_audit` surfacing — axon embeds them on `axon.complete`,
//! openai emits a `data: {"axon_metadata": {...}}` frame BEFORE
//! `data: [DONE]`, anthropic emits `event: axon.metadata` BEFORE
//! `event: message_stop`.
//! - **D5 closed-dialect terminators**: each adapter's
//! `flush_terminator()` emits the dialect's native terminator
//! (axon: `axon.complete`; openai: `data: [DONE]`; anthropic:
//! `event: message_stop`).
//! - **D9 wire byte-compat for canonical Step**: the axon-dialect
//! adapter MUST produce byte-identical output to the v1.27.1
//! inline emission. Test pack
//! `tests/fase33z_k_d_axon_adapter_byte_compat.rs` pins this.
//!
//! # Pillar trace (D10)
//!
//! - MATHEMATICS — each `translate` is a pure projection from one
//! `FlowExecutionEvent` to a `Vec<Event>`. Trait method invariant.
//! - LOGIC — closed catalog of 3 dialects; `select_adapter`
//! dispatch is exhaustive; unknown dialect defaults to axon.
//! - PHILOSOPHY — adopters' SDKs consume the wire format their
//! ecosystem documents; the language adapts to the adopter
//! layer, not the other way around (`Axon for Axon` discipline
//! per the founder principle).
//! - COMPUTING — adapter selection is O(1) at request time;
//! per-request adapter state is unbounded but small (~3-5
//! counters); no allocation per token translation.
use crateEnforcementSummaryWire;
use crateStepAuditRecord;
use crateFlowExecutionEvent;
use crateRuntimeWarning;
use Event;
/// §Fase 33.z.k.g (v1.28.0) — Envelope carrying all the side-channel
/// + summary data the SSE producer accumulates over the lifetime of
/// a flow. Passed to `adapter.build_complete_envelope_event()` at
/// FlowComplete time so dialect adapters can surface the data per
/// their wire-format conventions:
///
/// - **axon**: embeds the fields directly on `axon.complete` (D4
/// wire byte-compat with v1.27.1 inline `build_complete_event`).
/// - **openai**: emits a separate `data: {"axon_metadata": {...}}`
/// frame BEFORE `data: [DONE]` (Q7 ratification).
/// - **anthropic**: emits a separate `event: axon.metadata` frame
/// BEFORE `event: message_stop` (Q7).
///
/// Built by the producer from the same side-channels v1.27.1
/// `build_complete_event` consumed:
/// - `enforcement_summaries`: per-step enforcement counters from
/// the dispatcher's `StreamPolicyEnforcer` (Fase 33.x.d).
/// - `runtime_warnings`: closed-catalog axon-W002 etc. warnings
/// (Fase 33.x.g).
/// - `effect_policies`: per-step `<stream:<policy>>` declarations
/// (Fase 33.e).
/// - `step_audit_records`: per-step audit rows (step_name +
/// tokens_emitted + output_hash + effect_policy_applied +
/// counters), populated by the dispatcher (Fase 33.x.f). Surfaces
/// on the `axon.metadata` extension frame for openai + anthropic
/// dialects (Q7 algebraic-policy preservation channel — adopters
/// on those wires use this to satisfy banking PCI DSS Req 10 /
/// government FedRAMP AU-2 / legal FRE 502 / medicine 21 CFR Part
/// 11 §11.10 per-step provenance requirements).
/// - Flow envelope: trace_id, flow_name, backend, success, counters,
/// latency.
/// Wire-format adapter trait — translates internal flow-execution
/// events into per-dialect SSE wire events.
///
/// Adapters are **stateful** — a fresh adapter is constructed per
/// request via [`select_adapter`]. The adapter tracks per-request
/// state (event ID counter, step index, per-tool-call index, etc.)
/// internally.
///
/// All methods are `&mut self` to permit internal counter updates.
/// Adapters MUST be `Send` so the SSE producer can move them across
/// the spawn boundary.
/// Closed-catalog factory for wire-format adapters.
///
/// `dialect` is one of `"axon"` / `"openai"` / `"anthropic"` (Q3
/// ratified catalog). Unknown dialect strings default to
/// `axon` (defensive — caller already validated via
/// `AXONENDPOINT_TRANSPORT_DIALECTS` at parse time, but we never
/// panic on a stale input).
///
/// `trace_id` is reserved per-request (Fase 33.x.c contract); the
/// adapter embeds it in every emitted event for correlation.