Skip to main content

axon_frontend/
ast.rs

1//! AXON AST node definitions — direct port of axon/compiler/ast_nodes.py.
2//!
3//! Tier 1 constructs have fully typed structs.
4//! Tier 2+ constructs use `GenericDeclaration` (structural fallback).
5
6#![allow(dead_code)]
7
8use crate::tokens::Trivia;
9
10// ── Location helper ──────────────────────────────────────────────────────────
11
12/// Source location shared by all AST nodes.
13#[derive(Debug, Clone, Default)]
14pub struct Loc {
15    pub line: u32,
16    pub column: u32,
17}
18
19// ── Trivia channel (Fase 14.a — Lossless lexing) ─────────────────────────────
20//
21// The Python AST attaches `leading_trivia` / `trailing_trivia` directly
22// to each ASTNode (97+ subclasses inherit empty defaults). The Rust
23// structs do not have inheritance, so adding two `Vec<Trivia>` fields
24// to every node would require touching each of the 97 structs and
25// every fixture test that constructs them — high mechanical churn for
26// a use case (LSP / formatter / doc gen) that can be served just as
27// well by indexing trivia by declaration position.
28//
29// `DeclarationTrivia` is a side-channel attached to `Program`. The
30// parser populates it in lockstep with `declarations` so consumer code
31// can do `program.declaration_trivia[i]` to get the leading/trailing
32// trivia of `program.declarations[i]`. This preserves the AST shape
33// (no breaking changes), keeps `IRProgram` JSON byte-identical with
34// the Python reference (trivia is never serialised), and ships the
35// adopter-reported feature end-to-end.
36//
37// If a future sub-phase wants per-node trivia inside the AST itself
38// (mirror of the Python ASTNode shape), this side-channel is the seed:
39// every `DeclarationTrivia` already carries the data; spreading it
40// into the structs is a mechanical refactor at that point.
41
42/// Comments attached to a single top-level declaration. Indexed
43/// in parallel with `Program.declarations`.
44#[derive(Debug, Clone, Default)]
45pub struct DeclarationTrivia {
46    /// Comment trivia that appeared before the declaration's first
47    /// token (since the previous declaration or file start).
48    pub leading: Vec<Trivia>,
49    /// Comment trivia on the same line as the declaration's last
50    /// effective token, before the next newline.
51    pub trailing: Vec<Trivia>,
52}
53
54// ── Top-level ────────────────────────────────────────────────────────────────
55
56#[derive(Debug)]
57pub struct Program {
58    pub declarations: Vec<Declaration>,
59    /// Fase 14.a — comment trivia attached per declaration (parallel
60    /// with `declarations`). Empty by default; populated by the parser
61    /// when source carries comments. Defaults preserve every existing
62    /// `Program { declarations, loc }` constructor — `..Default::default()`
63    /// on a `Program` literal fills in the new field.
64    pub declaration_trivia: Vec<DeclarationTrivia>,
65    pub loc: Loc,
66}
67
68/// A single top-level declaration in an AXON program.
69#[derive(Debug)]
70pub enum Declaration {
71    Import(ImportNode),
72    Persona(PersonaDefinition),
73    Context(ContextDefinition),
74    Anchor(AnchorConstraint),
75    Memory(MemoryDefinition),
76    Tool(ToolDefinition),
77    Type(TypeDefinition),
78    Flow(FlowDefinition),
79    Intent(IntentNode),
80    Run(RunStatement),
81    Epistemic(EpistemicBlock),
82    Let(LetStatement),
83    /// Lambda Data (ΛD) — Epistemic State Vector definition.
84    LambdaData(LambdaDataDefinition),
85    // ── Tier 2 declarations (full AST) ──
86    Agent(AgentDefinition),
87    Shield(ShieldDefinition),
88    Pix(PixDefinition),
89    Psyche(PsycheDefinition),
90    Corpus(CorpusDefinition),
91    Dataspace(DataspaceDefinition),
92    Ots(OtsDefinition),
93    Mandate(MandateDefinition),
94    Compute(ComputeDefinition),
95    Daemon(DaemonDefinition),
96    AxonStore(AxonStoreDefinition),
97    AxonEndpoint(AxonEndpointDefinition),
98    /// §Fase 53 — Closed-catalog extension mechanism. Declares
99    /// adopter-specific PROVENANCE members for a closed catalog
100    /// (`effects` bases or shield `scan` categories) so the
101    /// type-checker + PCC treat them as first-class. Auditable +
102    /// gateable; never extends the enforceable effect set (invariant
103    /// #2 — provenance-class only).
104    Extension(ExtensionDefinition),
105    /// §λ-L-E Fase 1 — I/O cognitivo primitives.
106    Resource(ResourceDefinition),
107    Fabric(FabricDefinition),
108    Manifest(ManifestDefinition),
109    Observe(ObserveDefinition),
110    /// §λ-L-E Fase 3 — Control cognitivo primitives.
111    Reconcile(ReconcileDefinition),
112    Lease(LeaseDefinition),
113    Ensemble(EnsembleDefinition),
114    /// §λ-L-E Fase 4 — Topology + π-calculus binary sessions.
115    Session(SessionDefinition),
116    Topology(TopologyDefinition),
117    /// §λ-L-E Fase 5 — Cognitive immune system (per docs/paper_immune_v2.md).
118    Immune(ImmuneDefinition),
119    Reflex(ReflexDefinition),
120    Heal(HealDefinition),
121    /// §λ-L-E Fase 9 — UI cognitiva declarativa.
122    Component(ComponentDefinition),
123    View(ViewDefinition),
124    /// §λ-L-E Fase 13 — Mobile typed channels (paper_mobile_channels.md).
125    Channel(ChannelDefinition),
126    /// §Fase 41.b — typed WebSocket transport binding a `session` protocol
127    /// (paper_websocket_cognitive_primitive.md).
128    Socket(SocketDefinition),
129    /// Tier 3+ declarations parsed structurally (balanced braces, no detailed AST).
130    Generic(GenericDeclaration),
131}
132
133// ── §λ-L-E Fase 1 — Resource primitive ───────────────────────────────────────
134
135/// `resource Name { kind, endpoint, capacity, lifetime, certainty_floor, shield }`
136///
137/// An infrastructure resource declared as a linear, affine, or persistent
138/// token. Linear/affine resources cannot be aliased across manifests
139/// (Separation Logic `*` disjointness).
140#[derive(Debug, Default)]
141pub struct ResourceDefinition {
142    pub name: String,
143    pub kind: String, // postgres | redis | s3 | vpc | gpu | compute | file | custom
144    pub endpoint: String, // connection URI
145    pub capacity: Option<i64>, // pool size / instance count hint
146    pub lifetime: String, // linear | affine | persistent (default: affine)
147    pub certainty_floor: Option<f64>, // epistemic gate c ∈ [0.0, 1.0]
148    pub shield_ref: String, // optional shield reference
149    pub loc: Loc,
150    /// Fase 14.b — leading comment trivia attached to this declaration
151    /// (comments preceding the declaration's first token, since the
152    /// previous declaration or file start). Empty by default.
153    pub leading_trivia: Vec<crate::tokens::Trivia>,
154    /// Fase 14.b — trailing comment trivia (same line as the
155    /// declaration's last effective token). Empty by default.
156    pub trailing_trivia: Vec<crate::tokens::Trivia>,
157}
158
159/// `fabric Name { provider, region, zones, ephemeral, shield }`
160///
161/// A tagged substrate — the topological container where resources are
162/// provisioned. Maps to VPC / cluster / namespace.
163#[derive(Debug, Default)]
164pub struct FabricDefinition {
165    pub name: String,
166    pub provider: String, // aws | gcp | azure | kubernetes | bare_metal | custom
167    pub region: String,   // provider-specific region id
168    pub zones: Option<i64>, // number of availability zones
169    pub ephemeral: Option<bool>, // true = destroy on program end
170    pub shield_ref: String, // optional shield reference
171    pub loc: Loc,
172    /// Fase 14.b — leading comment trivia attached to this declaration
173    /// (comments preceding the declaration's first token, since the
174    /// previous declaration or file start). Empty by default.
175    pub leading_trivia: Vec<crate::tokens::Trivia>,
176    /// Fase 14.b — trailing comment trivia (same line as the
177    /// declaration's last effective token). Empty by default.
178    pub trailing_trivia: Vec<crate::tokens::Trivia>,
179}
180
181/// `manifest Name { resources, fabric, region, zones, compliance }`
182///
183/// A declarative specification of desired shape — not a "desired state" in
184/// the Terraform sense, a *belief* about structure. Linear/affine resources
185/// in `resources` must be disjoint (Separation Logic `*`).
186#[derive(Debug, Default)]
187pub struct ManifestDefinition {
188    pub name: String,
189    pub resources: Vec<String>, // references to ResourceDefinition names
190    pub fabric_ref: String,     // reference to FabricDefinition name
191    pub region: String,
192    pub zones: Option<i64>,
193    pub compliance: Vec<String>, // κ — regulatory class (Fase 6.1)
194    pub loc: Loc,
195    /// Fase 14.b — leading comment trivia attached to this declaration
196    /// (comments preceding the declaration's first token, since the
197    /// previous declaration or file start). Empty by default.
198    pub leading_trivia: Vec<crate::tokens::Trivia>,
199    /// Fase 14.b — trailing comment trivia (same line as the
200    /// declaration's last effective token). Empty by default.
201    pub trailing_trivia: Vec<crate::tokens::Trivia>,
202}
203
204/// `observe Name from Manifest { sources, quorum, timeout, on_partition, certainty_floor }`
205///
206/// A quorum-gated observation of a manifest's real state. Each output
207/// carries ΛD envelope E = ⟨c, τ, ρ, δ⟩; `τ` records observation lag.
208/// `on_partition: fail` raises a CT-3 (Network Error) — partitions are ⊥ void.
209#[derive(Debug, Default)]
210pub struct ObserveDefinition {
211    pub name: String,
212    pub target: String, // name of ManifestDefinition being observed
213    pub sources: Vec<String>,
214    pub quorum: Option<i64>,  // Byzantine quorum threshold
215    pub timeout: String,      // duration literal "5s", "100ms"
216    pub on_partition: String, // fail (CT-3) | shield_quarantine
217    pub certainty_floor: Option<f64>,
218    pub loc: Loc,
219    /// Fase 14.b — leading comment trivia attached to this declaration
220    /// (comments preceding the declaration's first token, since the
221    /// previous declaration or file start). Empty by default.
222    pub leading_trivia: Vec<crate::tokens::Trivia>,
223    /// Fase 14.b — trailing comment trivia (same line as the
224    /// declaration's last effective token). Empty by default.
225    pub trailing_trivia: Vec<crate::tokens::Trivia>,
226}
227
228// ── §λ-L-E Fase 3 — Control cognitivo primitives ─────────────────────────────
229
230/// `reconcile Name { observe, threshold, tolerance, on_drift, shield, mandate, max_retries }`
231///
232/// A cognitive control loop that minimises variational free energy
233/// `F = D_KL(q(s) || p(s, o))` between a manifest belief and an observe
234/// evidence. Acting on the environment (`on_drift: provision`) is one of
235/// the two classical routes to reducing F (the other is belief revision).
236#[derive(Debug, Default)]
237pub struct ReconcileDefinition {
238    pub name: String,
239    pub observe_ref: String,
240    pub threshold: Option<f64>, // epistemic gate c ∈ [0.0, 1.0]
241    pub tolerance: Option<f64>, // drift tolerance [0.0, 1.0]
242    pub on_drift: String,       // provision | alert | refine (default: provision)
243    pub shield_ref: String,
244    pub mandate_ref: String,
245    pub max_retries: i64, // default: 3
246    pub loc: Loc,
247    /// Fase 14.b — leading comment trivia attached to this declaration
248    /// (comments preceding the declaration's first token, since the
249    /// previous declaration or file start). Empty by default.
250    pub leading_trivia: Vec<crate::tokens::Trivia>,
251    /// Fase 14.b — trailing comment trivia (same line as the
252    /// declaration's last effective token). Empty by default.
253    pub trailing_trivia: Vec<crate::tokens::Trivia>,
254}
255
256/// `lease Name { resource, duration, acquire, on_expire }`
257///
258/// Affine/linear lease on a resource, with explicit Δt encoded in the `τ`
259/// of the ΛD envelope. Runtime materializes each lease as a revocable
260/// token; use post-expiry raises `LeaseExpiredError` (CT-2) per D2.
261#[derive(Debug, Default)]
262pub struct LeaseDefinition {
263    pub name: String,
264    pub resource_ref: String,
265    pub duration: String,  // "30s", "5m", "2h"
266    pub acquire: String,   // on_start | on_demand (default: on_start)
267    pub on_expire: String, // anchor_breach | release | extend (default: anchor_breach)
268    pub loc: Loc,
269    /// Fase 14.b — leading comment trivia attached to this declaration
270    /// (comments preceding the declaration's first token, since the
271    /// previous declaration or file start). Empty by default.
272    pub leading_trivia: Vec<crate::tokens::Trivia>,
273    /// Fase 14.b — trailing comment trivia (same line as the
274    /// declaration's last effective token). Empty by default.
275    pub trailing_trivia: Vec<crate::tokens::Trivia>,
276}
277
278/// `ensemble Name { observations, quorum, aggregation, certainty_mode }`
279///
280/// Byzantine quorum aggregator over ≥2 independent observations. Yields
281/// common knowledge `Cφ` (Fagin-Halpern) when at least `quorum` observers
282/// agree. Failed observations are excluded; below quorum raises CT-3.
283#[derive(Debug, Default)]
284pub struct EnsembleDefinition {
285    pub name: String,
286    pub observations: Vec<String>,
287    pub quorum: Option<i64>,
288    pub aggregation: String, // majority | weighted | byzantine (default: majority)
289    pub certainty_mode: String, // min | weighted | harmonic (default: min)
290    pub loc: Loc,
291    /// Fase 14.b — leading comment trivia attached to this declaration
292    /// (comments preceding the declaration's first token, since the
293    /// previous declaration or file start). Empty by default.
294    pub leading_trivia: Vec<crate::tokens::Trivia>,
295    /// Fase 14.b — trailing comment trivia (same line as the
296    /// declaration's last effective token). Empty by default.
297    pub trailing_trivia: Vec<crate::tokens::Trivia>,
298}
299
300// ── §λ-L-E Fase 4 — Topology + π-calculus binary sessions ──────────────────
301
302/// One step in a session protocol.
303///
304/// §Fase 4: `send T` | `receive T` | `loop` | `end`. §Fase 41.b adds **choice**:
305/// `select { ℓ: [..], … }` (⊕ — this role chooses) and `branch { ℓ: [..], … }`
306/// (& — this role offers); for those `op`s the labelled continuations live in
307/// [`SessionStep::branches`] (a nested sub-protocol per label).
308#[derive(Debug, Clone, Default)]
309pub struct SessionStep {
310    pub op: String,           // send | receive | loop | end | select | branch
311    pub message_type: String, // only meaningful for send / receive
312    /// §Fase 41.b — populated only for `op == "select" | "branch"`: the labelled
313    /// branches, each a nested step sequence (its own sub-protocol).
314    pub branches: Vec<SessionBranch>,
315    pub loc: Loc,
316}
317
318/// §Fase 41.b — one labelled arm of a `select`/`branch` choice: `ℓ: [steps]`.
319#[derive(Debug, Clone, Default)]
320pub struct SessionBranch {
321    pub label: String,
322    pub steps: Vec<SessionStep>,
323    pub loc: Loc,
324}
325
326/// One role in a binary session — name + ordered list of steps.
327#[derive(Debug, Default)]
328pub struct SessionRole {
329    pub name: String,
330    pub steps: Vec<SessionStep>,
331    pub loc: Loc,
332}
333
334/// `session Name { role1: [step, …]  role2: [step, …] }`
335///
336/// A binary session type — exactly two roles whose protocols MUST be
337/// pairwise Honda-Vasconcelos dual. Duality is verified by the type
338/// checker; non-dual programs are rejected at compile time.
339#[derive(Debug, Default)]
340pub struct SessionDefinition {
341    pub name: String,
342    pub roles: Vec<SessionRole>,
343    pub loc: Loc,
344    /// Fase 14.b — leading comment trivia attached to this declaration
345    /// (comments preceding the declaration's first token, since the
346    /// previous declaration or file start). Empty by default.
347    pub leading_trivia: Vec<crate::tokens::Trivia>,
348    /// Fase 14.b — trailing comment trivia (same line as the
349    /// declaration's last effective token). Empty by default.
350    pub trailing_trivia: Vec<crate::tokens::Trivia>,
351}
352
353/// `socket Name { protocol: SessionRef, backpressure: credit(n), reconnect:
354/// cognitive_state, legal_basis: ... }`
355///
356/// §Fase 41.b — the typed WebSocket transport (paper_websocket_cognitive_primitive.md).
357/// `socket` is NOT the protocol — the protocol is a `session` it references by
358/// name (protocol and transport kept separate but composable). The type checker
359/// resolves `protocol` to a declared `session` (whose two roles are already
360/// duality-checked via the §41.a algebra), so the dialogue carried over the WS
361/// connection is conformant + deadlock-free by construction.
362#[derive(Debug, Default)]
363pub struct SocketDefinition {
364    pub name: String,
365    /// The referenced `session` declaration's name — the protocol.
366    pub protocol: String,
367    /// The credit window of the typed-resource backpressure (`credit(n)`);
368    /// `None` if unspecified. A `0` credit is rejected by the type checker.
369    pub backpressure_credit: Option<i64>,
370    /// `reconnect: cognitive_state` → `true` (resume mid-dialogue via a sealed
371    /// §40.t snapshot); absent or `reconnect: none` → `false`.
372    pub reconnect: bool,
373    /// Optional `legal_basis:` annotation (enterprise audit/shield gate).
374    pub legal_basis: Option<String>,
375    pub loc: Loc,
376    /// Fase 14.b — leading comment trivia.
377    pub leading_trivia: Vec<crate::tokens::Trivia>,
378    /// Fase 14.b — trailing comment trivia.
379    pub trailing_trivia: Vec<crate::tokens::Trivia>,
380}
381
382/// `source -> target : Session` — one directed edge of a topology.
383///
384/// Convention: the source plays the FIRST role of the session; the target
385/// plays the SECOND role. Fixed so assignment is unambiguous.
386#[derive(Debug, Default)]
387pub struct TopologyEdge {
388    pub source: String,
389    pub target: String,
390    pub session_ref: String,
391    pub loc: Loc,
392}
393
394/// `topology Name { nodes: […]  edges: [A -> B : Session, …] }`
395///
396/// A typed directed graph over Axon entities. Edges carry session references
397/// whose duality the type checker enforces; the graph is statically analysed
398/// for Honda-liveness (deadlock-prone cycles).
399#[derive(Debug, Default)]
400pub struct TopologyDefinition {
401    pub name: String,
402    pub nodes: Vec<String>,
403    pub edges: Vec<TopologyEdge>,
404    pub loc: Loc,
405    /// Fase 14.b — leading comment trivia attached to this declaration
406    /// (comments preceding the declaration's first token, since the
407    /// previous declaration or file start). Empty by default.
408    pub leading_trivia: Vec<crate::tokens::Trivia>,
409    /// Fase 14.b — trailing comment trivia (same line as the
410    /// declaration's last effective token). Empty by default.
411    pub trailing_trivia: Vec<crate::tokens::Trivia>,
412}
413
414// ── §λ-L-E Fase 5 — Cognitive immune system (per paper_immune_v2.md) ────────
415
416/// `immune Name { watch, sensitivity, baseline, window, scope, tau, decay }`
417///
418/// A continuous anomaly sensor over a declared observation vector.
419/// Computes D_KL(q_baseline || p_observed) (paper §3.2) and emits a
420/// HealthReport at an epistemic level derived from the KL magnitude.
421///
422/// Pure sensor — `immune` takes NO action. Actions belong to `reflex`
423/// and `heal`, which consume its HealthReport.
424#[derive(Debug, Default)]
425pub struct ImmuneDefinition {
426    pub name: String,
427    pub watch: Vec<String>,       // observe / ensemble / any declared ref
428    pub sensitivity: Option<f64>, // [0.0, 1.0]
429    pub baseline: String,         // "learned" (default) or name of a prior
430    pub window: i64,              // samples used to estimate baseline (default: 100)
431    pub scope: String,            // tenant | flow | global (MANDATORY, paper §8.2)
432    pub tau: String,              // duration half-life
433    pub decay: String,            // exponential (default) | linear | none
434    pub loc: Loc,
435    /// Fase 14.b — leading comment trivia attached to this declaration
436    /// (comments preceding the declaration's first token, since the
437    /// previous declaration or file start). Empty by default.
438    pub leading_trivia: Vec<crate::tokens::Trivia>,
439    /// Fase 14.b — trailing comment trivia (same line as the
440    /// declaration's last effective token). Empty by default.
441    pub trailing_trivia: Vec<crate::tokens::Trivia>,
442}
443
444/// `reflex Name { trigger, on_level, action, scope, sla }`
445///
446/// Deterministic, O(1) motor response. Contract invariants (paper §4.2):
447/// never invokes an LLM; no long-running I/O; every activation emits a
448/// signed_trace; idempotent on the same HealthReport.
449#[derive(Debug, Default)]
450pub struct ReflexDefinition {
451    pub name: String,
452    pub trigger: String,  // immune name (MANDATORY)
453    pub on_level: String, // know | believe | speculate | doubt (default: doubt)
454    pub action: String,   // drop | revoke | emit | redact | quarantine | terminate | alert
455    pub scope: String,    // MANDATORY, paper §8.2
456    pub sla: String,      // duration budget (e.g. "1ms")
457    pub loc: Loc,
458    /// Fase 14.b — leading comment trivia attached to this declaration
459    /// (comments preceding the declaration's first token, since the
460    /// previous declaration or file start). Empty by default.
461    pub leading_trivia: Vec<crate::tokens::Trivia>,
462    /// Fase 14.b — trailing comment trivia (same line as the
463    /// declaration's last effective token). Empty by default.
464    pub trailing_trivia: Vec<crate::tokens::Trivia>,
465}
466
467/// `heal Name { source, on_level, mode, scope, review_sla, shield, max_patches }`
468///
469/// Linear-Logic one-shot patch synthesis. Patch type:
470/// `!Synthesized ⊸ Applied ⊸ Collapsed` (paper §6) — each transition
471/// consumes its predecessor, guaranteeing single application + forced collapse.
472///
473/// Mode ∈ {audit_only | human_in_loop | adversarial} controls automation
474/// (paper §7); `adversarial` REQUIRES a shield gate (paper §7.3).
475#[derive(Debug, Default)]
476pub struct HealDefinition {
477    pub name: String,
478    pub source: String,     // immune name (MANDATORY)
479    pub on_level: String,   // know | believe | speculate | doubt
480    pub mode: String,       // audit_only | human_in_loop | adversarial
481    pub scope: String,      // MANDATORY
482    pub review_sla: String, // duration
483    pub shield_ref: String, // optional shield gate (required for adversarial)
484    pub max_patches: i64,   // bounded heal attempts (default: 3)
485    pub loc: Loc,
486    /// Fase 14.b — leading comment trivia attached to this declaration
487    /// (comments preceding the declaration's first token, since the
488    /// previous declaration or file start). Empty by default.
489    pub leading_trivia: Vec<crate::tokens::Trivia>,
490    /// Fase 14.b — trailing comment trivia (same line as the
491    /// declaration's last effective token). Empty by default.
492    pub trailing_trivia: Vec<crate::tokens::Trivia>,
493}
494
495// ── §λ-L-E Fase 9 — UI cognitiva (component / view) ─────────────────────────
496
497/// `component Name { renders, via_shield, on_interact, render_hint }`.
498///
499/// A reusable UI fragment. `renders` is the data type the component
500/// visualizes; if that type has κ, `via_shield` is mandatory and its
501/// compliance set MUST cover the type's κ (compile-time enforcement).
502#[derive(Debug, Default)]
503pub struct ComponentDefinition {
504    pub name: String,
505    pub renders: String,
506    pub via_shield: String,
507    pub on_interact: String,
508    pub render_hint: String, // card | list | form | chart | custom
509    pub loc: Loc,
510    /// Fase 14.b — leading comment trivia attached to this declaration
511    /// (comments preceding the declaration's first token, since the
512    /// previous declaration or file start). Empty by default.
513    pub leading_trivia: Vec<crate::tokens::Trivia>,
514    /// Fase 14.b — trailing comment trivia (same line as the
515    /// declaration's last effective token). Empty by default.
516    pub trailing_trivia: Vec<crate::tokens::Trivia>,
517}
518
519/// `view Name { title, components: [...], route }`.
520///
521/// A top-level screen. `components` is an ordered list of declared
522/// `component` names composed in the view's primary layout.
523#[derive(Debug, Default)]
524pub struct ViewDefinition {
525    pub name: String,
526    pub title: String,
527    pub components: Vec<String>,
528    pub route: String,
529    pub loc: Loc,
530    /// Fase 14.b — leading comment trivia attached to this declaration
531    /// (comments preceding the declaration's first token, since the
532    /// previous declaration or file start). Empty by default.
533    pub leading_trivia: Vec<crate::tokens::Trivia>,
534    /// Fase 14.b — trailing comment trivia (same line as the
535    /// declaration's last effective token). Empty by default.
536    pub trailing_trivia: Vec<crate::tokens::Trivia>,
537}
538
539// ── Tier 2+ structural fallback ──────────────────────────────────────────────
540
541/// A declaration we recognize by keyword but parse only structurally.
542/// Validates brace balance and captures keyword + name.
543#[derive(Debug)]
544pub struct GenericDeclaration {
545    pub keyword: String,
546    pub name: String,
547    pub loc: Loc,
548    /// Fase 14.b — leading comment trivia attached to this declaration
549    /// (comments preceding the declaration's first token, since the
550    /// previous declaration or file start). Empty by default.
551    pub leading_trivia: Vec<crate::tokens::Trivia>,
552    /// Fase 14.b — trailing comment trivia (same line as the
553    /// declaration's last effective token). Empty by default.
554    pub trailing_trivia: Vec<crate::tokens::Trivia>,
555}
556
557// ── Agent ────────────────────────────────────────────────────────────────────
558
559#[derive(Debug)]
560pub struct AgentDefinition {
561    pub name: String,
562    pub goal: String,
563    pub tools: Vec<String>,
564    pub memory_ref: String,
565    pub strategy: String, // react | reflexion | plan_and_execute | custom
566    pub on_stuck: String, // forge | hibernate | escalate | retry
567    pub shield_ref: String,
568    pub max_iterations: Option<i64>,
569    pub max_tokens: Option<i64>,
570    pub max_time: String,
571    pub max_cost: Option<f64>,
572    pub loc: Loc,
573    /// Fase 14.b — leading comment trivia attached to this declaration
574    /// (comments preceding the declaration's first token, since the
575    /// previous declaration or file start). Empty by default.
576    pub leading_trivia: Vec<crate::tokens::Trivia>,
577    /// Fase 14.b — trailing comment trivia (same line as the
578    /// declaration's last effective token). Empty by default.
579    pub trailing_trivia: Vec<crate::tokens::Trivia>,
580}
581
582// ── §Fase 53 — Closed-catalog extension mechanism ────────────────────────────
583
584/// One member of an `extension` declaration. For `category: effects`
585/// the `name` is a provenance base (e.g. `"epistemic:believe"`) with
586/// optional `semantics` + `default_confidence` (a CEILING, never a
587/// floor — §53.d tainted-overriding). For `category: scan` the `name`
588/// is a scan-category identifier and the metadata is typically absent.
589#[derive(Debug, Clone)]
590pub struct ExtensionMember {
591    pub name: String,
592    pub semantics: Option<String>,
593    pub default_confidence: Option<f64>,
594    pub loc: Loc,
595}
596
597/// `extension Name { category: effects|scan, members: [ "x" : { … }, … ] }`
598///
599/// §Fase 53. A first-class, auditable + gateable declaration that
600/// expands a closed catalog with adopter-specific PROVENANCE members.
601/// Soundness invariants (validated in §53.c/§53.d): members are
602/// provenance-class only (never the enforceable effect set), must not
603/// shadow a canonical base/category, and ride in the IR + proof bundle
604/// so an independent PCC verifier re-derives against the same artifact.
605#[derive(Debug)]
606pub struct ExtensionDefinition {
607    pub name: String,
608    /// `effects` | `scan` — validated against the closed category set
609    /// in §53.c (the type-checker), not the parser.
610    pub category: String,
611    pub members: Vec<ExtensionMember>,
612    pub loc: Loc,
613    /// Fase 14.b — leading comment trivia. Empty by default.
614    pub leading_trivia: Vec<crate::tokens::Trivia>,
615    /// Fase 14.b — trailing comment trivia. Empty by default.
616    pub trailing_trivia: Vec<crate::tokens::Trivia>,
617}
618
619// ── Shield ───────────────────────────────────────────────────────────────────
620
621#[derive(Debug)]
622pub struct ShieldDefinition {
623    pub name: String,
624    pub scan: Vec<String>,
625    pub strategy: String, // pattern | classifier | dual_llm | canary | perplexity | ensemble
626    pub on_breach: String, // halt | sanitize_and_retry | escalate | quarantine | deflect
627    pub severity: String, // low | medium | high | critical
628    pub quarantine: String,
629    pub max_retries: Option<i64>,
630    pub confidence_threshold: Option<f64>,
631    pub allow_tools: Vec<String>,
632    pub deny_tools: Vec<String>,
633    pub sandbox: Option<bool>,
634    pub redact: Vec<String>,
635    pub log: String,
636    pub deflect_message: String,
637    pub taint: String,
638    /// §ESK Fase 6.1 — regulatory coverage (HIPAA, PCI_DSS, GDPR, …).
639    pub compliance: Vec<String>,
640    pub loc: Loc,
641    /// Fase 14.b — leading comment trivia attached to this declaration
642    /// (comments preceding the declaration's first token, since the
643    /// previous declaration or file start). Empty by default.
644    pub leading_trivia: Vec<crate::tokens::Trivia>,
645    /// Fase 14.b — trailing comment trivia (same line as the
646    /// declaration's last effective token). Empty by default.
647    pub trailing_trivia: Vec<crate::tokens::Trivia>,
648}
649
650// ── Pix ──────────────────────────────────────────────────────────────────────
651
652#[derive(Debug)]
653pub struct PixDefinition {
654    pub name: String,
655    pub source: String,
656    pub depth: Option<i64>,
657    pub branching: Option<i64>,
658    pub model: String,
659    pub loc: Loc,
660    /// Fase 14.b — leading comment trivia attached to this declaration
661    /// (comments preceding the declaration's first token, since the
662    /// previous declaration or file start). Empty by default.
663    pub leading_trivia: Vec<crate::tokens::Trivia>,
664    /// Fase 14.b — trailing comment trivia (same line as the
665    /// declaration's last effective token). Empty by default.
666    pub trailing_trivia: Vec<crate::tokens::Trivia>,
667}
668
669// ── Psyche ───────────────────────────────────────────────────────────────────
670
671#[derive(Debug)]
672pub struct PsycheDefinition {
673    pub name: String,
674    pub dimensions: Vec<String>,
675    pub manifold_noise: Option<f64>,
676    pub manifold_momentum: Option<f64>,
677    pub safety_constraints: Vec<String>,
678    pub quantum_enabled: Option<bool>,
679    pub inference_mode: String, // active | passive
680    pub loc: Loc,
681    /// Fase 14.b — leading comment trivia attached to this declaration
682    /// (comments preceding the declaration's first token, since the
683    /// previous declaration or file start). Empty by default.
684    pub leading_trivia: Vec<crate::tokens::Trivia>,
685    /// Fase 14.b — trailing comment trivia (same line as the
686    /// declaration's last effective token). Empty by default.
687    pub trailing_trivia: Vec<crate::tokens::Trivia>,
688}
689
690// ── Corpus ───────────────────────────────────────────────────────────────────
691
692#[derive(Debug)]
693pub struct CorpusDefinition {
694    pub name: String,
695    pub documents: Vec<String>, // simplified: list of pix refs
696    pub mcp_server: String,
697    pub mcp_resource_uri: String,
698    pub loc: Loc,
699    /// Fase 14.b — leading comment trivia attached to this declaration
700    /// (comments preceding the declaration's first token, since the
701    /// previous declaration or file start). Empty by default.
702    pub leading_trivia: Vec<crate::tokens::Trivia>,
703    /// Fase 14.b — trailing comment trivia (same line as the
704    /// declaration's last effective token). Empty by default.
705    pub trailing_trivia: Vec<crate::tokens::Trivia>,
706}
707
708// ── Dataspace ────────────────────────────────────────────────────────────────
709
710#[derive(Debug)]
711pub struct DataspaceDefinition {
712    pub name: String,
713    pub loc: Loc,
714    /// Fase 14.b — leading comment trivia attached to this declaration
715    /// (comments preceding the declaration's first token, since the
716    /// previous declaration or file start). Empty by default.
717    pub leading_trivia: Vec<crate::tokens::Trivia>,
718    /// Fase 14.b — trailing comment trivia (same line as the
719    /// declaration's last effective token). Empty by default.
720    pub trailing_trivia: Vec<crate::tokens::Trivia>,
721}
722
723// ── OTS ──────────────────────────────────────────────────────────────────────
724
725#[derive(Debug)]
726pub struct OtsDefinition {
727    pub name: String,
728    pub teleology: String,
729    pub homotopy_search: String, // shallow | deep | speculative
730    pub loss_function: String,
731    pub loc: Loc,
732    /// Fase 14.b — leading comment trivia attached to this declaration
733    /// (comments preceding the declaration's first token, since the
734    /// previous declaration or file start). Empty by default.
735    pub leading_trivia: Vec<crate::tokens::Trivia>,
736    /// Fase 14.b — trailing comment trivia (same line as the
737    /// declaration's last effective token). Empty by default.
738    pub trailing_trivia: Vec<crate::tokens::Trivia>,
739}
740
741// ── Mandate ──────────────────────────────────────────────────────────────────
742
743#[derive(Debug)]
744pub struct MandateDefinition {
745    pub name: String,
746    pub constraint: String,
747    pub kp: Option<f64>,
748    pub ki: Option<f64>,
749    pub kd: Option<f64>,
750    pub tolerance: Option<f64>,
751    pub max_steps: Option<i64>,
752    pub on_violation: String, // coerce | halt | retry
753    pub loc: Loc,
754    /// Fase 14.b — leading comment trivia attached to this declaration
755    /// (comments preceding the declaration's first token, since the
756    /// previous declaration or file start). Empty by default.
757    pub leading_trivia: Vec<crate::tokens::Trivia>,
758    /// Fase 14.b — trailing comment trivia (same line as the
759    /// declaration's last effective token). Empty by default.
760    pub trailing_trivia: Vec<crate::tokens::Trivia>,
761}
762
763// ── Compute ──────────────────────────────────────────────────────────────────
764
765#[derive(Debug)]
766pub struct ComputeDefinition {
767    pub name: String,
768    pub shield_ref: String,
769    pub loc: Loc,
770    /// Fase 14.b — leading comment trivia attached to this declaration
771    /// (comments preceding the declaration's first token, since the
772    /// previous declaration or file start). Empty by default.
773    pub leading_trivia: Vec<crate::tokens::Trivia>,
774    /// Fase 14.b — trailing comment trivia (same line as the
775    /// declaration's last effective token). Empty by default.
776    pub trailing_trivia: Vec<crate::tokens::Trivia>,
777}
778
779// ── Daemon ───────────────────────────────────────────────────────────────────
780
781#[derive(Debug)]
782pub struct DaemonDefinition {
783    pub name: String,
784    pub goal: String,
785    pub tools: Vec<String>,
786    pub memory_ref: String,
787    pub strategy: String, // react | reflexion | plan_and_execute | custom
788    pub on_stuck: String, // hibernate | escalate | retry | forge
789    pub shield_ref: String,
790    pub max_tokens: Option<i64>,
791    pub max_time: String,
792    pub max_cost: Option<f64>,
793    /// §λ-L-E Fase 13 D4 — listen blocks captured for type-checker
794    /// validation (typed-channel ref + dual-mode deprecation warning).
795    /// Pre-Fase 13 the parser discarded these structurally; we now
796    /// retain them so 13.b/13.f can validate emit/publish/discover
797    /// inside listener bodies and surface D4 string-topic warnings.
798    pub listeners: Vec<ListenStep>,
799    pub loc: Loc,
800    /// Fase 14.b — leading comment trivia attached to this declaration
801    /// (comments preceding the declaration's first token, since the
802    /// previous declaration or file start). Empty by default.
803    pub leading_trivia: Vec<crate::tokens::Trivia>,
804    /// Fase 14.b — trailing comment trivia (same line as the
805    /// declaration's last effective token). Empty by default.
806    pub trailing_trivia: Vec<crate::tokens::Trivia>,
807}
808
809// ── AxonStore ────────────────────────────────────────────────────────────────
810
811#[derive(Debug)]
812pub struct AxonStoreDefinition {
813    pub name: String,
814    pub backend: String, // sqlite | postgresql | mysql
815    pub connection: String,
816    pub confidence_floor: Option<f64>,
817    pub isolation: String, // read_committed | repeatable_read | serializable
818    pub on_breach: String, // rollback | raise | log
819    /// §Fase 35.j (D11) — Pillar IV: the capability slug required to
820    /// access this store. Empty = no capability gate. Validated at
821    /// parse time against the closed slug grammar (shared with the
822    /// Fase 32.g `requires:` grammar).
823    pub capability: String,
824    /// §Fase 38.b (D1) — the OPTIONAL column-schema declaration. Three
825    /// closed forms (inline / manifest-ref / env-var); `None` means the
826    /// 37.x runtime+deploy path applies verbatim (D5 absolute). The
827    /// §38.d / §38.e `StoreColumnProof` pass consumes this; the §38.h
828    /// CLI exports it.
829    pub column_schema: Option<crate::store_schema::StoreColumnSchema>,
830    pub loc: Loc,
831    /// Fase 14.b — leading comment trivia attached to this declaration
832    /// (comments preceding the declaration's first token, since the
833    /// previous declaration or file start). Empty by default.
834    pub leading_trivia: Vec<crate::tokens::Trivia>,
835    /// Fase 14.b — trailing comment trivia (same line as the
836    /// declaration's last effective token). Empty by default.
837    pub trailing_trivia: Vec<crate::tokens::Trivia>,
838}
839
840// ── AxonEndpoint ─────────────────────────────────────────────────────────────
841
842#[derive(Debug)]
843pub struct AxonEndpointDefinition {
844    pub name: String,
845    pub method: String, // GET | POST | PUT | DELETE
846    pub path: String,
847    pub body_type: String,
848    pub execute_flow: String,
849    pub output_type: String,
850    pub shield_ref: String,
851    pub retries: Option<i64>,
852    pub timeout: String,
853    /// §ESK Fase 6.1 — regulatory coverage on the boundary.
854    pub compliance: Vec<String>,
855    /// §Fase 30 — HTTP wire transport for the response. Closed enum
856    /// per D2 ratified 2026-05-10: {"json" | "sse" | "ndjson"}.
857    /// Default "json" (D1 — backwards-compat preserved). When set
858    /// to "sse", the type-checker (30.c) verifies that
859    /// `execute_flow` produces a Stream<T> (D3).
860    pub transport: String,
861    /// §Fase 30 — Keepalive comment interval for SSE transport (D6).
862    /// Optional; default applied at runtime when transport == "sse"
863    /// (default 15s). Closed enum at parse time:
864    /// {"5s" | "15s" | "30s" | "60s"}. Empty string means
865    /// "use runtime default".
866    pub keepalive: String,
867    /// §Fase 31.b — Type-Driven Wire Inference (D1, D7).
868    /// `transport_explicit` is `true` if the source declared
869    /// `transport:` explicitly (any of json/sse/ndjson). `false` if
870    /// the field was omitted, in which case `transport` reflects the
871    /// D1 default `"json"` but `implicit_transport` (computed by the
872    /// `axon_frontend::type_checker::compute_implicit_transports`
873    /// pass) carries the inferred value.
874    pub transport_explicit: bool,
875    /// §Fase 31.b — Inferred wire transport per D1:
876    ///   implicit_transport(E) =
877    ///     declared_transport(E)   if transport_explicit
878    ///     "sse"                    if produces_stream(execute_flow) ∧ ¬explicit
879    ///     "json"                   otherwise
880    /// Empty string `""` before the type-checker runs. The Python
881    /// reference implementation in `axon/compiler/type_checker.py`
882    /// sets the field byte-identically (D7 cross-stack contract).
883    pub implicit_transport: String,
884    /// §Fase 32.g (D8) — Auth scope: capability slugs the request
885    /// bearer must hold for the endpoint to dispatch. Empty vec
886    /// means "no auth gate" (D9 backwards-compat). Slug grammar
887    /// (closed): `^[a-z][a-z0-9_]*(\.[a-z][a-z0-9_]*)*$`. Examples:
888    /// `admin`, `legal.read`, `hipaa.phi.read`. The runtime checks
889    /// declared_requires ⊆ token_capabilities (AND semantics — every
890    /// declared capability must be present in the bearer's claims).
891    pub requires_capabilities: Vec<String>,
892    /// §Fase 32.h — Replay-token binding (D9 plan-vivo).
893    /// `replay_explicit` is `true` when the source declared `replay:`
894    /// explicitly. `false` when the field was omitted, in which case
895    /// `replay` reflects the method-default (POST/PUT → true, GET/
896    /// DELETE → false) computed at deploy time. When the effective
897    /// value resolves to `true`, every successful 2xx response is
898    /// recorded in the runtime's axonendpoint replay log keyed by
899    /// trace_id; auditors retrieve it via GET /v1/replay/<trace_id>.
900    pub replay_explicit: bool,
901    pub replay: bool,
902    /// §Fase 33.z.k.b (v1.28.0) — Selected SSE wire-format dialect.
903    ///
904    /// Populated when the source uses the parametrized grammar
905    /// `transport: sse(<dialect>)`. Closed catalog
906    /// (`AXONENDPOINT_TRANSPORT_DIALECTS`): `{axon, openai, anthropic}`.
907    /// Empty string `""` when:
908    ///   - the source declared a non-SSE transport (`json`/`ndjson`), OR
909    ///   - the source declared bare `transport: sse` without parens, OR
910    ///   - the source omitted `transport:` entirely (D1 implicit path).
911    ///
912    /// When empty + the effective wire is SSE (per the runtime
913    /// classifier `classify_dynamic_route_wire`), the runtime
914    /// resolves the dialect via the Q1 algebraic-effect-driven
915    /// default: openai for tool-streaming flows (algebraic predicate
916    /// true), axon for type-annotation-only flows (algebraic predicate
917    /// false). D3 explicit `transport: sse(<dialect>)` overrides the
918    /// default.
919    pub transport_dialect: String,
920    /// §Fase 33.z.k.1 (v1.27.1) — Algebraic-effect override predicate.
921    ///
922    /// `true` when `execute_flow` references a tool that declares
923    /// `effects: <stream:<policy>>` (Fase 30 algebraic-effect surface).
924    /// Mirrors `type_checker::flow_uses_streaming_tool(execute_flow, program)`.
925    ///
926    /// Used by the runtime classifier
927    /// (`axon_server::classify_dynamic_route_wire`) to OVERRIDE the
928    /// v1.22.0 D6 backwards-compat gate: a tool with a declared stream
929    /// effect is a LANGUAGE-LEVEL commitment to streaming, not a
930    /// client preference. When this field is `true` AND
931    /// `transport: json` is NOT explicitly declared (D3 opt-out remains
932    /// sacred), the route wire is unconditionally `Sse` — no
933    /// `Accept: text/event-stream` header required, no
934    /// `AXON_STRICT_TYPE_DRIVEN_TRANSPORT=1` runtime flag required.
935    ///
936    /// Computed in lockstep with `implicit_transport` by the
937    /// `compute_implicit_transports` pass. Default `false` before the
938    /// pass runs (matches AST construction defaults; D9 backwards-
939    /// compat preserved for older AST consumers).
940    pub has_algebraic_stream_effect: bool,
941    /// §Fase 36.d (D2) — the declared execution backend for the flow
942    /// behind this endpoint. Empty string `""` means "not declared"
943    /// (the endpoint resolves its backend down the Fase 36 D1
944    /// precedence ladder — server default → environment-available
945    /// `auto`). When non-empty the parser has validated it against the
946    /// closed catalog [`crate::parser::AXONENDPOINT_BACKEND_VALUES`]
947    /// and the type-checker rejects an unknown name as a compile
948    /// error. A declared `backend:` is rung 2 of the resolution
949    /// contract.
950    pub backend: String,
951    /// §Fase 37.y (D1) — Path parameter names extracted from the
952    /// `path:` string at parse time. For `path: "/api/tenants/{tenant_id}/secrets/{secret_name}"`
953    /// this is `["tenant_id", "secret_name"]`. Empty Vec when the
954    /// path has no `{name}` placeholders (D5 backwards-compat — an
955    /// endpoint without path params produces byte-identical IR to
956    /// v1.38.4).
957    ///
958    /// Names are deduplicated + recorded in declaration order. A
959    /// duplicate `{tenant_id}` in the same path is a parse error
960    /// (HTTP route patterns reject duplicates structurally — `axum`
961    /// would panic at registration). Type binding is always `Text`
962    /// in v1.38.5 (HTTP path-segment convention); a future Fase 37.z
963    /// may add per-placeholder type-override grammar `{tenant_id: Uuid}`.
964    ///
965    /// The Fase 37 D2 totality check (extended by 37.y D3) treats
966    /// every name here as covering an equivalent flow parameter
967    /// declared `Text`. Collision with a body field of the same name
968    /// is a compile error (`axon-T901`, D4).
969    pub path_params: Vec<String>,
970    /// §Fase 37.y (D2) — Query parameters declared via the inline
971    /// `query: { name: Type, name: Type? }` block on the endpoint.
972    /// Empty Vec when the source omits the block (D5 backwards-compat).
973    ///
974    /// Closed type catalog (parser-enforced):
975    /// `{Text, Int, Float, Bool, Uuid}`. The runtime receives every
976    /// query value as a textual `String` and binds it to the same-named
977    /// flow parameter; the closed catalog enables future per-type
978    /// parsing/validation without breaking the manifest format.
979    ///
980    /// The optional flag (`?` suffix in the source) reuses
981    /// `TypeExpr.optional`. An optional query param need not be
982    /// covered by a flow parameter (D3 totality is over required
983    /// params); a required query param missing from the flow signature
984    /// is a `axon-T?nn` future arm. For v1.38.5 the totality check
985    /// treats every query param as a binding-source candidate for any
986    /// same-named flow param.
987    ///
988    /// Reusing `TypeField` (shared with body type declarations) keeps
989    /// the D2 totality check uniform — the same `field.type_expr.name
990    /// == param.type_expr.name` comparator works for body fields AND
991    /// query params.
992    pub query_params: Vec<TypeField>,
993    pub loc: Loc,
994    /// Fase 14.b — leading comment trivia attached to this declaration
995    /// (comments preceding the declaration's first token, since the
996    /// previous declaration or file start). Empty by default.
997    pub leading_trivia: Vec<crate::tokens::Trivia>,
998    /// Fase 14.b — trailing comment trivia (same line as the
999    /// declaration's last effective token). Empty by default.
1000    pub trailing_trivia: Vec<crate::tokens::Trivia>,
1001}
1002
1003// ── Import ───────────────────────────────────────────────────────────────────
1004
1005#[derive(Debug)]
1006pub struct ImportNode {
1007    pub module_path: Vec<String>,
1008    pub names: Vec<String>,
1009    pub loc: Loc,
1010    /// Fase 14.b — leading comment trivia attached to this declaration
1011    /// (comments preceding the declaration's first token, since the
1012    /// previous declaration or file start). Empty by default.
1013    pub leading_trivia: Vec<crate::tokens::Trivia>,
1014    /// Fase 14.b — trailing comment trivia (same line as the
1015    /// declaration's last effective token). Empty by default.
1016    pub trailing_trivia: Vec<crate::tokens::Trivia>,
1017}
1018
1019// ── Persona ──────────────────────────────────────────────────────────────────
1020
1021#[derive(Debug)]
1022pub struct PersonaDefinition {
1023    pub name: String,
1024    pub domain: Vec<String>,
1025    pub tone: String,
1026    pub confidence_threshold: Option<f64>,
1027    pub cite_sources: Option<bool>,
1028    pub refuse_if: Vec<String>,
1029    pub language: String,
1030    pub description: String,
1031    pub loc: Loc,
1032    /// Fase 14.b — leading comment trivia attached to this declaration
1033    /// (comments preceding the declaration's first token, since the
1034    /// previous declaration or file start). Empty by default.
1035    pub leading_trivia: Vec<crate::tokens::Trivia>,
1036    /// Fase 14.b — trailing comment trivia (same line as the
1037    /// declaration's last effective token). Empty by default.
1038    pub trailing_trivia: Vec<crate::tokens::Trivia>,
1039}
1040
1041// ── Context ──────────────────────────────────────────────────────────────────
1042
1043#[derive(Debug)]
1044pub struct ContextDefinition {
1045    pub name: String,
1046    pub memory_scope: String,
1047    pub language: String,
1048    pub depth: String,
1049    pub max_tokens: Option<i64>,
1050    pub temperature: Option<f64>,
1051    pub cite_sources: Option<bool>,
1052    pub loc: Loc,
1053    /// Fase 14.b — leading comment trivia attached to this declaration
1054    /// (comments preceding the declaration's first token, since the
1055    /// previous declaration or file start). Empty by default.
1056    pub leading_trivia: Vec<crate::tokens::Trivia>,
1057    /// Fase 14.b — trailing comment trivia (same line as the
1058    /// declaration's last effective token). Empty by default.
1059    pub trailing_trivia: Vec<crate::tokens::Trivia>,
1060}
1061
1062// ── Anchor ───────────────────────────────────────────────────────────────────
1063
1064#[derive(Debug)]
1065pub struct AnchorConstraint {
1066    pub name: String,
1067    pub require: String,
1068    pub reject: Vec<String>,
1069    pub enforce: String,
1070    pub description: String,
1071    pub confidence_floor: Option<f64>,
1072    pub unknown_response: String,
1073    pub on_violation: String,
1074    pub on_violation_target: String,
1075    pub loc: Loc,
1076    /// Fase 14.b — leading comment trivia attached to this declaration
1077    /// (comments preceding the declaration's first token, since the
1078    /// previous declaration or file start). Empty by default.
1079    pub leading_trivia: Vec<crate::tokens::Trivia>,
1080    /// Fase 14.b — trailing comment trivia (same line as the
1081    /// declaration's last effective token). Empty by default.
1082    pub trailing_trivia: Vec<crate::tokens::Trivia>,
1083}
1084
1085// ── Memory ───────────────────────────────────────────────────────────────────
1086
1087#[derive(Debug)]
1088pub struct MemoryDefinition {
1089    pub name: String,
1090    pub store: String,
1091    pub backend: String,
1092    pub retrieval: String,
1093    pub decay: String,
1094    pub loc: Loc,
1095    /// Fase 14.b — leading comment trivia attached to this declaration
1096    /// (comments preceding the declaration's first token, since the
1097    /// previous declaration or file start). Empty by default.
1098    pub leading_trivia: Vec<crate::tokens::Trivia>,
1099    /// Fase 14.b — trailing comment trivia (same line as the
1100    /// declaration's last effective token). Empty by default.
1101    pub trailing_trivia: Vec<crate::tokens::Trivia>,
1102}
1103
1104// ── Tool ─────────────────────────────────────────────────────────────────────
1105
1106#[derive(Debug)]
1107pub struct ToolDefinition {
1108    pub name: String,
1109    pub provider: String,
1110    pub max_results: Option<i64>,
1111    pub filter_expr: String,
1112    pub timeout: String,
1113    pub runtime: String,
1114    pub sandbox: Option<bool>,
1115    pub effects: Option<EffectRow>,
1116    /// §Fase 58.a — the tool's typed INPUT SCHEMA (W2: the caller↔tool
1117    /// contract). Each entry is a named, typed parameter that the canonical
1118    /// `use Tool(k = v, …)` invocation binds against and the type-checker
1119    /// validates the caller's args against (CT-2 caller blame, pre-HTTP).
1120    /// Empty for a schema-less tool — the legacy single-`on <arg>` form still
1121    /// applies (§58 D5 back-compat). Reuses `Parameter` (same `TypeExpr`
1122    /// grammar as flow params).
1123    pub parameters: Vec<Parameter>,
1124    /// §Fase 58.a — the tool's declared OUTPUT type, so a tool-step's result
1125    /// is referenceable as `${Step.output}` with a real type (§58 D8). Flat
1126    /// string (mirrors step `output:`); `None` when undeclared.
1127    pub output_type: Option<String>,
1128    pub loc: Loc,
1129    /// Fase 14.b — leading comment trivia attached to this declaration
1130    /// (comments preceding the declaration's first token, since the
1131    /// previous declaration or file start). Empty by default.
1132    pub leading_trivia: Vec<crate::tokens::Trivia>,
1133    /// Fase 14.b — trailing comment trivia (same line as the
1134    /// declaration's last effective token). Empty by default.
1135    pub trailing_trivia: Vec<crate::tokens::Trivia>,
1136}
1137
1138#[derive(Debug)]
1139pub struct EffectRow {
1140    pub effects: Vec<String>,
1141    pub epistemic_level: String,
1142    pub loc: Loc,
1143}
1144
1145// ── Type ─────────────────────────────────────────────────────────────────────
1146
1147#[derive(Debug)]
1148pub struct TypeDefinition {
1149    pub name: String,
1150    pub fields: Vec<TypeField>,
1151    pub range_constraint: Option<RangeConstraint>,
1152    pub where_clause: Option<WhereClause>,
1153    /// §ESK Fase 6.1 — κ regulatory class attached to a type.
1154    pub compliance: Vec<String>,
1155    pub loc: Loc,
1156    /// Fase 14.b — leading comment trivia attached to this declaration
1157    /// (comments preceding the declaration's first token, since the
1158    /// previous declaration or file start). Empty by default.
1159    pub leading_trivia: Vec<crate::tokens::Trivia>,
1160    /// Fase 14.b — trailing comment trivia (same line as the
1161    /// declaration's last effective token). Empty by default.
1162    pub trailing_trivia: Vec<crate::tokens::Trivia>,
1163}
1164
1165#[derive(Debug, Clone)]
1166pub struct TypeExpr {
1167    pub name: String,
1168    pub generic_param: String,
1169    pub optional: bool,
1170    pub loc: Loc,
1171}
1172
1173#[derive(Debug)]
1174pub struct TypeField {
1175    pub name: String,
1176    pub type_expr: TypeExpr,
1177    pub loc: Loc,
1178}
1179
1180#[derive(Debug)]
1181pub struct RangeConstraint {
1182    pub min_value: f64,
1183    pub max_value: f64,
1184    pub loc: Loc,
1185}
1186
1187#[derive(Debug)]
1188pub struct WhereClause {
1189    pub expression: String,
1190    pub loc: Loc,
1191}
1192
1193// ── Flow ─────────────────────────────────────────────────────────────────────
1194
1195#[derive(Debug)]
1196pub struct FlowDefinition {
1197    pub name: String,
1198    pub parameters: Vec<Parameter>,
1199    pub return_type: Option<TypeExpr>,
1200    pub body: Vec<FlowStep>,
1201    pub loc: Loc,
1202    /// Fase 14.b — leading comment trivia attached to this declaration
1203    /// (comments preceding the declaration's first token, since the
1204    /// previous declaration or file start). Empty by default.
1205    pub leading_trivia: Vec<crate::tokens::Trivia>,
1206    /// Fase 14.b — trailing comment trivia (same line as the
1207    /// declaration's last effective token). Empty by default.
1208    pub trailing_trivia: Vec<crate::tokens::Trivia>,
1209}
1210
1211#[derive(Debug)]
1212pub struct Parameter {
1213    pub name: String,
1214    pub type_expr: TypeExpr,
1215    pub loc: Loc,
1216}
1217
1218/// Statements that can appear inside a flow body.
1219#[derive(Debug)]
1220pub enum FlowStep {
1221    Step(StepNode),
1222    If(ConditionalNode),
1223    ForIn(ForInStatement),
1224    Let(LetStatement),
1225    Return(ReturnStatement),
1226    /// Fase 19.e — `break` keyword. Payload-free; carries only its
1227    /// source location for error reporting.
1228    Break(BreakStatement),
1229    /// Fase 19.e — `continue` keyword. Payload-free; same shape as
1230    /// `Break`.
1231    Continue(ContinueStatement),
1232    /// Lambda Data application in a flow step.
1233    LambdaDataApply(LambdaDataApplyNode),
1234    // ── Tier 2 flow steps ──
1235    Probe(ProbeStep),
1236    Reason(ReasonStep),
1237    Validate(ValidateStep),
1238    Refine(RefineStep),
1239    Weave(WeaveStep),
1240    UseTool(UseToolStep),
1241    Remember(RememberStep),
1242    Recall(RecallStep),
1243    Par(ParBlock),
1244    Hibernate(HibernateStep),
1245    Deliberate(DeliberateBlock),
1246    Consensus(ConsensusBlock),
1247    Forge(ForgeBlock),
1248    Focus(FocusStep),
1249    Associate(AssociateStep),
1250    Aggregate(AggregateStep),
1251    ExploreStep(ExploreStepNode),
1252    Ingest(IngestStep),
1253    ShieldApply(ShieldApplyStep),
1254    Stream(StreamBlock),
1255    Navigate(NavigateStep),
1256    Drill(DrillStep),
1257    Trail(TrailStep),
1258    Corroborate(CorroborateStep),
1259    OtsApply(OtsApplyStep),
1260    MandateApply(MandateApplyStep),
1261    ComputeApply(ComputeApplyStep),
1262    Listen(ListenStep),
1263    DaemonStep(DaemonStepNode),
1264    /// §λ-L-E Fase 13 — π-calculus output prefix `c⟨v⟩.P` (Chan-Output / Chan-Mobility).
1265    Emit(EmitStatement),
1266    /// §λ-L-E Fase 13 — capability extrusion (Publish-Ext, paper §4.3).
1267    Publish(PublishStatement),
1268    /// §λ-L-E Fase 13 — dual of publish (dynamic typed handle import).
1269    Discover(DiscoverStatement),
1270    Persist(PersistStep),
1271    Retrieve(RetrieveStep),
1272    Mutate(MutateStep),
1273    Purge(PurgeStep),
1274    Transact(TransactBlock),
1275    /// Flow-level statements we recognize but parse structurally.
1276    GenericStep(GenericFlowStep),
1277}
1278
1279/// A flow step we recognize by keyword but parse only structurally.
1280#[derive(Debug)]
1281pub struct GenericFlowStep {
1282    pub keyword: String,
1283    pub loc: Loc,
1284}
1285
1286// ── Step ─────────────────────────────────────────────────────────────────────
1287
1288#[derive(Debug)]
1289pub struct StepNode {
1290    pub name: String,
1291    pub persona_ref: String,
1292    pub given: String,
1293    pub ask: String,
1294    pub output_type: String,
1295    pub confidence_floor: Option<f64>,
1296    pub navigate_ref: String,
1297    pub apply_ref: String,
1298    pub loc: Loc,
1299}
1300
1301// ── Intent ───────────────────────────────────────────────────────────────────
1302
1303#[derive(Debug)]
1304pub struct IntentNode {
1305    pub name: String,
1306    pub given: String,
1307    pub ask: String,
1308    pub output_type: Option<TypeExpr>,
1309    pub confidence_floor: Option<f64>,
1310    pub loc: Loc,
1311    /// Fase 14.b — leading comment trivia attached to this declaration
1312    /// (comments preceding the declaration's first token, since the
1313    /// previous declaration or file start). Empty by default.
1314    pub leading_trivia: Vec<crate::tokens::Trivia>,
1315    /// Fase 14.b — trailing comment trivia (same line as the
1316    /// declaration's last effective token). Empty by default.
1317    pub trailing_trivia: Vec<crate::tokens::Trivia>,
1318}
1319
1320// ── Run ──────────────────────────────────────────────────────────────────────
1321
1322#[derive(Debug)]
1323pub struct RunStatement {
1324    pub flow_name: String,
1325    pub arguments: Vec<String>,
1326    pub persona: String,
1327    pub context: String,
1328    pub anchors: Vec<String>,
1329    pub on_failure: String,
1330    pub on_failure_params: Vec<(String, String)>,
1331    pub output_to: String,
1332    pub effort: String,
1333    pub loc: Loc,
1334    /// Fase 14.b — leading comment trivia attached to this declaration
1335    /// (comments preceding the declaration's first token, since the
1336    /// previous declaration or file start). Empty by default.
1337    pub leading_trivia: Vec<crate::tokens::Trivia>,
1338    /// Fase 14.b — trailing comment trivia (same line as the
1339    /// declaration's last effective token). Empty by default.
1340    pub trailing_trivia: Vec<crate::tokens::Trivia>,
1341}
1342
1343// ── Epistemic ────────────────────────────────────────────────────────────────
1344
1345#[derive(Debug)]
1346pub struct EpistemicBlock {
1347    pub mode: String,
1348    pub body: Vec<Declaration>,
1349    pub loc: Loc,
1350    /// Fase 14.b — leading comment trivia attached to this declaration
1351    /// (comments preceding the declaration's first token, since the
1352    /// previous declaration or file start). Empty by default.
1353    pub leading_trivia: Vec<crate::tokens::Trivia>,
1354    /// Fase 14.b — trailing comment trivia (same line as the
1355    /// declaration's last effective token). Empty by default.
1356    pub trailing_trivia: Vec<crate::tokens::Trivia>,
1357}
1358
1359// ── Control flow ─────────────────────────────────────────────────────────────
1360
1361#[derive(Debug)]
1362pub struct ConditionalNode {
1363    pub condition: String,
1364    pub comparison_op: String,
1365    pub comparison_value: String,
1366    pub then_body: Vec<FlowStep>,
1367    pub else_body: Vec<FlowStep>,
1368    pub conditions: Vec<(String, String, String)>,
1369    pub conjunctor: String,
1370    pub loc: Loc,
1371}
1372
1373#[derive(Debug)]
1374pub struct ForInStatement {
1375    pub variable: String,
1376    pub iterable: String,
1377    pub body: Vec<FlowStep>,
1378    pub loc: Loc,
1379}
1380
1381#[derive(Debug)]
1382pub struct LetStatement {
1383    pub identifier: String,
1384    pub value_expr: String,
1385    /// Fase 17.a — preserves the parser's tokenization intent so the
1386    /// runtime dispatcher can distinguish a quoted literal from a
1387    /// dotted-identifier reference. One of "literal", "reference",
1388    /// "expression". Defaults to "literal" so any pre-Fase-17 caller
1389    /// that constructs a LetStatement directly behaves as a literal.
1390    pub value_kind: String,
1391    pub loc: Loc,
1392    /// Fase 14.b — leading comment trivia attached to this declaration
1393    /// (comments preceding the declaration's first token, since the
1394    /// previous declaration or file start). Empty by default.
1395    pub leading_trivia: Vec<crate::tokens::Trivia>,
1396    /// Fase 14.b — trailing comment trivia (same line as the
1397    /// declaration's last effective token). Empty by default.
1398    pub trailing_trivia: Vec<crate::tokens::Trivia>,
1399}
1400
1401#[derive(Debug)]
1402pub struct ReturnStatement {
1403    pub value_expr: String,
1404    pub loc: Loc,
1405}
1406
1407/// Fase 19.e — `break` keyword inside a for-in body. Carries no
1408/// payload; the runner translates it into a sentinel that
1409/// terminates the loop. Parser scope check (`loop_depth`)
1410/// guarantees this only appears inside a for-in body.
1411#[derive(Debug)]
1412pub struct BreakStatement {
1413    pub loc: Loc,
1414}
1415
1416/// Fase 19.e — `continue` keyword inside a for-in body. Same
1417/// shape as ``BreakStatement``; the runner uses a different
1418/// sentinel type to distinguish loop-exit from iteration-skip.
1419#[derive(Debug)]
1420pub struct ContinueStatement {
1421    pub loc: Loc,
1422}
1423
1424// ── Lambda Data (ΛD) — Epistemic State Vectors ─────────────────────────────
1425
1426/// Top-level ΛD definition: ψ = ⟨T, V, E⟩ where E = ⟨c, τ, ρ, δ⟩.
1427#[derive(Debug)]
1428pub struct LambdaDataDefinition {
1429    pub name: String,
1430    pub ontology: String,             // T ∈ O — ontological type
1431    pub certainty: f64,               // c ∈ [0,1] — epistemic certainty scalar
1432    pub temporal_frame_start: String, // τ_start
1433    pub temporal_frame_end: String,   // τ_end
1434    pub provenance: String,           // ρ ∈ EntityRef — causal origin
1435    pub derivation: String, // δ ∈ Δ — see derivation catalogue (raw, derived, inferred, aggregated, transformed)
1436    pub loc: Loc,
1437    /// Fase 14.b — leading comment trivia attached to this declaration
1438    /// (comments preceding the declaration's first token, since the
1439    /// previous declaration or file start). Empty by default.
1440    pub leading_trivia: Vec<crate::tokens::Trivia>,
1441    /// Fase 14.b — trailing comment trivia (same line as the
1442    /// declaration's last effective token). Empty by default.
1443    pub trailing_trivia: Vec<crate::tokens::Trivia>,
1444}
1445
1446/// In-flow ΛD application: binds epistemic state vector to a data target.
1447#[derive(Debug)]
1448pub struct LambdaDataApplyNode {
1449    pub lambda_data_name: String, // reference to LambdaDataDefinition
1450    pub target: String,           // expression to bind
1451    pub output_type: String,      // result type after epistemic binding
1452    pub loc: Loc,
1453}
1454
1455// ── Tier 2 flow step nodes ──────────────────────────────────────────────────
1456
1457#[derive(Debug)]
1458pub struct ProbeStep {
1459    pub target: String,
1460    pub loc: Loc,
1461}
1462#[derive(Debug)]
1463pub struct ReasonStep {
1464    pub strategy: String,
1465    pub target: String,
1466    pub loc: Loc,
1467}
1468#[derive(Debug)]
1469pub struct ValidateStep {
1470    pub target: String,
1471    pub rule: String,
1472    pub loc: Loc,
1473}
1474#[derive(Debug)]
1475pub struct RefineStep {
1476    pub target: String,
1477    pub strategy: String,
1478    pub loc: Loc,
1479}
1480#[derive(Debug)]
1481pub struct WeaveStep {
1482    pub sources: Vec<String>,
1483    pub target: String,
1484    pub format_type: String,
1485    pub priority: Vec<String>,
1486    pub style: String,
1487    pub loc: Loc,
1488}
1489/// §Fase 58.b — the closed catalog of `use <Tool>` argument forms. The
1490/// invocation surfaces are mutually exclusive, so a sum type models them
1491/// exactly (no ambiguous dual-empty state). NOTE: `apply: Tool given: <struct>`
1492/// (the splat form) is NOT here — it rides `StepNode.apply_ref` and is
1493/// validated against the tool schema in §58.d, not parsed as a `use`.
1494#[derive(Debug, Clone, PartialEq)]
1495pub enum UseArgs {
1496    /// `use Tool on "${arg}"` / `use Tool on query` — the §54.b single
1497    /// positional argument. D5 back-compat: behaves byte-identically to the
1498    /// pre-58 `argument: String` (empty string when no `on` clause).
1499    LegacyPositional(String),
1500    /// `use Tool(query = "${q}", max_results = 5)` — D2 canonical multi-field
1501    /// keyword args. Each entry is `(name, value, value_kind)`: `value` is the
1502    /// expression STRING (the frontend has no structured `Expr`; mirrors
1503    /// `argument` / `parse_argument_list`); `value_kind` is `"literal"` or
1504    /// `"reference"` — the §Fase 60 classification from `parse_let_atom`, so the
1505    /// runtime resolves a bare identifier / `Step.output` as a binding lookup
1506    /// (like `let`) instead of passing the name literally. The type-checker
1507    /// (§58.d + §60.c) validates each entry against the tool's declared input
1508    /// schema (W2 / CT-2 caller blame) and references against their source.
1509    Named(Vec<(String, String, String)>),
1510}
1511
1512impl UseArgs {
1513    /// §58.b transitional — the legacy single-arg string for the IR `argument`
1514    /// field (still `String` until §58.c carries structured named args).
1515    /// `Named` projects an empty argument here; the type-checker validates
1516    /// named args from the AST, and §58.c/e wire their structured dispatch.
1517    pub fn legacy_argument(&self) -> String {
1518        match self {
1519            UseArgs::LegacyPositional(s) => s.clone(),
1520            UseArgs::Named(_) => String::new(),
1521        }
1522    }
1523}
1524
1525#[derive(Debug)]
1526pub struct UseToolStep {
1527    pub tool_name: String,
1528    pub args: UseArgs,
1529    pub loc: Loc,
1530}
1531#[derive(Debug)]
1532pub struct RememberStep {
1533    pub expression: String,
1534    pub memory_target: String,
1535    pub loc: Loc,
1536}
1537#[derive(Debug)]
1538pub struct RecallStep {
1539    pub query: String,
1540    pub memory_source: String,
1541    pub loc: Loc,
1542}
1543#[derive(Debug)]
1544pub struct ParBlock {
1545    pub loc: Loc,
1546}
1547#[derive(Debug)]
1548pub struct HibernateStep {
1549    pub event_name: String,
1550    pub timeout: String,
1551    pub loc: Loc,
1552}
1553#[derive(Debug)]
1554pub struct DeliberateBlock {
1555    pub loc: Loc,
1556}
1557#[derive(Debug)]
1558pub struct ConsensusBlock {
1559    pub loc: Loc,
1560}
1561#[derive(Debug)]
1562pub struct ForgeBlock {
1563    pub loc: Loc,
1564}
1565#[derive(Debug)]
1566pub struct FocusStep {
1567    pub expression: String,
1568    pub loc: Loc,
1569}
1570#[derive(Debug)]
1571pub struct AssociateStep {
1572    pub left: String,
1573    pub right: String,
1574    pub using_field: String,
1575    pub loc: Loc,
1576}
1577#[derive(Debug)]
1578pub struct AggregateStep {
1579    pub target: String,
1580    pub group_by: Vec<String>,
1581    pub alias: String,
1582    pub loc: Loc,
1583}
1584#[derive(Debug)]
1585pub struct ExploreStepNode {
1586    pub target: String,
1587    pub limit: Option<i64>,
1588    pub loc: Loc,
1589}
1590#[derive(Debug)]
1591pub struct IngestStep {
1592    pub source: String,
1593    pub target: String,
1594    pub loc: Loc,
1595}
1596#[derive(Debug)]
1597pub struct ShieldApplyStep {
1598    pub shield_name: String,
1599    pub target: String,
1600    pub output_type: String,
1601    pub loc: Loc,
1602}
1603#[derive(Debug)]
1604pub struct StreamBlock {
1605    pub loc: Loc,
1606}
1607#[derive(Debug)]
1608pub struct NavigateStep {
1609    pub pix_name: String,
1610    pub corpus_name: String,
1611    pub query_expr: String,
1612    pub trail_enabled: bool,
1613    pub output_name: String,
1614    pub loc: Loc,
1615}
1616#[derive(Debug)]
1617pub struct DrillStep {
1618    pub pix_name: String,
1619    pub subtree_path: String,
1620    pub query_expr: String,
1621    pub output_name: String,
1622    pub loc: Loc,
1623}
1624#[derive(Debug)]
1625pub struct TrailStep {
1626    pub navigate_ref: String,
1627    pub loc: Loc,
1628}
1629#[derive(Debug)]
1630pub struct CorroborateStep {
1631    pub navigate_ref: String,
1632    pub output_name: String,
1633    pub loc: Loc,
1634}
1635#[derive(Debug)]
1636pub struct OtsApplyStep {
1637    pub ots_name: String,
1638    pub target: String,
1639    pub output_type: String,
1640    pub loc: Loc,
1641}
1642#[derive(Debug)]
1643pub struct MandateApplyStep {
1644    pub mandate_name: String,
1645    pub target: String,
1646    pub output_type: String,
1647    pub loc: Loc,
1648}
1649#[derive(Debug)]
1650pub struct ComputeApplyStep {
1651    pub compute_name: String,
1652    pub arguments: Vec<String>,
1653    pub output_name: String,
1654    pub loc: Loc,
1655}
1656/// §λ-L-E Fase 13 D4 — dual-mode listen.
1657///
1658/// `channel_is_ref = true` ⇒ `channel` is the name of a declared
1659/// `ChannelDefinition` (canonical Fase 13 form).  `false` ⇒ legacy
1660/// string topic (deprecated; type checker emits a warning).
1661#[derive(Debug)]
1662pub struct ListenStep {
1663    pub channel: String,
1664    pub channel_is_ref: bool,
1665    pub event_alias: String,
1666    pub loc: Loc,
1667}
1668#[derive(Debug)]
1669pub struct DaemonStepNode {
1670    pub daemon_ref: String,
1671    pub loc: Loc,
1672}
1673#[derive(Debug)]
1674pub struct PersistStep {
1675    pub store_name: String,
1676    /// §Fase 35.o — the `{ col: value }` field block. Empty when the
1677    /// step is written without a block (`persist <store>`), in which
1678    /// case the runtime falls back to writing the flow's user
1679    /// bindings as a row (backward-compatible with v1.30.0).
1680    pub fields: Vec<(String, String)>,
1681    pub loc: Loc,
1682}
1683#[derive(Debug)]
1684pub struct RetrieveStep {
1685    pub store_name: String,
1686    pub where_expr: String,
1687    pub alias: String,
1688    pub loc: Loc,
1689}
1690#[derive(Debug)]
1691pub struct MutateStep {
1692    pub store_name: String,
1693    pub where_expr: String,
1694    /// §Fase 35.p — the `{ col: value }` SET assignments. Empty when
1695    /// the step declares no columns, in which case the runtime falls
1696    /// back to writing the flow's user bindings as the `SET` clause
1697    /// (backward-compatible with v1.31.0).
1698    pub fields: Vec<(String, String)>,
1699    pub loc: Loc,
1700}
1701#[derive(Debug)]
1702pub struct PurgeStep {
1703    pub store_name: String,
1704    pub where_expr: String,
1705    pub loc: Loc,
1706}
1707#[derive(Debug)]
1708pub struct TransactBlock {
1709    pub loc: Loc,
1710}
1711
1712// ── §λ-L-E Fase 13 — Mobile Typed Channels ──────────────────────────────────
1713
1714/// `channel Name { message: T, qos: X, lifetime: ℓ, persistence: π, shield: σ }`.
1715///
1716/// First-class affine resource carrying a typed message.  Direct port
1717/// of `axon.compiler.ast_nodes.ChannelDefinition`.  `message` retains
1718/// the surface spelling (e.g. `"Order"` or `"Channel<Order>"`) so the
1719/// type checker can resolve nested mobility (paper §3.3).
1720#[derive(Debug)]
1721pub struct ChannelDefinition {
1722    pub name: String,
1723    pub message: String,     // type name OR "Channel<T>" for second-order
1724    pub qos: String,         // at_most_once | at_least_once | exactly_once | broadcast | queue
1725    pub lifetime: String,    // linear | affine | persistent (D1 default: affine)
1726    pub persistence: String, // ephemeral | persistent_axonstore
1727    pub shield_ref: String,  // optional σ-shield gate for publish (D8)
1728    pub loc: Loc,
1729    /// Fase 14.b — leading comment trivia attached to this declaration
1730    /// (comments preceding the declaration's first token, since the
1731    /// previous declaration or file start). Empty by default.
1732    pub leading_trivia: Vec<crate::tokens::Trivia>,
1733    /// Fase 14.b — trailing comment trivia (same line as the
1734    /// declaration's last effective token). Empty by default.
1735    pub trailing_trivia: Vec<crate::tokens::Trivia>,
1736}
1737
1738/// `emit ChannelName(value_ref)` — π-calculus output prefix `c⟨v⟩.P`.
1739///
1740/// Direct port of `axon.compiler.ast_nodes.EmitStatement`.  Handles
1741/// both Chan-Output (scalar payload) and Chan-Mobility (channel-as-
1742/// value); the type checker dispatches based on whether `value_ref`
1743/// resolves to a `ChannelDefinition`.
1744#[derive(Debug)]
1745pub struct EmitStatement {
1746    pub channel_ref: String,
1747    pub value_ref: String,
1748    pub loc: Loc,
1749}
1750
1751/// `publish ChannelName within ShieldName` — capability extrusion.
1752///
1753/// Paper §4.3 (Publish-Ext) materialized as a flow step.  The `within
1754/// <Shield>` clause is mandatory (D8) — the parser rejects bare
1755/// `publish C`, the type checker rejects publishes whose shield does
1756/// not cover κ(message_type) (Fase 6.1 + paper §3.4).
1757#[derive(Debug)]
1758pub struct PublishStatement {
1759    pub channel_ref: String,
1760    pub shield_ref: String,
1761    pub loc: Loc,
1762}
1763
1764/// `discover ChannelName as alias` — dual of publish.
1765///
1766/// Imports a previously-published handle into a fresh affine local
1767/// binding.  The `as <alias>` is mandatory; the type checker rejects
1768/// discovery of channels that were never declared with `shield_ref`.
1769#[derive(Debug)]
1770pub struct DiscoverStatement {
1771    pub capability_ref: String,
1772    pub alias: String,
1773    pub loc: Loc,
1774}