//! The closed registry of every primitive AXON exposes as a named
//! language construct.
//!
//! # Why this exists
//!
//! Before §Fase 6.a, the answer to "what primitives does AXON have?"
//! was scattered across the parser dispatch table, the type checker's
//! validation arms, the ℰMCP knowledge corpus, and a half-dozen
//! markdown reference pages. There was no machine-readable canonical
//! list. A new primitive landing in the parser could go undocumented
//! for a release cycle (or three) before someone noticed.
//!
//! `PRIMITIVE_REGISTRY` closes that gap. It is **the** single source
//! of truth for the closed set of primitive names — consumed by:
//!
//! - **ℰMCP coverage gate** — tests under `axon-emcp` that assert
//! every `Documented` entry has a markdown body in the corpus, AND
//! that every markdown body has a `Documented` entry here. The
//! closed set is enforced on BOTH sides; the corpus cannot drift.
//! - **`axon-emcp scaffold-primitive` CLI** — reads the entry, stamps
//! a markdown skeleton with frontmatter pre-populated from the
//! registry. Reduces "add new primitive doc" to a 30-second task.
//! - **Future LSP completions / docs site / `axon.primitives()` tool**
//! — any consumer that needs a deterministic catalogue iterates
//! over `PRIMITIVE_REGISTRY` directly.
//!
//! # Discipline
//!
//! When a new primitive lands in the parser, the SAME PR adds the
//! entry here AND the markdown doc under
//! `src/knowledge/primitives/<name>.md`. The two are atomic. No
//! orphan parser productions, no orphan corpus entries.
//!
//! For primitives that exist in the parser today but haven't been
//! documented yet, the entry lives here with `doc_status: Pending`.
//! The §Fase 6.b–d roadmap flips each `Pending` → `Documented` as
//! its `.md` lands.
/// One primitive's **shallow** metadata. Deep documentation (grammar,
/// fields, runtime behaviour, examples, see-also) lives in the
/// markdown corpus under `src/knowledge/primitives/<name>.md` —
/// surfaced by the ℰMCP catalogue loader via
/// `axon.primitive_doc(<name>)`. The registry carries only what every
/// consumer needs to identify and classify the primitive.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct PrimitiveInfo {
/// Canonical name as it appears in source (`persona`, `flow`,
/// `socket`, `axonendpoint`, …). Doubles as the markdown file
/// stem (`<name>.md`) and the URL slug for
/// `axon://primitives/{name}`.
pub name: &'static str,
/// Closed-catalogue family. Drives the
/// `axon.primitives(filter)` facet and the `category:` field of
/// the corpus frontmatter. Valid values: `"cognition"`,
/// `"cognitive_io"`, `"data_plane"`, `"session_types"`, `"wire"`,
/// `"operators"`. Validated against the ℰMCP `Category` enum at
/// catalog-load time — a category string here that does not
/// deserialize into a `Category` is a coverage-gate failure.
pub category: &'static str,
/// `true` ⇒ this primitive is a top-level declaration (it stands
/// alone at the program root). `false` ⇒ it only appears nested
/// inside another construct (e.g. `step` inside a `flow`).
pub top_level: bool,
/// The cycle that introduced this primitive (e.g. `"v0.1.0"`,
/// `"Fase 41.b (v2.3.0)"`). Surfaced verbatim in the corpus
/// frontmatter `since:` field.
pub since: &'static str,
/// One-line summary used by `axon.primitives()` listings and by
/// the `axon-emcp scaffold-primitive` CLI when stamping a new
/// doc's frontmatter. Should fit on one line, end with a period.
pub summary: &'static str,
/// Whether the primitive has a corresponding markdown doc in the
/// ℰMCP corpus today. The §Fase 6 plan ships every primitive's
/// doc in tiers (6.b, 6.c, 6.d); entries flip from `Pending` to
/// `Documented` as their `.md` lands.
pub doc_status: DocStatus,
}
/// Coverage status for one primitive's documentation. The coverage
/// gate in `axon-emcp` asserts that:
///
/// 1. every `Documented` entry has a `.md` under
/// `src/knowledge/primitives/`;
/// 2. every `.md` under that directory has a `Documented` entry here.
///
/// `Pending` entries are visible in the registry (so the catalogue
/// is honestly complete) but the coverage gate does NOT require
/// their docs yet — that is the §Fase 6.b–d roadmap.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum DocStatus {
/// Documented — has a markdown body in the corpus + passes the
/// drift-gated canonical-program test where applicable. The
/// coverage gate requires `<name>.md` to exist.
Documented,
/// Pending — the primitive exists in the language but its
/// markdown doc has not landed yet. The §Fase 6 roadmap names
/// the cycle (6.b / 6.c / 6.d) that closes the gap.
Pending,
}
impl DocStatus {
/// Stringify for diagnostics. Mirrors the `serde` rename rule
/// the ℰMCP catalogue uses for its own enums.
pub fn as_str(self) -> &'static str {
match self {
DocStatus::Documented => "documented",
DocStatus::Pending => "pending",
}
}
}
/// The closed catalogue — **56 primitives**, ordered by category
/// for readability. Consumers must not depend on declaration order;
/// they iterate and filter.
///
/// Section breakdown:
/// - Cognition (15) — what an LLM does.
/// - Cognitive I/O (10) — resources + reconciliation + self-defence.
/// - Data plane (7) — typed persistence + provenance.
/// - Session types (4) — §Fase 41 algebra (+ §80 upstream/voice).
/// - Wire (6) — actor + transport surfaces.
/// - Operators (10) — specialised cognitive transforms (incl. §51 quant/observable).
///
/// Tier 0 — Documented as of §Fase 5 (7): `persona`, `flow`, `step`,
/// `anchor`, `tool`, `reason`, `socket`.
///
/// Tier 1 / 2 / 3 — Pending (40), landing in §Fase 6.b / 6.c / 6.d.
pub const PRIMITIVE_REGISTRY: &[PrimitiveInfo] = &[
// ── Cognition ─────────────────────────────────────────────────────
PrimitiveInfo {
name: "persona",
category: "cognition",
top_level: true,
since: "v0.1.0",
summary: "Declares the identity, expertise, and refusal posture an agent adopts when executing a flow.",
doc_status: DocStatus::Documented,
},
PrimitiveInfo {
name: "context",
category: "cognition",
top_level: true,
since: "v0.1.0",
summary: "Declares the conversational frame — memory scope, depth, max tokens, temperature — a flow operates within.",
doc_status: DocStatus::Documented,
},
PrimitiveInfo {
name: "flow",
category: "cognition",
top_level: true,
since: "v0.1.0",
summary: "The orchestration primitive — a typed, ordered composition of cognitive steps with parameters and a return type.",
doc_status: DocStatus::Documented,
},
PrimitiveInfo {
name: "anchor",
category: "cognition",
top_level: true,
since: "v0.1.0",
summary: "A typed grounding constraint — declares the conditions a flow's outputs MUST satisfy, with a structured violation policy.",
doc_status: DocStatus::Documented,
},
PrimitiveInfo {
name: "tool",
category: "cognition",
top_level: true,
since: "v0.1.0",
summary: "A declarative binding for an external capability (search, web fetch, code interpreter, …) callable from within a flow.",
doc_status: DocStatus::Documented,
},
PrimitiveInfo {
name: "intent",
category: "cognition",
top_level: true,
since: "v0.1.0",
summary: "A declarative target outcome — what the flow is trying to achieve, separately from how it gets there.",
doc_status: DocStatus::Documented,
},
PrimitiveInfo {
name: "memory",
category: "cognition",
top_level: true,
since: "v0.1.0",
summary: "Declares a typed memory store — session, persistent, vector — for cross-step state with retrieval + decay semantics.",
doc_status: DocStatus::Documented,
},
PrimitiveInfo {
name: "agent",
category: "cognition",
top_level: true,
since: "Fase 18",
summary: "An orchestrated cognitive entity — composes personas, tools, contexts under a coordination strategy.",
doc_status: DocStatus::Documented,
},
PrimitiveInfo {
name: "run",
category: "cognition",
top_level: true,
since: "v0.1.0",
summary: "Binds a flow to a persona, context, and anchors — the statement that EXECUTES a declared flow.",
doc_status: DocStatus::Documented,
},
PrimitiveInfo {
name: "step",
category: "cognition",
top_level: false,
since: "v0.1.0",
summary: "A single cognitive operation inside a flow — typed input (given), prompt (ask), and typed output.",
doc_status: DocStatus::Documented,
},
PrimitiveInfo {
name: "reason",
category: "cognition",
top_level: false,
since: "v0.1.0",
summary: "An explicit-reasoning operation — declares HOW the model should think (chain-of-thought, debate, …).",
doc_status: DocStatus::Documented,
},
PrimitiveInfo {
name: "probe",
category: "cognition",
top_level: false,
since: "v0.1.0",
summary: "A diagnostic / probing operation inside a step — emits observations without changing the trajectory.",
doc_status: DocStatus::Documented,
},
PrimitiveInfo {
name: "validate",
category: "cognition",
top_level: false,
since: "v0.1.0",
summary: "Enforces a typed invariant on a step's output before subsequent steps consume it.",
doc_status: DocStatus::Documented,
},
PrimitiveInfo {
name: "refine",
category: "cognition",
top_level: false,
since: "v0.1.0",
summary: "Iteratively improves a candidate output via a declared refinement strategy.",
doc_status: DocStatus::Documented,
},
PrimitiveInfo {
name: "weave",
category: "cognition",
top_level: false,
since: "v0.1.0",
summary: "Multi-thread reasoning braid — composes multiple sub-derivations into a unified conclusion.",
doc_status: DocStatus::Documented,
},
// ── Cognitive I/O ─────────────────────────────────────────────────
PrimitiveInfo {
name: "resource",
category: "cognitive_io",
top_level: true,
since: "Fase 6",
summary: "Declares an external compute/storage resource (database, S3, ML endpoint) consumable by a flow.",
doc_status: DocStatus::Documented,
},
PrimitiveInfo {
name: "fabric",
category: "cognitive_io",
top_level: true,
since: "Fase 6",
summary: "The cloud-substrate declaration — provider, region, zones, ephemerality, bound shield.",
doc_status: DocStatus::Documented,
},
PrimitiveInfo {
name: "manifest",
category: "cognitive_io",
top_level: true,
since: "Fase 6",
summary: "Bundles resources + fabric + compliance tags into a deployable, audit-tracked unit.",
doc_status: DocStatus::Documented,
},
PrimitiveInfo {
name: "observe",
category: "cognitive_io",
top_level: true,
since: "Fase 6",
summary: "Declares an observability surface — sources, quorum, timeout, certainty floor, partition policy.",
doc_status: DocStatus::Documented,
},
PrimitiveInfo {
name: "reconcile",
category: "cognitive_io",
top_level: true,
since: "Fase 6",
summary: "A typed reconciliation loop — observes drift against a manifest and applies bounded corrections.",
doc_status: DocStatus::Documented,
},
PrimitiveInfo {
name: "lease",
category: "cognitive_io",
top_level: true,
since: "Fase 6",
summary: "Time-bounded resource acquisition with typed expiry, renewal, and revocation semantics.",
doc_status: DocStatus::Documented,
},
PrimitiveInfo {
name: "ensemble",
category: "cognitive_io",
top_level: true,
since: "Fase 6",
summary: "Coordinates multiple cognitive entities under a consensus or quorum protocol with structured tie-breaking.",
doc_status: DocStatus::Documented,
},
PrimitiveInfo {
name: "immune",
category: "cognitive_io",
top_level: true,
since: "Fase 19",
summary: "Continuous-monitoring agent that learns a baseline + emits epistemic-level signals on anomalies.",
doc_status: DocStatus::Documented,
},
PrimitiveInfo {
name: "reflex",
category: "cognitive_io",
top_level: true,
since: "Fase 19",
summary: "An automatic-response trigger bound to an immune system's level — fires structured actions on threshold breach.",
doc_status: DocStatus::Documented,
},
PrimitiveInfo {
name: "heal",
category: "cognitive_io",
top_level: true,
since: "Fase 19",
summary: "A recovery routine bound to an immune system's level — runs scoped repairs, often human-in-the-loop.",
doc_status: DocStatus::Documented,
},
// ── Data plane ────────────────────────────────────────────────────
PrimitiveInfo {
name: "type",
category: "data_plane",
top_level: true,
since: "v0.1.0",
summary: "Declares a structured data type with optional refinements, ranges, where clauses, and compliance tags.",
doc_status: DocStatus::Documented,
},
PrimitiveInfo {
name: "json",
category: "data_plane",
top_level: false,
since: "Fase 73",
summary: "The open, semi-structured value type — a totally-navigable JSON document, refinable by an optional `Json<T>` shape lens, total and honest always.",
doc_status: DocStatus::Documented,
},
PrimitiveInfo {
name: "axonstore",
category: "data_plane",
top_level: true,
since: "Fase 36",
summary: "A typed, audit-chained data store — relational backend, isolation level, encryption, retention, on-breach policy.",
doc_status: DocStatus::Documented,
},
PrimitiveInfo {
name: "dataspace",
category: "data_plane",
top_level: true,
since: "Fase 36",
summary: "A named, isolated data namespace — multi-tenant by construction, with cross-tenant proof obligations.",
doc_status: DocStatus::Documented,
},
PrimitiveInfo {
name: "corpus",
category: "data_plane",
top_level: true,
since: "Fase 36",
summary: "A retrieval-ready collection of documents — backs RAG and grounded retrieval with citation provenance.",
doc_status: DocStatus::Documented,
},
PrimitiveInfo {
name: "pix",
category: "data_plane",
top_level: true,
since: "Fase 19",
summary: "PIX retrieval navigator — an embeddings-free structural index navigated by conditional-mutual-information descent (no vector store). Consumed by navigate/drill/trail.",
doc_status: DocStatus::Documented,
},
PrimitiveInfo {
name: "ledger",
category: "data_plane",
top_level: true,
since: "Fase 62",
summary: "Audit chain — an append-only, hash-linked record of every state transition over a bound surface, tamper-evident by construction (formerly the Provenance-Index reading of pix).",
doc_status: DocStatus::Documented,
},
PrimitiveInfo {
name: "transact",
category: "data_plane",
top_level: false,
since: "Fase 36",
summary: "A flow-body block that wraps multiple data-plane mutations in a single transactional unit with rollback semantics.",
doc_status: DocStatus::Documented,
},
// ── Session types (§Fase 41) ──────────────────────────────────────
PrimitiveInfo {
name: "session",
category: "session_types",
top_level: true,
since: "Fase 41.a (v2.3.0)",
summary: "Declares the typed bidirectional dialogue protocol a socket carries — §41 algebra (send/receive/select/branch/loop/end).",
doc_status: DocStatus::Documented,
},
PrimitiveInfo {
name: "socket",
category: "session_types",
top_level: true,
since: "Fase 41.b (v2.3.0)",
summary: "Session-typed WebSocket transport with credit-refined backpressure, typed reconnection, and SSE-as-fragment projection.",
doc_status: DocStatus::Documented,
},
PrimitiveInfo {
name: "upstream",
category: "session_types",
top_level: true,
since: "Fase 80.b (v2.37.0)",
summary: "Outbound vendor connection (the client dual of socket): config-resolved dial, declared auth, and a compile-time-total wire↔session projection — a new vendor is a declaration, not new code.",
doc_status: DocStatus::Documented,
},
PrimitiveInfo {
name: "voice",
category: "session_types",
top_level: true,
since: "Fase 80.g (v2.37.0)",
summary: "The voice-agent simplicity layer: macro-expands (inspectable via axon desugar) to ots codecs + a carrier session/socket + upstream vendor legs — a blessed-preset phone agent in under 20 lines.",
doc_status: DocStatus::Documented,
},
// ── Wire ──────────────────────────────────────────────────────────
PrimitiveInfo {
name: "axonendpoint",
category: "wire",
top_level: true,
since: "Fase 32",
summary: "HTTP REST primitive — exposes a flow on a typed route with body/output schemas, transport classification, and compliance.",
doc_status: DocStatus::Documented,
},
PrimitiveInfo {
name: "axpoint",
category: "wire",
top_level: true,
since: "Fase 32",
summary: "Lightweight axonendpoint — for simple request/response flows without the full request-binding schema scaffolding.",
doc_status: DocStatus::Documented,
},
PrimitiveInfo {
name: "daemon",
category: "wire",
top_level: true,
since: "Fase 16",
summary: "A long-lived, supervised cognitive process — reacts to events on declared listeners with structured restart semantics.",
doc_status: DocStatus::Documented,
},
PrimitiveInfo {
name: "mcp",
category: "wire",
top_level: true,
since: "Fase 33+",
summary: "Declares an outbound MCP server binding — turns axon into an MCP client of another server.",
doc_status: DocStatus::Documented,
},
// §Fase 6.c — `taint` was registered in 6.a as a wire primitive
// but has no parser production (the lexer recognises the
// keyword token; no `parse_taint` exists; the language treats
// `taint` only as part of the epistemic-uncertainty lattice
// wording in `epistemic.rs`). Registry is the source of truth
// for what the parser actually accepts as a top-level
// declaration; an entry without a parser production lies. We
// remove it here. If a future Fase introduces `taint <Name> {
// ... }`, re-add an entry with that Fase's `since:` tag.
PrimitiveInfo {
name: "listen",
category: "wire",
top_level: false,
since: "Fase 16",
summary: "A flow/daemon-body listener — binds to an event source and dispatches typed messages downstream.",
doc_status: DocStatus::Documented,
},
// §Fase 77 — the π-calc channel quartet, undocumented since Fase 13
// (Kivi brief #51 §B.2: `axon.primitive_doc` answered *unknown
// primitive* for constructs the parser accepts). Registered +
// documented together, per the atomicity discipline above.
PrimitiveInfo {
name: "channel",
category: "wire",
top_level: true,
since: "Fase 13",
summary: "A typed π-calculus channel — message type, qos, lifetime, persistence, and shield gate for in-process delivery and signed external egress.",
doc_status: DocStatus::Documented,
},
PrimitiveInfo {
name: "emit",
category: "wire",
top_level: false,
since: "Fase 13",
summary: "The π-calculus output prefix — emits a typed value onto a channel; durable channels append to the at-least-once outbox.",
doc_status: DocStatus::Documented,
},
PrimitiveInfo {
name: "publish",
category: "wire",
top_level: false,
since: "Fase 13",
summary: "Capability extrusion — publishes a shield-gated channel for discovery; under a signing shield it declares the channel for signed webhook egress.",
doc_status: DocStatus::Documented,
},
PrimitiveInfo {
name: "discover",
category: "wire",
top_level: false,
since: "Fase 13",
summary: "The dual of publish — imports a previously published channel capability under a local alias.",
doc_status: DocStatus::Documented,
},
// ── Operators ─────────────────────────────────────────────────────
PrimitiveInfo {
name: "shield",
category: "operators",
top_level: true,
since: "Fase 20",
summary: "A composable defence layer — scans inputs/outputs for declared threats with a structured on-breach policy.",
doc_status: DocStatus::Documented,
},
PrimitiveInfo {
name: "window",
category: "operators",
top_level: true,
since: "Fase 71",
summary: "A timezone-aware temporal execution guard — gates a scheduled daemon's ticks to allowed day/hour spans (minus holiday dates) with a skip/warn/defer policy.",
doc_status: DocStatus::Documented,
},
PrimitiveInfo {
name: "cors",
category: "operators",
top_level: true,
since: "Fase 83 (v2.38.0)",
summary: "A named, referenced browser-origin policy — `axonendpoint.cors:` resolves it dynamically per tenant at the enterprise HTTP edge, secure by default when absent.",
doc_status: DocStatus::Documented,
},
PrimitiveInfo {
name: "cache",
category: "operators",
top_level: true,
since: "Fase 85 (v2.40.0)",
summary: "A named, referenced result-memoization policy — cacheability derives from the type system's `effects: pure` proof; `tool.cache:` / `retrieve.cache:` opt in, a single `default: true` auto-covers every pure tool, and a non-pure cache must carry a finite `ttl:`.",
doc_status: DocStatus::Documented,
},
PrimitiveInfo {
name: "mandate",
category: "operators",
top_level: true,
since: "Fase 21",
summary: "A typed approval requirement — gates a flow's execution on a capability check + optional segregation of duties.",
doc_status: DocStatus::Documented,
},
PrimitiveInfo {
name: "compute",
category: "operators",
top_level: true,
since: "Fase 17",
summary: "Binds a flow to a specific compute backend — model selection, effort hint, parallelism, deterministic seed.",
doc_status: DocStatus::Documented,
},
PrimitiveInfo {
name: "lambda",
category: "operators",
top_level: true,
since: "Fase 15",
summary: "An anonymous, typed function bound to a flow's data plane — supports lambda apply semantics for inline composition.",
doc_status: DocStatus::Documented,
},
PrimitiveInfo {
name: "forge",
category: "operators",
top_level: false,
since: "Fase 18 (stub); Fase 86 (v2.41.0)",
summary: "Directed Creative Synthesis — a flow-body block running the Poincaré-Hadamard four-phase creative process under a measured, fail-closed novelty guarantee (NCD), so an LLM can genuinely CREATE, not just interpolate.",
doc_status: DocStatus::Documented,
},
PrimitiveInfo {
name: "ots",
category: "operators",
top_level: true,
since: "Fase 11",
summary: "One-shot transform — a closed-catalogue media transformation (audio, image, format) with native/ffmpeg backend dispatch.",
doc_status: DocStatus::Documented,
},
PrimitiveInfo {
name: "psyche",
category: "operators",
top_level: true,
since: "Fase 14",
summary: "Declares the psychological model a persona enacts — beliefs, desires, traits, behavioural disposition.",
doc_status: DocStatus::Documented,
},
PrimitiveInfo {
name: "observable",
category: "operators",
top_level: true,
since: "Fase 51 (v2.19.0)",
summary: "Declares a Hermitian observable — a Pauli-sum M = Σ cₖ Pₖ — measured by a quant block to collapse a Hilbert-space state back to a classical expectation.",
doc_status: DocStatus::Documented,
},
PrimitiveInfo {
name: "quant",
category: "operators",
top_level: false,
since: "Fase 51 (v2.19.0)",
summary: "A flow-body block that lifts a continuous carrier tensor into a finite Hilbert space, evolves it, and yields the expectation of a declared observable (the cognitive↔quantum bridge; OSS simulator capped at n≤10).",
doc_status: DocStatus::Documented,
},
PrimitiveInfo {
name: "savant",
category: "operators",
top_level: true,
since: "Fase 87",
summary: "The long-horizon autonomous research primitive — a governed ORCHESTRATOR that composes memory/corpus, budget, quant, forge and daemon into a budget-bounded, interruptible, fail-closed, provenance-witnessed research loop. Enterprise-exclusive at scale; the keyword + type discipline + PCC live in OSS.",
doc_status: DocStatus::Documented,
},
PrimitiveInfo {
name: "synth",
category: "operators",
top_level: true,
since: "Fase 87",
summary: "A dynamic tool-synthesis policy — the safety envelope (risk ceiling, source language, mandatory WASM zero-trust sandbox, Coder/Reviewer consensus) under which a savant may synthesise and run a tool at runtime. OSS disciplines the policy and ships a deny-by-default backend; the Extism executor is enterprise.",
doc_status: DocStatus::Documented,
},
PrimitiveInfo {
name: "warden",
category: "operators",
top_level: false,
since: "Fase 88",
summary: "An adversarial security-analysis flow-body block — `warden(<target>) within <Scope>` audits a target under a paraconsistent adversarial framing (abduction over authorized evidence), emitting attested `Vulnerability` findings (a witness, not LLM prose). Authorization-native: the `within <Scope>` clause is mandatory (fail-closed). The active auditor of a TARGET, distinct from `shield` (the passive I/O firewall of the AGENT).",
doc_status: DocStatus::Documented,
},
PrimitiveInfo {
name: "scope",
category: "operators",
top_level: true,
since: "Fase 88",
summary: "A named authorization scope — the signed envelope (`targets` allowlist + `depth` ceiling + `approver`) a `warden` analysis MUST run `within`. The load-bearing safety construct that makes adversarial analysis a governed, auditable, fail-closed capability rather than an unscoped weapon.",
doc_status: DocStatus::Documented,
},
PrimitiveInfo {
name: "credential",
category: "operators",
top_level: true,
since: "Fase 92",
summary: "A named ephemeral-credential contract — `ttl:` (≤ 24h, axon-T894) + `grants:` (dotted capability slugs, axon-T893). `mint <Name> as <binding>` mints a TTL-bounded bearer carrying exactly the grants, admitted only when grants ⊆ capabilities(minter) — `authority_only_attenuates`, the delegation dual of the enterprise service account.",
doc_status: DocStatus::Documented,
},
PrimitiveInfo {
name: "mint",
category: "wire",
top_level: false,
since: "Fase 92",
summary: "The credential-minting flow verb — `mint <Credential> as <binding>` mints a declared ephemeral contract at runtime (fail-closed without a minter port) and binds the raw bearer, shown once and never persisted (axon-T896).",
doc_status: DocStatus::Documented,
},
PrimitiveInfo {
name: "rotate",
category: "wire",
top_level: false,
since: "Fase 94",
summary: "The mediated secret-renewal flow verb — `rotate <SecretsStore> [where \"<filter>\"] with <Tool> as <binding>` renews every custody entry of a `backend: secrets` store's class matching the §67 filter through ONE runtime-mediated exchange per key (reveal → tool renews → CAS commit at version+1), binding the metadata-only summary. `rotation_without_revelation`: no term evaluates to a secret value; fail-closed without a custody port. Target must be a secrets store (axon-T898), the tool declared (axon-T899).",
doc_status: DocStatus::Documented,
},
// §Fase 6.d — `logic` was registered in 6.a as an operators
// primitive but has NO parser production (the lexer recognises
// the `logic` keyword token; no `parse_logic` exists; the
// top-level dispatch in `parse_declaration` has no `Logic`
// arm). Same situation `taint` was in at 6.c. Discipline
// applies: registry entries match parser productions
// one-to-one. We remove `logic` here; if a future Fase
// introduces `logic <Name> { … }`, re-add the entry with
// that Fase's `since:` tag.
];
/// Lookup one primitive by canonical name. O(n) over the 54-entry
/// table — n is small, the linear scan beats any hash overhead.
/// Returns `None` for unknown names; callers surface a structured
/// "unknown primitive" diagnostic.
pub fn find(name: &str) -> Option<&'static PrimitiveInfo> {
PRIMITIVE_REGISTRY.iter().find(|i| i.name == name)
}
/// Filter the registry by closed-catalogue category. Returns an
/// iterator so callers can chain into collectors of their choice.
/// An unknown category returns an empty iterator — by design;
/// validation against the closed set is the caller's responsibility.
///
/// Lifetime `'a` ties the returned iterator to the input string so
/// edition-2021 implicit-capture rules accept the closure's borrow.
pub fn by_category<'a>(category: &'a str) -> impl Iterator<Item = &'static PrimitiveInfo> + 'a {
PRIMITIVE_REGISTRY.iter().filter(move |i| i.category == category)
}
/// Filter the registry by documentation status. The §Fase 6 coverage
/// gate uses `with_status(DocStatus::Documented)` to know which
/// entries MUST have a corresponding `.md`.
pub fn with_status(status: DocStatus) -> impl Iterator<Item = &'static PrimitiveInfo> {
PRIMITIVE_REGISTRY.iter().filter(move |i| i.doc_status == status)
}
/// Count primitives by `(category, doc_status)`. Used in tests + the
/// `axon-emcp` coverage gate's diagnostic output so a gate failure
/// surfaces a structured "what's missing" report rather than an
/// opaque assertion.
pub fn coverage_summary() -> CoverageSummary {
let mut summary = CoverageSummary::default();
for info in PRIMITIVE_REGISTRY {
match info.doc_status {
DocStatus::Documented => summary.documented += 1,
DocStatus::Pending => summary.pending += 1,
}
}
summary.total = PRIMITIVE_REGISTRY.len();
summary
}
/// Aggregate documentation-coverage counts. Used by the §Fase 6
/// coverage gate + future telemetry to surface "we have N
/// primitives, M documented, N-M pending" at a glance.
#[derive(Debug, Default, Clone, Copy)]
pub struct CoverageSummary {
pub total: usize,
pub documented: usize,
pub pending: usize,
}
#[cfg(test)]
mod tests {
use super::*;
use std::collections::HashSet;
/// The valid category strings — must match the closed set in
/// the ℰMCP `Category` enum. The coverage gate test in
/// `axon-emcp` does the cross-check; here we just validate
/// shape locally so the registry is self-consistent without
/// needing the downstream crate.
const VALID_CATEGORIES: &[&str] = &[
"cognition",
"cognitive_io",
"data_plane",
"session_types",
"wire",
"operators",
];
#[test]
fn registry_contains_the_expected_count() {
// Total count is pinned — a regression that drops a primitive
// surfaces as a smaller catalogue. §Fase 6.c removed `taint`
// (47→46); §Fase 6.d removed `logic` (46→45). Both were lex-
// recognised keywords with NO parser production, and the
// "registry entries = parser productions" discipline meant
// they could not stay. Future Fases that add or remove
// primitives update this assertion in the same PR.
// §Fase 62.0 added `ledger` (the audit chain) as a distinct top-level
// primitive when `pix` was reassigned to the retrieval navigator (45→46).
// §Fase 51 (v2.19.0) added `observable` + `quant` (the Hilbert-space
// cognitive primitive + its Hermitian-observable companion) → 46→48.
// §Fase 71 added `window` (the temporal execution guard) → 48→49.
// §Fase 73 added `json` (the open semi-structured value type) → 49→50.
// §Fase 77 added the π-calc channel quartet `channel` / `emit` /
// `publish` / `discover` (parsed since Fase 13, undocumented until
// Kivi brief #51 §B.2 caught the gap) → 50→54.
// §Fase 80.b added `upstream` (the outbound vendor connection,
// the client dual of `socket`) → 54→55.
// §Fase 80.g added `voice` (the inspectable voice-agent sugar) → 55→56.
// §Fase 83 added `cors` (the named, referenced browser-origin
// policy) → 56→57.
// §Fase 85 added `cache` (the named, referenced result-memoization
// policy) → 57→58.
// §Fase 87 added `savant` (the long-horizon autonomous research
// primitive) + `synth` (the dynamic tool-synthesis policy) → 58→60.
// §Fase 88 added `warden` (the adversarial security-analysis block) +
// `scope` (the authorization-scope policy) → 60→62.
// §Fase 92 added `credential` (the ephemeral-credential contract) +
// `mint` (the minting flow verb) → 62→64.
// §Fase 94 added `rotate` (the mediated secret-renewal verb) → 64→65.
assert_eq!(
PRIMITIVE_REGISTRY.len(),
65,
"PRIMITIVE_REGISTRY count drift — add/remove the primitive intentionally + update this assertion"
);
}
#[test]
fn every_entry_has_a_non_empty_name_and_summary() {
for info in PRIMITIVE_REGISTRY {
assert!(!info.name.is_empty(), "empty name in registry");
assert!(
!info.summary.is_empty(),
"primitive `{}` has an empty summary — scaffold + listings would be unhelpful",
info.name
);
assert!(
!info.since.is_empty(),
"primitive `{}` has an empty since — corpus frontmatter would be invalid",
info.name
);
}
}
#[test]
fn every_entry_has_a_valid_category() {
for info in PRIMITIVE_REGISTRY {
assert!(
VALID_CATEGORIES.contains(&info.category),
"primitive `{}` has invalid category `{}` — valid: {VALID_CATEGORIES:?}",
info.name, info.category
);
}
}
#[test]
fn primitive_names_are_unique() {
let mut seen: HashSet<&str> = HashSet::new();
for info in PRIMITIVE_REGISTRY {
assert!(
seen.insert(info.name),
"duplicate primitive name in registry: `{}`",
info.name
);
}
}
#[test]
fn documented_tier_matches_phase_6d_baseline_full_coverage() {
// §Fase 6.d baseline (post-Tier-3): **45 primitives — every
// entry in the registry is Documented (100% coverage)**.
//
// Tier 0 (Fase 5, 7): persona, flow, step, anchor, tool, reason, socket
// Tier 1 (Fase 6.b, 10): context, intent, memory, agent, probe,
// validate, refine, weave, type, run
// Tier 2 (Fase 6.c, 12): resource, fabric, manifest, observe,
// reconcile, lease, ensemble, session,
// axonstore, dataspace, corpus, pix
// Tier 3 (Fase 6.d, 16): axonendpoint, axpoint, daemon, mcp,
// listen, shield, mandate, compute,
// lambda, forge, ots, psyche, immune,
// reflex, heal, transact
//
// Tier 2 ships 12 (not 13) — `taint` removed in 6.c (no
// parser production). Tier 3 ships 16 (not 17) — `logic`
// removed in 6.d (same reason). The discipline holds: every
// entry in the registry has a `.md` AND a parser production.
// A regression that flips a Documented entry back to Pending
// surfaces here.
let documented: HashSet<&str> = with_status(DocStatus::Documented)
.map(|i| i.name)
.collect();
let expected: HashSet<&str> = [
// Tier 0
"persona", "flow", "step", "anchor", "tool", "reason", "socket",
// Tier 1
"context", "intent", "memory", "agent", "probe", "validate",
"refine", "weave", "type", "run",
// Tier 2
"resource", "fabric", "manifest", "observe", "reconcile",
"lease", "ensemble", "session", "axonstore", "dataspace",
"corpus", "pix", "ledger",
// Tier 3
"axonendpoint", "axpoint", "daemon", "mcp", "listen",
"shield", "mandate", "compute", "lambda", "forge", "ots",
"psyche", "immune", "reflex", "heal", "transact",
// §Fase 51 (v2.19.0)
"observable", "quant",
// §Fase 71 — the temporal execution-window guard.
"window",
// §Fase 73 — the open semi-structured value type.
"json",
// §Fase 77 — the π-calc channel quartet (Kivi brief #51 §B.2).
"channel", "emit", "publish", "discover",
// §Fase 80.b/80.g — the outbound vendor connection + the
// inspectable voice-agent sugar.
"upstream", "voice",
// §Fase 83 — the named, referenced browser-origin policy.
"cors",
// §Fase 85 — the named, referenced result-memoization policy.
"cache",
// §Fase 87 — the long-horizon autonomous research primitive + its
// dynamic tool-synthesis policy.
"savant", "synth",
// §Fase 88 — the adversarial security-analysis block + its
// authorization-scope policy.
"warden", "scope",
// §Fase 92 — the ephemeral-credential contract + its minting verb.
"credential", "mint",
// §Fase 94 — the mediated secret-renewal verb.
"rotate",
]
.into_iter()
.collect();
assert_eq!(
documented, expected,
"Documented set drift — Fase 6.d baseline + §51 quant/observable + §71 window (full coverage)"
);
}
#[test]
fn coverage_summary_is_arithmetic() {
let s = coverage_summary();
// §Fase 62.0: 45 → 46 with `ledger` (audit chain) split out from `pix`.
// §Fase 51 (v2.19.0): 46 → 48 with `observable` + `quant`.
// §Fase 71: 48 → 49 with `window` (the temporal execution guard).
// §Fase 73: 49 → 50 with `json` (the open semi-structured value type).
// §Fase 77: 50 → 54 with the π-calc channel quartet
// (`channel` / `emit` / `publish` / `discover`).
// §Fase 80.b: 54 → 55 with `upstream`; §80.g: 55 → 56 with `voice`.
// §Fase 83: 56 → 57 with `cors`.
// §Fase 85: 57 → 58 with `cache`.
// §Fase 87: 58 → 60 with `savant` + `synth`.
// §Fase 88: 60 → 62 with `warden` + `scope`.
// §Fase 92: 62 → 64 with `credential` + `mint`.
// §Fase 94: 64 → 65 with `rotate` (the mediated secret-renewal verb).
assert_eq!(s.total, 65);
assert_eq!(s.documented + s.pending, s.total);
// §Fase 6.d achieves **100% coverage** — every entry in the
// registry has a `.md` and a passing drift-gated canonical
// program. Pending count is 0; any future drop is a
// regression the gate catches.
assert_eq!(s.documented, 65);
assert_eq!(s.pending, 0);
}
#[test]
fn find_resolves_documented_and_pending_entries() {
assert_eq!(find("persona").map(|i| i.name), Some("persona"));
assert_eq!(find("axonendpoint").map(|i| i.name), Some("axonendpoint"));
assert!(find("does_not_exist").is_none());
}
#[test]
fn by_category_filters_to_the_named_family() {
let cog: Vec<&str> = by_category("cognition").map(|i| i.name).collect();
assert!(cog.contains(&"persona"));
assert!(cog.contains(&"flow"));
assert!(!cog.contains(&"socket"), "socket is session_types, not cognition");
assert!(!cog.contains(&"axonendpoint"), "axonendpoint is wire, not cognition");
}
#[test]
fn nested_primitives_carry_top_level_false() {
// The "lives only inside a parent" set — coverage gate cross-
// checks against `axon://grammar/top_level` which is the
// human-readable mirror of this same polarity.
for nested in ["step", "reason", "probe", "validate", "refine", "weave",
"listen", "forge", "transact", "quant",
// §Fase 77 — the channel quartet's nested members.
"emit", "publish", "discover"] {
let info = find(nested).expect("must be in registry");
assert!(
!info.top_level,
"primitive `{}` should be nested (top_level: false)",
info.name
);
}
}
}