Structured Language for Agentic Coding — a spec and linter for agentic coding loops.
Project description
SLAC — Structured Language for Agentic Coding
SLAC is a small, declarative language for agentic coding loops. You write what a loop should achieve, who does the work, how it's checked, and when it's done — in a single markdown file. A validator checks the loop is well-formed before an agent runs it, so agents don't fall flat on a half-specified task.
A SLAC file is just markdown + YAML frontmatter — it is a valid
Open Knowledge Format
document (type: slac.loop), so any OKF-aware agent can read it, and a SLAC engine
can execute it.
Supported engines
SLAC is tool-agnostic: the same .slac.md loop compiles down onto the loop
primitives of the agent harnesses people actually use.
| Engine | SLAC lowers to | Mapping |
|---|---|---|
/loop cron (CronTask) + subagents |
mappings/claude-code.md | |
/goal (objective + budget) + spawn_agent |
mappings/codex.md |
Each mapping also documents what the engine cannot yet enforce — notably, neither Claude Code's
/loopnor Codex's/goalenforces a separate checker agent. That gap is the reason SLAC exists (see below).
A loop in 20 lines
---
type: slac.loop
loop: pr_babysitter
until: ci.green and tests.passed == tests.total and consecutive_green >= 2
context:
- cmd: gh pr checks
- signal: ci
agents:
maker: { model: opus }
checker: { model: opus, mode: refute } # a SEPARATE agent verifies "done"
boundaries:
never: [edit the public API, skip tests]
max_iterations: 20
---
# Goal
Get this PR's CI green without changing public behavior.
Why SLAC exists
We read the real source of both shipping loop tools:
- Claude Code
/loopis interval cron — it reschedules a prompt and expires after ~7 days. It never evaluates whether the goal was met. - Codex
/goallets the same working model mark its own goalcomplete. The maker grades its own homework — exactly the footgun Addy Osmani warns about ("the model grades its own work too leniently").
SLAC adds the missing structure both lack: an explicit, independently-judged
stop condition (until) and a mandatory separate checker agent. In
compiler terms, the checker is the type-checker the fuzzy LLM executor took away,
moved to runtime. See SPEC.md for the full rationale.
Install
The linter is zero-dependency — stock Python 3.8+. (pyyaml is used
automatically if present for maximal YAML coverage; otherwise a bundled parser
handles the SLAC subset.)
# one-line install (wraps pipx)
curl -fsSL https://raw.githubusercontent.com/ramanshrivastava/slac/main/install.sh | bash
# …or pick a package manager
pipx install slac-lang # recommended: isolated CLI on your PATH (installs the `slac` command)
pip install slac-lang # into the current environment
# …or no install at all — run straight from a clone
python3 linter/slac_lint.py examples/*.slac.md
Distribution status (v0.0.1): the package is built for PyPI as
slac-lang(the bare nameslacis blocked by PyPI as too similar to an existing project; the installed command is stillslac);pipx/pipare the primary channels and thecurl … | bashscript just wrapspipx. A Homebrew tap is planned once there's a tagged release. Nothing is published yet — these are the targets, andinstall.shalready installs from a local clone today.
Use the slac CLI
slac lint examples/*.slac.md # validate (type-check + lint)
slac lint --json my_loop.slac.md # machine-readable findings (agents auto-fix the `safe` ones)
slac lint --strict examples/*.slac.md # CI mode: warnings become errors
slac new my_loop # scaffold a starter loop that lints clean
slac explain NoCheckerWarning # what a diagnostic means (or list them all)
Diagnostics read like a Python traceback, not a barcode — errors are named
like Python exceptions (MissingFieldError, UnknownFieldError, TypeError)
and halt the loop; warnings (NoCheckerWarning, RunawayWarning) notify
but let it run. See linter/rules.md.
Use it from an agent
A .slac.md is a loop definition; an agent harness runs it. The bundled
Claude Code skill teaches an agent to
consume one: validate with slac lint, then drive the loop (fetch context → run
the maker → run a separate checker → evaluate until → repeat) by lowering
onto /loop. Drop it in ~/.claude/skills/run-slac-loop/ and say "run this
loop." See mappings/ for the field-by-field lowering onto Claude
Code /loop and Codex /goal.
Repository layout
slac/
SPEC.md the language definition (fields, semantics, lifecycle)
pyproject.toml packaging — installs the `slac` CLI
src/slac/
cli.py the `slac` command (lint / new / explain)
linter.py zero-dependency validator (OKF → schema → semantic)
slac.schema.json JSON Schema for the frontmatter (the type-check)
linter/slac_lint.py back-compat shim (zero-install entry point)
linter/rules.md every diagnostic, with rationale
tests/test_linter.py the test suite (stdlib unittest)
examples/
index.md OKF directory index (the "loopbook")
pr_babysitter.slac.md
bug_fixer.slac.md
flaky_hunter.slac.md
mappings/
claude-code.md how SLAC lowers onto /loop
codex.md how SLAC lowers onto /goal
integrations/
claude-code/SKILL.md skill: teach an agent to run a .slac.md loop
Makefile .pre-commit-config.yaml
Relationship to OKF
Open Knowledge Format
(Google Cloud, 2026) standardizes curated knowledge for agents as markdown +
frontmatter. OKF is the fuel; SLAC is the loop that consumes it. SLAC is an
OKF profile: every loop sets the required type field to slac.loop, reuses
OKF's optional fields (title, description, tags, timestamp), and uses OKF's
reserved log.md as the loop's on-disk memory between runs.
License
Apache-2.0 — matching OKF, to keep the ecosystem interoperable.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file slac_lang-0.0.1.tar.gz.
File metadata
- Download URL: slac_lang-0.0.1.tar.gz
- Upload date:
- Size: 23.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.11
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
05ac118dcd15e93b2c763f57339c5a1247e552267a3cce386682bb14393d2d80
|
|
| MD5 |
ee081eda518b365fb44c0e1ad7a4c79f
|
|
| BLAKE2b-256 |
9debb81ca35d44442a002360aa1d6bea8114a00696412003cfb8090eebf684f9
|
File details
Details for the file slac_lang-0.0.1-py3-none-any.whl.
File metadata
- Download URL: slac_lang-0.0.1-py3-none-any.whl
- Upload date:
- Size: 19.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.11
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b61a77fb082aa57b498596115490cfc76c2f24940091a0b37a14b1c101497a57
|
|
| MD5 |
a5383baf433b6a3cbfcf9cfc67bb92ad
|
|
| BLAKE2b-256 |
30e58a71f871ca5053917b51bbac445e5999cbe3928c493817d7134983bd388d
|