You pass the task statement, the context and the tools to POST /v1/intents. Provely compiles a completion contract: the steps, the evidence, the correlation keys and the negative postconditions. You confirm it once with POST /v1/intents/{id}/confirm. You never write it.

A contract is a postcondition, and a negative postcondition is the check that catches a duplicate side effect. Writing them by hand is the work this removes.

A contract can be honest and still answer the wrong question. "Buy the cheapest blue shirt under 50 dollars" compiled to "an order exists" verifies truthfully and misses the ask. The three controls below stop that.

What do you pass?

What you passExample
statement"Refund order 4471 for $142 and email the customer."
context{ order_id: "4471", customer: "cus_8k2Rv1LmQ9xT" }
tools[stripe.refunds, shopify.inventory, resend.emails]
“Refund order 4471 for $142and email the customer.”context, toolsyou pass thiscompilestepstripe.refund.succeededevidenceE2 readback + E3 refund.updatedcorrelaterefund_id, payment_intentnegativeno second settled refundREQUIRES_REVIEW“the customer” resolves to one addresswhat done meanshow the runtime proves ityou confirm this once
The prompt goes in. The postconditions come out, and you confirm them.
In words
  • The prompt and the context go into the compiler.
  • The compiler returns the steps, the evidence for each step, and the postconditions.
  • A part that no contract can check is marked REQUIRES_REVIEW.
  • You confirm the contract before it verifies anything.

What does the compiler return?

One step of the task, one contract, one evidence plan.
StepEvidenceHow Provely checks it
stripe.refund.succeededE2 + E3Read the refund by id, then wait for refund.updated. Correlate by refund id and payment intent. Amount 14200 usd.
shopify.inventory.adjustedE2Read the inventory level back. Correlate by line item, never by a matching count.
resend.email.deliveredE3Wait for the delivery event. Accepted and sent are different promises.

The negative postcondition. No second settled refund exists for this payment intent.

Marked REQUIRES_REVIEW. “the customer” must resolve to one address. Confirm it before the run.

Provely never drops a part of the task in silence. A part that no contract can check is marked REQUIRES_REVIEW, and it says so on the confirmation screen.

Which calls do I make?

The four calls, in this order.
CallWhat it doesSDK
POST /v1/intentsCompiles the task. The answer carries the proposal, the review page, and every part that the contract does not check.compileIntent, compile_intent
GET /v1/intents/{id}Reads the proposal again. A confirmation screen loads it by identity.—
POST /v1/intents/{id}/confirmRecords the decision of one person. The call freezes the contract and hashes it. A decision that misses one part is refused.confirmIntent, confirm_intent
POST /v1/operationsBegins the operation under the frozen contract. State the confirmation, and the receipt binds the ask to the promise.—

A second decision for the same proposal is refused. A confirmation binds one person to one document. Compile the task again for another decision.

What does the code look like?

Compile, confirm, verify
// You state the task. Provely compiles the contract. A person confirms it.
const proposal = await provely.compileIntent({ statement: task.prompt, context, tools })

// proposal.unchecked holds every part the contract cannot check. Show them, then confirm.
const { contract, confirmationId } = await provely.confirmIntent(proposal.proposalId, {
  proposalHash: proposal.proposalHash,
  confirmedBy: reviewer.email,
  acknowledge: proposal.unchecked.map((part) => part.id),
})

const op = await provely.begin({
  contractId: contract.id,
  contractVersion: contract.version,
  confirmationId,
})

await agent.run(task, { idempotencyKey: op.idempotencyKey })

const v = await provely.verify(op.operationId, { waitMs: 600_000 })
What it compiled
contract: order.refund.completed     # compiled from the intent
subject:  { order_id: "4471" }
steps:
  - stripe.refund.succeeded          # E2 readback + E3 event
    correlate: [refund_id, payment_intent]
    amount:    14200 usd
  - shopify.inventory.adjusted       # E2 readback, by line item
  - resend.email.delivered           # E3 delivery event
negative:
  - no second settled refund for this payment intent
review:
  - "the customer" resolves to one address
Acting on the verdict
const v = await provely.verify(op.operationId, { waitMs: 600_000 })

switch (v.verdict) {
  // PENDING: wait. Never run the action again: a retry duplicates the side effect.
  case "PENDING":
    return resumeLater(op.operationId)

  // UNVERIFIABLE: no evidence yet. The verdict names each step that carries none.
  case "UNVERIFIABLE":
    return runAgain(v.verdictDocument.steps_requiring_review)

  // FAILED: the provider refused. The key of the first attempt stops a double effect.
  case "FAILED":
    await stripe.refunds.create(input, { idempotencyKey: op.idempotencyKey })
    return provely.verify(op.operationId)

  // CONTRADICTED: reality already differs from the promise. A person decides.
  case "CONTRADICTED":
    return escalate(v.verdictDocument.decided_by_step)
}

Which controls hold intent fidelity?

  1. You confirm the compiled contract before it runs. The screen states what the contract does not check.
  2. The receipt binds the intent to the promise. It carries the intent statement, the contract id, the contract version and the contract hash. A compiled contract adds the proposal, the person who confirmed it, and every unchecked part. An auditor reads one document and compares the ask with the promise.
  3. A part that no contract can check is marked REQUIRES_REVIEW. That is the assertion the compiler will not write for you. Provely never drops a part of the task in silence.

The contract is immutable, versioned, hashed and signed before it verifies anything. Read what a completion contract contains.

Can a language model decide that the task is complete?

No. A language model may propose the contract. The runtime evaluates the contract with operators against provider evidence, and it gives no evidence to a language model.

Can I still write a contract by hand?

Yes. The schema and the loader are public. Read what a completion contract contains for the members and the rules.