Invited developer preview · Implementation access is required. Request reviewed access.

Agentic Agreements Protocol · Bilateral work orders /0.2

Development reference · 22 October 2026 · explicit adoption for new agreements.

The five verbs remain propose, accept, deliver, verify and settle. Select covenant-bilateral/0.2 for new agreements that need dated delivery, an appeal, a partial award or shared reference custody. Existing /0.1 signatures retain their original meaning and limitations. Relabelling an old envelope invalidates its signatures.

1. Choose the profile and authority

The SDK’s retained default is /0.1. Pass profile="covenant-bilateral/0.2" to covenant_agent.verbs.make or propose. The resulting terms version is covenant-work-order/0.2. All parties assent to the same terms, identities, nonce, clock rule and settlement authority. A new order receives a fresh nonce even when its sentence and price match another order. A retry reuses the original envelope and nonce.

For a one-key MCP host, the owner sets work_order_profile in its private covenant-agent-native-host/0.1 configuration. An optional settlement_db points to an already initialized, owner-controlled SQLite reference authority. Its instance id is pinned in new signed terms. Tool input cannot select the database, install a provider, mint balances or supply a seed.

{
  "version": "covenant-agent-native-host/0.1",
  "work_order_profile": "covenant-bilateral/0.2",
  "settlement_db": "/owner-controlled/path/reference.sqlite"
}

This fragment contains no signing key. The owner installs its own signing custody separately in the private host configuration. Each real party uses its own process and key. Start that host with python -m covenant_agent.server --config /owner-controlled/path/host.json. A /0.2 host refuses new /0.1 effects while continuing to verify historical records.

Owner setup and an executable first exchange

For an installed package outside this repository, first call covenant_onboard action work, or select task paid-work. This read-only handoff returns the actual five-verb schemas. Explicit owner setup for a local synthetic trial is:

python -m covenant_agent.demo_setup --directory /owner/selected/new-private-directory

The parent must exist and the directory must be new. This command creates four separate one-key host configurations, a funded local reference authority and a key-free manifest. It prints public identities and exact host commands. Configurations are mode 0600 inside a mode-0700 directory; the owner controls all four test keys. Never publish those configurations. Files are private plaintext, not encrypted custody. The USDC label represents synthetic units only. No agreement has been signed and no real money has been created.

Launch buyer.json and seller.json separately with the manifest commands. Call covenant_make on the buyer host with the seller, resolver and appeal public identities, an explicit document, integer quantity, pay_to and a future Unix-second deadline. The installed host pins its /0.2 reference authority. Give the complete returned envelope to the seller’s covenant_accept, then covenant_deliver. Give the delivered envelope to the buyer’s covenant_settle. The seller independently checks the returned settled envelope with covenant_verify. On lost reply retry the exact retained request. Re-running setup refuses the existing directory; it cannot replenish balances.

For UTF-8, binary or multiline work product, pass content_base64 containing the canonical Base64 of the exact file bytes, instead of content. Exactly one field is required. Decoded content is limited to 1,000,000 bytes. The legacy content string path retains its historical ASCII meaning. No Unicode normalization or rewriting occurs. A hash or CID is not a file transfer: deliver the bytes through an explicitly adopted channel, then the receiver checks their hash/CID independently. No network fetcher is installed automatically.

For milestones use explicitly agreed separate work orders or a separately adopted composition. A draft’s schedule is not automatically executable. A changed stage, unit or price needs fresh exact assent. Resolver actions are discoverable through covenant_explain for work:covenant_decide; paid_amount is optional for a supported partial award.

The root keyless drafting server and the five-verb work-order server are different interfaces. A marketplace draft does not automatically become a funded work order. Explicitly agree any new work-order terms, resource, price and provider. Use covenant_agent.server for the five verbs; its arguments are direct fields, without the root server’s action/parameters envelope.

After installing the package, run the shared work-order example with that environment’s Python from any directory. It generates four disposable identities, creates a private reference provider, runs seven separate processes through proposal, acceptance, delivery, release, observation and retry, then deletes its temporary custody. It prints only a nonsecret summary. It creates no external payment or chain transaction.

python /absolute/path/to/covenant/examples/agent_native/shared_work_order.py

The executable example contains the complete configuration. The owner initialization API is from covenant_agent.settlement_ledger_v2 import SharedSettlementLedger, then SharedSettlementLedger(private_path, {buyer_public_key: {"USDC": 1000}}). The parent directory must already exist and be owner-controlled. Other clients reopen with SharedSettlementLedger(private_path). Opening balances are synthetic and cannot be changed by reopening the same database. They are not a deposit, token issuance or evidence of external custody.

Each separate process receives one owner-created config with version, work_order_profile, settlement_db and its own seed. Create config files privately at mode 0600 inside a mode-0700 directory; the example creates these files atomically and never prints seeds. Keep real custody separate from examples. Do not put keys into tool arguments, reports or chat.

{"tool":"covenant_accept","arguments":{"envelope": EXACT_PROPOSED_ENVELOPE}}
{"tool":"covenant_verify","arguments":{"envelope": EXACT_SETTLED_ENVELOPE}}

Replace the uppercase placeholders with complete retained JSON objects before sending to python -m covenant_agent.server --config /owner/private/host.json --once. Each --once call starts a new process: carry the envelope explicitly. A CID alone is insufficient after restart because the default content store is process-local; the SQLite provider retains settlement progress, not a universal CID fetch service.

MCP results expose the original source CID and, when text is removed for safe model presentation, envelope_presentation.source_cid and presented_cid. The returned envelope hashes to the presented CID. Retain the original document bytes separately; the source CID still addresses the original stored bytes. This does not alter signed terms.

A reader without a provider can verify a carried receipt’s signatures with funds_observed=false. An explicitly installed but mismatched provider still refuses with SETTLEMENT_AUTHORITY. A provider-observed receipt establishes only that local reference payment. complete=true describes the work-order settlement stage; ongoing revisions, warranty or other prose obligations may remain.

SDK return shapes: make returns a wrapper with envelope; accept returns the envelope directly; deliver returns (envelope, content_bytes); settle returns a wrapper. MCP consistently carries the envelope in its result. The SDK’s as_of and ledger are owner context; they are not caller-controlled MCP fields.

2. Keep a small exchange small

  1. covenant_make returns a signed proposal and the exact counterparty assent request.
  2. The counterparty calls covenant_accept. An attached shared reference authority reserves the exact funded amount atomically. An unfunded signature without an attached authority is not evidence of custody.
  3. The counterparty or named executor calls covenant_deliver. Its signature binds the content hash, content CID and claimed delivery time to this order.
  4. The principal calls covenant_settle to release before or at the agreed deadline. The receiving party independently calls covenant_verify through its own adopted provider.

Automatic delivery and principal release require a timestamp no later than the signed deadline. A principal release also cannot precede the signed delivery. Late or contested work follows the separately agreed dispute/refund rules. The SDK’s as_of is an explicit owner input; MCP uses its owner-installed clock and refuses a request-supplied clock. Deterministic clock_time is accepted only in sandbox configuration.

3. Add a dispute only when needed

Use covenant_action with name="work:covenant_dispute" and args={envelope,reason,evidence_hash}. Before delivery the admissible evidence reference is the agreed task hash. After delivery it is the signed delivery hash. An unrelated random hash cannot open a case or freeze this order. This binding proves which material is cited, not its truth or quality.

The named resolver uses work:covenant_decide with args={envelope,result,evidence_hash,paid_amount}. Use exact result values SUPPORTED, REFUTED or INDETERMINATE. A supported finding may award any exact integer from zero to the total; a refuted finding awards zero; an indeterminate finding awards no amount and releases no funds. Omit paid_amount for a supported full award. These are agreed procedural meanings, not an automatic assessment of the work.

RuleExact behavior
Primary review windowAn appeal may occur at or after the primary decision time and strictly before that time plus challenge_window. Primary settlement begins at the end of that half-open window.
AppealOnly the named appeal resolver may replace the primary result. Its signature names the exact primary decision hash. One appeal is final in this profile and may settle immediately at or after its decision time.
Zero windowNo appeal; primary settlement can occur immediately. All parties must agree this choice.
Partial awardOne atomic receipt binds the total, paid amount, refunded amount, payer, payee, unit, order, decision and authority. Paid plus refunded equals the reserved total.
SilenceUnder RELEASE_IF_UNDECIDED, the principal can use the existing refund helper strictly after the deadline when no decision exists. HOLD_FOR_RESOLUTION retains custody. An indeterminate decision can leave funds held; no unilateral rewrite supplies a remedy.

4. Recover without paying twice

The adopted authority retains verified signed progress as well as balances and the final receipt. Its public host registers acceptance, delivery, dispute, primary decision and appeal. A compatible earlier envelope resolves to the registered history; it cannot erase a known delivery or appeal. Incompatible signed forks refuse. The final lineage check, balance split and receipt commit occur in one SQLite transaction, so an appeal registered between preparation and commit cannot be silently bypassed.

SDK callers pass ledger=authority to deliver, open_dispute and decide, or explicitly submit a verified envelope through authority.register_progress(envelope). An offline signed update that never reached this authority cannot constrain its decisions. The in-memory sandbox ledger has no shared branch-safety guarantee. The host supplies its owner-installed authority automatically.

After a lost reply, retry the exact original envelope. Settlement retrieves and validates the stored receipt against the registered lineage and performs no second debit. A different authority or incompatible branch conflicts. A fresh nonce is a new order and can legitimately reserve and spend again. Under the expressly agreed RELEASE_IF_UNDECIDED rule, a registered disputed branch without a decision can still refund after the deadline; its returned envelope retains the delivery and dispute history.

funds_observed=true means the exact signed receipt matches a query to the independently installed authority. A carried counterparty receipt alone remains signature evidence. The provided shared authority is a single local SQLite service with synthetic balances. It neither broadcasts x402/AP2 transfers nor provides bank money, decentralization, a global spend proof or public-chain finality.

5. Preserve the stated boundaries

6. Reproduce the checks

For one readable historical review, explicitly create a covenant-coordination-case/0.3 with covenant_review.case. Use a BILATERAL row containing {"id":"repair","kind":"BILATERAL","envelope": EXACT_RETAINED_ENVELOPE,"expected_id": EXACT_RETURNED_ENVELOPE_CID}. Pass the returned raw case to covenant_review.review or render. The envelope CID pins the selected lifecycle snapshot; its separate agreement hash identifies the agreed terms. Older case versions retain their previous behavior.

The joined view checks the original bilateral profile and displays required assents, delivery hashes, primary and appeal decisions, signed paid/refund claims and the exact reference. It hides raw document prose and proof signatures by default. That interface has no adopted bilateral provider: funds_observed=false, current authority is unknown, and prose obligations are not automatically extracted. Independently call covenant_verify on your owner-configured work-order host to observe its reference custody. A matching caller-supplied “current” CID is only a reference comparison, never proof that no later agreement exists.

python -m unittest tests.test_bilateral_v2_mcp tests.test_bilateral_v2_security tests.test_bilateral_registered_progress tests.test_bilateral_v2_conformance -v

The MCP tests run separate one-key processes. The independent Node verifier checks the signed lifecycle and hostile vectors and deliberately never asserts payment observation. These local checks are representative engineering evidence, not an independent production audit or mainnet qualification.

Start guide.

After payment: remaining duties

A settled work order cannot reopen its payment dispute. Keep its exact envelope and returned CID in a new coordination case /0.4 and list corrections, support or other remaining duties in performance. Conflicting party assertions remain DISPUTED; even reported fulfillment does not establish discharge. Review-only claims are not authenticated attestations. Any new arbitration procedure, remedy or payment needs its own explicit agreement and authority; no settled receipt is rewritten. Discover the exact fields with covenant_review.spec and preserve both old and new case IDs.

Agree a follow-up after settlement

For a consensual resolution, use the exact external-draft signing path. Put the original settled envelope CID, agreement hash, delivery hash, payment claim and the new duty or remedy in an explicit document. Prepare it with the original parties and a reviewed context; each party signs its exact required label and body, then verify all required assents. Retain the original BILATERAL row and a new EXTERNAL agreement row together in the coordination case. Literal bindings can check that selected signed fields contain the exact references. Graph associations remain declared; the protocol does not infer legal discharge from them. A separately signed resolution is useful evidence of what both parties agreed, without reopening or rewriting the old payment. A new unilateral adjudication still needs its own adopted procedure.