Skill Stacking
Skill stacking composes multiple agent capabilities into a verified workflow. Each skill step is compiled to a Vein binary with its own fingerprint, and a SkillStack manifest references those fingerprints to guarantee the workflow hasn’t been tampered with.
Schema: SkillStep
A single step in a skill stack — one atomic capability an agent can execute.
skill-step-v1.lode
{
"schema": "lode",
"version": 1,
"name": "SkillStep",
"fields": [
{ "id": 1, "name": "stepName", "type": "string", "required": true },
{ "id": 2, "name": "skillRef", "type": "string", "required": true },
{ "id": 3, "name": "dependsOn", "type": "string[]", "required": false },
{ "id": 4, "name": "inputs", "type": "map<string,string>", "required": false },
{ "id": 5, "name": "outputs", "type": "string[]", "required": false },
{ "id": 6, "name": "fingerprint", "type": "string", "required": false }
]
}Schema: SkillStack
The workflow manifest that references compiled steps by fingerprint.
skill-stack-v1.lode
{
"schema": "lode",
"version": 1,
"name": "SkillStack",
"fields": [
{ "id": 1, "name": "name", "type": "string", "required": true },
{ "id": 2, "name": "version", "type": "string", "required": true },
{ "id": 3, "name": "description", "type": "string", "required": true },
{ "id": 4, "name": "steps", "type": "string[]", "required": true },
{ "id": 5, "name": "stepFingerprints", "type": "map<string,string>", "required": true },
{ "id": 6, "name": "entryPoint", "type": "string", "required": false },
{ "id": 7, "name": "metadata", "type": "map<string,string>", "required": false }
]
}Example: Code Review Pipeline
Three skill steps form a code review workflow:
lint-step.json
{
"stepName": "lint",
"skillRef": "skill:eslint-check",
"dependsOn": [],
"inputs": { "configPath": ".eslintrc.json" },
"outputs": ["lint-report.json"]
}analyze-step.json
{
"stepName": "static-analysis",
"skillRef": "skill:static-analysis",
"dependsOn": ["lint"],
"inputs": { "language": "typescript", "strictMode": "true" },
"outputs": ["report.json", "annotations.sarif"]
}review-step.json
{
"stepName": "ai-review",
"skillRef": "skill:code-review",
"dependsOn": ["lint", "static-analysis"],
"inputs": { "model": "claude-opus-4-6", "maxTokens": "4096" },
"outputs": ["review-comments.json"]
}Compilation
Compile each step, then bundle fingerprints into the stack manifest:
$ lodec compile lint-step.json -s skill-step-v1.lode -o steps/lint.vein
Compiled lint-step.json → steps/lint.vein (92 bytes)
Fingerprint: a3f8c2e9...
$ lodec compile analyze-step.json -s skill-step-v1.lode -o steps/analyze.vein
Fingerprint: d1e4b7f0...
$ lodec compile review-step.json -s skill-step-v1.lode -o steps/review.vein
Fingerprint: f9c1a02b...Stack Manifest
code-review-stack.json
{
"name": "code-review-pipeline",
"version": "1.0.0",
"description": "Lint, analyze, and AI-review code changes",
"steps": ["lint", "static-analysis", "ai-review"],
"stepFingerprints": {
"lint": "a3f8c2e9...",
"static-analysis": "d1e4b7f0...",
"ai-review": "f9c1a02b..."
},
"entryPoint": "lint",
"metadata": { "team": "platform", "triggerOn": "pull_request" }
}Workflow Verification
Before executing a skill stack, the orchestrator verifies every step:
async function verifyStack(stack: SkillStack, stepDir: string): Promise<boolean> {
for (const stepName of stack.steps) {
const vein = await readFile(`${stepDir}/${stepName}.vein`);
const schema = loadLode("skill-step-v1.lode");
const step = decode(vein, schema);
const actual = fingerprint(step);
if (actual !== stack.stepFingerprints[stepName]) {
console.error(`Step "${stepName}" tampered: expected ${stack.stepFingerprints[stepName]}, got ${actual}`);
return false;
}
}
return true;
}If any step’s fingerprint doesn’t match, the entire workflow is rejected — no partial execution of a tampered pipeline.
Last updated on