# SwarmOps > Version control for swarms of coding agents: many writers, one store, one JSON envelope per command. Each link below is a page of the documentation as Markdown; the same address without `.md` is the page as HTML. ## For agents - [For agents and programs](https://swarmops.cc/docs/agents.md): After this page a program or a coding agent can find every SwarmOps page, fetch it as Markdown, and know which parts of a command's answer it may rely on… - [SwarmOps documentation](https://swarmops.cc/docs.md): SwarmOps is version control designed for large pools of coding agents: their processes commit into one store at once, every command answers in one JSON… ## Start - [Install SwarmOps on Linux](https://swarmops.cc/docs/guides/install.md): After this page, swarmops and so, one program with two names, run on your Linux host, and you can pin, update, uninstall or build them from source. - [Quick start: a store and a first commit](https://swarmops.cc/docs/guides/quick-start.md): After this page you have a store with a first commit, work landed from three agents, a resolved conflict and an undone operation, in about ten minutes; known… - [Concepts](https://swarmops.cc/docs/concepts.md): After this page you can name each part of SwarmOps, from the store and its objects to refs, landing, the envelope and workspaces, and find the page that… ## Guides - [Commit and land](https://swarmops.cc/docs/guides/commit-and-land.md): After this page you can publish work into a store: write a change list, commit it, land it on main, and handle the conflicts and retries that come when other… - [Parallel coding agents on one repository](https://swarmops.cc/docs/guides/parallel-agents.md): SwarmOps is version control for swarms of coding agents. After this page you know where agents in one checkout or in git worktrees collide, how SwarmOps… - [Reading and repairing history](https://swarmops.cc/docs/guides/history-and-undo.md): After this page you can read a store's history without a checkout, compare two revisions, list every write, undo a mistaken ref move and check the store. - [Keep git: import, land and export](https://swarmops.cc/docs/guides/git-round-trip.md): SwarmOps is version control for swarms of coding agents, and git stays at both ends. After this page you can import a git repository, let agents land work,… - [GitHub as a remote: clone, fetch, push and sync](https://swarmops.cc/docs/guides/github-remote.md): After this page a store keeps a git remote, GitHub or any git host: you can clone from it, fetch, push and sync, and know what to do when a sync stops. - [A store as a remote: clone, push and sync another store](https://swarmops.cc/docs/guides/store-remote.md): After this page a store uses another store as its remote through swarmops serve: clone, fetch, push and sync over ssh or HTTPS, and know what crosses between… - [Use SwarmOps from Claude Code over MCP](https://swarmops.cc/docs/guides/claude-code.md): SwarmOps is version control for swarms of coding agents. After this page Claude Code agents read, commit and land in one store over MCP, one identity per… ## Develop - [MCP integration](https://swarmops.cc/docs/develop/mcp.md): After this page you can connect any MCP (Model Context Protocol) client to a store: register swarmops mcp, give each agent process its identity, call every… - [Scripting the CLI](https://swarmops.cc/docs/develop/cli-scripting.md): After this page you can drive SwarmOps from a script or a CI job: read the exit code and the JSON envelope, retry what may be retried, and make a retry safe… - [Code style](https://swarmops.cc/docs/develop/style.md): After this page you know how SwarmOps keeps its Rust style: what the gate enforces, what review reads for, how public types are built, and the few rules the… ## Operate - [Operating SwarmOps](https://swarmops.cc/docs/operations.md): After this page you can find the task page for running SwarmOps for a swarm of coding agents on one host, from the install through the daily loop to backup,… - [Stores](https://swarmops.cc/docs/operate/stores.md): After this page you can choose where a store lives, protect it, create it, and give every writer an identity. - [Install and upgrade](https://swarmops.cc/docs/operate/install-and-upgrade.md): After this page swarmops and so run on a host, and you can move the host and its stores to a new release. - [Give agents the store](https://swarmops.cc/docs/operate/agents.md): After this page Claude Code agents on the host reach the store through swarmops mcp, and a copy of every answer they get is kept for monitoring. - [The daily loop](https://swarmops.cc/docs/operate/daily-loop.md): After this page you can move work between the store and the git repository that people, CI and deployment use, every day, with a person's review before the… - [Build and test a change](https://swarmops.cc/docs/operate/build-and-test.md): After this page an agent can build and test a change on disk in a workspace, then land exactly the tree it tested. - [One writer per trunk](https://swarmops.cc/docs/operate/one-writer-per-trunk.md): After this page you can keep one writer on the git side of each trunk, tell a divergence from a lagging trunk, and act on each export refusal. - [Monitoring](https://swarmops.cc/docs/operate/monitoring.md): After this page you know what to collect from a swarm and what to read in it. - [Limits](https://swarmops.cc/docs/operate/limits.md): After this page you know the limits an operator meets first; known-limitations.md lists them all, each with the milestone that takes it. - [Making room](https://swarmops.cc/docs/operate/making-room.md): After this page you can remove what a store may lose: its leftovers with swarmops gc, and its derived values by hand, with every writer stopped. - [Backup and restore](https://swarmops.cc/docs/operate/backup-and-restore.md): After this page you can copy a store that agents are writing, check the copy, and put it back after damage. - [Verify and repair](https://swarmops.cc/docs/operate/verify-and-repair.md): After this page you can check a store for damage, read what a failed check names, and repair a damaged store. - [Serve over ssh](https://swarmops.cc/docs/operate/serve-over-ssh.md): After this page people and CI reach a store with stock git alone: clone, fetch, pull and push over ssh, through swarmops serve as the forced command of an… - [Serve over HTTP](https://swarmops.cc/docs/operate/serve-over-http.md): After this page people and CI reach a store with stock git over HTTPS, through swarmops serve --cgi behind a web server. - [Where serve answers differently from git](https://swarmops.cc/docs/operate/serve-differences.md): After this page you know each place where swarmops serve answers stock git differently from git's own server, and why. - [Troubleshooting](https://swarmops.cc/docs/troubleshooting.md): After this page you can go from what you see, an error code, a refusal or a server that stops, to why it happens and the command that fixes it. ## Reference - [CLI reference](https://swarmops.cc/docs/reference/cli.md): Every command of swarmops and so, its short form: the same program by a shorter name. This page and the command pages are generated from the command line's… - [Coming from git](https://swarmops.cc/docs/reference/coming-from-git.md): Where a SwarmOps operation does what a git command does, so runs it, with git's flags where they mean the same. Where the meaning differs the… - [Error codes](https://swarmops.cc/docs/reference/errors.md): A failed command prints an envelope whose error names a stable E_* code, the process exit code (exit) and whether running the operation again can succeed… - [Limits](https://swarmops.cc/docs/reference/limits.md): The limits of the SwarmOps contract: what a request may hold, with the error a request past a limit gets, and how far a response goes before it leaves the… - [Schema types](https://swarmops.cc/docs/reference/schema-types.md): The 190 request, response and value types of the API, as swarmops schema prints their JSON Schemas (2020-12); swarmops schema prints one. The command… - [MCP tools](https://swarmops.cc/docs/reference/mcp-tools.md): swarmops mcp serves the store's operations as an MCP server on stdin and stdout: JSON-RPC 2.0, one message per line. Each tool is one operation, named as the… ## Project - [Goals](https://swarmops.cc/docs/goals.md): SwarmOps is a version control system, written in Rust, for swarms of coding agents: tens of agent processes on one host committing into one repository at… - [Roadmap](https://swarmops.cc/docs/roadmap.md): What SwarmOps builds next, and how each step will be checked. This page is the detailed roadmap; the README's roadmap and the site's roadmap page summarise… - [SwarmOps architecture](https://swarmops.cc/docs/architecture.md): An overview, in English, of how SwarmOps is built, as of M5. The design specs are the authority. They are in Korean, and the maintainers keep them privately;… - [Known limitations](https://swarmops.cc/docs/known-limitations.md): What SwarmOps does not do yet, or does less well than it should, as of M20, and the milestone meant to change it. The items come from the M1 and M1.5 reviews… - [Performance ledger](https://swarmops.cc/docs/perf.md): Numbers measured on this host (WSL2, kernel 5.15, ext4 on the virtual disk /dev/sdd, 32 cores). Re-measure after any storage-layer change; just bench fails on… - [The pilot: SwarmOps on its own repository](https://swarmops.cc/docs/pilot.md): After this page you can run SwarmOps on its own repository as a first real use: import, one agent session, export, CI on the export, then four sessions at… - [Clean-room development](https://swarmops.cc/docs/policies/clean-room.md): SwarmOps is built from its own specification. Third-party designs, articles and code may inform what SwarmOps should do; they never supply how it is written.… - [Toolchain, MSRV and platforms](https://swarmops.cc/docs/policies/msrv-and-platforms.md): rust-toolchain.toml pins Rust 1.100.0 (with rustfmt, clippy and llvm-tools), so every local build and every CI run uses exactly that compiler. The one… - [Versioning and stability](https://swarmops.cc/docs/policies/versioning-and-stability.md): SwarmOps 0.1.0 was the first release, tagged v0.1.0, and each release is tagged v. Every crate of the workspace is at the workspace version… ## Optional - [swarmops ancestry](https://swarmops.cc/docs/reference/commands/ancestry.md): Compare two revisions' ancestry along every parent: whether FROM is an ancestor of TO, their merge bases, and a page of the changesets TO reaches and FROM… - [swarmops blob get](https://swarmops.cc/docs/reference/commands/blob-get.md): Print the blobs the IDs name, each with its size and content as cat gives a file's. - [swarmops blob has](https://swarmops.cc/docs/reference/commands/blob-has.md): Of the IDs given, list those the store holds blobs under. - [swarmops blob put](https://swarmops.cc/docs/reference/commands/blob-put.md): Store FILE's content as a blob, outside any commit, and print its id, which a change names it by: {"blob": ID}. A change list holds at most 64 MiB and a… - [swarmops cat](https://swarmops.cc/docs/reference/commands/cat.md): Print one file at a revision, or part of it: from a byte, or a range of lines. - [swarmops clone](https://swarmops.cc/docs/reference/commands/clone.md): Make a store from a git remote: a new store in --into, the remote recorded as --remote (origin), fetched, and its followed branch (--branch, else the remote's… - [swarmops commit](https://swarmops.cc/docs/reference/commands/commit.md): Record a changeset from a list of changes; with --advance, also move that ref to it. - [swarmops derive](https://swarmops.cc/docs/reference/commands/derive.md): Derive the eager derived values of new changesets, ahead of any reader. - [swarmops diff](https://swarmops.cc/docs/reference/commands/diff.md): List the files that differ between two revisions, a page at a time. - [swarmops fetch](https://swarmops.cc/docs/reference/commands/fetch.md): Fetch a git remote into the store's mirror, and its followed branch into the store. - [swarmops gc](https://swarmops.cc/docs/reference/commands/gc.md): Remove the store's leftovers: temp files past a day, a crashed create's staging, derived values of older versions, what an upgrade left. Never an object or a… - [swarmops git export](https://swarmops.cc/docs/reference/commands/git-export.md): Send the store's history to git: every commit of --ref's history that the last export into --branch does not reach is written into the git repository at PATH,… - [swarmops git import](https://swarmops.cc/docs/reference/commands/git-import.md): Bring a git repository's history in: every commit --ref reaches that the store does not hold becomes a changeset, parents first, and --into moves to the… - [swarmops history](https://swarmops.cc/docs/reference/commands/history.md): List the changesets that changed a path, newest first, along first parents. - [swarmops info](https://swarmops.cc/docs/reference/commands/info.md): Describe the store. - [swarmops init](https://swarmops.cc/docs/reference/commands/init.md): Create a store in DIR, and describe it. - [swarmops land-check](https://swarmops.cc/docs/reference/commands/land-check.md): Say what landing changes in order onto a ref would come to, writing nothing. - [swarmops land-group](https://swarmops.cc/docs/reference/commands/land-group.md): Land changes in order onto a ref as one operation: one changeset each, one move. - [swarmops land](https://swarmops.cc/docs/reference/commands/land.md): Merge a change three-way onto a ref and publish it there as one new changeset. - [swarmops log](https://swarmops.cc/docs/reference/commands/log.md): List history along first parents, newest first. - [swarmops ls](https://swarmops.cc/docs/reference/commands/ls.md): List one directory at a revision (the root without a PATH), and with --depth the directories below it. - [swarmops mcp](https://swarmops.cc/docs/reference/commands/mcp.md): Serve the store's operations to an agent as an MCP server on stdin and stdout. - [swarmops merge-base](https://swarmops.cc/docs/reference/commands/merge-base.md): Find where REV forks from ONTO along first parents, and list what REV changed since. - [swarmops op log](https://swarmops.cc/docs/reference/commands/op-log.md): List the store's operations, newest first: each write transaction, its changesets and its ref moves. - [swarmops op undo](https://swarmops.cc/docs/reference/commands/op-undo.md): Move every ref operation OP moved back to what it named before, all or none. - [swarmops push](https://swarmops.cc/docs/reference/commands/push.md): Send a store ref to a remote branch by compare-and-swap, never by force: the remote moves only from the head the last fetch saw, to a descendant of it. - [swarmops rebase](https://swarmops.cc/docs/reference/commands/rebase.md): Merge a change three-way onto a ref's head and record the result there as one changeset, moving no ref. - [swarmops ref delete](https://swarmops.cc/docs/reference/commands/ref-delete.md): Delete ref NAME. - [swarmops ref list](https://swarmops.cc/docs/reference/commands/ref-list.md): List every ref, or those whose names start with --prefix, each with its kind. - [swarmops ref log](https://swarmops.cc/docs/reference/commands/ref-log.md): List ref NAME's moves, newest first: the op log filtered to the ref. - [swarmops ref set](https://swarmops.cc/docs/reference/commands/ref-set.md): Point ref NAME at REV: move it from --expect, or --create it. - [swarmops ref txn](https://swarmops.cc/docs/reference/commands/ref-txn.md): Move several refs as one operation, each by compare-and-swap: all of them or none. - [swarmops remote add](https://swarmops.cc/docs/reference/commands/remote-add.md): Record a git remote in the store. - [swarmops remote list](https://swarmops.cc/docs/reference/commands/remote-list.md): List the store's git remotes. - [swarmops remote remove](https://swarmops.cc/docs/reference/commands/remote-remove.md): Forget a git remote, and the mirror's refs of it; no changeset is removed. - [swarmops repair](https://swarmops.cc/docs/reference/commands/repair.md): Rebuild what the journal can rebuild, quarantine damaged objects, drop damaged cache entries, then verify; the journal itself is never cut. - [swarmops resolve](https://swarmops.cc/docs/reference/commands/resolve.md): Name the changeset REV names, and whether REV is a ref's name. - [swarmops revert](https://swarmops.cc/docs/reference/commands/revert.md): Take back a changeset, or a range of a ref's history, by landing its inverse. - [swarmops schema](https://swarmops.cc/docs/reference/commands/schema.md): Print the JSON Schema of every request and response type, or of TYPE's. - [swarmops serve](https://swarmops.cc/docs/reference/commands/serve.md): Serve the stores under --root to stock git: fetch, clone and push over ssh as a forced command, or over smart HTTP as a CGI program. One process per… - [swarmops show](https://swarmops.cc/docs/reference/commands/show.md): Show one changeset. - [swarmops sync status](https://swarmops.cc/docs/reference/commands/sync-status.md): Show how main and a git remote's followed branch stand, as the last fetch saw it. - [swarmops sync](https://swarmops.cc/docs/reference/commands/sync.md): Fetch the remote, land main's unpublished changes onto its head, move main there, and push it. - [swarmops upgrade](https://swarmops.cc/docs/reference/commands/upgrade.md): Move the store to the latest format this build writes. Irreversible: older releases do not open it afterwards. - [swarmops verify](https://swarmops.cc/docs/reference/commands/verify.md): Check the store's consistency. - [swarmops whoami](https://swarmops.cc/docs/reference/commands/whoami.md): Show the identity this caller's changes carry. - [swarmops ws commit](https://swarmops.cc/docs/reference/commands/ws-commit.md): Record a workspace's edits as one changeset on its head. - [swarmops ws create](https://swarmops.cc/docs/reference/commands/ws-create.md): Make a workspace NAME in a directory of its own, and bootstrap it. - [swarmops ws delete](https://swarmops.cc/docs/reference/commands/ws-delete.md): Remove a workspace's directory, then its entry. - [swarmops ws diff](https://swarmops.cc/docs/reference/commands/ws-diff.md): A workspace's edits against its head, as diff gives a diff. - [swarmops ws discard](https://swarmops.cc/docs/reference/commands/ws-discard.md): Restore paths of a workspace from its head, every changed one without a PATH: the edits are lost. - [swarmops ws hook](https://swarmops.cc/docs/reference/commands/ws-hook.md): The agent hosts' hooks: read the hook's JSON on stdin, print what the hook expects. - [swarmops ws info](https://swarmops.cc/docs/reference/commands/ws-info.md): Describe one workspace: its directory, base, head and prefixes. - [swarmops ws land](https://swarmops.cc/docs/reference/commands/ws-land.md): Land a workspace's chain on its target; with --check, rebase, check and land the checked tree. - [swarmops ws list](https://swarmops.cc/docs/reference/commands/ws-list.md): List the store's workspaces. - [swarmops ws materialize](https://swarmops.cc/docs/reference/commands/ws-materialize.md): Write out more of a workspace's tree: the paths join its prefixes. - [swarmops ws rebase](https://swarmops.cc/docs/reference/commands/ws-rebase.md): Move a workspace's chain onto its target's head, and its files with it. - [swarmops ws resolve](https://swarmops.cc/docs/reference/commands/ws-resolve.md): Mark conflicting paths of a rebase resolved. - [swarmops ws snapshot](https://swarmops.cc/docs/reference/commands/ws-snapshot.md): Record a workspace's edits as a changeset on its head, which moves no ref. - [swarmops ws status](https://swarmops.cc/docs/reference/commands/ws-status.md): What changed in a workspace against its head, and how far its target has moved. - [ancestry](https://swarmops.cc/docs/reference/mcp-tools/ancestry.md): Along every parent, a merge's other parents too: whether from is an ancestor of to, their merge bases, and the changesets to reaches and from does not, newest… - [blob_has](https://swarmops.cc/docs/reference/mcp-tools/blob-has.md): Of the blob ids given, the ones the store holds blobs under: the contents a commit can name by id without storing them again. - [blob_put](https://swarmops.cc/docs/reference/mcp-tools/blob-put.md): Stores content as a blob, outside any commit, and gives its id: a commit's change then names it as {"blob": id} content instead of carrying its bytes, the way… - [commit](https://swarmops.cc/docs/reference/mcp-tools/commit.md): Records a changeset from an explicit change list, on parent or else on main's head. With advance it also moves that ref to the changeset in the same… - [diff](https://swarmops.cc/docs/reference/mcp-tools/diff.md): The files that differ between two revisions, in path order: with format names (the default) each one's path and status, with stat also its line counts, with… - [fetch](https://swarmops.cc/docs/reference/mcp-tools/fetch.md): Fetches a git remote, by its name, into the store's mirror, and its followed branch's commits into the store as changesets; main never moves. Run again with… - [gc](https://swarmops.cc/docs/reference/mcp-tools/gc.md): Removes the store's leftovers (temp files past a day, a crashed create's staging, derived values of older versions, what an upgrade left) and never an object… - [land_check](https://swarmops.cc/docs/reference/mcp-tools/land-check.md): Says what landing changes (1 to 32, each a head with an optional base and idempotency\_key) in order onto target, main by default, would come to, each merged… - [land_group](https://swarmops.cc/docs/reference/mcp-tools/land-group.md): Lands changes (1 to 32, each a head with an optional base and idempotency\_key) in order onto target, main by default, as one operation: each merged onto what… - [land](https://swarmops.cc/docs/reference/mcp-tools/land.md): Merges head (with its first-parent chain since base) three-way onto target, main by default, and publishes the result as one changeset in one transaction; on… - [log](https://swarmops.cc/docs/reference/mcp-tools/log.md): History along first parents, newest first, from main unless rev says otherwise; pass a limit of 100 or less and page on with the cursor, since clients limit… - [merge_base](https://swarmops.cc/docs/reference/mcp-tools/merge-base.md): Where rev forks from onto along first parents: the base, both revisions as full ids, and the first page of the unified diff from the base to rev; pass a limit… - [op_log](https://swarmops.cc/docs/reference/mcp-tools/op-log.md): The store's operations, newest first: each write transaction, with the id undo takes, its kind, the changesets it recorded and the refs it moved; pass a limit… - [path_history](https://swarmops.cc/docs/reference/mcp-tools/path-history.md): The changesets that changed a file, or anything below a directory, newest first along first parents from main unless rev says otherwise, each with what the… - [push](https://swarmops.cc/docs/reference/mcp-tools/push.md): Sends a store ref (main by default) to a git remote's branch by compare-and-swap, never by force: the remote moves only from what the last fetch saw. A remote… - [read_file](https://swarmops.cc/docs/reference/mcp-tools/read-file.md): Reads one file at a revision, without a checkout, as UTF-8 text or base64, from offset or the lines a range names; pass max\_bytes of 32768 or less (less for… - [read_tree](https://swarmops.cc/docs/reference/mcp-tools/read-tree.md): Lists one directory at a revision, without a checkout, a page of entries at a time, each file with its size, and with depth the directories below it too; pass… - [rebase](https://swarmops.cc/docs/reference/mcp-tools/rebase.md): Merges head (with its first-parent chain since base) three-way onto onto's head, main by default, as land merges it, and records the result as one changeset… - [ref_delete](https://swarmops.cc/docs/reference/mcp-tools/ref-delete.md): Removes a ref by compare-and-swap, if it still holds expected\_old, the full 64-hex changeset id it held when you read it; a ref name or a relative revision… - [ref_list](https://swarmops.cc/docs/reference/mcp-tools/ref-list.md): Every ref, the changeset it points at, and how many moves it has had. - [ref_log](https://swarmops.cc/docs/reference/mcp-tools/ref-log.md): One ref's moves, newest first: the op\_log entries that moved it, each with its op, old and new value, actor and time; a deleted ref lists its moves, and a… - [ref_set](https://swarmops.cc/docs/reference/mcp-tools/ref-set.md): Moves a ref, or creates one, by compare-and-swap: give create, or expected\_old, the full 64-hex changeset id the ref held when you read it; a ref name or a… - [ref_txn](https://swarmops.cc/docs/reference/mcp-tools/ref-txn.md): Moves 1 to 64 refs as one operation, each by compare-and-swap, all of them or none: each move names its ref, expect (the full 64-hex changeset id it holds… - [remote_list](https://swarmops.cc/docs/reference/mcp-tools/remote-list.md): The git remotes the store records: each one's name, URL, followed branch and the token variable it names, if any. Adding and removing remotes is the CLI's. - [repair](https://swarmops.cc/docs/reference/mcp-tools/repair.md): Rebuilds what the journal can rebuild (its offsets, the index, the ref files), quarantines damaged objects and drops damaged cache entries, then verifies; the… - [repo_info](https://swarmops.cc/docs/reference/mcp-tools/repo-info.md): What the store is and holds: its id and name, the changeset main points at, and how many changesets and refs it has. - [resolve_rev](https://swarmops.cc/docs/reference/mcp-tools/resolve-rev.md): The full id of the changeset a revision names (a ref name, a full id or a unique prefix of 12 or more hex digits, then any \~N suffixes), resolved as every… - [revert](https://swarmops.cc/docs/reference/mcp-tools/revert.md): Takes back changeset (with since, the first-parent range after since) on target, main by default, by landing its inverse: what the target gained since stays,… - [show](https://swarmops.cc/docs/reference/mcp-tools/show.md): One changeset in full: its parents, author, message, changes and signatures; pass max\_changes of 100 or less, since clients limit long tool results. - [sync_status](https://swarmops.cc/docs/reference/mcp-tools/sync-status.md): How main and a git remote's followed branch stand, as the last fetch saw the remote: how many changes are unpublished and how far behind main is, offline;… - [sync](https://swarmops.cc/docs/reference/mcp-tools/sync.md): Fetches a git remote, lands main's unpublished changes onto its head (those the remote holds already are dropped), moves main there and pushes it; with mode… - [undo](https://swarmops.cc/docs/reference/mcp-tools/undo.md): Moves every ref an operation of op\_log moved back to what it named before, by compare-and-swap in one transaction: all of them or none. It takes the… - [upgrade](https://swarmops.cc/docs/reference/mcp-tools/upgrade.md): Moves the store to the latest format this build writes, which takes free-form branches and tags; irreversible, older releases do not open it afterwards. On a… - [verify](https://swarmops.cc/docs/reference/mcp-tools/verify.md): Checks the whole store's consistency; deep re-hashes every object and checks the derived values against the objects too. - [Changelog](https://swarmops.cc/docs/changelog.md): Notable changes to SwarmOps. The format follows Keep a Changelog 1.1.0, and versions follow the versioning policy (Semantic Versioning, read the pre-1.0 way).