Expand description
Scripts as resources in any ikigai host. A script is not a feature beside the
resources; it IS one, named urn:script:{name}, and every way of reaching it (a REST
door, the REPL, an MCP agent, a timer, a panel) is a door onto the same names.
urn:script:{name} Source Exists Sink Delete the script: fetch WITHOUT running, publish, retire
urn:script:{name}:version:{digest} Source Exists one immutable, content-addressed version
urn:script:{name}:compiled Source the head prepared for its evaluator (cached)
urn:script:{name}:result Source run it as a READ: its answer
urn:script:{name}:runs Sink run it for EFFECTS: answers the run's IRI
urn:script:{name}:run:{id} Source Exists one recorded run
urn:script:eval Sink run supplied code under the caller's own authority
urn:script:catalog Source every script the caller may read§A host library
This crate binds no binary and mounts nowhere by itself. A host (ikigai-embedded,
gonk, the CMS) mounts space beside the evaluator it offers and decides the three
things only a host can — see SpaceConfig:
- where scripts live: a
Backend(MemoryBackend, orDirBackendfor plain files under a directory the host chooses); - the ceiling each script may run under (
authority::CeilingPolicy, from the host’s<config home>/script-authority/{name}); - who a request comes from: the principal its door mints into the request’s
capability (
Capability::with_principal,urn:cap:principal:<iri>), read back withauthority::principal_of, recorded on every publish and run and never taken from the caller.
use ikigai_core::{Capability, Fallback, Kernel, Space};
use ikigai_script::{authority, space, MemoryBackend, SpaceConfig};
use std::sync::Arc;
let scripts = space(SpaceConfig::new(
Arc::new(MemoryBackend::new()),
// Fail closed: a script the host has not given a ceiling may touch nothing.
authority::same_for_all(authority::Ceiling::nothing()),
));
// Beside the evaluator the scripts are written for (`ikigai_lisp::space()`):
let root = Fallback::new(vec![Arc::new(scripts) as Arc<dyn Space> /*, lisp, … */]);
let kernel = Kernel::new(Arc::new(root));§The authority rule
Three authorities, never merged: publish (urn:cap:script:write:{name}, and
…:delete:{name} to retire), run (urn:cap:script:run:{name}, or
authority::CAP_RUN_PUBLIC for a public script), and runs as. Each grant names one
script or a namespace of them (urn:cap:script:{act}:{namespace}-*,
authority::cap_namespace), and authority::holds decides. A run runs as:
runner's capability, attenuated to
{ declared } ∩ { what the publisher held at publish } ∩ { the host's ceiling }
+ every exclusion the publisher or the ceiling carriesNo elevation: a publish declaring a scope its publisher does not hold is refused,
a run never holds anything its runner does not, and the only way a run’s authority is
made is Invocation::issue_attenuated —
there is no form that widens. See authority.
§Languages are resources
A run is a sub-request to the language’s evaluator, so this crate links no interpreter:
- Lisp reaches
urn:lisp:eval, and the evaluator’s own capability (urn:cap:lisp) is part of what every Lisp script declares: evaluating code is itself authority. - SPARQL reaches the host’s store through its graph-scoped doors
(
sparql::SparqlDoor). A query’s form, its declared and typed parameters, and the authority it needs (the store’s per-graph grants) are all read from the parsed text, and parameter values are bound into the parsed algebra, never spliced. Each published query is its own catalog entry with its parameters as arguments. Seesparql. - Plans (
ik:Processgraphs) reach the host’surn:plan:eval. A plan is validated byurn:plan:validatebefore it is stored, its authority is DERIVED from its steps’ contracts byurn:plan:requires, and it is a read or a write by its steps’ verbs. Each published plan is its own catalog entry with its parameters as arguments. Seeplan.
Preference order when assembling anything: a query, then a plan, then Lisp. The first two derive their authority and are checked before they run; use Lisp for control flow a plan cannot express, and preferably as one step inside a plan.
Re-exports§
pub use backend::Backend;pub use backend::DirBackend;pub use backend::MemoryBackend;pub use endpoints::space;pub use endpoints::Catalog;pub use endpoints::CatalogEntry;pub use endpoints::ChangeHook;pub use endpoints::LastRun;pub use endpoints::Prepared;pub use endpoints::ScriptSpace;pub use endpoints::SpaceConfig;pub use endpoints::TRANSPORT_ARGUMENTS;pub use model::Head;pub use model::Language;pub use model::Outcome;pub use model::Run;pub use model::State;pub use model::Version;
Modules§
- authority
- The three authorities, never merged — and the one computation that decides what a run may touch.
- backend
- Where the atoms’ state lives: a
Backendthe host chooses. - endpoints
- The resources, as endpoints.
- graph
- The graph face (
as=text/turtle) of the catalog and the run records. - limits
- Bounds on caller-supplied SPARQL, checked before the parser sees a byte (ledger #915).
- model
- What the atoms hold: a script’s head, its immutable versions, and its runs.
- name
- Script names and the IRIs built from them.
- plan
- Plans as a script language: a stored
ik:Processgraph is a script whose language isplan. - sparql
- SPARQL as a script language: a stored query is a script whose language is SPARQL.