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 Ledger(LedgerDefinition),
90 Psyche(PsycheDefinition),
91 Corpus(CorpusDefinition),
92 Dataspace(DataspaceDefinition),
93 Ots(OtsDefinition),
94 Mandate(MandateDefinition),
95 Compute(ComputeDefinition),
96 Daemon(DaemonDefinition),
97 AxonStore(AxonStoreDefinition),
98 AxonEndpoint(AxonEndpointDefinition),
99 /// §Fase 53 — Closed-catalog extension mechanism. Declares
100 /// adopter-specific PROVENANCE members for a closed catalog
101 /// (`effects` bases or shield `scan` categories) so the
102 /// type-checker + PCC treat them as first-class. Auditable +
103 /// gateable; never extends the enforceable effect set (invariant
104 /// #2 — provenance-class only).
105 Extension(ExtensionDefinition),
106 /// §λ-L-E Fase 1 — I/O cognitivo primitives.
107 Resource(ResourceDefinition),
108 Fabric(FabricDefinition),
109 Manifest(ManifestDefinition),
110 Observe(ObserveDefinition),
111 /// §λ-L-E Fase 3 — Control cognitivo primitives.
112 Reconcile(ReconcileDefinition),
113 Lease(LeaseDefinition),
114 Ensemble(EnsembleDefinition),
115 /// §λ-L-E Fase 4 — Topology + π-calculus binary sessions.
116 Session(SessionDefinition),
117 Topology(TopologyDefinition),
118 /// §λ-L-E Fase 5 — Cognitive immune system (per docs/paper_immune_v2.md).
119 Immune(ImmuneDefinition),
120 Reflex(ReflexDefinition),
121 Heal(HealDefinition),
122 /// §λ-L-E Fase 9 — UI cognitiva declarativa.
123 Component(ComponentDefinition),
124 View(ViewDefinition),
125 /// §λ-L-E Fase 13 — Mobile typed channels (paper_mobile_channels.md).
126 Channel(ChannelDefinition),
127 /// §Fase 41.b — typed WebSocket transport binding a `session` protocol
128 /// (paper_websocket_cognitive_primitive.md).
129 Socket(SocketDefinition),
130 /// §Fase 51.c.2 — a Pauli-sum observable `M = Σ cₖ Pₖ` that a `quant`
131 /// block measures against (paper §3.2; plan D5).
132 Observable(ObservableDefinition),
133 /// §Fase 69.a — an Advantage Witness: a machine-checkable proof obligation
134 /// that a primitive's `claim` beats a cheaper `baseline` by a `metric` above
135 /// a `threshold` on real `data` (doctrine `axon://logic/no_unwitnessed_advantage`).
136 Witness(WitnessDefinition),
137 /// Tier 3+ declarations parsed structurally (balanced braces, no detailed AST).
138 Generic(GenericDeclaration),
139}
140
141// ── §λ-L-E Fase 1 — Resource primitive ───────────────────────────────────────
142
143/// `resource Name { kind, endpoint, capacity, lifetime, certainty_floor, shield }`
144///
145/// An infrastructure resource declared as a linear, affine, or persistent
146/// token. Linear/affine resources cannot be aliased across manifests
147/// (Separation Logic `*` disjointness).
148#[derive(Debug, Default)]
149pub struct ResourceDefinition {
150 pub name: String,
151 pub kind: String, // postgres | redis | s3 | vpc | gpu | compute | file | custom
152 pub endpoint: String, // connection URI
153 pub capacity: Option<i64>, // pool size / instance count hint
154 pub lifetime: String, // linear | affine | persistent (default: affine)
155 pub certainty_floor: Option<f64>, // epistemic gate c ∈ [0.0, 1.0]
156 pub shield_ref: String, // optional shield reference
157 pub loc: Loc,
158 /// Fase 14.b — leading comment trivia attached to this declaration
159 /// (comments preceding the declaration's first token, since the
160 /// previous declaration or file start). Empty by default.
161 pub leading_trivia: Vec<crate::tokens::Trivia>,
162 /// Fase 14.b — trailing comment trivia (same line as the
163 /// declaration's last effective token). Empty by default.
164 pub trailing_trivia: Vec<crate::tokens::Trivia>,
165}
166
167/// `fabric Name { provider, region, zones, ephemeral, shield }`
168///
169/// A tagged substrate — the topological container where resources are
170/// provisioned. Maps to VPC / cluster / namespace.
171#[derive(Debug, Default)]
172pub struct FabricDefinition {
173 pub name: String,
174 pub provider: String, // aws | gcp | azure | kubernetes | bare_metal | custom
175 pub region: String, // provider-specific region id
176 pub zones: Option<i64>, // number of availability zones
177 pub ephemeral: Option<bool>, // true = destroy on program end
178 pub shield_ref: String, // optional shield reference
179 pub loc: Loc,
180 /// Fase 14.b — leading comment trivia attached to this declaration
181 /// (comments preceding the declaration's first token, since the
182 /// previous declaration or file start). Empty by default.
183 pub leading_trivia: Vec<crate::tokens::Trivia>,
184 /// Fase 14.b — trailing comment trivia (same line as the
185 /// declaration's last effective token). Empty by default.
186 pub trailing_trivia: Vec<crate::tokens::Trivia>,
187}
188
189/// `manifest Name { resources, fabric, region, zones, compliance }`
190///
191/// A declarative specification of desired shape — not a "desired state" in
192/// the Terraform sense, a *belief* about structure. Linear/affine resources
193/// in `resources` must be disjoint (Separation Logic `*`).
194#[derive(Debug, Default)]
195pub struct ManifestDefinition {
196 pub name: String,
197 pub resources: Vec<String>, // references to ResourceDefinition names
198 pub fabric_ref: String, // reference to FabricDefinition name
199 pub region: String,
200 pub zones: Option<i64>,
201 pub compliance: Vec<String>, // κ — regulatory class (Fase 6.1)
202 pub loc: Loc,
203 /// Fase 14.b — leading comment trivia attached to this declaration
204 /// (comments preceding the declaration's first token, since the
205 /// previous declaration or file start). Empty by default.
206 pub leading_trivia: Vec<crate::tokens::Trivia>,
207 /// Fase 14.b — trailing comment trivia (same line as the
208 /// declaration's last effective token). Empty by default.
209 pub trailing_trivia: Vec<crate::tokens::Trivia>,
210}
211
212/// `observe Name from Manifest { sources, quorum, timeout, on_partition, certainty_floor }`
213///
214/// A quorum-gated observation of a manifest's real state. Each output
215/// carries ΛD envelope E = ⟨c, τ, ρ, δ⟩; `τ` records observation lag.
216/// `on_partition: fail` raises a CT-3 (Network Error) — partitions are ⊥ void.
217#[derive(Debug, Default)]
218pub struct ObserveDefinition {
219 pub name: String,
220 pub target: String, // name of ManifestDefinition being observed
221 pub sources: Vec<String>,
222 pub quorum: Option<i64>, // Byzantine quorum threshold
223 pub timeout: String, // duration literal "5s", "100ms"
224 pub on_partition: String, // fail (CT-3) | shield_quarantine
225 pub certainty_floor: Option<f64>,
226 pub loc: Loc,
227 /// Fase 14.b — leading comment trivia attached to this declaration
228 /// (comments preceding the declaration's first token, since the
229 /// previous declaration or file start). Empty by default.
230 pub leading_trivia: Vec<crate::tokens::Trivia>,
231 /// Fase 14.b — trailing comment trivia (same line as the
232 /// declaration's last effective token). Empty by default.
233 pub trailing_trivia: Vec<crate::tokens::Trivia>,
234}
235
236// ── §λ-L-E Fase 3 — Control cognitivo primitives ─────────────────────────────
237
238/// `reconcile Name { observe, threshold, tolerance, on_drift, shield, mandate, max_retries }`
239///
240/// A cognitive control loop that minimises variational free energy
241/// `F = D_KL(q(s) || p(s, o))` between a manifest belief and an observe
242/// evidence. Acting on the environment (`on_drift: provision`) is one of
243/// the two classical routes to reducing F (the other is belief revision).
244#[derive(Debug, Default)]
245pub struct ReconcileDefinition {
246 pub name: String,
247 pub observe_ref: String,
248 pub threshold: Option<f64>, // epistemic gate c ∈ [0.0, 1.0]
249 pub tolerance: Option<f64>, // drift tolerance [0.0, 1.0]
250 pub on_drift: String, // provision | alert | refine (default: provision)
251 pub shield_ref: String,
252 pub mandate_ref: String,
253 pub max_retries: i64, // default: 3
254 pub loc: Loc,
255 /// Fase 14.b — leading comment trivia attached to this declaration
256 /// (comments preceding the declaration's first token, since the
257 /// previous declaration or file start). Empty by default.
258 pub leading_trivia: Vec<crate::tokens::Trivia>,
259 /// Fase 14.b — trailing comment trivia (same line as the
260 /// declaration's last effective token). Empty by default.
261 pub trailing_trivia: Vec<crate::tokens::Trivia>,
262}
263
264/// `lease Name { resource, duration, acquire, on_expire }`
265///
266/// Affine/linear lease on a resource, with explicit Δt encoded in the `τ`
267/// of the ΛD envelope. Runtime materializes each lease as a revocable
268/// token; use post-expiry raises `LeaseExpiredError` (CT-2) per D2.
269#[derive(Debug, Default)]
270pub struct LeaseDefinition {
271 pub name: String,
272 pub resource_ref: String,
273 pub duration: String, // "30s", "5m", "2h"
274 pub acquire: String, // on_start | on_demand (default: on_start)
275 pub on_expire: String, // anchor_breach | release | extend (default: anchor_breach)
276 pub loc: Loc,
277 /// Fase 14.b — leading comment trivia attached to this declaration
278 /// (comments preceding the declaration's first token, since the
279 /// previous declaration or file start). Empty by default.
280 pub leading_trivia: Vec<crate::tokens::Trivia>,
281 /// Fase 14.b — trailing comment trivia (same line as the
282 /// declaration's last effective token). Empty by default.
283 pub trailing_trivia: Vec<crate::tokens::Trivia>,
284}
285
286/// `ensemble Name { observations, quorum, aggregation, certainty_mode }`
287///
288/// Byzantine quorum aggregator over ≥2 independent observations. Yields
289/// common knowledge `Cφ` (Fagin-Halpern) when at least `quorum` observers
290/// agree. Failed observations are excluded; below quorum raises CT-3.
291#[derive(Debug, Default)]
292pub struct EnsembleDefinition {
293 pub name: String,
294 pub observations: Vec<String>,
295 pub quorum: Option<i64>,
296 pub aggregation: String, // majority | weighted | byzantine (default: majority)
297 pub certainty_mode: String, // min | weighted | harmonic (default: min)
298 pub loc: Loc,
299 /// Fase 14.b — leading comment trivia attached to this declaration
300 /// (comments preceding the declaration's first token, since the
301 /// previous declaration or file start). Empty by default.
302 pub leading_trivia: Vec<crate::tokens::Trivia>,
303 /// Fase 14.b — trailing comment trivia (same line as the
304 /// declaration's last effective token). Empty by default.
305 pub trailing_trivia: Vec<crate::tokens::Trivia>,
306}
307
308// ── §λ-L-E Fase 4 — Topology + π-calculus binary sessions ──────────────────
309
310/// One step in a session protocol.
311///
312/// §Fase 4: `send T` | `receive T` | `loop` | `end`. §Fase 41.b adds **choice**:
313/// `select { ℓ: [..], … }` (⊕ — this role chooses) and `branch { ℓ: [..], … }`
314/// (& — this role offers); for those `op`s the labelled continuations live in
315/// [`SessionStep::branches`] (a nested sub-protocol per label).
316#[derive(Debug, Clone, Default)]
317pub struct SessionStep {
318 pub op: String, // send | receive | loop | end | select | branch
319 pub message_type: String, // only meaningful for send / receive
320 /// §Fase 41.b — populated only for `op == "select" | "branch"`: the labelled
321 /// branches, each a nested step sequence (its own sub-protocol).
322 pub branches: Vec<SessionBranch>,
323 pub loc: Loc,
324}
325
326/// §Fase 41.b — one labelled arm of a `select`/`branch` choice: `ℓ: [steps]`.
327#[derive(Debug, Clone, Default)]
328pub struct SessionBranch {
329 pub label: String,
330 pub steps: Vec<SessionStep>,
331 pub loc: Loc,
332}
333
334/// One role in a binary session — name + ordered list of steps.
335#[derive(Debug, Default)]
336pub struct SessionRole {
337 pub name: String,
338 pub steps: Vec<SessionStep>,
339 pub loc: Loc,
340}
341
342/// `session Name { role1: [step, …] role2: [step, …] }`
343///
344/// A binary session type — exactly two roles whose protocols MUST be
345/// pairwise Honda-Vasconcelos dual. Duality is verified by the type
346/// checker; non-dual programs are rejected at compile time.
347#[derive(Debug, Default)]
348pub struct SessionDefinition {
349 pub name: String,
350 pub roles: Vec<SessionRole>,
351 pub loc: Loc,
352 /// Fase 14.b — leading comment trivia attached to this declaration
353 /// (comments preceding the declaration's first token, since the
354 /// previous declaration or file start). Empty by default.
355 pub leading_trivia: Vec<crate::tokens::Trivia>,
356 /// Fase 14.b — trailing comment trivia (same line as the
357 /// declaration's last effective token). Empty by default.
358 pub trailing_trivia: Vec<crate::tokens::Trivia>,
359}
360
361/// `socket Name { protocol: SessionRef, backpressure: credit(n), reconnect:
362/// cognitive_state, legal_basis: ... }`
363///
364/// §Fase 41.b — the typed WebSocket transport (paper_websocket_cognitive_primitive.md).
365/// `socket` is NOT the protocol — the protocol is a `session` it references by
366/// name (protocol and transport kept separate but composable). The type checker
367/// resolves `protocol` to a declared `session` (whose two roles are already
368/// duality-checked via the §41.a algebra), so the dialogue carried over the WS
369/// connection is conformant + deadlock-free by construction.
370#[derive(Debug, Default)]
371pub struct SocketDefinition {
372 pub name: String,
373 /// The referenced `session` declaration's name — the protocol.
374 pub protocol: String,
375 /// The credit window of the typed-resource backpressure (`credit(n)`);
376 /// `None` if unspecified. A `0` credit is rejected by the type checker.
377 pub backpressure_credit: Option<i64>,
378 /// `reconnect: cognitive_state` → `true` (resume mid-dialogue via a sealed
379 /// §40.t snapshot); absent or `reconnect: none` → `false`.
380 pub reconnect: bool,
381 /// Optional `legal_basis:` annotation (enterprise audit/shield gate).
382 pub legal_basis: Option<String>,
383 pub loc: Loc,
384 /// Fase 14.b — leading comment trivia.
385 pub leading_trivia: Vec<crate::tokens::Trivia>,
386 /// Fase 14.b — trailing comment trivia.
387 pub trailing_trivia: Vec<crate::tokens::Trivia>,
388}
389
390/// `source -> target : Session` — one directed edge of a topology.
391///
392/// Convention: the source plays the FIRST role of the session; the target
393/// plays the SECOND role. Fixed so assignment is unambiguous.
394#[derive(Debug, Default)]
395pub struct TopologyEdge {
396 pub source: String,
397 pub target: String,
398 pub session_ref: String,
399 pub loc: Loc,
400}
401
402/// `topology Name { nodes: […] edges: [A -> B : Session, …] }`
403///
404/// A typed directed graph over Axon entities. Edges carry session references
405/// whose duality the type checker enforces; the graph is statically analysed
406/// for Honda-liveness (deadlock-prone cycles).
407#[derive(Debug, Default)]
408pub struct TopologyDefinition {
409 pub name: String,
410 pub nodes: Vec<String>,
411 pub edges: Vec<TopologyEdge>,
412 pub loc: Loc,
413 /// Fase 14.b — leading comment trivia attached to this declaration
414 /// (comments preceding the declaration's first token, since the
415 /// previous declaration or file start). Empty by default.
416 pub leading_trivia: Vec<crate::tokens::Trivia>,
417 /// Fase 14.b — trailing comment trivia (same line as the
418 /// declaration's last effective token). Empty by default.
419 pub trailing_trivia: Vec<crate::tokens::Trivia>,
420}
421
422// ── §λ-L-E Fase 5 — Cognitive immune system (per paper_immune_v2.md) ────────
423
424/// `immune Name { watch, sensitivity, baseline, window, scope, tau, decay }`
425///
426/// A continuous anomaly sensor over a declared observation vector.
427/// Computes D_KL(q_baseline || p_observed) (paper §3.2) and emits a
428/// HealthReport at an epistemic level derived from the KL magnitude.
429///
430/// Pure sensor — `immune` takes NO action. Actions belong to `reflex`
431/// and `heal`, which consume its HealthReport.
432#[derive(Debug, Default)]
433pub struct ImmuneDefinition {
434 pub name: String,
435 pub watch: Vec<String>, // observe / ensemble / any declared ref
436 pub sensitivity: Option<f64>, // [0.0, 1.0]
437 pub baseline: String, // "learned" (default) or name of a prior
438 pub window: i64, // samples used to estimate baseline (default: 100)
439 pub scope: String, // tenant | flow | global (MANDATORY, paper §8.2)
440 pub tau: String, // duration half-life
441 pub decay: String, // exponential (default) | linear | none
442 pub loc: Loc,
443 /// Fase 14.b — leading comment trivia attached to this declaration
444 /// (comments preceding the declaration's first token, since the
445 /// previous declaration or file start). Empty by default.
446 pub leading_trivia: Vec<crate::tokens::Trivia>,
447 /// Fase 14.b — trailing comment trivia (same line as the
448 /// declaration's last effective token). Empty by default.
449 pub trailing_trivia: Vec<crate::tokens::Trivia>,
450}
451
452/// `reflex Name { trigger, on_level, action, scope, sla }`
453///
454/// Deterministic, O(1) motor response. Contract invariants (paper §4.2):
455/// never invokes an LLM; no long-running I/O; every activation emits a
456/// signed_trace; idempotent on the same HealthReport.
457#[derive(Debug, Default)]
458pub struct ReflexDefinition {
459 pub name: String,
460 pub trigger: String, // immune name (MANDATORY)
461 pub on_level: String, // know | believe | speculate | doubt (default: doubt)
462 pub action: String, // drop | revoke | emit | redact | quarantine | terminate | alert
463 pub scope: String, // MANDATORY, paper §8.2
464 pub sla: String, // duration budget (e.g. "1ms")
465 pub loc: Loc,
466 /// Fase 14.b — leading comment trivia attached to this declaration
467 /// (comments preceding the declaration's first token, since the
468 /// previous declaration or file start). Empty by default.
469 pub leading_trivia: Vec<crate::tokens::Trivia>,
470 /// Fase 14.b — trailing comment trivia (same line as the
471 /// declaration's last effective token). Empty by default.
472 pub trailing_trivia: Vec<crate::tokens::Trivia>,
473}
474
475/// `heal Name { source, on_level, mode, scope, review_sla, shield, max_patches }`
476///
477/// Linear-Logic one-shot patch synthesis. Patch type:
478/// `!Synthesized ⊸ Applied ⊸ Collapsed` (paper §6) — each transition
479/// consumes its predecessor, guaranteeing single application + forced collapse.
480///
481/// Mode ∈ {audit_only | human_in_loop | adversarial} controls automation
482/// (paper §7); `adversarial` REQUIRES a shield gate (paper §7.3).
483#[derive(Debug, Default)]
484pub struct HealDefinition {
485 pub name: String,
486 pub source: String, // immune name (MANDATORY)
487 pub on_level: String, // know | believe | speculate | doubt
488 pub mode: String, // audit_only | human_in_loop | adversarial
489 pub scope: String, // MANDATORY
490 pub review_sla: String, // duration
491 pub shield_ref: String, // optional shield gate (required for adversarial)
492 pub max_patches: i64, // bounded heal attempts (default: 3)
493 pub loc: Loc,
494 /// Fase 14.b — leading comment trivia attached to this declaration
495 /// (comments preceding the declaration's first token, since the
496 /// previous declaration or file start). Empty by default.
497 pub leading_trivia: Vec<crate::tokens::Trivia>,
498 /// Fase 14.b — trailing comment trivia (same line as the
499 /// declaration's last effective token). Empty by default.
500 pub trailing_trivia: Vec<crate::tokens::Trivia>,
501}
502
503// ── §λ-L-E Fase 9 — UI cognitiva (component / view) ─────────────────────────
504
505/// `component Name { renders, via_shield, on_interact, render_hint }`.
506///
507/// A reusable UI fragment. `renders` is the data type the component
508/// visualizes; if that type has κ, `via_shield` is mandatory and its
509/// compliance set MUST cover the type's κ (compile-time enforcement).
510#[derive(Debug, Default)]
511pub struct ComponentDefinition {
512 pub name: String,
513 pub renders: String,
514 pub via_shield: String,
515 pub on_interact: String,
516 pub render_hint: String, // card | list | form | chart | custom
517 pub loc: Loc,
518 /// Fase 14.b — leading comment trivia attached to this declaration
519 /// (comments preceding the declaration's first token, since the
520 /// previous declaration or file start). Empty by default.
521 pub leading_trivia: Vec<crate::tokens::Trivia>,
522 /// Fase 14.b — trailing comment trivia (same line as the
523 /// declaration's last effective token). Empty by default.
524 pub trailing_trivia: Vec<crate::tokens::Trivia>,
525}
526
527/// `view Name { title, components: [...], route }`.
528///
529/// A top-level screen. `components` is an ordered list of declared
530/// `component` names composed in the view's primary layout.
531#[derive(Debug, Default)]
532pub struct ViewDefinition {
533 pub name: String,
534 pub title: String,
535 pub components: Vec<String>,
536 pub route: String,
537 pub loc: Loc,
538 /// Fase 14.b — leading comment trivia attached to this declaration
539 /// (comments preceding the declaration's first token, since the
540 /// previous declaration or file start). Empty by default.
541 pub leading_trivia: Vec<crate::tokens::Trivia>,
542 /// Fase 14.b — trailing comment trivia (same line as the
543 /// declaration's last effective token). Empty by default.
544 pub trailing_trivia: Vec<crate::tokens::Trivia>,
545}
546
547// ── Tier 2+ structural fallback ──────────────────────────────────────────────
548
549/// A declaration we recognize by keyword but parse only structurally.
550/// Validates brace balance and captures keyword + name.
551#[derive(Debug)]
552pub struct GenericDeclaration {
553 pub keyword: String,
554 pub name: String,
555 pub loc: Loc,
556 /// Fase 14.b — leading comment trivia attached to this declaration
557 /// (comments preceding the declaration's first token, since the
558 /// previous declaration or file start). Empty by default.
559 pub leading_trivia: Vec<crate::tokens::Trivia>,
560 /// Fase 14.b — trailing comment trivia (same line as the
561 /// declaration's last effective token). Empty by default.
562 pub trailing_trivia: Vec<crate::tokens::Trivia>,
563}
564
565// ── Agent ────────────────────────────────────────────────────────────────────
566
567#[derive(Debug)]
568pub struct AgentDefinition {
569 pub name: String,
570 pub goal: String,
571 pub tools: Vec<String>,
572 pub memory_ref: String,
573 pub strategy: String, // react | reflexion | plan_and_execute | custom
574 pub on_stuck: String, // forge | hibernate | escalate | retry
575 pub shield_ref: String,
576 pub max_iterations: Option<i64>,
577 pub max_tokens: Option<i64>,
578 pub max_time: String,
579 pub max_cost: Option<f64>,
580 pub loc: Loc,
581 /// Fase 14.b — leading comment trivia attached to this declaration
582 /// (comments preceding the declaration's first token, since the
583 /// previous declaration or file start). Empty by default.
584 pub leading_trivia: Vec<crate::tokens::Trivia>,
585 /// Fase 14.b — trailing comment trivia (same line as the
586 /// declaration's last effective token). Empty by default.
587 pub trailing_trivia: Vec<crate::tokens::Trivia>,
588}
589
590// ── §Fase 53 — Closed-catalog extension mechanism ────────────────────────────
591
592/// One member of an `extension` declaration. For `category: effects`
593/// the `name` is a provenance base (e.g. `"epistemic:believe"`) with
594/// optional `semantics` + `default_confidence` (a CEILING, never a
595/// floor — §53.d tainted-overriding). For `category: scan` the `name`
596/// is a scan-category identifier and the metadata is typically absent.
597#[derive(Debug, Clone)]
598pub struct ExtensionMember {
599 pub name: String,
600 pub semantics: Option<String>,
601 pub default_confidence: Option<f64>,
602 pub loc: Loc,
603}
604
605/// `extension Name { category: effects|scan, members: [ "x" : { … }, … ] }`
606///
607/// §Fase 53. A first-class, auditable + gateable declaration that
608/// expands a closed catalog with adopter-specific PROVENANCE members.
609/// Soundness invariants (validated in §53.c/§53.d): members are
610/// provenance-class only (never the enforceable effect set), must not
611/// shadow a canonical base/category, and ride in the IR + proof bundle
612/// so an independent PCC verifier re-derives against the same artifact.
613#[derive(Debug)]
614pub struct ExtensionDefinition {
615 pub name: String,
616 /// `effects` | `scan` — validated against the closed category set
617 /// in §53.c (the type-checker), not the parser.
618 pub category: String,
619 pub members: Vec<ExtensionMember>,
620 pub loc: Loc,
621 /// Fase 14.b — leading comment trivia. Empty by default.
622 pub leading_trivia: Vec<crate::tokens::Trivia>,
623 /// Fase 14.b — trailing comment trivia. Empty by default.
624 pub trailing_trivia: Vec<crate::tokens::Trivia>,
625}
626
627// ── Shield ───────────────────────────────────────────────────────────────────
628
629#[derive(Debug)]
630pub struct ShieldDefinition {
631 pub name: String,
632 pub scan: Vec<String>,
633 pub strategy: String, // pattern | classifier | dual_llm | canary | perplexity | ensemble
634 pub on_breach: String, // halt | sanitize_and_retry | escalate | quarantine | deflect
635 pub severity: String, // low | medium | high | critical
636 pub quarantine: String,
637 pub max_retries: Option<i64>,
638 pub confidence_threshold: Option<f64>,
639 pub allow_tools: Vec<String>,
640 pub deny_tools: Vec<String>,
641 pub sandbox: Option<bool>,
642 pub redact: Vec<String>,
643 pub log: String,
644 pub deflect_message: String,
645 pub taint: String,
646 /// §ESK Fase 6.1 — regulatory coverage (HIPAA, PCI_DSS, GDPR, …).
647 pub compliance: Vec<String>,
648 pub loc: Loc,
649 /// Fase 14.b — leading comment trivia attached to this declaration
650 /// (comments preceding the declaration's first token, since the
651 /// previous declaration or file start). Empty by default.
652 pub leading_trivia: Vec<crate::tokens::Trivia>,
653 /// Fase 14.b — trailing comment trivia (same line as the
654 /// declaration's last effective token). Empty by default.
655 pub trailing_trivia: Vec<crate::tokens::Trivia>,
656}
657
658// ── Pix ──────────────────────────────────────────────────────────────────────
659
660#[derive(Debug)]
661pub struct PixDefinition {
662 pub name: String,
663 pub source: String,
664 pub depth: Option<i64>,
665 pub branching: Option<i64>,
666 pub model: String,
667 pub loc: Loc,
668 /// Fase 14.b — leading comment trivia attached to this declaration
669 /// (comments preceding the declaration's first token, since the
670 /// previous declaration or file start). Empty by default.
671 pub leading_trivia: Vec<crate::tokens::Trivia>,
672 /// Fase 14.b — trailing comment trivia (same line as the
673 /// declaration's last effective token). Empty by default.
674 pub trailing_trivia: Vec<crate::tokens::Trivia>,
675}
676
677// ── Ledger ─────────────────────────────────────────────────────────────────
678// §Fase 62.0 — the append-only, hash-linked audit chain. Took over the
679// Provenance-Index role that `pix` historically (and only in the ℰMCP doc)
680// occupied, so `pix` is freed for its true meaning: the PIX retrieval
681// navigator (paper `paper_pix_formal_research.md`). A `ledger` binds a chain
682// recorder to an audited surface (`axonstore://X`, `flow://X`, …); `depth`
683// is chain retention, `branching` the Merkle factor, `model` the hash slug.
684
685#[derive(Debug)]
686pub struct LedgerDefinition {
687 pub name: String,
688 pub source: String,
689 pub depth: Option<i64>,
690 pub branching: Option<i64>,
691 pub model: String,
692 pub loc: Loc,
693 pub leading_trivia: Vec<crate::tokens::Trivia>,
694 pub trailing_trivia: Vec<crate::tokens::Trivia>,
695}
696
697// ── Psyche ───────────────────────────────────────────────────────────────────
698
699#[derive(Debug)]
700pub struct PsycheDefinition {
701 pub name: String,
702 pub dimensions: Vec<String>,
703 pub manifold_noise: Option<f64>,
704 pub manifold_momentum: Option<f64>,
705 pub safety_constraints: Vec<String>,
706 pub quantum_enabled: Option<bool>,
707 pub inference_mode: String, // active | passive
708 pub loc: Loc,
709 /// Fase 14.b — leading comment trivia attached to this declaration
710 /// (comments preceding the declaration's first token, since the
711 /// previous declaration or file start). Empty by default.
712 pub leading_trivia: Vec<crate::tokens::Trivia>,
713 /// Fase 14.b — trailing comment trivia (same line as the
714 /// declaration's last effective token). Empty by default.
715 pub trailing_trivia: Vec<crate::tokens::Trivia>,
716}
717
718// ── Corpus ───────────────────────────────────────────────────────────────────
719
720/// §Fase 63.A — a typed, weighted edge of an MDN corpus graph: `etype(from, to,
721/// weight)`. `etype` is from the closed relation catalog (cite / elaborate /
722/// corroborate / depend / implement / exemplify / contradict / supersede);
723/// `from`/`to` name documents declared in the corpus; `weight ∈ (0, 1]`.
724#[derive(Debug, Clone)]
725pub struct CorpusRelation {
726 pub etype: String,
727 pub from: String,
728 pub to: String,
729 pub weight: f64,
730 pub loc: Loc,
731}
732
733#[derive(Debug)]
734pub struct CorpusDefinition {
735 pub name: String,
736 pub documents: Vec<String>, // simplified: list of pix refs
737 /// §Fase 63.A — the typed weighted edges that make this corpus an MDN graph
738 /// `C = (D, R, τ, ω, σ)`. Empty ⇒ the flat (edgeless) corpus.
739 pub relations: Vec<CorpusRelation>,
740 /// §Fase 63.C — `adaptive: true` enables the memory endofunctor: navigations
741 /// over this corpus learn (semantic edge reinforcement + procedural bias),
742 /// and subsequent navigations use the memory-modified EPR. Requires the
743 /// graph to carry edges (static `relations:` OR a store-sourced edge store).
744 pub adaptive: bool,
745 pub mcp_server: String,
746 pub mcp_resource_uri: String,
747 /// §Fase 64.A — when `Some`, this is a DYNAMIC store-sourced MDN graph
748 /// (`corpus N from axonstore { documents: DocStore(id, title) relations:
749 /// EdgeStore(from, to, etype, weight) }`): the documents and typed edges live
750 /// as ROWS in two declared `axonstore`s and the graph is built from the live
751 /// rows at navigate-time (per-tenant, growing). Mutually exclusive with the
752 /// static §63 form — the `documents`/`relations`/`mcp_*` fields stay empty.
753 /// `None` ⇒ the static compile-time corpus (back-compat byte-identical).
754 pub store_source: Option<CorpusStoreSource>,
755 pub loc: Loc,
756 /// Fase 14.b — leading comment trivia attached to this declaration
757 /// (comments preceding the declaration's first token, since the
758 /// previous declaration or file start). Empty by default.
759 pub leading_trivia: Vec<crate::tokens::Trivia>,
760 /// Fase 14.b — trailing comment trivia (same line as the
761 /// declaration's last effective token). Empty by default.
762 pub trailing_trivia: Vec<crate::tokens::Trivia>,
763}
764
765/// §Fase 64.A — the dynamic, `axonstore`-sourced backing of an MDN corpus graph.
766/// The graph's documents and typed edges are ROWS in two declared `axonstore`s,
767/// so the graph grows at runtime (a new `persist` = a new node/edge) and is
768/// per-tenant by inheritance from the store's §40 column-proof / RLS scope. The
769/// runtime builds the `mdn::Corpus` from the live rows at navigate-time.
770///
771/// Surface:
772/// ```text
773/// corpus LtmGraph from axonstore {
774/// documents: LtmSummaries( id, summary ) // (id-col, title-col)
775/// relations: LtmEdges( from_id, to_id, etype, weight ) // (from, to, etype, weight)
776/// adaptive: true
777/// }
778/// ```
779/// Documents and edges live in SEPARATE stores (an `axonstore` is one table with
780/// one column schema). The type-checker (`check_corpus`) validates that both
781/// stores are declared and — when they carry a §38 column schema — that the
782/// mapped columns exist with compatible types (id present; title text-like;
783/// from/to match the id type; etype text-like; weight numeric). The weight-range
784/// invariant `ω ∈ (0, 1]` (G4) becomes a RUNTIME check here, since weights are
785/// per-row dynamic (clamp on read + store CHECK), not a compile-time literal.
786#[derive(Debug, Clone)]
787pub struct CorpusStoreSource {
788 pub doc_store: String,
789 pub doc_id_col: String,
790 pub doc_title_col: String,
791 pub edge_store: String,
792 pub edge_from_col: String,
793 pub edge_to_col: String,
794 pub edge_type_col: String,
795 pub edge_weight_col: String,
796 pub loc: Loc,
797}
798
799// ── Dataspace ────────────────────────────────────────────────────────────────
800
801#[derive(Debug)]
802pub struct DataspaceDefinition {
803 pub name: String,
804 pub loc: Loc,
805 /// Fase 14.b — leading comment trivia attached to this declaration
806 /// (comments preceding the declaration's first token, since the
807 /// previous declaration or file start). Empty by default.
808 pub leading_trivia: Vec<crate::tokens::Trivia>,
809 /// Fase 14.b — trailing comment trivia (same line as the
810 /// declaration's last effective token). Empty by default.
811 pub trailing_trivia: Vec<crate::tokens::Trivia>,
812}
813
814// ── OTS ──────────────────────────────────────────────────────────────────────
815
816#[derive(Debug)]
817pub struct OtsDefinition {
818 pub name: String,
819 pub teleology: String,
820 pub homotopy_search: String, // shallow | deep | speculative
821 pub loss_function: String,
822 pub loc: Loc,
823 /// Fase 14.b — leading comment trivia attached to this declaration
824 /// (comments preceding the declaration's first token, since the
825 /// previous declaration or file start). Empty by default.
826 pub leading_trivia: Vec<crate::tokens::Trivia>,
827 /// Fase 14.b — trailing comment trivia (same line as the
828 /// declaration's last effective token). Empty by default.
829 pub trailing_trivia: Vec<crate::tokens::Trivia>,
830}
831
832// ── Mandate ──────────────────────────────────────────────────────────────────
833
834#[derive(Debug)]
835pub struct MandateDefinition {
836 pub name: String,
837 pub constraint: String,
838 pub kp: Option<f64>,
839 pub ki: Option<f64>,
840 pub kd: Option<f64>,
841 pub tolerance: Option<f64>,
842 pub max_steps: Option<i64>,
843 pub on_violation: String, // coerce | halt | retry
844 pub loc: Loc,
845 /// Fase 14.b — leading comment trivia attached to this declaration
846 /// (comments preceding the declaration's first token, since the
847 /// previous declaration or file start). Empty by default.
848 pub leading_trivia: Vec<crate::tokens::Trivia>,
849 /// Fase 14.b — trailing comment trivia (same line as the
850 /// declaration's last effective token). Empty by default.
851 pub trailing_trivia: Vec<crate::tokens::Trivia>,
852}
853
854// ── Compute ──────────────────────────────────────────────────────────────────
855
856#[derive(Debug)]
857pub struct ComputeDefinition {
858 pub name: String,
859 pub shield_ref: String,
860 pub loc: Loc,
861 /// Fase 14.b — leading comment trivia attached to this declaration
862 /// (comments preceding the declaration's first token, since the
863 /// previous declaration or file start). Empty by default.
864 pub leading_trivia: Vec<crate::tokens::Trivia>,
865 /// Fase 14.b — trailing comment trivia (same line as the
866 /// declaration's last effective token). Empty by default.
867 pub trailing_trivia: Vec<crate::tokens::Trivia>,
868}
869
870// ── Daemon ───────────────────────────────────────────────────────────────────
871
872#[derive(Debug)]
873pub struct DaemonDefinition {
874 pub name: String,
875 pub goal: String,
876 pub tools: Vec<String>,
877 pub memory_ref: String,
878 pub strategy: String, // react | reflexion | plan_and_execute | custom
879 pub on_stuck: String, // hibernate | escalate | retry | forge
880 pub shield_ref: String,
881 pub max_tokens: Option<i64>,
882 pub max_time: String,
883 pub max_cost: Option<f64>,
884 /// §λ-L-E Fase 13 D4 — listen blocks captured for type-checker
885 /// validation (typed-channel ref + dual-mode deprecation warning).
886 /// Pre-Fase 13 the parser discarded these structurally; we now
887 /// retain them so 13.b/13.f can validate emit/publish/discover
888 /// inside listener bodies and surface D4 string-topic warnings.
889 pub listeners: Vec<ListenStep>,
890 /// §Fase 52.d — the capability scope a daemon's runs are confined to
891 /// (`requires: [cap, …]`, the same closed slug grammar as `axonendpoint
892 /// requires:`). A scheduled (cron) daemon MUST declare this (it is a
893 /// standing autonomous privilege); the enterprise supervisor mints a
894 /// per-run principal scoped to EXACTLY these capabilities (least privilege,
895 /// §52.d). Empty for event-only daemons / pre-§52 daemons.
896 pub requires_capabilities: Vec<String>,
897 pub loc: Loc,
898 /// Fase 14.b — leading comment trivia attached to this declaration
899 /// (comments preceding the declaration's first token, since the
900 /// previous declaration or file start). Empty by default.
901 pub leading_trivia: Vec<crate::tokens::Trivia>,
902 /// Fase 14.b — trailing comment trivia (same line as the
903 /// declaration's last effective token). Empty by default.
904 pub trailing_trivia: Vec<crate::tokens::Trivia>,
905}
906
907// ── AxonStore ────────────────────────────────────────────────────────────────
908
909#[derive(Debug)]
910pub struct AxonStoreDefinition {
911 pub name: String,
912 pub backend: String, // sqlite | postgresql | mysql
913 pub connection: String,
914 pub confidence_floor: Option<f64>,
915 pub isolation: String, // read_committed | repeatable_read | serializable
916 pub on_breach: String, // rollback | raise | log
917 /// §Fase 35.j (D11) — Pillar IV: the capability slug required to
918 /// access this store. Empty = no capability gate. Validated at
919 /// parse time against the closed slug grammar (shared with the
920 /// Fase 32.g `requires:` grammar).
921 pub capability: String,
922 /// §Fase 38.b (D1) — the OPTIONAL column-schema declaration. Three
923 /// closed forms (inline / manifest-ref / env-var); `None` means the
924 /// 37.x runtime+deploy path applies verbatim (D5 absolute). The
925 /// §38.d / §38.e `StoreColumnProof` pass consumes this; the §38.h
926 /// CLI exports it.
927 pub column_schema: Option<crate::store_schema::StoreColumnSchema>,
928 pub loc: Loc,
929 /// Fase 14.b — leading comment trivia attached to this declaration
930 /// (comments preceding the declaration's first token, since the
931 /// previous declaration or file start). Empty by default.
932 pub leading_trivia: Vec<crate::tokens::Trivia>,
933 /// Fase 14.b — trailing comment trivia (same line as the
934 /// declaration's last effective token). Empty by default.
935 pub trailing_trivia: Vec<crate::tokens::Trivia>,
936}
937
938// ── AxonEndpoint ─────────────────────────────────────────────────────────────
939
940#[derive(Debug)]
941pub struct AxonEndpointDefinition {
942 pub name: String,
943 pub method: String, // GET | POST | PUT | DELETE
944 pub path: String,
945 pub body_type: String,
946 pub execute_flow: String,
947 pub output_type: String,
948 pub shield_ref: String,
949 pub retries: Option<i64>,
950 pub timeout: String,
951 /// §ESK Fase 6.1 — regulatory coverage on the boundary.
952 pub compliance: Vec<String>,
953 /// §Fase 30 — HTTP wire transport for the response. Closed enum
954 /// per D2 ratified 2026-05-10: {"json" | "sse" | "ndjson"}.
955 /// Default "json" (D1 — backwards-compat preserved). When set
956 /// to "sse", the type-checker (30.c) verifies that
957 /// `execute_flow` produces a Stream<T> (D3).
958 pub transport: String,
959 /// §Fase 30 — Keepalive comment interval for SSE transport (D6).
960 /// Optional; default applied at runtime when transport == "sse"
961 /// (default 15s). Closed enum at parse time:
962 /// {"5s" | "15s" | "30s" | "60s"}. Empty string means
963 /// "use runtime default".
964 pub keepalive: String,
965 /// §Fase 31.b — Type-Driven Wire Inference (D1, D7).
966 /// `transport_explicit` is `true` if the source declared
967 /// `transport:` explicitly (any of json/sse/ndjson). `false` if
968 /// the field was omitted, in which case `transport` reflects the
969 /// D1 default `"json"` but `implicit_transport` (computed by the
970 /// `axon_frontend::type_checker::compute_implicit_transports`
971 /// pass) carries the inferred value.
972 pub transport_explicit: bool,
973 /// §Fase 31.b — Inferred wire transport per D1:
974 /// implicit_transport(E) =
975 /// declared_transport(E) if transport_explicit
976 /// "sse" if produces_stream(execute_flow) ∧ ¬explicit
977 /// "json" otherwise
978 /// Empty string `""` before the type-checker runs. The Python
979 /// reference implementation in `axon/compiler/type_checker.py`
980 /// sets the field byte-identically (D7 cross-stack contract).
981 pub implicit_transport: String,
982 /// §Fase 32.g (D8) — Auth scope: capability slugs the request
983 /// bearer must hold for the endpoint to dispatch. Empty vec
984 /// means "no auth gate" (D9 backwards-compat). Slug grammar
985 /// (closed): `^[a-z][a-z0-9_]*(\.[a-z][a-z0-9_]*)*$`. Examples:
986 /// `admin`, `legal.read`, `hipaa.phi.read`. The runtime checks
987 /// declared_requires ⊆ token_capabilities (AND semantics — every
988 /// declared capability must be present in the bearer's claims).
989 pub requires_capabilities: Vec<String>,
990 /// §Fase 32.h — Replay-token binding (D9 plan-vivo).
991 /// `replay_explicit` is `true` when the source declared `replay:`
992 /// explicitly. `false` when the field was omitted, in which case
993 /// `replay` reflects the method-default (POST/PUT → true, GET/
994 /// DELETE → false) computed at deploy time. When the effective
995 /// value resolves to `true`, every successful 2xx response is
996 /// recorded in the runtime's axonendpoint replay log keyed by
997 /// trace_id; auditors retrieve it via GET /v1/replay/<trace_id>.
998 pub replay_explicit: bool,
999 pub replay: bool,
1000 /// §Fase 33.z.k.b (v1.28.0) — Selected SSE wire-format dialect.
1001 ///
1002 /// Populated when the source uses the parametrized grammar
1003 /// `transport: sse(<dialect>)`. Closed catalog
1004 /// (`AXONENDPOINT_TRANSPORT_DIALECTS`): `{axon, openai, anthropic}`.
1005 /// Empty string `""` when:
1006 /// - the source declared a non-SSE transport (`json`/`ndjson`), OR
1007 /// - the source declared bare `transport: sse` without parens, OR
1008 /// - the source omitted `transport:` entirely (D1 implicit path).
1009 ///
1010 /// When empty + the effective wire is SSE (per the runtime
1011 /// classifier `classify_dynamic_route_wire`), the runtime
1012 /// resolves the dialect via the Q1 algebraic-effect-driven
1013 /// default: openai for tool-streaming flows (algebraic predicate
1014 /// true), axon for type-annotation-only flows (algebraic predicate
1015 /// false). D3 explicit `transport: sse(<dialect>)` overrides the
1016 /// default.
1017 pub transport_dialect: String,
1018 /// §Fase 33.z.k.1 (v1.27.1) — Algebraic-effect override predicate.
1019 ///
1020 /// `true` when `execute_flow` references a tool that declares
1021 /// `effects: <stream:<policy>>` (Fase 30 algebraic-effect surface).
1022 /// Mirrors `type_checker::flow_uses_streaming_tool(execute_flow, program)`.
1023 ///
1024 /// Used by the runtime classifier
1025 /// (`axon_server::classify_dynamic_route_wire`) to OVERRIDE the
1026 /// v1.22.0 D6 backwards-compat gate: a tool with a declared stream
1027 /// effect is a LANGUAGE-LEVEL commitment to streaming, not a
1028 /// client preference. When this field is `true` AND
1029 /// `transport: json` is NOT explicitly declared (D3 opt-out remains
1030 /// sacred), the route wire is unconditionally `Sse` — no
1031 /// `Accept: text/event-stream` header required, no
1032 /// `AXON_STRICT_TYPE_DRIVEN_TRANSPORT=1` runtime flag required.
1033 ///
1034 /// Computed in lockstep with `implicit_transport` by the
1035 /// `compute_implicit_transports` pass. Default `false` before the
1036 /// pass runs (matches AST construction defaults; D9 backwards-
1037 /// compat preserved for older AST consumers).
1038 pub has_algebraic_stream_effect: bool,
1039 /// §Fase 36.d (D2) — the declared execution backend for the flow
1040 /// behind this endpoint. Empty string `""` means "not declared"
1041 /// (the endpoint resolves its backend down the Fase 36 D1
1042 /// precedence ladder — server default → environment-available
1043 /// `auto`). When non-empty the parser has validated it against the
1044 /// closed catalog [`crate::parser::AXONENDPOINT_BACKEND_VALUES`]
1045 /// and the type-checker rejects an unknown name as a compile
1046 /// error. A declared `backend:` is rung 2 of the resolution
1047 /// contract.
1048 pub backend: String,
1049 /// §Fase 37.y (D1) — Path parameter names extracted from the
1050 /// `path:` string at parse time. For `path: "/api/tenants/{tenant_id}/secrets/{secret_name}"`
1051 /// this is `["tenant_id", "secret_name"]`. Empty Vec when the
1052 /// path has no `{name}` placeholders (D5 backwards-compat — an
1053 /// endpoint without path params produces byte-identical IR to
1054 /// v1.38.4).
1055 ///
1056 /// Names are deduplicated + recorded in declaration order. A
1057 /// duplicate `{tenant_id}` in the same path is a parse error
1058 /// (HTTP route patterns reject duplicates structurally — `axum`
1059 /// would panic at registration). Type binding is always `Text`
1060 /// in v1.38.5 (HTTP path-segment convention); a future Fase 37.z
1061 /// may add per-placeholder type-override grammar `{tenant_id: Uuid}`.
1062 ///
1063 /// The Fase 37 D2 totality check (extended by 37.y D3) treats
1064 /// every name here as covering an equivalent flow parameter
1065 /// declared `Text`. Collision with a body field of the same name
1066 /// is a compile error (`axon-T901`, D4).
1067 pub path_params: Vec<String>,
1068 /// §Fase 37.y (D2) — Query parameters declared via the inline
1069 /// `query: { name: Type, name: Type? }` block on the endpoint.
1070 /// Empty Vec when the source omits the block (D5 backwards-compat).
1071 ///
1072 /// Closed type catalog (parser-enforced):
1073 /// `{Text, Int, Float, Bool, Uuid}`. The runtime receives every
1074 /// query value as a textual `String` and binds it to the same-named
1075 /// flow parameter; the closed catalog enables future per-type
1076 /// parsing/validation without breaking the manifest format.
1077 ///
1078 /// The optional flag (`?` suffix in the source) reuses
1079 /// `TypeExpr.optional`. An optional query param need not be
1080 /// covered by a flow parameter (D3 totality is over required
1081 /// params); a required query param missing from the flow signature
1082 /// is a `axon-T?nn` future arm. For v1.38.5 the totality check
1083 /// treats every query param as a binding-source candidate for any
1084 /// same-named flow param.
1085 ///
1086 /// Reusing `TypeField` (shared with body type declarations) keeps
1087 /// the D2 totality check uniform — the same `field.type_expr.name
1088 /// == param.type_expr.name` comparator works for body fields AND
1089 /// query params.
1090 pub query_params: Vec<TypeField>,
1091 pub loc: Loc,
1092 /// Fase 14.b — leading comment trivia attached to this declaration
1093 /// (comments preceding the declaration's first token, since the
1094 /// previous declaration or file start). Empty by default.
1095 pub leading_trivia: Vec<crate::tokens::Trivia>,
1096 /// Fase 14.b — trailing comment trivia (same line as the
1097 /// declaration's last effective token). Empty by default.
1098 pub trailing_trivia: Vec<crate::tokens::Trivia>,
1099}
1100
1101// ── Import ───────────────────────────────────────────────────────────────────
1102
1103#[derive(Debug)]
1104pub struct ImportNode {
1105 pub module_path: Vec<String>,
1106 pub names: Vec<String>,
1107 pub loc: Loc,
1108 /// Fase 14.b — leading comment trivia attached to this declaration
1109 /// (comments preceding the declaration's first token, since the
1110 /// previous declaration or file start). Empty by default.
1111 pub leading_trivia: Vec<crate::tokens::Trivia>,
1112 /// Fase 14.b — trailing comment trivia (same line as the
1113 /// declaration's last effective token). Empty by default.
1114 pub trailing_trivia: Vec<crate::tokens::Trivia>,
1115}
1116
1117// ── Persona ──────────────────────────────────────────────────────────────────
1118
1119#[derive(Debug)]
1120pub struct PersonaDefinition {
1121 pub name: String,
1122 pub domain: Vec<String>,
1123 pub tone: String,
1124 pub confidence_threshold: Option<f64>,
1125 pub cite_sources: Option<bool>,
1126 pub refuse_if: Vec<String>,
1127 pub language: String,
1128 pub description: String,
1129 pub loc: Loc,
1130 /// Fase 14.b — leading comment trivia attached to this declaration
1131 /// (comments preceding the declaration's first token, since the
1132 /// previous declaration or file start). Empty by default.
1133 pub leading_trivia: Vec<crate::tokens::Trivia>,
1134 /// Fase 14.b — trailing comment trivia (same line as the
1135 /// declaration's last effective token). Empty by default.
1136 pub trailing_trivia: Vec<crate::tokens::Trivia>,
1137}
1138
1139// ── Context ──────────────────────────────────────────────────────────────────
1140
1141#[derive(Debug)]
1142pub struct ContextDefinition {
1143 pub name: String,
1144 pub memory_scope: String,
1145 pub language: String,
1146 pub depth: String,
1147 pub max_tokens: Option<i64>,
1148 pub temperature: Option<f64>,
1149 pub cite_sources: Option<bool>,
1150 pub loc: Loc,
1151 /// Fase 14.b — leading comment trivia attached to this declaration
1152 /// (comments preceding the declaration's first token, since the
1153 /// previous declaration or file start). Empty by default.
1154 pub leading_trivia: Vec<crate::tokens::Trivia>,
1155 /// Fase 14.b — trailing comment trivia (same line as the
1156 /// declaration's last effective token). Empty by default.
1157 pub trailing_trivia: Vec<crate::tokens::Trivia>,
1158}
1159
1160// ── Anchor ───────────────────────────────────────────────────────────────────
1161
1162#[derive(Debug)]
1163pub struct AnchorConstraint {
1164 pub name: String,
1165 pub require: String,
1166 pub reject: Vec<String>,
1167 pub enforce: String,
1168 pub description: String,
1169 pub confidence_floor: Option<f64>,
1170 pub unknown_response: String,
1171 pub on_violation: String,
1172 pub on_violation_target: String,
1173 pub loc: Loc,
1174 /// Fase 14.b — leading comment trivia attached to this declaration
1175 /// (comments preceding the declaration's first token, since the
1176 /// previous declaration or file start). Empty by default.
1177 pub leading_trivia: Vec<crate::tokens::Trivia>,
1178 /// Fase 14.b — trailing comment trivia (same line as the
1179 /// declaration's last effective token). Empty by default.
1180 pub trailing_trivia: Vec<crate::tokens::Trivia>,
1181}
1182
1183// ── Memory ───────────────────────────────────────────────────────────────────
1184
1185#[derive(Debug)]
1186pub struct MemoryDefinition {
1187 pub name: String,
1188 pub store: String,
1189 pub backend: String,
1190 pub retrieval: String,
1191 pub decay: String,
1192 pub loc: Loc,
1193 /// Fase 14.b — leading comment trivia attached to this declaration
1194 /// (comments preceding the declaration's first token, since the
1195 /// previous declaration or file start). Empty by default.
1196 pub leading_trivia: Vec<crate::tokens::Trivia>,
1197 /// Fase 14.b — trailing comment trivia (same line as the
1198 /// declaration's last effective token). Empty by default.
1199 pub trailing_trivia: Vec<crate::tokens::Trivia>,
1200}
1201
1202// ── Tool ─────────────────────────────────────────────────────────────────────
1203
1204#[derive(Debug)]
1205pub struct ToolDefinition {
1206 pub name: String,
1207 pub provider: String,
1208 pub max_results: Option<i64>,
1209 pub filter_expr: String,
1210 pub timeout: String,
1211 pub runtime: String,
1212 pub sandbox: Option<bool>,
1213 pub effects: Option<EffectRow>,
1214 /// §Fase 58.a — the tool's typed INPUT SCHEMA (W2: the caller↔tool
1215 /// contract). Each entry is a named, typed parameter that the canonical
1216 /// `use Tool(k = v, …)` invocation binds against and the type-checker
1217 /// validates the caller's args against (CT-2 caller blame, pre-HTTP).
1218 /// Empty for a schema-less tool — the legacy single-`on <arg>` form still
1219 /// applies (§58 D5 back-compat). Reuses `Parameter` (same `TypeExpr`
1220 /// grammar as flow params).
1221 pub parameters: Vec<Parameter>,
1222 /// §Fase 58.a — the tool's declared OUTPUT type, so a tool-step's result
1223 /// is referenceable as `${Step.output}` with a real type (§58 D8). Flat
1224 /// string (mirrors step `output:`); `None` when undeclared.
1225 pub output_type: Option<String>,
1226 pub loc: Loc,
1227 /// Fase 14.b — leading comment trivia attached to this declaration
1228 /// (comments preceding the declaration's first token, since the
1229 /// previous declaration or file start). Empty by default.
1230 pub leading_trivia: Vec<crate::tokens::Trivia>,
1231 /// Fase 14.b — trailing comment trivia (same line as the
1232 /// declaration's last effective token). Empty by default.
1233 pub trailing_trivia: Vec<crate::tokens::Trivia>,
1234}
1235
1236#[derive(Debug)]
1237pub struct EffectRow {
1238 pub effects: Vec<String>,
1239 pub epistemic_level: String,
1240 pub loc: Loc,
1241}
1242
1243// ── Type ─────────────────────────────────────────────────────────────────────
1244
1245#[derive(Debug)]
1246pub struct TypeDefinition {
1247 pub name: String,
1248 pub fields: Vec<TypeField>,
1249 pub range_constraint: Option<RangeConstraint>,
1250 pub where_clause: Option<WhereClause>,
1251 /// §ESK Fase 6.1 — κ regulatory class attached to a type.
1252 pub compliance: Vec<String>,
1253 pub loc: Loc,
1254 /// Fase 14.b — leading comment trivia attached to this declaration
1255 /// (comments preceding the declaration's first token, since the
1256 /// previous declaration or file start). Empty by default.
1257 pub leading_trivia: Vec<crate::tokens::Trivia>,
1258 /// Fase 14.b — trailing comment trivia (same line as the
1259 /// declaration's last effective token). Empty by default.
1260 pub trailing_trivia: Vec<crate::tokens::Trivia>,
1261}
1262
1263#[derive(Debug, Clone)]
1264pub struct TypeExpr {
1265 pub name: String,
1266 pub generic_param: String,
1267 pub optional: bool,
1268 pub loc: Loc,
1269}
1270
1271#[derive(Debug)]
1272pub struct TypeField {
1273 pub name: String,
1274 pub type_expr: TypeExpr,
1275 pub loc: Loc,
1276}
1277
1278#[derive(Debug)]
1279pub struct RangeConstraint {
1280 pub min_value: f64,
1281 pub max_value: f64,
1282 pub loc: Loc,
1283}
1284
1285#[derive(Debug)]
1286pub struct WhereClause {
1287 pub expression: String,
1288 pub loc: Loc,
1289}
1290
1291// ── Flow ─────────────────────────────────────────────────────────────────────
1292
1293#[derive(Debug)]
1294pub struct FlowDefinition {
1295 pub name: String,
1296 pub parameters: Vec<Parameter>,
1297 pub return_type: Option<TypeExpr>,
1298 pub body: Vec<FlowStep>,
1299 pub loc: Loc,
1300 /// Fase 14.b — leading comment trivia attached to this declaration
1301 /// (comments preceding the declaration's first token, since the
1302 /// previous declaration or file start). Empty by default.
1303 pub leading_trivia: Vec<crate::tokens::Trivia>,
1304 /// Fase 14.b — trailing comment trivia (same line as the
1305 /// declaration's last effective token). Empty by default.
1306 pub trailing_trivia: Vec<crate::tokens::Trivia>,
1307}
1308
1309#[derive(Debug)]
1310pub struct Parameter {
1311 pub name: String,
1312 pub type_expr: TypeExpr,
1313 pub loc: Loc,
1314}
1315
1316/// Statements that can appear inside a flow body.
1317#[derive(Debug)]
1318pub enum FlowStep {
1319 Step(StepNode),
1320 If(ConditionalNode),
1321 ForIn(ForInStatement),
1322 Let(LetStatement),
1323 Return(ReturnStatement),
1324 /// Fase 19.e — `break` keyword. Payload-free; carries only its
1325 /// source location for error reporting.
1326 Break(BreakStatement),
1327 /// Fase 19.e — `continue` keyword. Payload-free; same shape as
1328 /// `Break`.
1329 Continue(ContinueStatement),
1330 /// Lambda Data application in a flow step.
1331 LambdaDataApply(LambdaDataApplyNode),
1332 // ── Tier 2 flow steps ──
1333 Probe(ProbeStep),
1334 Reason(ReasonStep),
1335 Validate(ValidateStep),
1336 Refine(RefineStep),
1337 Weave(WeaveStep),
1338 UseTool(UseToolStep),
1339 Remember(RememberStep),
1340 Recall(RecallStep),
1341 Par(ParBlock),
1342 Hibernate(HibernateStep),
1343 Deliberate(DeliberateBlock),
1344 Consensus(ConsensusBlock),
1345 Forge(ForgeBlock),
1346 Focus(FocusStep),
1347 Associate(AssociateStep),
1348 Aggregate(AggregateStep),
1349 ExploreStep(ExploreStepNode),
1350 Ingest(IngestStep),
1351 ShieldApply(ShieldApplyStep),
1352 Stream(StreamBlock),
1353 Navigate(NavigateStep),
1354 Drill(DrillStep),
1355 Trail(TrailStep),
1356 Corroborate(CorroborateStep),
1357 OtsApply(OtsApplyStep),
1358 MandateApply(MandateApplyStep),
1359 ComputeApply(ComputeApplyStep),
1360 Listen(ListenStep),
1361 DaemonStep(DaemonStepNode),
1362 /// §λ-L-E Fase 13 — π-calculus output prefix `c⟨v⟩.P` (Chan-Output / Chan-Mobility).
1363 Emit(EmitStatement),
1364 /// §λ-L-E Fase 13 — capability extrusion (Publish-Ext, paper §4.3).
1365 Publish(PublishStatement),
1366 /// §λ-L-E Fase 13 — dual of publish (dynamic typed handle import).
1367 Discover(DiscoverStatement),
1368 Persist(PersistStep),
1369 Retrieve(RetrieveStep),
1370 Mutate(MutateStep),
1371 Purge(PurgeStep),
1372 Transact(TransactBlock),
1373 /// §Fase 51.a — `quant { … }` cognitive block (Hilbert-space projection).
1374 /// Carries an optional attribute header + a real nested body of flow steps
1375 /// (so §51.b's Continuous Type Invariant can scan it). Lives inside a flow
1376 /// body like `par`; NOT a top-level declaration.
1377 Quant(QuantBlock),
1378 /// §Fase 51.d.2 — `yield <expr>` measurement point inside a `quant` block.
1379 /// Collapses the evolved amplitudes back to classical silicon; the effect
1380 /// operation whose resolution is a one-shot delimited continuation. Only
1381 /// well-formed inside a `quant` block (the checker rejects it elsewhere).
1382 Yield(YieldStatement),
1383 /// §Fase 52.c — `run <Flow>(args)` as a flow-step: invoke a declared flow
1384 /// from inside a body (notably a `daemon`'s `listen` handler — the Q3 ask).
1385 /// Reuses the top-level [`RunStatement`] shape (flow name + args + optional
1386 /// persona/context/anchors). Distinct from `Declaration::Run` only by
1387 /// position (a step inside a body vs. a program-root run).
1388 Run(RunStatement),
1389 /// Flow-level statements we recognize but parse structurally.
1390 GenericStep(GenericFlowStep),
1391}
1392
1393/// A flow step we recognize by keyword but parse only structurally.
1394#[derive(Debug)]
1395pub struct GenericFlowStep {
1396 pub keyword: String,
1397 pub loc: Loc,
1398}
1399
1400// ── Step ─────────────────────────────────────────────────────────────────────
1401
1402#[derive(Debug)]
1403pub struct StepNode {
1404 pub name: String,
1405 pub persona_ref: String,
1406 pub given: String,
1407 pub ask: String,
1408 pub output_type: String,
1409 pub confidence_floor: Option<f64>,
1410 pub navigate_ref: String,
1411 pub apply_ref: String,
1412 /// §Fase 68.b — the step's declared MODEL CAPABILITY requirement: the
1413 /// context window (in tokens) the cognitive act needs. The §68.c resolver
1414 /// maps it to the smallest concrete model that satisfies it (per the
1415 /// resolved backend's §68.a catalog); `None` → the backend default
1416 /// (back-compat). Declare the NEED, not the vendor SKU (D68.1).
1417 pub requires_context: Option<u32>,
1418 pub loc: Loc,
1419}
1420
1421// ── Intent ───────────────────────────────────────────────────────────────────
1422
1423#[derive(Debug)]
1424pub struct IntentNode {
1425 pub name: String,
1426 pub given: String,
1427 pub ask: String,
1428 pub output_type: Option<TypeExpr>,
1429 pub confidence_floor: Option<f64>,
1430 pub loc: Loc,
1431 /// Fase 14.b — leading comment trivia attached to this declaration
1432 /// (comments preceding the declaration's first token, since the
1433 /// previous declaration or file start). Empty by default.
1434 pub leading_trivia: Vec<crate::tokens::Trivia>,
1435 /// Fase 14.b — trailing comment trivia (same line as the
1436 /// declaration's last effective token). Empty by default.
1437 pub trailing_trivia: Vec<crate::tokens::Trivia>,
1438}
1439
1440// ── Run ──────────────────────────────────────────────────────────────────────
1441
1442#[derive(Debug)]
1443pub struct RunStatement {
1444 pub flow_name: String,
1445 pub arguments: Vec<String>,
1446 pub persona: String,
1447 pub context: String,
1448 pub anchors: Vec<String>,
1449 pub on_failure: String,
1450 pub on_failure_params: Vec<(String, String)>,
1451 pub output_to: String,
1452 pub effort: String,
1453 pub loc: Loc,
1454 /// Fase 14.b — leading comment trivia attached to this declaration
1455 /// (comments preceding the declaration's first token, since the
1456 /// previous declaration or file start). Empty by default.
1457 pub leading_trivia: Vec<crate::tokens::Trivia>,
1458 /// Fase 14.b — trailing comment trivia (same line as the
1459 /// declaration's last effective token). Empty by default.
1460 pub trailing_trivia: Vec<crate::tokens::Trivia>,
1461}
1462
1463// ── Epistemic ────────────────────────────────────────────────────────────────
1464
1465#[derive(Debug)]
1466pub struct EpistemicBlock {
1467 pub mode: String,
1468 pub body: Vec<Declaration>,
1469 pub loc: Loc,
1470 /// Fase 14.b — leading comment trivia attached to this declaration
1471 /// (comments preceding the declaration's first token, since the
1472 /// previous declaration or file start). Empty by default.
1473 pub leading_trivia: Vec<crate::tokens::Trivia>,
1474 /// Fase 14.b — trailing comment trivia (same line as the
1475 /// declaration's last effective token). Empty by default.
1476 pub trailing_trivia: Vec<crate::tokens::Trivia>,
1477}
1478
1479// ── §Fase 70.a — the pure expression engine (`Expr`) ─────────────────────────
1480
1481/// A pure, total expression in AXON's closed-catalog expression sublanguage
1482/// (§Fase 70). Evaluates to a value with no side effects, no I/O, no recursion
1483/// and no unbounded loops — so it is decidable and const-foldable. Mounted as
1484/// the condition of an `if` (and, in later sub-fases, `let` values + `where:`
1485/// predicates). Field/index access and the builtin catalog land in §70.c/d.
1486#[derive(Debug, Clone)]
1487pub enum Expr {
1488 /// A typed literal (`42`, `3.14`, `true`, `"hello"`).
1489 Lit(ExprLit),
1490 /// A reference to a binding or dotted path (`x`, `User.tier`).
1491 Ref(String),
1492 /// A unary operation (`-x`, `not x`).
1493 Unary(UnOp, Box<Expr>),
1494 /// A binary operation (`a + b`, `a >= b`, `a and b`).
1495 Binary(BinOp, Box<Expr>, Box<Expr>),
1496 /// §Fase 70.c — a closed-catalog builtin call. `args[0]` is the receiver
1497 /// (the value before the `.`); any further entries are the call arguments.
1498 /// E.g. `recent.length` → `Call(Length, [Ref("recent")])`,
1499 /// `name.starts_with("Dr")` → `Call(StartsWith, [Ref("name"), Lit(Str)])`.
1500 Call(Builtin, Vec<Expr>),
1501 /// §Fase 70.d — field access on a non-reference base (`items[0].name`,
1502 /// `(expr).field`). A plain dotted path stays a `Ref` (`a.b.c`) for
1503 /// back-compat; this node is the structured form the JSONB SQL lowering
1504 /// (deferred §73) consumes. The `String` is the field name.
1505 Field(Box<Expr>, String),
1506 /// §Fase 70.d — index access `base[index]` (array element / string char).
1507 Index(Box<Expr>, Box<Expr>),
1508}
1509
1510/// The closed catalog of pure builtins (§Fase 70.c). All are total + pure.
1511/// Collection/string predicates only; the predicate-taking folds (`any`/`all`/
1512/// `none`) need lambdas and are deferred, as are `sum`/`min`/`max` and `in`/`??`.
1513#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1514pub enum Builtin {
1515 /// `.length` — collection element count, or character count of a string.
1516 Length,
1517 /// `.count` — alias of `length`.
1518 Count,
1519 /// `.is_empty` — `length == 0`.
1520 IsEmpty,
1521 /// `.is_null` — the value is absent / empty / `null`.
1522 IsNull,
1523 /// `.contains(x)` — array membership, or string substring.
1524 Contains,
1525 /// `.starts_with(s)` — string prefix test.
1526 StartsWith,
1527 /// `.ends_with(s)` — string suffix test.
1528 EndsWith,
1529}
1530
1531impl Builtin {
1532 /// The number of arguments AFTER the receiver (`args[0]`).
1533 pub fn extra_arity(self) -> usize {
1534 match self {
1535 Builtin::Length | Builtin::Count | Builtin::IsEmpty | Builtin::IsNull => 0,
1536 Builtin::Contains | Builtin::StartsWith | Builtin::EndsWith => 1,
1537 }
1538 }
1539
1540 /// The surface name (after the `.`).
1541 pub fn surface(self) -> &'static str {
1542 match self {
1543 Builtin::Length => "length",
1544 Builtin::Count => "count",
1545 Builtin::IsEmpty => "is_empty",
1546 Builtin::IsNull => "is_null",
1547 Builtin::Contains => "contains",
1548 Builtin::StartsWith => "starts_with",
1549 Builtin::EndsWith => "ends_with",
1550 }
1551 }
1552
1553 /// Resolve a name (after a `.`) to a builtin, or `None` if it is an ordinary
1554 /// field / path segment.
1555 pub fn from_name(name: &str) -> Option<Builtin> {
1556 Some(match name {
1557 "length" => Builtin::Length,
1558 "count" => Builtin::Count,
1559 "is_empty" => Builtin::IsEmpty,
1560 "is_null" => Builtin::IsNull,
1561 "contains" => Builtin::Contains,
1562 "starts_with" => Builtin::StartsWith,
1563 "ends_with" => Builtin::EndsWith,
1564 _ => return None,
1565 })
1566 }
1567}
1568
1569/// A literal value inside an [`Expr`]. The lexical form is preserved enough to
1570/// round-trip; the runtime evaluator (§70.f) coerces across these per the
1571/// existing string-runtime discipline.
1572#[derive(Debug, Clone)]
1573pub enum ExprLit {
1574 Int(i64),
1575 Float(f64),
1576 Bool(bool),
1577 Str(String),
1578}
1579
1580/// Unary operators (closed catalog).
1581#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1582pub enum UnOp {
1583 /// Arithmetic negation `-`.
1584 Neg,
1585 /// Boolean negation `not`.
1586 Not,
1587}
1588
1589/// Binary operators (closed catalog). Precedence is encoded in the Pratt parser.
1590#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1591pub enum BinOp {
1592 Add,
1593 Sub,
1594 Mul,
1595 Div,
1596 Mod,
1597 Eq,
1598 Ne,
1599 Lt,
1600 Le,
1601 Gt,
1602 Ge,
1603 And,
1604 Or,
1605}
1606
1607// ── Control flow ─────────────────────────────────────────────────────────────
1608
1609#[derive(Debug)]
1610pub struct ConditionalNode {
1611 pub condition: String,
1612 pub comparison_op: String,
1613 pub comparison_value: String,
1614 pub then_body: Vec<FlowStep>,
1615 pub else_body: Vec<FlowStep>,
1616 pub conditions: Vec<(String, String, String)>,
1617 pub conjunctor: String,
1618 /// §Fase 70.a — the parsed expression form of the condition. `None` when
1619 /// the condition fits the legacy `(condition, op, value)` + `or` shape
1620 /// (then the legacy fields drive evaluation, byte-identical to pre-§70);
1621 /// `Some` only for the richer forms the legacy triple cannot express
1622 /// (`and`, `not`, arithmetic, parentheses, nesting), which the runtime
1623 /// evaluates via the pure expression evaluator. Zero IR drift for existing
1624 /// programs.
1625 pub cond: Option<Expr>,
1626 pub loc: Loc,
1627}
1628
1629#[derive(Debug)]
1630pub struct ForInStatement {
1631 pub variable: String,
1632 pub iterable: String,
1633 pub body: Vec<FlowStep>,
1634 pub loc: Loc,
1635}
1636
1637#[derive(Debug)]
1638pub struct LetStatement {
1639 pub identifier: String,
1640 pub value_expr: String,
1641 /// Fase 17.a — preserves the parser's tokenization intent so the
1642 /// runtime dispatcher can distinguish a quoted literal from a
1643 /// dotted-identifier reference. One of "literal", "reference",
1644 /// "expression". Defaults to "literal" so any pre-Fase-17 caller
1645 /// that constructs a LetStatement directly behaves as a literal.
1646 pub value_kind: String,
1647 /// §Fase 51.c.3 — optional type annotation `let x: <TypeExpr> = …`.
1648 /// `None` for the bare `let x = …` form (all pre-51.c.3 lets). Inside a
1649 /// `quant` block the Continuous Type Invariant inspects this to enforce the
1650 /// continuous-carrier discipline (`DensityMatrix[D]` D=2ⁿ; reject discrete
1651 /// conversational types). Carries the typed encoder-boundary contract.
1652 pub type_annotation: Option<TypeExpr>,
1653 /// §Fase 70.f — the parsed expression form of the value, present only when
1654 /// `value_kind == "expression"` (`let total = price * qty + tax`). The
1655 /// runtime evaluates it via the pure expression evaluator instead of the
1656 /// pre-§70 behaviour (which treated an expression as an opaque literal
1657 /// string). `None` for literal / reference / list values (byte-identical to
1658 /// pre-§70.f).
1659 pub value_ast: Option<Expr>,
1660 pub loc: Loc,
1661 /// Fase 14.b — leading comment trivia attached to this declaration
1662 /// (comments preceding the declaration's first token, since the
1663 /// previous declaration or file start). Empty by default.
1664 pub leading_trivia: Vec<crate::tokens::Trivia>,
1665 /// Fase 14.b — trailing comment trivia (same line as the
1666 /// declaration's last effective token). Empty by default.
1667 pub trailing_trivia: Vec<crate::tokens::Trivia>,
1668}
1669
1670#[derive(Debug)]
1671pub struct ReturnStatement {
1672 pub value_expr: String,
1673 pub loc: Loc,
1674}
1675
1676/// §Fase 51.d.2 — `yield <expr>` measurement point inside a `quant` block.
1677#[derive(Debug)]
1678pub struct YieldStatement {
1679 /// The measured expression (the structural hypothesis / density-matrix
1680 /// surrogate collapsed out of the Hilbert-space scope).
1681 pub value_expr: String,
1682 /// Tokenization intent (`literal` / `reference` / `expression`), mirroring
1683 /// `LetStatement.value_kind` so the runtime resolves the yielded value.
1684 pub value_kind: String,
1685 pub loc: Loc,
1686}
1687
1688/// Fase 19.e — `break` keyword inside a for-in body. Carries no
1689/// payload; the runner translates it into a sentinel that
1690/// terminates the loop. Parser scope check (`loop_depth`)
1691/// guarantees this only appears inside a for-in body.
1692#[derive(Debug)]
1693pub struct BreakStatement {
1694 pub loc: Loc,
1695}
1696
1697/// Fase 19.e — `continue` keyword inside a for-in body. Same
1698/// shape as ``BreakStatement``; the runner uses a different
1699/// sentinel type to distinguish loop-exit from iteration-skip.
1700#[derive(Debug)]
1701pub struct ContinueStatement {
1702 pub loc: Loc,
1703}
1704
1705// ── Lambda Data (ΛD) — Epistemic State Vectors ─────────────────────────────
1706
1707/// Top-level ΛD definition: ψ = ⟨T, V, E⟩ where E = ⟨c, τ, ρ, δ⟩.
1708#[derive(Debug)]
1709pub struct LambdaDataDefinition {
1710 pub name: String,
1711 pub ontology: String, // T ∈ O — ontological type
1712 pub certainty: f64, // c ∈ [0,1] — epistemic certainty scalar
1713 pub temporal_frame_start: String, // τ_start
1714 pub temporal_frame_end: String, // τ_end
1715 pub provenance: String, // ρ ∈ EntityRef — causal origin
1716 pub derivation: String, // δ ∈ Δ — see derivation catalogue (raw, derived, inferred, aggregated, transformed)
1717 pub loc: Loc,
1718 /// Fase 14.b — leading comment trivia attached to this declaration
1719 /// (comments preceding the declaration's first token, since the
1720 /// previous declaration or file start). Empty by default.
1721 pub leading_trivia: Vec<crate::tokens::Trivia>,
1722 /// Fase 14.b — trailing comment trivia (same line as the
1723 /// declaration's last effective token). Empty by default.
1724 pub trailing_trivia: Vec<crate::tokens::Trivia>,
1725}
1726
1727/// In-flow ΛD application: binds epistemic state vector to a data target.
1728#[derive(Debug)]
1729pub struct LambdaDataApplyNode {
1730 pub lambda_data_name: String, // reference to LambdaDataDefinition
1731 pub target: String, // expression to bind
1732 pub output_type: String, // result type after epistemic binding
1733 pub loc: Loc,
1734}
1735
1736// ── Tier 2 flow step nodes ──────────────────────────────────────────────────
1737
1738#[derive(Debug)]
1739pub struct ProbeStep {
1740 pub target: String,
1741 pub loc: Loc,
1742}
1743#[derive(Debug)]
1744pub struct ReasonStep {
1745 pub strategy: String,
1746 pub target: String,
1747 pub loc: Loc,
1748}
1749#[derive(Debug)]
1750pub struct ValidateStep {
1751 pub target: String,
1752 pub rule: String,
1753 pub loc: Loc,
1754}
1755#[derive(Debug)]
1756pub struct RefineStep {
1757 pub target: String,
1758 pub strategy: String,
1759 pub loc: Loc,
1760}
1761#[derive(Debug)]
1762pub struct WeaveStep {
1763 pub sources: Vec<String>,
1764 pub target: String,
1765 pub format_type: String,
1766 pub priority: Vec<String>,
1767 pub style: String,
1768 pub loc: Loc,
1769}
1770/// §Fase 58.b — the closed catalog of `use <Tool>` argument forms. The
1771/// invocation surfaces are mutually exclusive, so a sum type models them
1772/// exactly (no ambiguous dual-empty state). NOTE: `apply: Tool given: <struct>`
1773/// (the splat form) is NOT here — it rides `StepNode.apply_ref` and is
1774/// validated against the tool schema in §58.d, not parsed as a `use`.
1775#[derive(Debug, Clone, PartialEq)]
1776pub enum UseArgs {
1777 /// `use Tool on "${arg}"` / `use Tool on query` — the §54.b single
1778 /// positional argument. D5 back-compat: behaves byte-identically to the
1779 /// pre-58 `argument: String` (empty string when no `on` clause).
1780 LegacyPositional(String),
1781 /// `use Tool(query = "${q}", max_results = 5)` — D2 canonical multi-field
1782 /// keyword args. Each entry is `(name, value, value_kind)`: `value` is the
1783 /// expression STRING (the frontend has no structured `Expr`; mirrors
1784 /// `argument` / `parse_argument_list`); `value_kind` is `"literal"` or
1785 /// `"reference"` — the §Fase 60 classification from `parse_let_atom`, so the
1786 /// runtime resolves a bare identifier / `Step.output` as a binding lookup
1787 /// (like `let`) instead of passing the name literally. The type-checker
1788 /// (§58.d + §60.c) validates each entry against the tool's declared input
1789 /// schema (W2 / CT-2 caller blame) and references against their source.
1790 Named(Vec<(String, String, String)>),
1791}
1792
1793impl UseArgs {
1794 /// §58.b transitional — the legacy single-arg string for the IR `argument`
1795 /// field (still `String` until §58.c carries structured named args).
1796 /// `Named` projects an empty argument here; the type-checker validates
1797 /// named args from the AST, and §58.c/e wire their structured dispatch.
1798 pub fn legacy_argument(&self) -> String {
1799 match self {
1800 UseArgs::LegacyPositional(s) => s.clone(),
1801 UseArgs::Named(_) => String::new(),
1802 }
1803 }
1804}
1805
1806#[derive(Debug)]
1807pub struct UseToolStep {
1808 pub tool_name: String,
1809 pub args: UseArgs,
1810 pub loc: Loc,
1811}
1812#[derive(Debug)]
1813pub struct RememberStep {
1814 pub expression: String,
1815 pub memory_target: String,
1816 pub loc: Loc,
1817}
1818#[derive(Debug)]
1819pub struct RecallStep {
1820 pub query: String,
1821 pub memory_source: String,
1822 pub loc: Loc,
1823}
1824#[derive(Debug)]
1825pub struct ParBlock {
1826 /// §Fase 65 — the concurrent branches. Each top-level statement inside
1827 /// `par { … }` is one branch (a single-statement body); they execute
1828 /// concurrently at runtime. Empty for a `par {}` with no statements
1829 /// (degenerate no-op). Before §65 this was payload-free (the branches were
1830 /// skipped at parse time), so `par` ran as a stub.
1831 pub branches: Vec<Vec<FlowStep>>,
1832 pub loc: Loc,
1833}
1834#[derive(Debug)]
1835pub struct HibernateStep {
1836 pub event_name: String,
1837 pub timeout: String,
1838 pub loc: Loc,
1839}
1840#[derive(Debug)]
1841pub struct DeliberateBlock {
1842 pub loc: Loc,
1843}
1844#[derive(Debug)]
1845pub struct ConsensusBlock {
1846 pub loc: Loc,
1847}
1848#[derive(Debug)]
1849pub struct ForgeBlock {
1850 pub loc: Loc,
1851}
1852#[derive(Debug)]
1853pub struct FocusStep {
1854 pub expression: String,
1855 pub loc: Loc,
1856}
1857#[derive(Debug)]
1858pub struct AssociateStep {
1859 pub left: String,
1860 pub right: String,
1861 pub using_field: String,
1862 pub loc: Loc,
1863}
1864#[derive(Debug)]
1865pub struct AggregateStep {
1866 pub target: String,
1867 pub group_by: Vec<String>,
1868 pub alias: String,
1869 pub loc: Loc,
1870}
1871#[derive(Debug)]
1872pub struct ExploreStepNode {
1873 pub target: String,
1874 pub limit: Option<i64>,
1875 pub loc: Loc,
1876}
1877#[derive(Debug)]
1878pub struct IngestStep {
1879 pub source: String,
1880 pub target: String,
1881 pub loc: Loc,
1882}
1883#[derive(Debug)]
1884pub struct ShieldApplyStep {
1885 pub shield_name: String,
1886 pub target: String,
1887 pub output_type: String,
1888 pub loc: Loc,
1889}
1890#[derive(Debug)]
1891pub struct StreamBlock {
1892 pub loc: Loc,
1893}
1894#[derive(Debug)]
1895pub struct NavigateStep {
1896 pub pix_name: String,
1897 pub corpus_name: String,
1898 pub query_expr: String,
1899 pub trail_enabled: bool,
1900 pub output_name: String,
1901 /// §Fase 63.B — for MDN corpus-graph navigation: the seed document `from:`
1902 /// to start the ε-informative traversal. Empty for PIX tree navigation.
1903 pub seed: String,
1904 /// §Fase 63.B — for MDN: the `budget:` (max documents). `None` = default.
1905 pub budget: Option<i64>,
1906 /// §Fase 66 (Q2) — optional column-scope filter (`where:`) for a
1907 /// `corpus from axonstore`. A raw filter expr (same shape as `retrieve …
1908 /// where`) pushed to the SELECT sourcing the corpus rows, so an adopter
1909 /// multiplexing sub-tenants in one axon-tenant via a column can scope the
1910 /// MDN graph to a single sub-tenant. Empty = no column filter (RLS-only).
1911 pub where_expr: String,
1912 pub loc: Loc,
1913}
1914#[derive(Debug)]
1915pub struct DrillStep {
1916 pub pix_name: String,
1917 pub subtree_path: String,
1918 pub query_expr: String,
1919 pub output_name: String,
1920 pub loc: Loc,
1921}
1922#[derive(Debug)]
1923pub struct TrailStep {
1924 pub navigate_ref: String,
1925 pub loc: Loc,
1926}
1927#[derive(Debug)]
1928pub struct CorroborateStep {
1929 pub navigate_ref: String,
1930 pub output_name: String,
1931 pub loc: Loc,
1932}
1933#[derive(Debug)]
1934pub struct OtsApplyStep {
1935 pub ots_name: String,
1936 pub target: String,
1937 pub output_type: String,
1938 pub loc: Loc,
1939}
1940#[derive(Debug)]
1941pub struct MandateApplyStep {
1942 pub mandate_name: String,
1943 pub target: String,
1944 pub output_type: String,
1945 pub loc: Loc,
1946}
1947#[derive(Debug)]
1948pub struct ComputeApplyStep {
1949 pub compute_name: String,
1950 pub arguments: Vec<String>,
1951 pub output_name: String,
1952 pub loc: Loc,
1953}
1954/// §λ-L-E Fase 13 D4 — dual-mode listen.
1955///
1956/// `channel_is_ref = true` ⇒ `channel` is the name of a declared
1957/// `ChannelDefinition` (canonical Fase 13 form). `false` ⇒ legacy
1958/// string topic (deprecated; type checker emits a warning).
1959#[derive(Debug)]
1960pub struct ListenStep {
1961 pub channel: String,
1962 pub channel_is_ref: bool,
1963 pub event_alias: String,
1964 /// §Fase 52.a — the handler body: real flow-steps executed on each event /
1965 /// scheduled tick. Pre-§52.a the `{ … }` block was `skip_braced_block`'d
1966 /// (the listener was inert); now it is parsed so a `daemon` can run logic
1967 /// (e.g. `run <Flow>(…)`) per trigger. Empty for a bodyless `listen`.
1968 pub body: Vec<FlowStep>,
1969 pub loc: Loc,
1970}
1971#[derive(Debug)]
1972pub struct DaemonStepNode {
1973 pub daemon_ref: String,
1974 pub loc: Loc,
1975}
1976#[derive(Debug)]
1977pub struct PersistStep {
1978 pub store_name: String,
1979 /// §Fase 35.o — the `{ col: value }` field block. Empty when the
1980 /// step is written without a block (`persist <store>`), in which
1981 /// case the runtime falls back to writing the flow's user
1982 /// bindings as a row (backward-compatible with v1.30.0).
1983 pub fields: Vec<(String, String)>,
1984 pub loc: Loc,
1985}
1986#[derive(Debug)]
1987pub struct RetrieveStep {
1988 pub store_name: String,
1989 pub where_expr: String,
1990 pub alias: String,
1991 /// §Fase 67.b — optional `order_by:` clause: a closed
1992 /// comma-separated list of `column [asc|desc]` (same identifier
1993 /// discipline as `where:` columns — no injection). Empty = no
1994 /// ordering. Raw string, parsed + validated by the runtime
1995 /// (`filter::render_bounds`) and at `axon check` (§38.d `axon-T807`).
1996 pub order_by: String,
1997 /// §Fase 67.b — optional `limit:` clause: a `u32` literal OR a
1998 /// `${binding}` resolved to a `u32` at runtime. Empty = no limit.
1999 /// Raw string (`"100"` or `"${max}"`), validated at `axon check`
2000 /// (§38.d `axon-T808`).
2001 pub limit_expr: String,
2002 pub loc: Loc,
2003}
2004#[derive(Debug)]
2005pub struct MutateStep {
2006 pub store_name: String,
2007 pub where_expr: String,
2008 /// §Fase 35.p — the `{ col: value }` SET assignments. Empty when
2009 /// the step declares no columns, in which case the runtime falls
2010 /// back to writing the flow's user bindings as the `SET` clause
2011 /// (backward-compatible with v1.31.0).
2012 pub fields: Vec<(String, String)>,
2013 pub loc: Loc,
2014}
2015#[derive(Debug)]
2016pub struct PurgeStep {
2017 pub store_name: String,
2018 pub where_expr: String,
2019 pub loc: Loc,
2020}
2021#[derive(Debug)]
2022pub struct TransactBlock {
2023 pub loc: Loc,
2024}
2025
2026/// §Fase 51.a — the `quant` cognitive primitive block surface
2027/// (`docs/papers/paper_primitiva_quant.md`; enterprise §Fase 51).
2028///
2029/// `quant` projects an MEK semantic tensor into a complex Hilbert space,
2030/// evolves it under a variational / kernel-feature map, and collapses back to
2031/// classical silicon. The attribute header is OPTIONAL — the bare `quant { … }`
2032/// form (the paper's example) leaves every attribute defaulted. The richer form
2033/// `quant(encoding: amplitude, observable: M, qubits: 10, depth: 4,
2034/// bandwidth: 0.5, backend: quant_sim) { … }` pins the encoding scheme (D2),
2035/// the Pauli-sum observable (D5), the register width / circuit depth, the
2036/// projected-kernel bandwidth γ (D7), and the algebraic-effect backend (D1/D9).
2037///
2038/// §51.a ships the SURFACE only. The Continuous Type Invariant over `body`
2039/// (§51.b), the typed continuous grammar incl. typed `let` + `Observable`
2040/// (§51.c), and the `quant_sim`/`qpu_native` effect injection + `yield`
2041/// measurement point (§51.d) land in subsequent sub-fases.
2042#[derive(Debug, Default)]
2043pub struct QuantBlock {
2044 /// `encoding:` — `amplitude` (default) or `angle` (shallow). `None` = the
2045 /// compiler default (amplitude). Carried as the surface spelling; §51.c
2046 /// validates against the closed scheme set.
2047 pub encoding: Option<String>,
2048 /// `observable:` — the name of a declared `Observable` (Pauli-sum, D5).
2049 /// `None` if unspecified (§51.c resolves + Hermiticity-checks it).
2050 pub observable: Option<String>,
2051 /// `qubits:` — the register width n (D = 2ⁿ). `None` = inferred from the
2052 /// encoded tensor dimensionality. The OSS reference backend caps n ≤ 10
2053 /// (D1); that bound is enforced at §51.e, not here.
2054 pub qubits: Option<i64>,
2055 /// `depth:` — the variational circuit depth L. `None` = backend default.
2056 pub depth: Option<i64>,
2057 /// `bandwidth:` — the projected-quantum-kernel bandwidth γ (D7). `None` =
2058 /// backend default.
2059 pub bandwidth: Option<f64>,
2060 /// §Fase 69.c — `reupload:` L, the number of DATA RE-UPLOADING layers. `None`
2061 /// or `1` = no re-uploading (the data enters once → a quadratic form, provably
2062 /// classical for amplitude+Pauli, §69.b). `L ≥ 2` interleaves the data
2063 /// encoding with entangling layers L times — the ONLY provable escape from the
2064 /// quadratic bound (Havlíček-style; canonical with `encoding: angle`). The
2065 /// resulting kernel must still pass an Advantage Witness to be deployed
2066 /// claiming advantage (§69.a/b).
2067 pub reupload: Option<i64>,
2068 /// The algebraic-effect backend tag: `quant_sim` (default) or `qpu_native`
2069 /// (D1/D9). Stored as the bare backend name; §51.d injects the full
2070 /// `ots:backend:<tag>` effect into the enclosing flow's effect row.
2071 pub effect: String,
2072 /// The nested flow-body statements (parsed like `par` branches, so §51.b
2073 /// can apply the Continuous Type Invariant to real AST). Empty for an
2074 /// empty `quant {}`.
2075 pub body: Vec<FlowStep>,
2076 pub loc: Loc,
2077}
2078
2079/// §Fase 51.c.2 — one term `cₖ · Pₖ` of a Pauli-sum observable.
2080///
2081/// `coefficient` is a real scalar (parsed as `f64`); `pauli` is a Pauli string
2082/// over the closed alphabet `{I, X, Y, Z}` (one char per qubit), e.g. `"ZZ"` or
2083/// `"XI"`. A real linear combination of Pauli strings is **Hermitian by
2084/// construction** (each Pauli string is Hermitian; real-weighted sums preserve
2085/// Hermiticity), which is why the observable needs no separate Hermiticity check.
2086#[derive(Debug, Default, Clone)]
2087pub struct PauliTerm {
2088 pub coefficient: f64,
2089 pub pauli: String,
2090 pub loc: Loc,
2091}
2092
2093/// §Fase 51.c.2 — the `observable <Name> { qubits, term: cₖ·Pₖ … }` declaration
2094/// (paper §3.2; plan D5). A typed Pauli-sum `M = Σ cₖ Pₖ` that a `quant` block
2095/// measures the evolved state against. The type-checker validates the closed
2096/// `{I,X,Y,Z}` alphabet + equal term lengths + non-empty sum; Hermiticity is
2097/// guaranteed by construction (real coefficients).
2098#[derive(Debug, Default)]
2099pub struct ObservableDefinition {
2100 pub name: String,
2101 /// `qubits: n` — the register width every Pauli string must span. `None`
2102 /// = inferred from the (equal) term lengths.
2103 pub qubits: Option<i64>,
2104 pub terms: Vec<PauliTerm>,
2105 pub loc: Loc,
2106 /// Fase 14.b — leading comment trivia.
2107 pub leading_trivia: Vec<crate::tokens::Trivia>,
2108 /// Fase 14.b — trailing comment trivia.
2109 pub trailing_trivia: Vec<crate::tokens::Trivia>,
2110}
2111
2112/// §Fase 69.a — `witness <Name> { claim: <ref> against: <baseline>
2113/// metric: <metric> threshold: <ε> data: <source> }`. The Advantage-Witness
2114/// proof obligation. The compiler proves it WELL-FORMED (§69.a, `axon-E0790`);
2115/// the advantage VALUE is computed on real `data` at deploy/runtime and carried
2116/// as a verdict (§69.b+). Fields are order-free `key: value` pairs.
2117#[derive(Debug)]
2118pub struct WitnessDefinition {
2119 pub name: String,
2120 /// The primitive instance whose advantage is claimed (e.g. an `observable` /
2121 /// `corpus` name, or a quant kernel reference).
2122 pub claim: String,
2123 /// The cheaper alternative the claim must beat (a closed-catalog baseline
2124 /// like `cosine` / `flat_retrieval` / `single_shot`, or a reference).
2125 pub baseline: String,
2126 /// How advantage is measured — a closed-catalog metric (`geometric_difference`,
2127 /// `kernel_target_alignment`, `ranking_lift`, `outcome_lift`).
2128 pub metric: String,
2129 /// The minimum advantage that justifies the cost (ε ≥ 0).
2130 pub threshold: f64,
2131 /// The real-data source the witness is evaluated on (a ref to an axonstore /
2132 /// corpus / labelled set). Required — advantage cannot be claimed in the abstract.
2133 pub data: String,
2134 pub loc: Loc,
2135 pub leading_trivia: Vec<crate::tokens::Trivia>,
2136 pub trailing_trivia: Vec<crate::tokens::Trivia>,
2137}
2138
2139// ── §λ-L-E Fase 13 — Mobile Typed Channels ──────────────────────────────────
2140
2141/// `channel Name { message: T, qos: X, lifetime: ℓ, persistence: π, shield: σ }`.
2142///
2143/// First-class affine resource carrying a typed message. Direct port
2144/// of `axon.compiler.ast_nodes.ChannelDefinition`. `message` retains
2145/// the surface spelling (e.g. `"Order"` or `"Channel<Order>"`) so the
2146/// type checker can resolve nested mobility (paper §3.3).
2147#[derive(Debug)]
2148pub struct ChannelDefinition {
2149 pub name: String,
2150 pub message: String, // type name OR "Channel<T>" for second-order
2151 pub qos: String, // at_most_once | at_least_once | exactly_once | broadcast | queue
2152 pub lifetime: String, // linear | affine | persistent (D1 default: affine)
2153 pub persistence: String, // ephemeral | persistent_axonstore
2154 pub shield_ref: String, // optional σ-shield gate for publish (D8)
2155 pub loc: Loc,
2156 /// Fase 14.b — leading comment trivia attached to this declaration
2157 /// (comments preceding the declaration's first token, since the
2158 /// previous declaration or file start). Empty by default.
2159 pub leading_trivia: Vec<crate::tokens::Trivia>,
2160 /// Fase 14.b — trailing comment trivia (same line as the
2161 /// declaration's last effective token). Empty by default.
2162 pub trailing_trivia: Vec<crate::tokens::Trivia>,
2163}
2164
2165/// `emit ChannelName(value_ref)` — π-calculus output prefix `c⟨v⟩.P`.
2166///
2167/// Direct port of `axon.compiler.ast_nodes.EmitStatement`. Handles
2168/// both Chan-Output (scalar payload) and Chan-Mobility (channel-as-
2169/// value); the type checker dispatches based on whether `value_ref`
2170/// resolves to a `ChannelDefinition`.
2171#[derive(Debug)]
2172pub struct EmitStatement {
2173 pub channel_ref: String,
2174 pub value_ref: String,
2175 pub loc: Loc,
2176}
2177
2178/// `publish ChannelName within ShieldName` — capability extrusion.
2179///
2180/// Paper §4.3 (Publish-Ext) materialized as a flow step. The `within
2181/// <Shield>` clause is mandatory (D8) — the parser rejects bare
2182/// `publish C`, the type checker rejects publishes whose shield does
2183/// not cover κ(message_type) (Fase 6.1 + paper §3.4).
2184#[derive(Debug)]
2185pub struct PublishStatement {
2186 pub channel_ref: String,
2187 pub shield_ref: String,
2188 pub loc: Loc,
2189}
2190
2191/// `discover ChannelName as alias` — dual of publish.
2192///
2193/// Imports a previously-published handle into a fresh affine local
2194/// binding. The `as <alias>` is mandatory; the type checker rejects
2195/// discovery of channels that were never declared with `shield_ref`.
2196#[derive(Debug)]
2197pub struct DiscoverStatement {
2198 pub capability_ref: String,
2199 pub alias: String,
2200 pub loc: Loc,
2201}