The skill compiler · SKILL.md → runnable agent harness

Don't prompt the skill. Compile it.

You write a skill in plain Markdown. Sigil compiles it into a typed agent harness, a program the model runs inside, so every step, rule and check in the skill is enforced by structure, not hoped for in a prompt. Small and local models included.

SKILL.md → AG-IR → agent.jac · the whole gated pipeline, one command

New postAgent skills should be compiled, not just readRead it →
Compile a skill
your terminal
sigil compile ./SKILL.md -e agent.jac
./agent.jac "extract the tables from report.pdf"

No API key? Compile on the Claude Code CLI you already have — and serve the skills back to it as tools.

Install · macOS & Linux
$
curl -fsSL https://github.com/sigilagent/sigil/releases/latest/download/install.sh | bash
See it

Compile it, then run it — both are terminal-native.

sigil compile — the live build view
Compiling is a live build view — every stage, with counts and timing.
a compiled artifact, run in a terminal
Running a compiled skill is a terminal app — node-by-node, with its output.

The compiler

Everywhere else, a skill is a prompt. Here, it's source code.

A SKILL.md loaded into context is a hope: the model reads the instructions, and you hope it follows them. Sigil's compiler reads the same file and emits a typed, runnable harness: every mandatory step becomes a node the run must visit, every prohibition a constraint, every code snippet a runnable tool body, every check a gate. The model's judgment is confined to typed slots at exactly the points the skill calls for judgment.

01 · IN

SKILL.md

Plain-markdown instructions: the skill you'd hand any agent.

02 · LIFT

Author the AG-IR

A frontier model extracts a typed graph contract, with every rule pinned to a verbatim quote from the skill.

03 · GATE

Prove it

A gate battery audits coverage, drift and structure; the compile oracle round-trips the IR through the real type-checker.

04 · LOWER

Transpile

The mechanical back-end lowers the IR as written: every construct has exactly one lowering, zero judgment.

05 · RUN

Any model

The harness runs on small, cheap, even fully-local models. Structure can't be skipped.

COMPILEDStep order is control flow; MUSTs are nodes the run visits; prohibitions are constraints, never paths.
GROUNDEDThe model proposes, code disposes: a rule that doesn't quote the skill verbatim is dropped deterministically.
EJECTED-e packages one self-contained runnable file. No sigil, no session, no graph needed to run it.

Why it matters: the compiled harness carries structure a weak model cannot skip: step order, embodied tools, grounded verification. The model isn't asked to be disciplined; the harness is the discipline. That is how a skill written once runs faithfully on any model, and how capability transfers from the frontier model that compiled it to the small one that runs it.


Works with Claude Code

Claude Code decides when. The compiled harness decides how.

Sigil plugs into the agent harness you already use, in both directions — and needs no API key to do it. Compile on the claude CLI you already have, then serve every skill you compile back into it as a tool. Inside that tool call there is no prompt left to drift from: the skill's steps are nodes the run must visit.

1 · compile on your subscription
# every model tier runs on the claude CLI — no ANTHROPIC_API_KEY,
# no proxy, no second auth
sigil --claude compile ./SKILL.md

# opt-in: let an agent author the typed IR itself, against the
# compile oracle — grounded spec loop and gate battery still run
sigil --claude compile ./SKILL.md --agent
2 · serve the skills back to it
# one MCP tool per compiled skill, triggered by the skill's own
# `description:` frontmatter — the "use when…" line you wrote
claude mcp add sigil -- sigil mcp-serve

# Claude then calls skill_clean_csv, skill_writing_plans, …
# and the harness — not the model — guarantees the steps
NO KEYbyLLM dispatches through litellm, and litellm lets you own a provider prefix — so a headless claude -p is just another model. Typed returns and tool-using slots included.
SKILLS AS TOOLSEvery compiled skill becomes a tool in your session, described by its own trigger line and carrying its run record, so routing is a decision with evidence behind it.
SELF-REPAIRINGWhen a compile fails its gate, a tool-using session gets the workspace and the compile oracle as a command, and iterates until it passes. The oracle stays the authority.

The point isn't that Sigil talks to Claude Code — it's what a tool call becomes once the skill behind it is compiled. A prompt-loaded skill is advice the model may follow. A compiled one is a program it runs inside. Read the reference →


The runtime

Compiled skills live on a persistent graph agent.

Around the compiler, Sigil ships a full agent runtime. Every compiled skill persists as a TaskGraph on one living graph, next to the agent's identity, memory and schedules. Ask for something it has a skill for and it runs it on the small, cheap model. Ask for something new and the frontier model compiles a skill first, then it's cheap forever.

Embodies Anchored Knows Remembers Owns Crystallized Ran MutatedFrom root Soul persona · ethos · tiers Registry the skills Spec AG-IR contract Memory durable facts TaskGraph a compiled skill Attempt every run
Procedural

Skills

The compiled skills themselves: each one covers a whole class of task, not just one. This is what the agent has learned to do.

Episodic

History

Every run, its outcome and a summary. The record of what the agent has done and how it went.

Semantic

Memory

Durable facts, retrieved by deterministic lexical recall and injected at run time, grown automatically by distilling each completed task.

Soul is identity and config as state you mutate in place: persona, ethos, model tiers, channels. The compiled skill stays class-general; instance-specific memory is injected only at execution time, never baked into the harness. On a small-model failure, the frontier mutates the skill and retries; the graph keeps the whole lineage.


Inside the compiler

Built like a compiler. Gated like one, too.

A classic two-half design: an AI front-end (LIFT) that owns all the judgment, and a mechanical back-end (LOWER) that owns none, with typed gates between them, so an unfaithful skill can never slip through silently.

tested

Grounded spec loop

The model proposes, code disposes. Every extracted rule must quote the skill verbatim; a hallucinated rule can't produce a matching span, so it's dropped deterministically.

tested

Compile oracle

Every candidate IR round-trips through the real back-end and the type-checker before it's accepted: a deterministic ground truth on every iteration. The gates diagnose rather than veto — autofix, scoped repair, then typed findings on whatever remains.

tested

Eject to one file

-e emits a single self-contained runnable: shebang'd, runtime embedded. No sigil, no session, no graph needed to run it. Pick the model with an env var.

tested

Skill linter

Compiling offers to lint the skill first: obligations that are underspecified or self-contradictory come back as findings, and one do / maybe / don't answer writes the sentence that settles it into the SKILL.md.

any model

52 providers & local models

Compile with a frontier model (GPT, Claude, Gemini) and run the harness on anything, including fully local via Ollama. The structure carries the discipline, not the model.

tested

Three ingress forms

Hand it a plain-Markdown skill (the compiler runs), a hand-authored AG-IR (no model call), or an already-compiled module; all land as skills on the graph.

tested

MCP tools, bound at compile time

Connect any tool server and the compiler binds its tools by name into the skills it builds; live runs dispatch to whichever server exposes the tool.

new

Plugs into Claude Code, both ways

Compile on the Claude Code CLI you already have — no API key. Then serve every compiled skill back to it as a tool: Claude decides when, the harness decides how.

tested

A full runtime included

Chat with tool use and exec approvals, Discord / Slack / Telegram channels, cron scheduling, three-layer memory, hooks, all driving the same graph the compiler writes to.

tested

Observatory

A live web Control-UI: the agent-graph and every compiled skill rendered in real time, with 100% token observability on every run.


The workflow

Compile the skill. Then run it anywhere.

One command takes a plain-Markdown skill through the whole gated pipeline. Keep the result on Sigil's graph, or eject it as a single runnable file that needs nothing else.

compile a skill
# the gated pipeline: spec loop → views → gates → compiled skill
sigil compile ./SKILL.md

# …and eject ONE self-contained runnable program
sigil compile ./SKILL.md -e agent.jac
./agent.jac "extract the tables from report.pdf"

# the harness is the discipline: pick any execution model
SIGIL_MODEL=ollama_chat/qwen3:8b ./agent.jac "..."
skills & tools, three ingress forms
# plain Markdown: the compiler runs
sigil register-skill ./my-skill/SKILL.md

# a hand-authored AG-IR (no model call) · a precompiled module
sigil register-skill ./procedure.agir agir
sigil register-skill ./skills/report_v1.jac osp

# MCP servers: the compiler binds their tools into new skills
sigil add-mcp github stdio gh-mcp
no API key: compile on Claude Code
# every model tier runs on the claude CLI you already have
sigil --claude compile ./SKILL.md

# opt-in: an agent authors the AG-IR against the compile oracle,
# keeping the grounded spec loop and the whole gate battery
sigil --claude compile ./SKILL.md --agent

# the oracle is a command — for a hand-written IR, or CI
sigil gate agent.ir
…then serve the skills back to it
# one MCP tool per compiled skill, triggered by its own description
claude mcp add sigil -- sigil mcp-serve

# Claude Code decides WHEN. The compiled harness decides HOW —
# inside the tool call there is no prompt left to drift from.

Download & install

One command. The compiler and the whole agent.

The installer pulls the self-contained jac runtime, fetches Sigil, provisions its one compiler dependency, and drops a sigil launcher on your PATH. No root, no pip install, safe to re-run.

$
curl -fsSL https://github.com/sigilagent/sigil/releases/latest/download/install.sh | bash

macOS & Linux · installs to ~/.sigil/app · override with SIGIL_HOME, SIGIL_BIN_DIR, SIGIL_REF

01

Native runtime

Installs one small self-contained program; no Python, no dependencies to manage.

02

Fetches Sigil

Clones the source into ~/.sigil/app (or a tarball if you have no git).

03

Provisions dependencies

One jac install: the model backend (litellm), the compiler's PyYAML, and the chat REPL.

04

Puts sigil on PATH

A launcher so sigil serve / sigil solve work from anywhere.

Prefer to install by hand?
manual install
# 1 · install one small self-contained runtime
curl -fsSL https://raw.githubusercontent.com/jaseci-labs/jaseci/main/scripts/install.sh | bash
export PATH="$HOME/.local/bin:$PATH"

# 2 · clone Sigil & provision its dependencies (reads jac.toml — don't name packages)
git clone https://github.com/sigilagent/sigil.git && cd sigil
jac install

# 3 · configure cognition (frontier needs a provider key)
export OPENAI_API_KEY=sk-...
export SIGIL_FRONTIER=gpt-5                 # default
export SIGIL_SMALL=ollama_chat/qwen3:32b     # can be local

Verify the build with the test suite (jac test src/*.test.jac src/report_fix_tests.jac) or launch the live Observatory Control-UI with jac start observatory.jac. Then compile your first skill:


Use it

Or skip the files entirely and just ask the agent.

Point it at models once: a frontier one to compile with, and a small or fully-local one (via ollama) to run with. solve compiles a skill the first time it meets a class of task, and reuses it every time after.

your terminal
# first time: the frontier compiles a skill for this class of task
sigil solve "turn report.pdf into a clean CSV"

# a similar ask is a HIT: it runs the compiled skill on the small model
sigil solve "pull the tables out of invoice.pdf"

# the compiled skills with run stats, and everything else it knows
sigil library
sigil soul
sigil teach "always give me CSV with a header row"

Three ways to run it

In your terminal. sigil compile a skill, or sigil solve "…" and let it compile on demand.

As a dashboard. Run sigil serve for a live web view; watch it compile and run every skill, in your browser.

Standalone. Eject a skill to one file and run it anywhere, no sigil installed at all.

Pay for intelligence once

The frontier model is paid once per class of task, to compile the harness.

Every run after rides that structure on a small, cheap model. If the small model fails, the frontier mutates the skill and retries; the skill gets better under pressure.

Teach it something and it remembers. Point it at a different model and it switches. All of it, live.


The paper

The research behind Sigil.

Sigil is the artifact of a research project on skill compilation: what happens to an agent's faithfulness when the instructions stop being a prompt and start being a program.

SIGIL: Compiling Agent Skills into Typed Harnesses

Jayanaka Dantanarayana · Savini Kashmira · Lingjia Tang · Jason Mars — University of Michigan, Ann Arbor

arXiv · 2026 · arXiv:2607.27309 [cs.SE] · CC-BY-4.0

86%

of mandated steps executed by a compiled skill

56%

the same skill, read as a prompt

0.58×

the tokens of the prose baseline

Cite it

Dantanarayana, J., Kashmira, S., Tang, L., & Mars, J. (2026). SIGIL: Compiling agent skills into typed harnesses. arXiv:2607.27309. https://doi.org/10.48550/arXiv.2607.27309

BibTeX
@misc{dantanarayana2026sigil,
  title         = {SIGIL: Compiling Agent Skills into Typed Harnesses},
  author        = {Dantanarayana, Jayanaka and Kashmira, Savini and Tang, Lingjia and Mars, Jason},
  year          = {2026},
  eprint        = {2607.27309},
  archivePrefix = {arXiv},
  primaryClass  = {cs.SE},
  doi           = {10.48550/arXiv.2607.27309},
  url           = {https://arxiv.org/abs/2607.27309}
}

Write the skill once. Compile it. Run it on any model.

Sigil is free and open-source (MIT). Your skills stop being prompts and start being programs.