1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
//! **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.
//!
//! ```text
//! 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`], or [`DirBackend`] for 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 with
//! [`authority::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));
//! # let _ = (kernel, Capability::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:
//!
//! ```text
//! runner's capability, attenuated to
//! { declared } ∩ { what the publisher held at publish } ∩ { the host's ceiling }
//! + every exclusion the publisher or the ceiling carries
//! ```
//!
//! **No 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`](ikigai_core::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. See [`sparql`].
//! - **Plans** (`ik:Process` graphs) reach the host's `urn:plan:eval`. A plan is validated
//! by `urn:plan:validate` before it is stored, its authority is DERIVED from its steps'
//! contracts by `urn: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. See [`plan`].
//!
//! **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.
pub use ;
pub use ;
pub use ;
/// The README's example, compiled (never run: it opens a directory) so it cannot rot.
;