v10.0 · capability reference

The Strains

A strain is an agent with a role, a key, a journal and a scope, living in your Google Cloud project. This page is the full inventory of what v10.0 gives it — the buyer-facing claim first, then the mechanism that makes the claim true, down to the envelope byte layout and the error codes.

Serverless git Post-quantum at rest Dual-era MCP ~55 tools A2A agent cards Portable state Apache-2.0
Orientation

One image, your project, no vendor in the path

Everything below runs inside a Google Cloud project you own, from a single container image built by ./install.sh. There is no Paracoding-hosted tier, no relay, no telemetry endpoint to opt out of. The licence is Apache-2.0 and the source ships with the thing it describes, so every mechanism on this page is one git clone from being checked rather than believed.

How to read this page. Each section opens with the plain claim a buyer needs and then gives the engineer the exact structure — the transaction boundary, the byte layout, the error code, the failure mode. If a paragraph does not survive being read by someone who will go and look at the file, it should not be here.
Version control

Serverless git — no server, no clone, no disk

Your agents get real git — commits, branches, diffs, logs, archives — with nothing to run and nothing to pay for when nobody is asking. There is no git server to patch, no persistent disk to fill, no clone to go stale. It scales to zero between requests.

The engine is isomorphic-git running inside Cloud Run over a split backing store. Mutable, small, transactional state lives in Firestore documents: refs, HEAD, config, the .git/index, packed-refs, and the working tree. Immutable, large, content-addressed state lives in Google Cloud Storage: the objects. Each store is used for the thing it is actually good at, which is why there is no disk in the picture at all.

Firestore
refs, HEAD, config, .git/index, packed-refs, working tree — small, mutable, transactional
GCS
git objects — large, immutable, content-addressed, each one sealed in a PCV1 envelope
Compute
Cloud Run, request-scoped, scales to zero; no attached volume, no local repository state between requests

Compare-and-swap lives above the library, not inside it

This is the load-bearing design decision. Isomorphic-git's native writeRef is a blind overwrite: it takes the value you hand it and stores it, with no notion of what the ref pointed at a moment ago. Its AsyncLock is an in-process mutex, which is worth exactly nothing on Cloud Run, where two concurrent requests are routinely two different container instances that share no memory. Relying on either would give you a race that only appears under load and only corrupts history when it does.

So the compare-and-swap is lifted above the library. A ref update is a Firestore transaction that reads the current OID, checks it against the expected prior OID the caller supplied, and writes the new value only if they match — with Firestore's own transactional retry semantics doing the arbitration between instances. The library is never trusted to serialise anything. It is used as an object-format implementation and nothing more.

The ref resolver

The second correctness rule: every call into isomorphic-git receives an already-resolved 40-hex object ID. Symbolic names, short OIDs, HEAD, branch names and tags are resolved before the library sees them, and a value that is not exactly forty hex characters never reaches it. That removes a whole class of ambiguity where a library resolves a name against a store it half-understands and returns a plausible wrong answer.

ref update = firestore.runTransaction(tx => {
  const current = tx.get(refDoc);          // observed OID, or absent
  if (current !== expectedPriorOid) throw STALE / NOT_FOUND;
  tx.set(refDoc, { oid: newOid40Hex });    // only reachable on match
});
// isomorphic-git is called only with resolved 40-hex OIDs.
// There is no code path that writes a ref without the expected-prior check.

Push outcomes are classified, not retried

A push that loses the race is not silently attempted again. The outcome is classified and returned to the caller, which for an agent is the difference between rebasing on new work and quietly clobbering it.

OutcomeWhat the transaction sawWhat it means for the caller
ALREADY_EXISTS The ref is already at the OID you proposed. Success, idempotently. A retried or duplicated push converges instead of erroring; nothing is written twice.
NOT_FOUND The ref, or the base the update is anchored to, is not there. Refused. You asked to move something from a state that does not exist. Re-read the ref and decide deliberately.
STALE The ref exists but is at an OID other than your expected prior. Refused. Someone committed under you. Fetch the current head, rebase the work, push again.
No force push exists. Not hidden behind a flag, not behind a role — there is no code path in the tree that writes a ref without the expected-prior check. An agent that has convinced itself the fastest way past a conflict is to overwrite the branch cannot do it. The worst it can do is get told STALE again.
Encryption at rest

Post-quantum envelopes on every object

Your repository contents are encrypted in your own project before they touch storage, with key encapsulation designed to survive a quantum adversary. The threat model is harvest-now-decrypt-later: an object copied out of a bucket today should still be useless to whoever copied it in fifteen years.

Every git object is sealed in a PCV1 envelope. The layout is fixed and self-describing:

PCV1 envelope
+---------+-------+-------+------------+---------------------+---------+
| magic   | epoch | flags | nonce (12) | ciphertext (n)      | tag(16) |
+---------+-------+-------+------------+---------------------+---------+

cipher : AES-256-GCM
kdf    : HKDF-SHA256
aad    : the full GCS object key of this exact blob
kem    : X-Wing hybrid  =  ML-KEM-768  +  X25519   (1120 bytes of KEM ciphertext)
unwrap : Cloud KMS, useToDecapsulate
magic
Identifies the envelope format, so a stored blob is never guessed at. A byte string that is not a PCV1 envelope is rejected rather than parsed hopefully.
epoch
The key-scheme generation. Epoch 0 used ML-KEM-1024; epoch 1 is the X-Wing hybrid. Epoch is read from the envelope, so old objects stay readable without a rewrite.
flags
Reserved envelope-level bits, checked on open. Unknown flags fail the open instead of being ignored.
nonce (12)
Per-object GCM nonce. Twelve bytes, the GCM-native size, so no rehashing step is introduced between the nonce and the cipher.
tag (16)
The GCM authentication tag. Any bit flipped anywhere in the envelope — including in the AAD — fails the open. There is no unauthenticated read path.

The AAD is the point

The additional authenticated data binds the ciphertext to the full GCS object key it is stored under. That is not decoration. Without it, a valid envelope from one repository is a valid envelope everywhere: an attacker with write access to the bucket could move a blob from one project path to another, or from a repo you do not care about into one you do, and the decrypt would succeed and hand you attacker-chosen content that authenticates cleanly. Binding the object key means an envelope decrypts at exactly one path and nowhere else. Two repos with identical paths, identical trees and identical plaintext still cannot collide.

X-Wing: break the lattice and the curve

Key encapsulation is X-Wing hybrid post-quantum: ML-KEM-768 combined with X25519, 1120 bytes of KEM ciphertext, unwrapped through Cloud KMS with useToDecapsulate so the long-term private half never leaves KMS. Hybrid is chosen deliberately. ML-KEM is young enough that a structural break is a real possibility; X25519 is old enough to be well understood but falls to a sufficiently large quantum computer. An attacker has to break both to recover a key — the lattice and the elliptic curve. Betting on either one alone is the thing this design refuses to do.

Cross-validated, 57 of 57

A hand-rolled envelope format is worth nothing if the implementation quietly disagrees with the specification it claims to follow. The v10.0 implementation is cross-validated against an independent implementation across 57 vectors, 57 of 57 passing, byte-identical under a fixed nonce. Fixing the nonce is what makes the comparison meaningful: with a random nonce two correct implementations produce different bytes and you can only check round-trips, which hides whole categories of derivation bug. Pinning it means the output is compared byte for byte.

Migration is a read-time property, not a maintenance window. Epoch 1 moved key encapsulation from ML-KEM-1024 to the X-Wing hybrid. Because the epoch travels in the envelope header, an object written under the old scheme is still opened correctly by the current code. There is no flag day, no bulk re-encrypt job that has to complete before your history is readable again.
Protocol

Dual-era MCP on one endpoint

Your clients connect and work. A 2025-era client and a 2026-era client hit the same URL and each gets the protocol it understands, with no version in the path, no second deployment and no migration window where half your tools are unreachable.

A single POST /mcp serves MCP revision 2026-07-28 — stateless, per-request metadata, structured error codes -32020, -32021 and -32022 — alongside the 2025-era initialize handshake with its session-oriented lifecycle. Both eras are first-class. Neither is a shim bolted onto the other.

Era routing is a pure function of one request's bytes

The router looks at the bytes of the request in front of it and nothing else. No connection state. No cache keyed on client identity. No clock, no cutover date, no "after this timestamp assume the new era". That property is what makes the endpoint safe on Cloud Run, where the next request from the same client may land on a different instance that has never seen it, and where an instance may be recycled mid-conversation. A stateful router would produce the worst kind of bug: correct in development, correct under low load, and intermittently wrong in production exactly when traffic is interesting.

POST /mcp
  |
  +-- classify(request bytes)  -- pure; no session, no cache, no clock
  |     |
  |     +-- 2026-07-28 : stateless, per-request metadata, -32020/-32021/-32022
  |     +-- 2025 era   : initialize handshake, session lifecycle
  |
  +-- one handler set, one tool registry, one auth path

The boot assertion that is deliberately uncaught

SDK v2 loadability is asserted at container boot, and the assertion is deliberately not wrapped in a try/catch. If the dependency is broken, the process dies on startup.

That looks reckless for about five seconds, and then it is obviously the safe choice. Cloud Run only shifts traffic to a revision that comes up healthy. A container that fails its boot assertion never becomes the serving revision, so the previous good revision keeps taking traffic and your agents keep working. The alternative — catching the error, logging a warning, and starting anyway — produces a green, healthy-looking box that is quietly missing a capability, and you find out through a client failing in a way nobody can reproduce. Failing at boot converts a subtle correctness bug into a loud deployment failure. Loud deployment failures are cheap.

Tools

Your own MCP server, not a tenant on someone else's

Roughly 55 tools behind full OAuth 2.1, running in your project, with the source in the same repository as the description. Nobody else's rate limit, nobody else's retention policy, nobody else's outage.

The tools are grouped by what they touch. Everything below is called by a strain over MCP, attributed to that strain's identity, and written into the journal.

Work items
A durable queue: post_work_item, list_work_items, complete_work_item, cancel_work_item. Work outlives the conversation that created it.
Memory graph
Entities, relations and observations: create_entities, create_relations, add_observations, delete_entities, delete_relations, delete_observations, read_graph, search_nodes, open_nodes.
Journal & history
append_journal, read_journal, log_history, read_history, search_history. Append-oriented, per-strain, searchable.
Files
list_files, read_file, write_file, put_file — encrypted project storage, not a scratch disk on an instance that is about to be recycled.
Git
git_list, git_read, git_log, git_diff, git_archive, git_propose, git_propose_patch, git_push — the serverless engine described above.
Execution
run_command, stage_privileged_job, run_status, run_roll, read_job_log, list_pending_confirm — the staged, signed path documented on the security page.
Infrastructure
gcp_api plus lifecycle tools for compute — start, stop, status, resize. Your project, your quota, your bill.
Messaging (A2A)
ask_agent, answer_message, check_answer, list_my_messages. Strain-to-strain, durable, journalled.
Session
whoami, get_time, refresh — identity, an authoritative clock, and re-reading state after someone else has changed it.
It also ships as an Agent Plugins package. The same server is published in the agent-plugins.org format, so any client that reads that format can connect without bespoke wiring. Full OAuth 2.1 either way — there is no long-lived shared secret pasted into a config file as the supported path.
Multi-agent

A2A, the work queue, and per-strain identity

More than one agent, working at once, without a shared account and without a group chat where everybody sees everything and nobody is accountable for anything.

Agent-to-agent messaging is three primitives: ask_agent puts a question to another strain, answer_message answers one, check_answer collects the reply. Messages are durable, so a strain can ask something and go away; the answer is waiting when it comes back rather than lost with the session. On top of that sits a work-item queue with a Vertex-backed model bus, so a unit of work is a record with a lifecycle rather than a sentence in a transcript.

Identity is per strain, not per installation

Every strain has its own identity. Every action is attributed to it, scoped by its role, and written to the journal under that role. The security consequence is direct and worth stating plainly: a leaked key leaks a role, not the system. Whoever holds it can do the things that role can do, in the places that role can reach, and every one of those actions is journalled with the role's name attached. That is a bounded, visible incident. A single shared credential across every agent is an unbounded, invisible one.

Agent cards

Each strain publishes an A2A agent card at a well-known path, so another system can discover what a strain is and what it does without a human writing an integration document:

GET /agents/{role}/.well-known/agent-card.json

Discovery follows the same rule as everything else here: the card describes a role, so what is discoverable is a capability surface, not a set of credentials.

Continuity

Portable agent state

Hit a usage limit, switch plans, change providers, change laptops. Paste the bootstrap and the agent picks up where it stopped, with its full history. You are not renting your agent's memory from the vendor whose limit you just hit.

Memory, journal, history, files and git all live in your project, encrypted with the PCV1 envelopes described above. None of it is in the chat transcript, which means none of it is hostage to the chat transcript. The transcript is a view onto the state; it is not the state.

Memory graph
Entities, relations, observations — in Firestore, in your project.
Journal
Per-strain append log of what was done and what it returned.
History
Searchable record across sessions, not truncated to fit a window.
Files
Encrypted object storage, addressed by path, bound by AAD to that path.
Git
Full history, refs and objects — the work itself, not a summary of it.

The practical test is the one everybody eventually runs by accident: you are mid-task, you run out of quota, and you move. With state in the project, the move costs a paste. With state in the vendor's session, the move costs the work.

The Flow Hood

It builds and it deploys

Ask a strain in the console chat for a service. It writes it, builds the container, deploys it to Cloud Run in your project, then fetches the result anonymously and reports the HTTP code back to you.

The last step is the one that matters. Plenty of systems will tell you a deployment succeeded because the deploy API returned 200. This one goes back and asks the internet, with no credentials attached, what your service actually says — and reports that code. An anonymous fetch answers a different question from a deploy response: not "did the platform accept my request" but "can something outside this project reach the thing I just made, and what does it get". A 403 there is real information about your IAM, not a failure of the build.

1

Ask

You describe the service in the console chat. The strain writes the code into your project's git.

2

Build

The container is built in your project, from your source, on your billing account.

3

Deploy

It goes to Cloud Run as a new revision. Cloud Run's own rule applies: traffic only moves to a revision that comes up healthy.

4

Verify

An anonymous request is made to the deployed URL and the HTTP status is reported back into the chat.

5

Journal

Who asked, what was staged, what ran and what it returned, recorded under the strain's role.

Console

Strain settings, in one panel

The things you actually change — who is allowed in, which key is current, what the substrate is, how a session hands off — are in one place, not scattered across six cloud consoles.

The Paracoding console settings panel, showing theme selection, the substrate (Google Cloud project) the strain is bound to, key rotation, session paste handoff, and the list of allowed accounts.

Strain settings: theme, substrate, key rotation, session pastes, allowed accounts.

Substrate
The Google Cloud project this strain lives in. Everything — Firestore documents, GCS objects, KMS keys, Cloud Run revisions — is in that project and on that bill.
Key rotation
Rotate a strain's credential from the console. Because identity is per strain, rotating one key does not interrupt every other strain.
Session pastes
The bootstrap handoff. This is the mechanism behind portable state: paste it into a new session, on a new plan, and the agent resumes against the same project.
Allowed accounts
Who may reach the console at all. Read Security before you edit this list — and add your second in-domain account before you need it, not after.
Theme
Cosmetic, and included here for completeness, because a settings page that hides its boring options is a settings page people stop trusting.
Institutional memory

The internal wiki

A place inside your own install where what was learned gets written down — readable by the next strain and by the next human, without leaving the project.

The journal answers "what happened". The wiki answers "what do we know". They are different questions and they age differently: a journal entry is true forever about one moment, and a wiki page is supposed to be true right now about a subject. Keeping them apart stops the journal from being edited to look tidy and stops the wiki from becoming an unreadable chronological log.

Wiki pages are stored in the same encrypted project storage as everything else, so they travel with the state: they are covered by the same PCV1 envelopes, the same per-strain attribution, and the same portability. A strain that works something out — a quirk of your IAM layout, why a build flag is set the way it is, which of two plausible approaches already failed — can write it where the next strain will find it instead of re-deriving it at your expense on every future run.

Why this belongs in the product and not in a SaaS wiki. Documentation about your infrastructure is a description of how to operate your infrastructure. Keeping it in the same project, under the same encryption and the same access controls as the infrastructure itself, means there is one perimeter to reason about rather than two.
Supply chain

The release proves things about itself

You should not have to take a release's word for what is in it. v10.0 is generated deterministically, archived reproducibly, and shipped with a hash for every file.

Deterministic cut
The release generator is run twice and the two trees are compared with diff -r. The expected result is zero differences. A build that cannot reproduce itself on the same machine cannot be reproduced by you.
Reproducible archives
Fixed mtime, gzip level 9, file modes taken from the tree. Timestamps and compression settings are the usual reason two identical trees produce two different tarballs; both are pinned.
Per-file manifest
SHA-256 for every file in the release, so verification is per file rather than one hash over one blob you have to trust wholesale.
Leak ratchets
Automated checks for secrets and sensitive strings, ratcheted — the threshold only tightens. A check that can be relaxed to make a release go out is not a check.
Defect-seeded smoke tests
For every assertion, a defect is deliberately seeded and the verdict is required to flip. A check that cannot fail is worse than no check: it produces confidence without evidence.

The defect-seeding rule is the one worth internalising. A test suite that has never seen a failure has not been shown to detect anything — a green run is equally consistent with "the code is correct" and "the assertion is inert". Seeding a defect for each assertion and requiring the verdict to flip is the difference between a suite that reports and a suite that merely agrees.

Verify before you install. The tarball, the manifest and the tag are on the v10.0 release page. Check the per-file hashes against the manifest, read install.sh, then run it. It takes no arguments.
Provenance

How this was built

By one human and a fleet of strains, in public, with the console open beside the model that was helping write it.

Launch day: the Paracoding console running beside Claude Max in Cowork, the agent control plane and the model that helped build it side by side on one screen.

Launch day — the console beside Claude Max in Cowork.

Paracoding is what happened when the tooling for building it became the product. The serverless git exists because agents needed version control that scaled to zero and did not require a box to babysit. The classified push outcomes exist because an agent that retries a lost race destroys work. The defect-seeded tests exist because a fleet writing its own tests will cheerfully write assertions that always pass. Every mechanism on this page is a scar from building the thing with the thing.

That is also why the source ships with it, under Apache-2.0, with no paid tier and no unlock. What you pay is your own Google Cloud bill and your own model plans. There is nothing to buy here, which is the strongest form of the claim that nothing on this page depends on us staying in business.