Write your AI agent instructions once. Run them anywhere, on any model.
iso is Razroo's toolchain for making agent harnesses isomorphic — the
same authored source produces the same agent behavior across every coding
harness (Cursor, Claude Code, Codex, OpenCode) and across every model tier
(frontier models down to 7B local models).
Today, writing agent instructions is fragmented on two axes:
- Harness fragmentation. Each coding agent reads a different file
layout —
CLAUDE.md,AGENTS.md,.cursor/rules/*.mdc,.opencode/agents/*.md,.mcp.jsonvsopencode.jsonvs.codex/config.toml. Keeping them in sync is copy-paste drift. - Model fragmentation. A prompt written with a frontier model in mind
quietly breaks on smaller models: soft imperatives (
should,when relevant), taste words, ambiguous cross-references, and unstructured rationale all drop silently at 7B. You don't find out until the agent misbehaves in production.
Seven packages solve that in one pipeline with a feedback loop:
- Four build-time tools turn your authored source into every harness's file layout:
@razroo/agentmdvalidates structure,@razroo/isolintrewrites prose for small-model safety,@razroo/iso-harnessfans out to every harness, and@razroo/iso-routecompiles one model policy into each harness's config. - One wrapper runs the whole build chain:
@razroo/isochains the above into a singleiso build. - Two feedback tools close the loop after deploy:
@razroo/iso-evalscores did the agent complete the task? and@razroo/iso-traceparses production transcripts to show what the agent actually did.
authoring build output feedback
┌────────────────────┐ agentmd ┌───────────────────┐ isolint ┌─────────────────┐ iso-harness ┌───────────────────────┐ iso-eval ──▶ per-task pass / fail
│ agent.md │ ────────▶ │ validated rules, │ ────────▶ │ small-model- │ ────────────▶ │ CLAUDE.md │ (behavioral scoring)
│ + fixtures │ lint │ scope labels, │ lint/fix │ safe prose │ build │ AGENTS.md │
│ │ render │ load-bearing why │ │ │ │ .cursor/rules/* │ iso-trace ──▶ production events,
└────────────────────┘ └───────────────────┘ └─────────────────┘ │ .opencode/agents/* │ which rules ever fired,
│ settings.json │ regression-fixture mining
┌────────────────────┐ │ .codex/config.toml │
│ models.yaml │ ───────────────────── iso-route build ─────────────────────────────────────▶│ opencode.json │
│ (roles + fallback) │ │ .mcp.json │
└────────────────────┘ └───────────────────────┘
@razroo/iso chains agentmd → isolint → iso-route (when models.yaml exists) → iso-harness in one command.
Most users want @razroo/iso — one install, one command, every harness:
npm install -D @razroo/iso
npx iso build .Given an agent.md (or an existing iso/instructions.md) and an iso/
source directory, this lints the authored source, rewrites it for
small-model safety, and fans it out into CLAUDE.md, AGENTS.md,
.cursor/rules/*, .opencode/*, and the matching MCP config files.
See packages/iso for the full CLI reference and
library API, or examples/dogfood/ for a runnable
project that exercises the wrapper end-to-end.
-
packages/iso—@razroo/iso· recommended entry point The wrapper CLI for the whole flow. Ifagent.mdis your authored source,iso buildrunsagentmd lint,agentmd render,isolint lint, theniso-harness buildin one command. Use this unless you have a reason to reach for a sub-package directly. -
packages/agentmd—@razroo/agentmdA structured-markdown dialect for agent prompts. Rules are scoped ([H1]hard limit,[D1]default) with load-bearingwhy:rationale. Ships a linter for structure (missing rationale, dangling refs, no fallback row) and a fixture-driven harness that measures per-rule adherence against the target model. -
packages/isolint—@razroo/isolintLints the compiled prose for phrases weak small models can't parse —should,when relevant,one of the usual categories, taste words, long sentences, unclosedetc.lists.--fix --llmrewrites offenders and re-lints the rewrite before accepting. Also ships an Isomorphic Plan engine for fully-deterministic large-model-plans → small-model-run pipelines. -
packages/iso-harness—@razroo/iso-harnessOneiso/source directory → the file layout each coding agent actually reads. Transpiles instructions, subagents, slash commands, and MCP servers intoCLAUDE.md,AGENTS.md,.cursor/rules/*.mdc,.opencode/agents/*.md, etc., so all four harnesses stay in lockstep. -
packages/iso-route—@razroo/iso-routeOne model policy, every harness. Declare a default model plus named roles (planner,fast-edit,reviewer, …) in a singlemodels.yaml; iso-route compiles that into.claude/settings.json,.codex/config.toml,opencode.json, and a resolved role map thatiso-harnessconsumes when stamping per-subagent frontmatter. Honest about ceilings — warns loudly where a harness (e.g. Cursor) can't bind models programmatically. -
packages/iso-eval—@razroo/iso-evalBehavioral eval runner for the produced harness. Snapshots a workspace per task, hands it to a runner with the task prompt, then scores the resulting filesystem / command state — answering "did the agent actually do it?" that structural and prose lints can't. Ships a deterministicfakerunner for CI smoke; real-agent runners plug in via the libraryRunnerFninterface. -
packages/iso-trace—@razroo/iso-traceLocal observability for real agent transcripts. Parses Claude Code JSONL sessions (Codex / OpenCode additive) into a harness-agnostic event model so you can ask "which rules ever actually fired?", "which tools does my agent reach for most?", and "which captured sessions would make good regression fixtures?" Zero upload — everything is local reads and user-controlled output.
Each package is independently published on npm and works on its own. They're in one repo because they're designed to compose.
Working on integrations across packages? Read
INTEGRATIONS.md. It lists the open composition
work with target end-states, touch points, and verification steps — so
an AI agent (or human) pointed at this repo knows which compositions
are planned vs. which are deliberately kept decoupled.
Install any one package globally or per-project; every CLI below is the bin exposed by that package.
iso build # run agentmd → isolint → iso-harness on ./
iso build path/to/project # target another project
iso build . --out dist # write generated harness files under ./dist
iso build . --target claude,cursor
iso build . --skip-isolint # skip the portable-prose pass
iso build . --dry-run # dry-run the final iso-harness write
iso plan . # print planned steps without executingagentmd lint <file> # structural lint (rule IDs, refs, why:)
agentmd render <file> [--out compiled.md] # render compiled prompt with scope labels
agentmd test <file> --fixtures <path> [--via api|claude-code] [--model <id>]isolint lint . # default preset
isolint lint . --preset recommended,performance
isolint lint . --since origin/main --fail-on warn # gate PRs
isolint lint . --format sarif > lint.sarif # for GitHub code scanning
isolint lint . --fix --llm --large anthropic/claude-3.5-sonnet
isolint plan <spec> # generate portable instructions from a planiso-harness build # reads ./iso, writes to ./
iso-harness build --target claude,cursor # subset of targets
iso-harness build --source path/to/iso --out path/to/project
iso-harness build --dry-run # print planned writes
iso-harness build --watch # rebuild on every source changeiso-route build models.yaml --out . # emit .claude/settings.json, config.toml, etc.
iso-route build models.yaml --targets claude,codex # subset of harnesses
iso-route build models.yaml --dry-run # preview without touching disk
iso-route plan models.yaml # print resolved role tableiso-eval run eval.yml # run the suite
iso-eval run eval.yml --filter write-greeting --concurrency 2 --json
iso-eval run eval.yml --keep-workspaces # keep tmpdirs for debugging
iso-eval plan eval.yml # list tasks + checks, no executioniso-trace sources # detected transcript roots + parser status
iso-trace list # recent sessions across every root
iso-trace list --since 7d --cwd .
iso-trace show <id-or-prefix> [--events tool_call,file_op]
iso-trace show <id> --grep "H3" # regex across messages + tool input
iso-trace stats [ids…] [--since 7d] [--cwd .] # aggregate tool/rule stats
iso-trace stats --source path/to/sample.jsonl # one file, no discovery
iso-trace export <id> --format jsonl > session.jsonliso/
├── package.json # workspaces root
├── tsconfig.base.json # shared compiler options
└── packages/
├── agentmd/ # structure + adherence
├── isolint/ # portable prose
├── iso-harness/ # one source, every harness
├── iso/ # one command for the whole pipeline
├── iso-route/ # one model policy → per-harness config
├── iso-eval/ # behavioral eval on the produced harness
└── iso-trace/ # parse + query real agent transcripts (observability)
npm install # install all workspace deps
npm run build # build every package
npm run test # run every package's tests
npm run typecheck # typecheck every package
npm run test:dogfood # wrapper-level local dogfood project
npm run test:pack # pack local tarballs and smoke installed CLIs
npm run test:pipeline # end-to-end demo (agentmd → isolint → iso-harness)
npm --workspace @razroo/iso-eval run example # iso-eval against the bundled example suite
npm --workspace @razroo/iso-trace run example # iso-trace stats on the bundled sample transcript
# Target a single package
npm run build --workspace @razroo/isolint
npm run test --workspace @razroo/agentmd
npm run test --workspace @razroo/isoVersion bumps are driven by Changesets. Every PR that changes a package should include a changeset describing the user-visible impact:
npm run changeset # interactive — pick packages + bump level + summary
npm run changeset:status # preview what the next `version` would doWhen you're ready to cut a release:
npm run version # bumps package versions + writes CHANGELOG.md
git commit -am "Version packages"
git tag <pkg>-v<version> # e.g. agentmd-v0.3.0
git push && git push --tags
gh release create <pkg>-v<version> --generate-notesThe tag-triggered release workflows in .github/workflows/*-release.yml
take over from there — verify the tag matches package.json, run tests,
build, and npm publish --provenance.
examples/pipeline/ is an executable demonstration
of the composed pipeline: one authored agent.md is structurally linted,
rendered, prose-linted, and fanned out into the 11 files each coding-agent
harness expects. Run npm run test:pipeline to exercise the core pipeline,
or use @razroo/iso in your own project when you want the same chain behind
one CLI.
examples/dogfood/ is a local dogfood project for the
wrapper CLI itself. It starts from agent.md + iso/ source and runs the
repo's local packages/iso/bin/iso.mjs entrypoint to produce the full harness
fan-out. Run npm run test:dogfood to exercise the same wrapper path a
downstream repo would use.
npm run test:pack goes one level further: it packs the local workspaces into
tarballs, installs them into fresh temp projects, and smoke-tests the packaged
iso-harness, iso, iso-eval, and iso-trace CLIs. This guards against
packaging regressions that workspace-only tests can miss.
packages/iso-eval/examples/suites/echo-basic/
is a runnable eval suite for the downstream side: a baseline workspace, a
task prompt, and a set of file/command checks. Run npm --workspace @razroo/iso-eval run example to see the full pass-report against the
bundled fake runner.