pages / example / reseller_sale

example · reseller_sale

canister coord://offchain/genie/program/reseller_sale@v1/9f78557cf1a2b9d3 · v1 · artifact root 0x9f78557cf1a2b9d34f3b327ba39d042c608f33d99dacb2987b4bab99927b3f16 · previous none (first version) · superroot at publish not sealed yet

sealed cases that reached it: 0 — sealed cases that reached this word (the store counts, never reads)

the words it says

its helpdesk graph

reseller sale (a .genie program) in the studio: 9 symptoms, 9 fixes

the source

// _GENIE_RESELLER_E2E_v1_ — one sale of a reseller's builder, end to end: a child key the reseller minted buys one call through a named
// exchange edge, and the layer's own answers say what happened: the agreement the call was made under, the delivery, the meter line the
// call wrote, and the edge's state after it. On a Base edge the call is paid from the reseller's USDC balance under the child key's cap
// (the meter line says `paid.by == "balance"`); a key payment never makes an edge live, so the edge must stay where it was. On a devnet
// edge (chain 36927) the call is metered in test units and nothing is paid.
// `node lang/genie/cli.mjs e2e` runs it whole: mint the child key, run `keyed_sale` under it, read the reseller's view, revoke the key.
// Run the agent alone: COORD_API_KEY=<a key> node lang/genie/cli.mjs run lang/genie/examples/reseller_sale.genie \
//   --input edge_id=edge_<16 hex> --input task="…" [--send]
genie reseller_sale v1
about "A reseller's builder buys one call through an exchange edge under a capped child key, and the layer's answers prove the sale: agreement, delivery, meter line, edge state"

agent keyed_sale is "one call through a named edge under the caller's key, read back from the edge's meter"
  states picked agreed called delivered fetched collected metered no_edge not_checked not_live unpaid refused not_delivered not_collected not_metered recorded_test kept_quoted promoted_by_key
  start picked
  final no_edge not_checked not_live unpaid refused not_delivered not_collected not_metered recorded_test kept_quoted promoted_by_key
  failed no_edge not_checked not_live unpaid refused not_delivered not_collected not_metered promoted_by_key
  read GET /v1/exchanges as edge pick rows where row.edge_id == input.edge_id
  move picked -> no_edge when not edge
  move picked -> not_checked when not edge.check.passed
  move picked -> agreed op GET /v1/exchanges/:edge_id/agreement with edge_id from edge.edge_id into agreement
  move agreed -> called op POST /v1/exchanges/:edge_id/call with edge_id from edge.edge_id with class from edge.class with task from input.task with tool from input.tool with args from input.args into sale effect record
  move called -> unpaid when sale.code == "payment_required"
  move called -> not_live when sale.code == "edge_not_live"
  move called -> not_delivered when sale.code == "not_delivered"
  move called -> not_delivered when sale.ok == true and not sale.delivery.status == "ready"
  move called -> delivered when sale.ok == true and sale.meter_line.id
  move called -> refused
  move delivered -> collected when sale.delivery.answer.text
  move delivered -> fetched op GET /v1/handshake/:id with id from sale.delivery.handshake_id with full from "1" into reply when sale.delivery.handshake_id
  move delivered -> not_collected
  move fetched -> collected when reply.delivery.reply_full
  move fetched -> not_collected
  move collected -> metered op GET /v1/exchanges/:edge_id/meter with edge_id from edge.edge_id with limit from "1" into lines
  move metered -> not_metered when not lines.lines.0.id == sale.meter_line.id
  move metered -> promoted_by_key when sale.sale.by == "balance" and sale.edge.promoted == true
  move metered -> kept_quoted when sale.sale.by == "balance" and sale.meter_line.paid.by == "balance" and sale.edge.promoted == false
  move metered -> recorded_test when edge.chain_id == 36927 and sale.meter_line.edge_id == edge.edge_id
  move metered -> not_metered
  say no_edge "GET /v1/exchanges lists no edge by that id"
  say not_checked "The edge has not passed its check: no call is sold through it"
  say not_live "The edge takes no calls in its state"
  say unpaid "The edge answered 402: the key's balance did not pay (a child key past its cap, a balance that is not USDC-funded, or no balance)"
  say refused "The edge refused the call before any payment: read sale.code (the agreement, the house bound, the policy)"
  say not_delivered "The seller's reply carried no content, or an MCP seller with several tools was called with none named (sale.delivery.tools): nothing was charged"
  say not_collected "The call was charged as delivered and the buyer cannot read the work: no answer in the call and no reply on its handshake"
  say not_metered "The call answered and its meter line cannot be read back from the edge's meter"
  say recorded_test "The devnet seller answered through the edge and the layer wrote one meter line in test units: nothing was paid"
  say kept_quoted "The call was paid from the reseller's USDC balance under the child key, delivered, metered, and the edge stayed where it was: a key payment is not an outside payer"
  say promoted_by_key "A key payment moved the edge: only an outside x402 payer may make an edge live"
  next picked agreed "Name an edge GET /v1/exchanges lists (edge_id) and the task to send"
  next agreed called "The call is made under the edge's agreement; a Base edge takes the key's USDC balance"
  next delivered collected "The buyer holds the work: a house edge answers it in the call (delivery.answer); a seller's edge holds it on the handshake, read with GET /v1/handshake/:id?full=1 under the same key"
  next collected metered "The meter line the call wrote is read back from GET /v1/exchanges/:edge_id/meter"

knowledge
  symptom "the run ends at unpaid" caused_by "the child key's cap is spent, the reseller's balance is empty, or its credit is not USDC-funded" fixed_by "GET /v1/access/reseller/children shows the key's spent and left; the reseller tops up with POST /v1/access/topup"
  symptom "the run ends at not_collected" caused_by "the seller's reply was not held, or the key that reads it did not open the handshake" fixed_by "read GET /v1/handshake/:id?full=1 with the key that made the call; only the opener reads the reply"
  symptom "the run ends at not_delivered with sale.delivery.status tool_required" caused_by "the seller speaks MCP and offers several tools; a call that names none gets the tool list, which is no delivery" fixed_by "send the same task with tool and args, one of sale.delivery.tools (genie e2e --tool <name> --args <json>)"
  symptom "the run ends at not_metered" caused_by "another call wrote a newer meter line, or the store answered late" fixed_by "read GET /v1/exchanges/:edge_id/meter?limit=50 and find sale.meter_line.id"
  symptom "the run ends at promoted_by_key" caused_by "the edge was moved by a key payment" fixed_by "a defect of the layer: paid-in.cue says only an outside x402 payer makes an edge live; report it"
  rule "the program never holds a key: the host's call does; the e2e driver mints, uses and revokes the child key"
  rule "every value a step sends comes from the run's input or an answer bound before it"