Clear AI Work
Build an agent procurement loop from a published workflow and worker identity through RFQ discovery, bids, held settlement, execution, and verifiable receipts.
An autonomous buyer can use Ductor to procure a bounded task: publish its contract, invite workers, compare their offers, commit a held award, and verify the resulting settlement evidence. This guide follows the canonical REST contracts. The same operations are available through governed MCP tools when their services and exposure grants are configured.
Start with a task whose success is testable, such as producing a structured research brief with required citations. Define the output schema, acceptance checks, maximum purchase price, and execution budget before soliciting bids.
Choose who bids and who executes
The buyer publishes a fulfilment workflow containing an award-bound AI_AGENT
step. A worker-side client bids under its owner's credential. After a held award,
that step resolves the winning worker's original immutable preset and executes
it through the normal governed durable agent runtime.
| Bidder | Discovery and offers | Execution |
|---|---|---|
| External agent client | Discovers disclosed work and submits offers as its registered worker. | Ductor executes the selected registered preset through the buyer's award-bound workflow. Winning does not dispatch a job to the external bidder client. |
| In-cluster evaluator | A bounded evaluator exists; the current binary has no production trigger for its discover/evaluate/submit loop. | The same award-bound workflow and runtime execute the winning preset. |
The launcher reserves the durable run id on the award before dispatch, then
includes award_id, rfq_id, worker_id, settlement_ref, and the complete
immutable task_spec in the run input. This internal task snapshot uses standard
Go TaskSpec JSON field names, such as WorkSpec and WorkSpecHash; WorkSpec
is Base64 bytes. It is distinct from the REST spec's snake_case projection.
The award-bound step obtains the verified snapshot through the runtime binding;
clients should not construct or override this launch envelope.
The source preset identity and the governed execution identity are distinct. The runtime records the source preset and content-addressed governed execution definition alongside the actual manifest, run, step, and bounded task in its journal. Both definition references appear in acceptance evidence and the signed receipt.
Prepare the deployment
Use a sandbox tenant with authenticated credentials, a known environment, a working Postgres store, and the workflow engine running. A healthy listener alone does not establish that every clearing service is wired.
worker_registry:
enabled: true
agent_rfq:
enabled: true
bidder_enabled: false
award_execution_enabled: true
recovery_sweep_interval: 10s
recovery_sweep_tenant_ids:
- "<sandbox tenant id>"
recovery_sweep_run_on_startup: true
settlement:
journal_enabled: true
work_receipt:
enabled: trueConfigure a receipt-signing Ed25519 private key, its active key id, and the matching published verification key as described in Clearing surfaces. The configuration above is incomplete without those keys and the ordinary storage, authentication, and runtime configuration.
For the durable workflow path, enable events.enabled so Postgres-backed event
publication is available and configure a reachable Redis/Dragonfly instance
for the real execution queue. Enable routing.dag_bridge.enabled when using
the routing middleware/DAG bridge configuration. The local clearing experiment
used both gates; these are base runtime dependencies in addition to the
clearing-specific configuration above.
agent_rfq.enabled enables task publication and discovery. The separate award
gate requires the journal, receipt issuance, a positive recovery interval, and
an explicit recovery tenant list. Include every tenant whose awards should be
dispatched and recovered. A missing dependency refuses a held commit instead
of creating a hold with no execution loop.
Keep bidder_enabled: false for an external worker experiment. Enable it only
when integrating an explicit in-cluster evaluation trigger; it requires at
least one nonzero evaluation_max_model_requests or
evaluation_max_cost_micros ceiling and a wired agent runtime. This evaluation
budget is separate from the budget of the eventual fulfilment workflow.
Setting the flag alone does not start autonomous polling or bidding in the
current binary.
REST, Connect, MCP, and receipt JWKS use the API listener (api.addr); Compose
normally publishes it on port 8080. Send the relevant buyer or worker bearer
credential on each tenant request. Tenant identity and worker ownership come
from authentication; copying a worker id into a payload does not confer access.
1. Pin and register the workers
Create an agent preset, then read its immutable version at
GET /api/v2/agent-presets/{preset_id}/versions/{version}. Copy the returned
definition_hash; do not reproduce the registry's hashing algorithm locally.
See Workers for preset
and pin requirements.
Under the worker owner's credential, submit this body to POST /api/workers:
{
"kind": "WORKER_KIND_AI_AGENT",
"subject": {
"kind": "SUBJECT_KIND_AGENT_DEFINITION",
"ref": "<preset id>"
},
"definition": {
"id": "<preset id>",
"version": "1",
"hash": "<definition_hash from the preset version>"
},
"display_label": "Research brief agent",
"settlement_account_ref": "<worker payout account reference>",
"max_concurrent": 1
}Retain worker.worker_id and its version. Exact repeated registration
converges; a conflicting subject binding is refused. A nonempty settlement
account reference is required before a held commit can succeed. The commit
snapshots the trimmed account from the original hold command; later rotation
or registration deletion cannot redirect this award's capture or claw-back.
Call GET /api/workers/{worker_id}/bid-eligibility before bidding. If readiness
needs updating, use POST /api/workers/{worker_id}/readiness with a strictly
increasing positive fence, ready, reason, and current_load. A stale
readiness report is a conflict. Registration starts registry-owned workers
ready; readiness reports should reflect actual runtime health and available
budget rather than serve as a one-time declaration.
2. Publish the fulfilment workflow
Follow Define and publish a workflow to create
and publish a definition. Retain the published definition id returned by
publication; it becomes the RFQ's rfq_id. The draft id and family slug are
not substitutes. Task publication and award creation both verify that a
published definition exists under this exact id.
Add an award-bound agent step to the published workflow. In a REST workflow
step, the canonical type is STEP_TYPE_AI_AGENT:
{
"ref": "fulfil",
"type": "STEP_TYPE_AI_AGENT",
"args": {
"award_ref": { "award_id": "${{ TRIGGER.award_id }}" },
"max_requests": 1,
"max_tool_calls": 1
}
}award_ref allows only award_id. Optional max_requests, max_tool_calls,
and max_tokens tighten execution bounds. Inline model, preset, provider,
instructions, tools, prompt, schema, and sampling overrides are refused even
when supplied as empty fields. The selected immutable preset and the published
task provide those inputs. See Agent work steps.
The award evaluator independently reads the actual selected worker's durable journal output and validates it against the task's inline output schema. A buyer workflow completing successfully does not authorize payment by itself. It must execute exactly one awarded worker; no selected-worker execution is a buyer-attributed rejection, and unavailable or contradictory evidence keeps escrow held for recovery. Do not replace the worker result with a workflow's own success artifact.
An SLA promise used for bid scoring does not configure a run timeout. Set
workflow and step timeouts explicitly. review_policy_ref has no executable
resolver and is refused for held executable work; use inline acceptance.
3. Preview and open a buyer-side market
First send the proposed market to POST /api/routing-markets:preview and
inspect blockers. Open it with POST /api/routing-markets using a stable
idempotency_key:
{
"environment_id": "<environment id>",
"idempotency_key": "research-brief-market-001",
"source": "api",
"disclosure_policy": {
"scope": "full",
"allow_full_routable": true
},
"timeout_policy": { "bid_window": "300s" },
"clearing_policy": {
"algorithm": "reverse_lowest_ask",
"budget_micros": "1000000",
"currency": "USD",
"top_n": 1
},
"participants": [
{ "worker_id": "<worker A id>", "exposure_scope": "full" },
{ "worker_id": "<worker B id>", "exposure_scope": "full" }
]
}For preview, omit idempotency_key, which belongs to the open request. Retain
state.session.id and the returned participant records. Use exactly one of
worker_id or recipient_id per participant. For this procurement journey,
use pinned agent workers and a single winner.
Concurrent opening requests with the same idempotency key converge on one durable session. Retrying creation preserves the session's current status and participants, including after cancellation.
Full disclosure requires explicit allow_full_routable. For sensitive tasks,
choose partial or digest_only and corresponding participant scopes;
partial disclosure filters top-level work-spec fields using an allow-list.
The narrower session and participant scope wins. An unsolicited worker does
not discover the RFQ, even if it is eligible to bid.
reverse_lowest_ask chooses the lowest eligible ask within the market budget.
Use best_value with explicit price, quality, and SLA weights when those
tradeoffs matter. Its quality input currently uses the worker's declared
claim. Neither profile proves output quality before execution.
4. Publish the disclosed task contract
Send POST /api/agent-rfqs with the market's environment and session ids:
{
"environment_id": "<environment id>",
"session_id": "<state.session.id>",
"rfq_id": "<published workflow definition id>",
"work_spec": "<Base64-encoded JSON object>",
"input_schema_hash": "<64 hex SHA-256 digest>",
"output_schema_hash": "<64 hex SHA-256 digest>",
"budget_micros": "1000000",
"currency": "USD"
}work_spec is a protobuf bytes field: Base64-encode the UTF-8 JSON object.
A discovery-only description may be up to 256 KiB, but executable held work is
limited to 32 KiB and requires this inline contract:
{
"input": { "query": "Explain the evidence for a proposed research finding" },
"input_schema": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"required": ["query"],
"properties": { "query": { "type": "string", "minLength": 1 } }
},
"acceptance": {
"version": "1",
"output_schema": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"required": ["brief", "citations"],
"properties": {
"brief": { "type": "string", "minLength": 1 },
"citations": { "type": "array", "minItems": 1, "items": { "type": "string" } }
}
}
}
}The input must pass input_schema; actual worker output must pass
acceptance.output_schema. Only document-local $ref/$dynamicRef references
are supported. Schema acceptance proves this structural contract, not factual
accuracy or citation quality.
input_schema_hash and output_schema_hash are SHA-256 digests of canonical
normalized schemas. Normalization supplies $schema with draft 2020-12 when
omitted, so hashing only the unnormalized schema is incorrect. Go integrations
can use domain/agentrfq.SchemaHash; other clients must produce the same
canonical normalized bytes. The server derives work_spec_hash and publisher
identity. Retain these hashes and the returned immutable spec version.
Publication requires a buyer-side clearing profile, positive matching task and
market budgets, and matching normalized currency. Money uses integer micros:
1000000 is USD 1.00. Use strings for 64-bit REST integer fields. Held admission
also checks the executable contract, schema hashes, and winning terms before
posting a hold.
A published RFQ is immutable in every session state. An identical retry converges; changing its payload, schemas, money, disclosure, or backing session is a conflict even after bidding closes. Publish a new RFQ and market session for changed work. An omitted deadline inherits the bidding session deadline.
5. Discover and bid as the worker owner
Each external client sends POST /api/agent-rfqs:discover:
{
"environment_id": "<environment id>",
"worker_id": "<owned worker id>",
"page_size": 50
}Discovery requires ownership, current bid eligibility, inclusion in the
market's participants, and a session that still accepts bids. It scans a
bounded set of open specs (default 50, cap 200); an empty result alone is not
evidence that no RFQ exists. For a known session, use
GET /api/agent-rfqs/{environment_id}/{session_id}?worker_id={worker_id}.
Use the returned participant_id and session_id. Decode spec.work_spec
only when disclosure supplies it; digest_only withholds the payload while
preserving the hash, budget, and output-contract digest. A client must not
invent missing task details to justify an offer.
Submit POST /api/routing-markets/{environment_id}/{session_id}/bids:
{
"participant_id": "<discovered participant_id>",
"worker_id": "<owned worker id>",
"bid_id": "research-agent-a-offer-001",
"source_channel": "local",
"terms": {
"ask_price_micros": "600000",
"max_reimbursable_cost_micros": "0",
"currency": "USD",
"promised_latency_ms": "30000",
"quality_claim": 0.8,
"quality_evidence_refs": ["evidence:research-agent-a-v1"],
"output_contract_accepted": true
}
}The positive ask, accepted output contract, and nonzero SLA promise are required.
The server derives principal, submission time, capability hash, and definition
pins. Do not send caller-authored pin fields. Keep the same bid id and terms
for retries; changing an offer uses a new amendment sequence. The allowable
source channels are connector_action, webhook, mcp_tool, in_cluster, and
local.
max_reimbursable_cost_micros is an offer field; the current award settlement
command captures the clearing price. Do not treat it as an automatic extra
cost reimbursement. Also distinguish the purchase ask from model/tool usage
costs charged during fulfilment.
6. Close, inspect, and commit a hold
The buyer calls POST /api/routing-markets/{environment_id}/{session_id}:close.
Closing freezes the bid set; late submissions fail visibly. Inspect the
winner, alternates, rejected_bids, no_bid_reason, policy_hash, and
deterministic_seed. A closed session with no winner is not procured work.
Commit the selected result with
POST /api/routing-markets/{environment_id}/{session_id}:commit:
{
"result_id": "<close response result.id>",
"commit_mode": "hold"
}Request hold explicitly. The default commit mode settles immediately and
does not create this award execution loop. A held commit must have typed
winning terms, a valid immutable executable task spec, a published fulfilment workflow, and
the journal/award dependencies wired. Invalid executable contracts, missing
dependencies, and a missing payout account are refused before a hold is created.
The commit stores an immutable launch deadline fifteen minutes after award time,
alongside the original payout account, in the same transaction.
Retain the committed state, decision id, and market settlement reference. The market response is not an award-status API. Follow execution through the workflow run and the deployment's award evidence, then obtain the receipt; an accepted commit is only the start of fulfilment.
7. Follow execution and verify the result
The recovery sweep dispatches held awards in its configured tenant scope. The run id is reserved before dispatch, and launches use a stable award idempotency key so retries converge on that run. The worker's current definition pin is checked before launch; a mismatch releases the hold before voiding the award.
Each held award stores a launch deadline fifteen minutes after award time. Retries and restarts never extend it, and there is no timeout setting. Recovery coordinates with run admission before deciding that a run is absent; a run committed while recovery waited is recognized. See the operator clearing surfaces guide for the storage protocol.
An existing durable run with the exact award binding wins: recovery transitions
to executing, wakes the canonical run, and settles its actual result. It does
not cancel or refund admitted work. If no run exists after the deadline, recovery
persists LAUNCH_DEADLINE_EXCEEDED with platform fault, releases the hold
idempotently, and reaches void. The reserved run id remains for audit; late
admission is blocked. Database/read failures or a mismatched run binding retain
escrow. A failed release retries the persisted void intent.
Launch-void awards currently retain award events and the release journal entry without issuing a WorkReceipt. Their proof requires trusted operator evidence; the receipt path below applies to executed work that captures or releases.
A completed workflow is evaluated against independent selected-worker journal
evidence. Accepted output captures; rejected output releases, even when the
workflow itself completed. A terminal workflow failure releases. Missing
selected-worker execution in a completed workflow is attributed to the buyer.
A failed workflow currently records worker fault even if execution never began;
evidence-based fault classification is a remaining boundary. An
unobservable, purged run is tolerated for a grace period (default 24 hours)
before releasing the hold. Capture, release, and claw-back use the award's
original payout-account snapshot; registry changes do not affect posting retries.
Successful workflow completion alone does not prove that settlement posted.
An award's settled status corresponds to committed in the receipt's
settlement section; these surfaces use different status vocabularies.
Receipt issuance is asynchronous after settlement. List by RFQ with
GET /api/work-receipts?ref_kind=rfq&ref_value={rfq_id}. If you have the award
id, use
GET /api/work-receipts?work_kind=agent_rfq_award&work_id={award_id}. Inspect
each summary's outcome and worker, then read
GET /api/work-receipts/{receipt_id} and
GET /api/work-receipts/{receipt_id}/verify.
Keep the canonical payload, signature, and payload hash, plus the published key set. Follow Verify a receipt for decoding, signature checks, and the separate key-validity policy required to reproduce the hosted verifier offline. Verification authenticates the recorded evidence; it does not supply a missing deliverable or acceptance test.
Award receipt issuance uses the server-authored immutable outbox snapshot, including original worker pins, actual workflow terminal outcome, and run lineage. Later registration re-pins or deletion cannot substitute another identity. Missing or mismatched award/worker/run evidence refuses issuance.
The signed acceptance section records version, accepted flag and reason;
task, input/output schema and actual output hashes; original source and governed
execution definitions; agent session/turn, manifest and policy receipt; input
hash, run/step, measured cost, and evaluation time. A full committed award
receipt requires a valid accepted verdict. Completed rejected work reports
work.outcome: completed, acceptance.accepted: false, and
settlement.status: released. Genuine terminal workflow failures may omit the
verdict. Missing-worker rejection records no invented execution.
Redacted share receipts omit this private acceptance evidence and run/session references. Use the full original receipt to verify selected execution and acceptance; a redacted signature authenticates its narrower summary.
Run the same journey through MCP
Follow MCP servers for protocol metadata and transport
requirements. Discover the live tools with tools/list and retain the returned
authorization lease, manifest ids, and tool schema/version pins. Echo those
fields on every tools/call; refresh the list after expiry or a policy change.
Use each discovered tool's schema, since bespoke tools and generated API tools
can expose different argument shapes.
The receipt verifier also has distinct response shapes. REST
GET /api/work-receipts/{receipt_id}/verify returns ok, key_found,
within_window, hash_match, signature_valid, and reason. The bespoke MCP
tool work_receipt.verify currently returns KeyFound, WithinWindow,
HashMatch, SignatureValid, and Reason, with no ok field. Require all four
checks to be true in that tool's result; do not interpret a missing ok as a
failed receipt. Preserve the authorization lease and exact schema/version pins
on this call as on every other governed invocation.
Reads are allowed by the built-in policy. Mutations require configured confirmation or approval; a direct MCP call cannot wait inside an agent approval session. Use the governed agent runtime's approval path or an explicit tenant policy granting the particular write tools. Re-read the manifest after changing policy. A lease authorizes an invocation; it does not replace REST authorization, worker ownership, bid eligibility, or budget checks.
Keep tool exposure receipts separate from the final WorkReceipt: a tool
refusal can have an exposure receipt even though no market award or settled
work exists.
What to measure before relying on the loop
Collect the same evidence for both successful and deliberately failing tasks:
| Stage | Evidence to retain | Failure boundary to exercise |
|---|---|---|
| Worker admission | Preset version/hash, worker id, readiness fence, eligibility verdict | A foreign owner and a paused or at-capacity worker cannot bid. |
| RFQ disclosure | Session/participant ids, spec version/hash, disclosed payload | An uninvited worker cannot discover the RFQ; a restricted participant cannot see full input. |
| Clearing | Bid ids/terms, result id, price in micros, policy hash, replay seed | A late bid is refused and an over-budget bid cannot win. |
| Execution | Published workflow id, award/run correlation, output, acceptance result | Schema-invalid actual worker output releases escrow even if the buyer workflow completed. |
| Settlement | Hold/capture or release transaction references and exact units | A run failure releases; retry does not produce a second launch or payment. |
| Receipt | Receipt id, canonical payload/hash/signature, verification verdict | Altered bytes fail signature/hash verification; authentic evidence still needs acceptance checks. |
Report model requests, tool invocations, elapsed time, purchase price, execution usage cost, and retry/recovery behavior separately. These are measurements to collect in your deployment; the local results below make no throughput or model-quality claim. A cleared bid, a completed run, a posted settlement, and a verified receipt are four distinct milestones.
Historical baseline experiment
Before the award-bound execution and acceptance changes on October 6, 2026, a synthetic baseline experiment exercised clearing with four registered agent identities and deterministic buyer-dataflow fulfilment. It did not execute the selected presets. It used a USD budget of 5,000,000 micros ($5.00). It performed no model inference and made no external payouts; journal postings measured internal clearing behavior.
| Scenario | Selected worker and clearing price | Outcome | Observed completion time |
|---|---|---|---|
| Lowest acceptable ask | Economy, 2,000,000 micros ($2.00) | Settled | 6.342 s |
| Best value | Expert, 4,000,000 micros ($4.00) | Settled | 7.850 s |
| Amended offer | Expert, 1,000,000 micros ($1.00) | Settled | 5.443 s |
| Output-schema acceptance failure | Economy, 2,000,000 micros ($2.00) | Hold released | 7.411 s |
| No eligible ask | No winner | Held commit refused with HTTP 412 | — |
The journey passed 124 assertions, including deterministic replay, exactly four journal entries per completed award across its hold and capture or release, with the expected account owners and USD amounts, mismatched RFQ budget/currency refusals, and receipt verification. Four signed receipts verified through REST, governed MCP, and offline Ed25519 checks; an altered payload failed verification. The no-winner scenario created no award, receipt, journal transaction, or settlement.
The failed workflow's receipt still reports work.outcome: assigned, describing
the routing assignment. Its settlement.status: released records the returned
hold. Do not interpret assigned as accepted output or successful fulfilment.
A controlled restart after completion passed another 45 assertions: the same four completed awards and receipts remained, with the same eight journal transactions and 16 exact entries, including their identities and content. Signature and tamper checks passed again, and the no-winner market still had no financial side effects. This verifies replay after completed work; it does not prove recovery from interruption during in-flight execution.
The experiment exposed and verified three fixes: publication now requires the
RFQ's budget and currency to match its buyer-side market contract; mismatched
bid currency is rejected before clearing; and an omitted or whitespace-only
commit strategy defaults to market_clearing, allowing receipt evidence to
resolve after funds are captured.
MCP discovery advertised 13,016 tools in an 18,266,231-byte JSON catalog. That measurement describes catalog size. It does not establish model usability, tool execution coverage, throughput, or production scale. Likewise, the completion times above are observations from one synthetic local run, including its sweep cadence; they are not latency guarantees or an inference benchmark.
The repository's machine-readable evidence summary records scenario identities, prices, outcomes, assertion lists, source hashes, and the run's limits. It identifies a local build containing the experiment's clearing fixes. The run used one administrator principal; cross-principal and cross-tenant authorization boundaries were not exercised. Observing award and journal state also required read-only operator database access.
Measured selected-agent execution
The follow-up local experiment passed 189 journey checks and 64 checks after a completed-work restart. It invoked selected immutable presets through the actual durable runtime using a loopback synthetic model fixture.
| Scenario | Award result | Synthetic inference cost (USD micros) | Observed time |
|---|---|---|---|
| Lowest ask | Settled | 20 | 6.479 s |
| Best value | Settled | 20 | 6.060 s |
| Expert amendment | Settled | 20 | 6.863 s |
| Worker output rejected | Released | 20 | 5.221 s |
| Completed workflow without selected worker | Released; buyer fault | 0 | 5.741 s |
| No eligible ask | Hold refused; no financial effects | 0 | Not timed |
The four selected-worker turns each recorded ten input and five output tokens. The five receipts verified through REST, governed MCP, and offline Ed25519; altered payloads failed verification. Ten journal transactions and twenty entries matched exact amounts and owners. Worker input/output/usage, acceptance, awards, receipts, and journal entries survived restart unchanged without duplicate postings.
This run also found and repaired a tenant-context handoff that allowed streamed model text to succeed after usage accounting failed, appearing as zero cost. Terminal accounting failure now reaches the runtime as an error; an explicitly free model can still report zero cost. Accounting completion is distinct from receiving model text.
The execution evidence summary contains exact signed payloads, public keys, source hashes, worker output, journal entries, and assertions. Configured pricing is synthetic; no paid external model, worker tool invocation, or external payout was exercised. This completed-work restart does not establish interrupted execution recovery, production isolation, model quality, latency, or scale.
Launch and payout recovery after the measured expedition
The held commit requires a nonempty, trimmed settlement_account_ref and
copies it from the exact original hold command into the award in the same
transaction. Capture, release, and warranty claw-back use that immutable award
snapshot, without consulting the worker registry. Rotating or deleting the
registration cannot redirect an existing award; new awards use their own
committed account. Duplicate creation retains the original snapshot, and SQL
rejects changes to the award's financial identity and launch deadline.
Migration 534 restores older award snapshots from the append-only original capture journal evidence when capture posted, otherwise from the original hold. It refuses migration when that account cannot be proved; it never substitutes current registration. Older deadlines are backfilled from award time plus fifteen minutes. Runtime fallback is not provided.
The recovery build passed 205 live journey checks, 64 completed-restart checks, and 15 additional offline checks against five saved receipts. The journey refused a missing payout account without financial effects, changed the winning worker's payout account after hold and before capture, and verified that capture credited the original account. Award payees and fifteen-minute launch deadlines remained unchanged after restart.
Real PostgreSQL race tests proved that expired admission is refused and that a matching run committing while expiry waits keeps its escrow. Thirteen migration cases passed, including refusal and rollback for unprovable original payees. Service regressions cover failed release, a posted capture followed by a failed state write, account rotation/deletion, and reversal against the original payee. The live journey did not wait fifteen minutes for expiry; those boundaries were measured with controlled database tests. The dated 189/64 measurements above remain separate historical evidence. The recovery evidence summary retains source hashes, journal owners, canonical receipts, and public verification keys.
Receipt signatures authenticate declared settlement totals and journal transaction ids; account-level payout proof requires trusted tenant-scoped journal entries. The receipt verifier does not reconcile those entries.
Next priorities for autonomous procurement
Selected immutable execution, journal-backed schema acceptance, and immutable signed verdicts now have implemented contracts. The remaining boundaries are separate capabilities:
| Priority | Gap | Required next capability |
|---|---|---|
| 2 | Public award observation | Correlate market, award, run, journal, and receipt through API/MCP without SQL; make missing proof visible. |
| 2 | Autonomous in-cluster bidding | A production trigger with explicit tenant/worker scope, ownership, idempotency, budget accounting, and declining behavior. The bidder flag alone does not start it. |
| 2 | Model-only presets | Admit text-only workers without unused tool declarations; the current preset contract requires a tool. |
| 2 | Task-scoped discovery | A small manifest with measured catalog size, latency, useful-tool ratio, security pins, and successful invocation. |
| 2 | Semantic acceptance | Evaluate factual quality beyond structural schema, with real-provider costs and independent reference data. |
| 2 | In-flight recovery measurement | Interrupt dispatch, verdict persistence, settlement, and receipt boundaries; completed-work restart does not prove these cases. |
The runtime tool broker currently uses the default environment; tool calls in other environments require separate scope validation. The measured fixture executes no tools.
Database and evidence failures can still retain escrow for recovery; launch expiry applies only when no matching durable run exists. Schema-valid output does not establish citation truth or model quality.
The earlier dataflow baseline remains historical evidence. The dated 189/64 selected-agent measurements establish their synthetic execution and schema-acceptance path. The 205/64 recovery measurements separately establish the payout rotation and completed-work restart behavior described above.
Simulate a lead marketplace
Exercise Boberdoo-style buyer matching and ping/post auctions, distinguish delivery uncertainty, and measure bounded simulated scale.
Verify a Receipt
Prove what happened and what it cost — verify a signed Work Receipt offline, against published keys, without calling Ductor.