On this page
Runtime — loader & resolver
@skill-wiki/runtime reads compiled artifacts on disk and serves
metadata + projection paths to the MCP server. It never reads chunk bodies.
Modules
| Module | Role |
|---|---|
atom-loader.ts | Reads atom.yaml + graph.yaml per atom; never reads chunks. |
index-loader.ts | Parses _index.xml, builds the in-memory atom map. |
projection-resolver.ts | Returns the on-disk path for a (atom, level) pair. |
domain-config.ts | Recursive domain.yaml discovery + DomainRegistry. |
edge-walker.ts | BFS / DFS over the in-memory edge graph. |
Boot sequence
async function boot(primeDir: string) {
// 1. Discover domain plugins.
const domains = await discoverDomains(primeDir);
for (const d of domains) DomainRegistry.register(d);
// 2. Parse the index.
const index = await loadIndex(`${primeDir}/_index.xml`);
// 3. Build the in-memory graph.
// Atoms map id → metadata; no chunk content read here.
const graph = buildGraph(index);
return { domains, index, graph };
} The "never read chunk content" rule
The runtime contract says that chunks/{summary,core,full}.md is
not the runtime's job. Why?
- Consistent with how the agent works. The agent has a
Readtool. Doubling it in the runtime invites format drift and caching bugs. - Memory bound. Chunk content scales with corpus size. Metadata + the index do not (~50 KB even for 1k atoms).
- Hot reload. The runtime can hot-reload the index without invalidating the agent's view of any specific atom.
// packages/runtime/src/atom-loader.ts
//
// IMPORTANT: This module NEVER reads chunks/*.md content.
// It only reads _index.xml and atom.yaml (metadata).
// Chunk content is exclusively for the agent to pull via the Read tool. Edge walker
Used by the MCP server to satisfy contract resolution and walk
requires chains:
function walkRequires(seed: AtomMeta, depth = 5): AtomMeta[] {
const out: AtomMeta[] = [];
const seen = new Set<string>([seed.id]);
const queue: [AtomMeta, number][] = [[seed, 0]];
while (queue.length > 0) {
const [atom, d] = queue.shift()!;
if (d >= depth) continue;
for (const edge of atom.edges) {
if (edge.verb !== 'requires' || seen.has(edge.target)) continue;
const target = byId.get(edge.target);
if (!target) continue;
seen.add(target.id);
out.push(target);
queue.push([target, d + 1]);
}
}
return out;
} Public API
import { Runtime } from "@skill-wiki/runtime";
const rt = await Runtime.boot({ primeDir: "/path/to/compiled" });
// Lookup
const atom = rt.lookup("@recipes/method-pan-sauce");
// Resolve a projection (returns a path, NOT content)
const path = rt.resolveProjection(atom.id, "core");
// Walk
const deps = rt.walkRequires(atom);
// Domains
console.log(rt.domains); // [DomainConfig, ...]