Skill compilation

The core of Sigil: turning a plain-markdown SKILL.md into a typed, runnable agent harness. The compiler has two halves (src/compiler/):

The pipeline

flowchart LR
    S["SKILL.md"] --> SPEC["spec loop\n(grounded rules)"]
    SPEC --> SPINE["workflow spine\n(the CFG)"]
    SPINE --> FLOWS["annotator flows\nIO · context · knowledge · HIL"]
    FLOWS --> ASM["assemble\n(one AG-IR)"]
    ASM --> GATES{"gates\nG1…G6 · compile oracle\nSTRUCT-COV"}
    GATES -->|fail| REPAIR["bounded repair"] --> FLOWS
    GATES -->|pass| OUT["agent.jac"]

The gates

Compilation fails loudly, with rule-level diagnostics, when:

Gate Rejects
G1 standalone a tool or knowledge entry that points at content instead of embodying it ("see FORMS.md")
G3 artifact boundary a mandated deliverable that nothing actually writes to disk
G4 compile oracle an AG-IR that doesn't lower to a clean-compiling module (real jac check, every time)
G5 STRUCT-COV a mandate folded into some other slot's interior (monolithic — model-dependent, same risk as prose)
G6 human gates a route that consumes human feedback but leaves the decision to model judgment

Failures route back through a bounded repair pass — each flow fixes its own view — and an unfixable lift returns its issues honestly; nothing unfaithful is persisted.

Using it

sigil compile ./SKILL.md                 # compile → skill set on the graph
sigil compile ./SKILL.md -e agent.jac    # …and eject ONE self-contained runnable
./agent.jac "extract the tables"         # runs on any model: SIGIL_MODEL=…
sigil register-skill ./x.agir agir       # hand-authored AG-IR, no model call
sigil register-skill ./y.jac osp         # drop in a precompiled module
sigil replay agent.jac obs.jsonl "task"  # re-run a recorded run's cognition — free

Running a compiled artifact

An ejected artifact is a terminal app, not a script. Run it in a terminal and you get a live TUI: a banner, the walker's node path rendering as it executes (with per-node timings), human gates asked inline (? question → type your answer — the compiled skill's clarify loops become a real conversation), and a styled outcome with the report and every artifact the run created. No task argument? It prompts for one. Zero extra dependencies — pure ANSI, part of the compiled runtime. Piped, captured, or in CI the same run is byte-identical to the old plain output (AGIR_TUI=0/1 overrides detection).

Compiled runs are honest by construction: a walker that never reaches its terminal reports INCOMPLETE (never a silent success), runaway loops abort at AGIR_STEP_BUDGET (default 256) naming the node, and human gates ask a real channel when one is attached (HIL_QA_FILE; an honest sentinel in batch). Every run leaves a node-path trace (AGIR_PROGRESS) and, under the runtime, a per-call token/cost log — so any step traces back to the exact sentence in the skill that mandated it.