Skip to content

Knowledge packs

An agent with a knowledge store (a triple store such as quipu) can keep the fleet as a graph and query it with SPARQL. yen.lib.rdf.share r gives the eval result as sorted N-Triples: scopes, kinds, parents, active aspects, every routed element as a node with its origin, and errors. It adds a sha256 and a count.

modules/hosts.nix
{ yen, ... }:
{
yen.environment.prod.domain = "example.com";
yen.host.web.environment = yen.environment.prod;
yen.host.db.environment = yen.environment.prod;
yen.aspects.nginx = {
at = yen.host.web;
services = "nginx";
};
}
<https://yen.dev/fleet/edge/32d0c078116c66f5> <https://yen.dev/fleet/yen/from> <https://yen.dev/fleet/scope/fleet:main> .
<https://yen.dev/fleet/edge/32d0c078116c66f5> <https://yen.dev/fleet/yen/origin> "aspect pack" .
<https://yen.dev/fleet/edge/32d0c078116c66f5> <https://yen.dev/fleet/yen/sink> "out" .
<https://yen.dev/fleet/edge/32d0c078116c66f5> <https://yen.dev/fleet/yen/to> <https://yen.dev/fleet/scope/fleet:main> .
<https://yen.dev/fleet/edge/a8c8404b6ebdf537> <https://yen.dev/fleet/yen/from> <https://yen.dev/fleet/scope/fleet:main/host:web> .
<https://yen.dev/fleet/edge/a8c8404b6ebdf537> <https://yen.dev/fleet/yen/origin> "aspect nginx" .
<https://yen.dev/fleet/edge/a8c8404b6ebdf537> <https://yen.dev/fleet/yen/sink> "services" .
<https://yen.dev/fleet/edge/a8c8404b6ebdf537> <https://yen.dev/fleet/yen/to> <https://yen.dev/fleet/scope/fleet:main/host:web> .
<https://yen.dev/fleet/instance/environment/prod> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <https://yen.dev/fleet/kind/environment> .
<https://yen.dev/fleet/instance/environment/prod> <https://yen.dev/fleet/yen/name> "prod" .
<https://yen.dev/fleet/instance/fleet/main> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <https://yen.dev/fleet/kind/fleet> .
<https://yen.dev/fleet/instance/fleet/main> <https://yen.dev/fleet/yen/name> "main" .
…
result
{
count = 31;
sha256 = "7d5008a92e83eb458e7a6975294ade014204a79975d870a2c385e87a1ecd3f5e";
}

The triples are sorted, and yen gives the same answer whatever the file order. So two revisions compare by hash first. The docs check it: the files of this template, loaded in reverse order, give the same sha256.

A fleet can give its pack as a flake output:

modules/pack.nix
# The routing graph as a knowledge pack: sorted N-Triples with a sha256. Same fleet, same hash, any file order.
{ yen, ... }:
{
yen.aspects.pack = {
at = yen.kinds.fleet;
out.rdfPack = removeAttrs (yen.lib.rdf.share {
graph = yen.lib.graph;
active = { };
errors = [ ];
}) [ "ntriples" ];
};
}

yen.lib.rdf.shacl r gives SHACL shapes from the schema: one node shape per kind with scopes, yen:name required, yen:parent of the spawning kind, each field at most once, and sh:class for ref fields.

@prefix sh: <http://www.w3.org/ns/shacl#> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
<https://yen.dev/fleet/kind/fleet> a sh:NodeShape ;
sh:targetClass <https://yen.dev/fleet/kind/fleet> ;
sh:property [ sh:path <https://yen.dev/fleet/yen/name> ; sh:minCount 1 ; sh:maxCount 1 ; sh:datatype xsd:string ; ] ;
sh:property [ sh:path <https://yen.dev/fleet/yen/parent> ; sh:maxCount 1 ; ] ;
.
<https://yen.dev/fleet/kind/host> a sh:NodeShape ;
sh:targetClass <https://yen.dev/fleet/kind/host> ;
sh:property [ sh:path <https://yen.dev/fleet/yen/name> ; sh:minCo…
Contribute Community Sponsor