pub fn is_lisp_extension(path: &Path) -> boolExpand description
Predicate: assert that path terminates in the canonical
LISP_SOURCE_EXTENSION (lowercase .lisp) — the file-type
shape every M2 typed path-slot the wasm-engine instantiator reads
as tatara-lisp source must take. The contract:
- the path has an extension component (no-extension paths like
"lib/init"or"a"fail); - the extension’s UTF-8 string form is exactly
"lisp"— lowercase, no trailing residue, no double-extension shadow like".lisp.bak".
Returns true on accept, false on reject. Each per-axis caller
— crate::BehaviorSpec::validate on :behavior :on-* paths
(c97815a), [crate::UpgradeInstruction::StateChange::validate]
on :upgrade-from :state-change :script (this commit), every
future axis admitting a tatara-lisp source path — wraps the
boolean into its own typed *NonLispExtension { slot, path } /
*NonLispExtensionScript { script } enum variant so the
diagnostic still names which slot carried the non-.lisp
value. The predicate is axis-agnostic; the wrapping per-axis
variant carries the slot identity.
Lifted from caixa-core::behavior where the same single-line
gate (path.extension().and_then(|ext| ext.to_str()) == Some("lisp")) was inlined verbatim across the first call site
(BehaviorSpec::validate_callback_path) — the PRIME DIRECTIVE
duplication-budget rule (THEORY.md §I.3.5: “every recurring shape
becomes a generator before it becomes a pattern; every pattern
becomes a library before it becomes duplicated code. The
duplication budget is zero.”) promotes the gate to a typed
substrate-side predicate on the same trajectory the path-shape
gate is_sandboxed_relative_path already follows (lifted from
the same two call sites once the second consumer appeared). The
third caller — the future :bibliotecas per-entry tatara-lisp
source-file axis (the feira build loop reads each through the
same tatara_lisp::read reader at parse time), the future :exe
:kind Binario entry-point axis (the nix-built binary’s entry
point loads as Lisp source), the future M2.5 wasm-engine
pre-warm hook axis — lands as a thin two-line wrapper rather
than re-inlining the same extension check.
Pairs with the per-axis *NonLispExtension / *NonLispExtensionScript
variants on crate::BehaviorError and crate::UpgradeError
— those remain the typed surface authors see; this predicate is
the single-source-of-truth gate the caixa-build pipeline consults
to produce them.