pub struct Spec {
pub name: String,
pub description: String,
pub model: ModelRef,
pub data_policy: DataPolicy,
pub read_roots: Vec<PathBuf>,
pub fetch_prefixes: Vec<String>,
pub embedding_model: Option<ModelRef>,
pub warehouse: Option<PathBuf>,
pub nodes: NodeGraph,
pub branches: Branches,
}Expand description
A parsed spec.
Fields§
§name: StringJob name, used to submit against it.
description: StringTrigger conditions for a calling agent — when to use this, never how it works. A description that summarises the workflow invites an agent to act on the summary instead of reading the real contract.
model: ModelRefWhich model serves this job’s inference.
data_policy: DataPolicyData-handling policy; see DataPolicy.
read_roots: Vec<PathBuf>Directories this job may read beneath. Empty means none.
fetch_prefixes: Vec<String>URL prefixes this job may fetch, from Fetch "https://host/path".
An allowlist by prefix, exactly as read_roots is for the
filesystem: a corpus that lives on the web is still a corpus, and the
capability list has to describe reaching it or it stops being a
truthful account of what the job touches. Empty means the job cannot
fetch anything, which is the default.
embedding_model: Option<ModelRef>The model serving embed, if the spec declares one.
Separate from model on purpose: an embedding model and a chat model
are different things, and reusing one field would let a spec ask a
chat model for vectors — which either fails or returns something
shaped like an embedding that is not one.
warehouse: Option<PathBuf>Where to write a medallion warehouse of this job’s results, if anywhere.
Opt-in, and alongside the JSONL projection rather than instead of
it: downstream nodes read results_path with open/slice, so
replacing it would break every existing spec. A job that just wants an
answer pays nothing for a warehouse it never asked for.
Relative paths resolve against the spec’s own directory, like every other path in a spec.
nodes: NodeGraphThe proc-blocks implementing the job, as a graph of nodes.
Each node’s declared input is typechecked against the nodes feeding
it before anything runs. block = "..."; is sugar for a one-node
graph — see crate::graph::NodeGraph::single.
branches: BranchesConditional dispatch: which branch target fires for each labeled route a branching node produces. Empty when the spec has none.
Implementations§
Source§impl Spec
impl Spec
Sourcepub fn validate_host_read_paths(&self) -> Result<(), SpecError>
pub fn validate_host_read_paths(&self) -> Result<(), SpecError>
Refuse a spec whose host-read paths sit outside its granted roots.
Fan-out manifests and acceptance schemas are read by the host,
which is not sandboxed — so nothing would otherwise stop either
reading a path the spec never granted. Requiring them inside a
declared Read root keeps the capability list a truthful description
of everything the job touches, which is the property the whole
capability model rests on.
Call this after resolving read_roots, over and schema paths
against the spec’s directory, so both sides are absolute and
canonical. Comparing them as written cannot work: a spec that grants
an absolute root and names a relative manifest is entirely ordinary,
and lexically a relative path never starts with an absolute one.