Skip to content

razroo/iso

Repository files navigation

iso

iso

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:

  1. Harness fragmentation. Each coding agent reads a different file layout — CLAUDE.md, AGENTS.md, .cursor/rules/*.mdc, .opencode/agents/*.md, .mcp.json vs opencode.json vs .codex/config.toml. Keeping them in sync is copy-paste drift.
  2. 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/agentmd validates structure, @razroo/isolint rewrites prose for small-model safety, @razroo/iso-harness fans out to every harness, and @razroo/iso-route compiles one model policy into each harness's config.
  • One wrapper runs the whole build chain: @razroo/iso chains the above into a single iso build.
  • Two feedback tools close the loop after deploy: @razroo/iso-eval scores did the agent complete the task? and @razroo/iso-trace parses 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.

Quickstart

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

  • packages/iso@razroo/iso · recommended entry point The wrapper CLI for the whole flow. If agent.md is your authored source, iso build runs agentmd lint, agentmd render, isolint lint, then iso-harness build in one command. Use this unless you have a reason to reach for a sub-package directly.

  • packages/agentmd@razroo/agentmd A structured-markdown dialect for agent prompts. Rules are scoped ([H1] hard limit, [D1] default) with load-bearing why: 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/isolint Lints the compiled prose for phrases weak small models can't parse — should, when relevant, one of the usual categories, taste words, long sentences, unclosed etc. lists. --fix --llm rewrites 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-harness One iso/ source directory → the file layout each coding agent actually reads. Transpiles instructions, subagents, slash commands, and MCP servers into CLAUDE.md, AGENTS.md, .cursor/rules/*.mdc, .opencode/agents/*.md, etc., so all four harnesses stay in lockstep.

  • packages/iso-route@razroo/iso-route One model policy, every harness. Declare a default model plus named roles (planner, fast-edit, reviewer, …) in a single models.yaml; iso-route compiles that into .claude/settings.json, .codex/config.toml, opencode.json, and a resolved role map that iso-harness consumes 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-eval Behavioral 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 deterministic fake runner for CI smoke; real-agent runners plug in via the library RunnerFn interface.

  • packages/iso-trace@razroo/iso-trace Local 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.

Commands cheat sheet

Install any one package globally or per-project; every CLI below is the bin exposed by that package.

@razroo/iso — wrapper (recommended)

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 executing

@razroo/agentmd — author structure

agentmd 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>]

@razroo/isolint — portable prose

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 plan

@razroo/iso-harness — fan out to every harness

iso-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 change

@razroo/iso-route — one model policy, every harness

iso-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 table

@razroo/iso-eval — did the agent actually do the task?

iso-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 execution

@razroo/iso-trace — what the agent actually did (production)

iso-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.jsonl

Layout

iso/
├── 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)

Build & test

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/iso

Releasing

Version 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 do

When 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-notes

The 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.

End-to-end example

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.

About

Isomorphic agent tooling: author once, run on frontier or 7B. Build, lint, fan out, eval, and trace AI agent harnesses across Cursor, Claude Code, Codex, and OpenCode.

Topics

Resources

Stars

Watchers

Forks

Packages

 
 
 

Contributors