@nuanu-ai/agentify-contracts 0.3.2 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -23,7 +23,7 @@ The contract is versioned, and the version is how an SDK and a gateway agree
23
23
  that they read the same vocabulary; a worker whose version the gateway does not
24
24
  share stops at startup rather than half understanding a document. What the
25
25
  merchant-facing side of all this looks like in use is at
26
- <https://app.agentify.ad/docs/>.
26
+ <https://agentify.ad/docs/>.
27
27
 
28
28
  ## License
29
29
 
package/dist/api.d.ts CHANGED
@@ -225,9 +225,11 @@ export declare const ReceiptListSchema: z.ZodObject<{
225
225
  /**
226
226
  * The question a merchant puts in the query string when listing orders.
227
227
  *
228
- * `open=true` narrows the list to the orders that are still owed something —
229
- * which includes the two that stay open after the purchase itself is over, an
230
- * order owing a refund and one delivered but never paid for. Leaving it out
228
+ * `open=true` narrows the list to the orders a restarted worker should walk:
229
+ * ones the merchant was handed and has not finished, and the two that stay
230
+ * open after the purchase itself is over, an order owing a refund and one
231
+ * delivered but never paid for. An order that was priced and never paid, and
232
+ * never reached the handler, is not in that narrowing. Leaving the field out
231
233
  * asks for everything.
232
234
  *
233
235
  * The value is text and not a boolean, because that is what a query string
@@ -455,9 +457,9 @@ export declare const PurchaseRequestSchema: z.ZodObject<{
455
457
  /**
456
458
  * What became of a purchase, told to the agent that made it.
457
459
  *
458
- * Four fields, and the shape of the list is the decision rather than its
459
- * length. This document is what the buyer is owed — where their order stands,
460
- * what it cost them, and the goods once those exist — and it is deliberately
460
+ * The shape of the list is the decision rather than its length. This document
461
+ * is what the buyer is owed — where their order stands, what it cost them, the
462
+ * goods once those exist, and where to ask again — and it is deliberately
461
463
  * smaller than the merchant's own view of the same order. It carries no
462
464
  * merchant, no merchant's key for the product, none of the parameters the
463
465
  * buyer sent and nothing about any other order, because whoever holds an
@@ -490,6 +492,7 @@ export declare const PurchaseRequestSchema: z.ZodObject<{
490
492
  */
491
493
  export declare const AgentOrderStatusSchema: z.ZodObject<{
492
494
  order_id: z.ZodString;
495
+ status_url: z.ZodURL;
493
496
  status: z.ZodEnum<{
494
497
  delivered: "delivered";
495
498
  in_progress: "in_progress";
@@ -1826,6 +1829,7 @@ export declare const API_ROUTES: Readonly<{
1826
1829
  response: {
1827
1830
  document: z.ZodObject<{
1828
1831
  order_id: z.ZodString;
1832
+ status_url: z.ZodURL;
1829
1833
  status: z.ZodEnum<{
1830
1834
  delivered: "delivered";
1831
1835
  in_progress: "in_progress";
@@ -1861,6 +1865,7 @@ export declare const API_ROUTES: Readonly<{
1861
1865
  response: {
1862
1866
  document: z.ZodObject<{
1863
1867
  order_id: z.ZodString;
1868
+ status_url: z.ZodURL;
1864
1869
  status: z.ZodEnum<{
1865
1870
  delivered: "delivered";
1866
1871
  in_progress: "in_progress";
package/dist/api.js CHANGED
@@ -129,9 +129,11 @@ export const ReceiptListSchema = z
129
129
  /**
130
130
  * The question a merchant puts in the query string when listing orders.
131
131
  *
132
- * `open=true` narrows the list to the orders that are still owed something —
133
- * which includes the two that stay open after the purchase itself is over, an
134
- * order owing a refund and one delivered but never paid for. Leaving it out
132
+ * `open=true` narrows the list to the orders a restarted worker should walk:
133
+ * ones the merchant was handed and has not finished, and the two that stay
134
+ * open after the purchase itself is over, an order owing a refund and one
135
+ * delivered but never paid for. An order that was priced and never paid, and
136
+ * never reached the handler, is not in that narrowing. Leaving the field out
135
137
  * asks for everything.
136
138
  *
137
139
  * The value is text and not a boolean, because that is what a query string
@@ -146,7 +148,7 @@ export const OrderListQuerySchema = z
146
148
  open: z.enum(["true", "false"]).optional(),
147
149
  })
148
150
  .meta({
149
- description: 'Which orders to list. Written as text because a query string carries text. "true" narrows the list to the orders that are still owed something, which includes the two that stay open after the purchase itself is over: an order owing a refund, and one delivered but never paid for. Leaving the field out asks for everything.',
151
+ description: 'Which orders to list. Written as text because a query string carries text. "true" narrows the list to the orders a restarted worker should walk: ones the merchant was handed and has not finished, an order owing a refund, and one delivered but never paid for. An order that was priced and never paid, and never reached the handler, is not in that narrowing. Leaving the field out asks for everything.',
150
152
  });
151
153
  /**
152
154
  * What a worker asks of one poll.
@@ -309,9 +311,9 @@ export const PurchaseRequestSchema = z
309
311
  /**
310
312
  * What became of a purchase, told to the agent that made it.
311
313
  *
312
- * Four fields, and the shape of the list is the decision rather than its
313
- * length. This document is what the buyer is owed — where their order stands,
314
- * what it cost them, and the goods once those exist — and it is deliberately
314
+ * The shape of the list is the decision rather than its length. This document
315
+ * is what the buyer is owed — where their order stands, what it cost them, the
316
+ * goods once those exist, and where to ask again — and it is deliberately
315
317
  * smaller than the merchant's own view of the same order. It carries no
316
318
  * merchant, no merchant's key for the product, none of the parameters the
317
319
  * buyer sent and nothing about any other order, because whoever holds an
@@ -345,6 +347,38 @@ export const PurchaseRequestSchema = z
345
347
  export const AgentOrderStatusSchema = z
346
348
  .strictObject({
347
349
  order_id: IdentifierSchema,
350
+ /**
351
+ * Where this order is read again: the whole address of its status route,
352
+ * scheme and host included.
353
+ *
354
+ * It exists for the agent that bought goods that come later. That agent
355
+ * holds this document and nothing else, it has already paid, and the
356
+ * goods are collected at this address. The path is not something it could
357
+ * work out from what it holds — the purchase was made at an address that
358
+ * names the product rather than the order — and a guess that misses is
359
+ * answered `no_such_route`, which says nothing about the order at all.
360
+ *
361
+ * Absolute, so that it is called as it stands: a bare path would have to
362
+ * be joined onto a host the agent was never told was the right one. It is
363
+ * built from the address the gateway is configured to answer as and never
364
+ * from the request that asked, because behind the proxy that ends an
365
+ * agent's TLS connection the request says plain http and names whatever
366
+ * host the proxy or the caller wrote. Plain http is allowed by the pattern
367
+ * all the same, because a gateway on a developer's own machine answers on
368
+ * it; a deployment's address is https because its configuration is.
369
+ *
370
+ * The scheme is a pattern rather than zod's own protocol option for the
371
+ * reason the price hook's is (`PriceCheckSchema` in `card.ts`): a pattern
372
+ * is what survives into the JSON Schema export, so a client generated from
373
+ * that document refuses a bare path as well. It is case-sensitive because
374
+ * a flag on a pattern does not survive that export, and a schema that read
375
+ * the scheme without regard to case would accept what the exported
376
+ * document refuses. Nothing is lost by it: the gateway's configuration
377
+ * already requires its public address in lower case.
378
+ */
379
+ status_url: z
380
+ .url()
381
+ .regex(/^https?:\/\//, "an order's status address is a whole http or https address, not a path"),
348
382
  status: OrderStatusSchema,
349
383
  /**
350
384
  * The price this order was priced at, or null where nobody ever named one
@@ -412,7 +446,7 @@ export const AgentOrderStatusSchema = z
412
446
  refusal: RefusalSchema.optional(),
413
447
  })
414
448
  .meta({
415
- description: 'What became of one purchase, in the words an agent and a merchant both read: where the order stands, what it was priced at, the goods once they are the buyer\'s, and why the merchant would not sell where that is what ended it. It is smaller than the merchant\'s own view of the same order on purpose — no merchant, no merchant\'s own key for the product, none of the purchase parameters and nothing about any other order. The price is what the buyer was asked for and not proof that anything was charged: an order that was priced and then ended without a sale still carries it, and the status is what says which happened. A null price means nobody ever named one for this order, and a null delivery means there are no goods here to hand over; both fields are always present, because an absent field is a silence a reader cannot tell from an oversight. "refusal" is the exception and is present only where a merchant refused: their own short code to branch on and their own sentence to show, carried across unchanged. The code is an open set — "out_of_stock", "invalid_params" and "cannot_fulfill" are read the same way by everybody, and a merchant whose reason fits none of them sends their own word, so an unfamiliar code has to fall through to the sentence rather than break a reader. An absent "refusal" means there is no refusal to quote and never that one was dropped, which leaves two endings still coarse: "rejected" also covers a product that was gone and a payment that failed its check, and neither of those was worded by anybody — the first because a price answer of "not available" carries no words, the second because it is refused at the door in an error envelope instead. A null delivery is likewise not a promise that no goods were ever made: a purchase whose charge failed or went unanswered can leave goods the buyer has not paid for, and this document withholds them rather than describing them. Every answer says whether the money behind the purchase was real: a gateway settling against nothing produces every other field here exactly as a real charge would, so a reader taking this for proof of a payment has to read that word first.',
449
+ description: 'What became of one purchase, in the words an agent and a merchant both read: where the order stands, what it was priced at, the goods once they are the buyer\'s, and why the merchant would not sell where that is what ended it. "status_url" is where this document is read again — the whole address of the order\'s status route, and the place an agent that bought goods that come later collects them. It is absolute and called as it stands, and it is the address the gateway is configured to answer as, never one taken from the request that asked. It is smaller than the merchant\'s own view of the same order on purpose — no merchant, no merchant\'s own key for the product, none of the purchase parameters and nothing about any other order. The price is what the buyer was asked for and not proof that anything was charged: an order that was priced and then ended without a sale still carries it, and the status is what says which happened. A null price means nobody ever named one for this order, and a null delivery means there are no goods here to hand over; both fields are always present, because an absent field is a silence a reader cannot tell from an oversight. "refusal" is the exception and is present only where a merchant refused: their own short code to branch on and their own sentence to show, carried across unchanged. The code is an open set — "out_of_stock", "invalid_params" and "cannot_fulfill" are read the same way by everybody, and a merchant whose reason fits none of them sends their own word, so an unfamiliar code has to fall through to the sentence rather than break a reader. An absent "refusal" means there is no refusal to quote and never that one was dropped, which leaves two endings still coarse: "rejected" also covers a product that was gone and a payment that failed its check, and neither of those was worded by anybody — the first because a price answer of "not available" carries no words, the second because it is refused at the door in an error envelope instead. A null delivery is likewise not a promise that no goods were ever made: a purchase whose charge failed or went unanswered can leave goods the buyer has not paid for, and this document withholds them rather than describing them. Every answer says whether the money behind the purchase was real: a gateway settling against nothing produces every other field here exactly as a real charge would, so a reader taking this for proof of a payment has to read that word first.',
416
450
  });
417
451
  /**
418
452
  * The catalog as an agent reads it.
@@ -680,7 +714,7 @@ export const API_ROUTES = Object.freeze({
680
714
  method: "POST",
681
715
  path: "/v0/catalog/publish",
682
716
  auth: "merchant_key",
683
- description: "Publishes one product, or says what is wrong with the card. Republishing under the same merchant_item_id is how a card is changed rather than how a second one appears. The catalog identifier comes back beside ok, and from then on it is what an agent, a purchase and a receipt all use. A card that is not published comes back as ok:false under the code card_rejected, never retryable, with every finding named in the error's problems. Two of the findings this can come back with are not about the card at all. A merchant who has not set the name their products are sold under gets a finding whose code is no_seller_name, and the way past it is POST /v0/seller-name: a card published without one reaches a buyer's agent inside a payment request that names no seller. And on a deployment that settles on a real chain, a merchant who has set no wallet gets one whose code is no_payout_wallet, with POST /v0/payout-wallet as the way past it: the money from that card's sales is paid to the merchant's own address directly, and without one there is nowhere for it to go. Both come back in the same problems list as whatever is wrong with the card, so one answer carries everything standing between this card and the catalog.",
717
+ description: "Publishes one product, or says what is wrong with the card. Republishing under the same merchant_item_id is how a card is changed rather than how a second one appears. The catalog identifier comes back beside ok, and from then on it is what an agent, a purchase and a receipt all use. A card that is not published comes back as ok:false under the code card_rejected, never retryable, with every finding named in the error's problems. Three findings this can come back with are not about the card at all. A merchant who has not set the name their products are sold under gets no_seller_name, and the way past it is POST /v0/seller-name: a card published without one reaches a buyer's agent inside a payment request that names no seller. On a deployment that settles on a real chain, a merchant who has set no wallet gets no_payout_wallet, with POST /v0/payout-wallet as the way past it: the money from that card's sales is paid to the merchant's own address directly, and without one there is nowhere for it to go. On the live deployment, a merchant the operator has not admitted once gets no_operator_approval. That decision has no merchant API: test publication remains available, while live publication remains closed until the operator grants it. Every applicable finding comes back in the same problems list as whatever is wrong with the card, so one answer carries everything standing between this card and the catalog.",
684
718
  request: CardSchema,
685
719
  response: { document: PublishResultSchema },
686
720
  },
@@ -804,7 +838,7 @@ export const API_ROUTES = Object.freeze({
804
838
  method: "GET",
805
839
  path: "/v0/orders",
806
840
  auth: "merchant_key",
807
- description: "Orders and the states they are in. With open=true, only the ones still owed something — which includes the two that stay open after the purchase itself is over, an order owing a refund and one delivered but never paid for. One kind of order is not in this list at all, with or without the flag: one that closed before anybody named a price for it, because the product was gone or a price question went unanswered. Every row here is written in a document that carries a sale price and those orders have none, so they are readable one at a time by their identifier, where the refusal says what became of them. A merchant reconciling against this list is reconciling against the orders that were priced.",
841
+ description: "Orders and the states they are in. With open=true, only the ones a restarted worker should walk — ones the merchant was handed and has not finished, which includes the two that stay open after the purchase itself is over, an order owing a refund and one delivered but never paid for. An order that was priced and never paid, and never reached the handler, is not in that narrowing; it is readable by its identifier, where its status is the buyer's word for a purchase that has not finished. One kind of order is not in this list at all, with or without the flag: one that closed before anybody named a price for it, because the product was gone or a price question went unanswered. Every row here is written in a document that carries a sale price and those orders have none, so they are readable one at a time by their identifier, where the refusal says what became of them. A merchant reconciling against this list is reconciling against the orders that were priced.",
808
842
  query: OrderListQuerySchema,
809
843
  response: { document: OrderListSchema },
810
844
  },
@@ -874,7 +908,7 @@ export const API_ROUTES = Object.freeze({
874
908
  method: "POST",
875
909
  path: "/x402/:item_id/purchase",
876
910
  auth: "none",
877
- description: "Buying one product. The payment is what stands in for authorisation, so there is no key on this call. It begins with the payment exchange of the x402 protocol: a call with no payment on it is answered with a challenge, which travels in a header and carries no document. What a paid purchase is answered with is the state of the order it made — the same document the status route answers with, whatever the card's mode and whether the purchase ended in the goods or in something else, so an agent that bought and an agent that came back later read one shape. No receipt of ours is in it: a receipt is the merchant's record of the sale and is read behind the merchant's key. What an agent is told about its own money is the price and the word for whether that money was real, and, where the payment executed as the last step of this exchange, the settlement the payment layer signs into a header on this answer — a card whose money moves as the order is opened has already spent that step, so no settlement comes back here and the two fields are the whole of it. The address answers on GET as well as on POST, because that is how the validators and crawlers that list a paid resource ask for it. An unpaid call that carries no document — a GET, or a POST with nothing or with an empty document — is answered with the challenge and never a purchase, and a GET is never read for payment; the challenge describes the purchase, which is a POST with a JSON body. An unpaid POST that carries that document is answered with the price of the very order it opened, and a document of some other shape is refused with the fields that are wrong. A product that is not on sale answers neither method with a challenge: it is refused, so that a catalog built from these challenges never carries a product nobody can buy.",
911
+ description: "Buying one product. The payment is what stands in for authorisation, so there is no key on this call. It begins with the payment exchange of the x402 protocol: a call with no payment on it is answered with a challenge, which travels in a header and carries no document. What a paid purchase is answered with is the state of the order it made — the same document the status route answers with, whatever the card's mode and whether the purchase ended in the goods or in something else, so an agent that bought and an agent that came back later read one shape. That document names, in status_url, the whole address where the order is read again, which is where goods that come later are collected. No receipt of ours is in it: a receipt is the merchant's record of the sale and is read behind the merchant's key. What an agent is told about its own money is the price and the word for whether that money was real, and, where the payment executed as the last step of this exchange, the settlement the payment layer signs into a header on this answer — a card whose money moves as the order is opened has already spent that step, so no settlement comes back here and the two fields are the whole of it. The address answers on GET as well as on POST, because that is how the validators and crawlers that list a paid resource ask for it. An unpaid call that carries no document — a GET, or a POST with nothing or with an empty document — is answered with the challenge and never a purchase, and a GET is never read for payment; the challenge describes the purchase, which is a POST with a JSON body. An unpaid POST that carries that document is answered with the price of the very order it opened, and a document of some other shape is refused with the fields that are wrong. A product that is not on sale answers neither method with a challenge: it is refused, so that a catalog built from these challenges never carries a product nobody can buy.",
878
912
  request: PurchaseRequestSchema,
879
913
  also_answers_on: ["GET"],
880
914
  response: { document: AgentOrderStatusSchema },
@@ -883,7 +917,7 @@ export const API_ROUTES = Object.freeze({
883
917
  method: "GET",
884
918
  path: "/x402/orders/:order_id/status",
885
919
  auth: "order_id",
886
- description: "What became of a purchase, for the agent that made it: where the order stands, what it sold for, and the goods once they are the buyer's. It is the route an agent that bought a product whose goods come later collects them on, and without it half a catalogue takes money and hands back an order nobody can act on. Knowing the order's identifier is the proof (ADR-0011), so this call takes no key: an agent has no account and no registration, and the identifier is handed to exactly one party. No answer of ours hands the agent this address either — it is built from the order's identifier and the address the agent already bought at, which is why it is written the way a stranger would write it and carries no version to guess at. Two things follow for whoever mounts it. Which door a call is behind is read off auth and never off the address, whatever the prefixes happen to agree on today. And an identifier that names no order must be answered exactly as any other unknown one is, or the refusal becomes a way of counting the orders behind it.",
920
+ description: "What became of a purchase, for the agent that made it: where the order stands, what it sold for, and the goods once they are the buyer's. It is the route an agent that bought a product whose goods come later collects them on, and without it half a catalogue takes money and hands back an order nobody can act on. Every answer that carries the order document names this address in status_url, whole and ready to call, the purchase's own answer included. An order whose goods come later is owed them by the delivery deadline its card carried when the order was opened, counted from its payment: fulfill_deadline_seconds where the card names one, and a day where it names none. An order still without goods at that deadline becomes refund_due, and a paid order the merchant refuses or leaves behind becomes it sooner: the merchant owes the buyer the goods or the money back. That is not an ending, and it carries no further deadline. Goods the merchant delivers after it still appear here and settle the debt, and the order becomes delivered. Nor does refund_due say whether the money has come back: the merchant returns it from their own wallet, the gateway has no way yet to record that they did, and until it has one no order moves on to refunded — a buyer already paid back still reads refund_due here. So an agent holding refund_due can still collect goods here, nothing here tells it when to stop asking, and its own wallet is where a refund shows. Knowing the order's identifier is the proof (ADR-0011), so this call takes no key: an agent has no account and no registration, and the identifier is handed to exactly one party. Two things follow for whoever mounts it. Which door a call is behind is read off auth and never off the address, whatever the prefixes happen to agree on today. And an identifier that names no order must be answered exactly as any other unknown one is, or the refusal becomes a way of counting the orders behind it.",
887
921
  response: { document: AgentOrderStatusSchema },
888
922
  },
889
923
  });
package/dist/index.d.ts CHANGED
@@ -76,6 +76,7 @@ export declare const schemas: Readonly<{
76
76
  }, z.core.$strict>;
77
77
  agent_order_status: z.ZodObject<{
78
78
  order_id: z.ZodString;
79
+ status_url: z.ZodURL;
79
80
  status: z.ZodEnum<{
80
81
  delivered: "delivered";
81
82
  in_progress: "in_progress";
@@ -68,8 +68,10 @@ export const ORDER_STATUSES = Object.freeze([
68
68
  */
69
69
  "rejected",
70
70
  /**
71
- * Closed, and nobody can say whether the buyer was charged: the payment
72
- * network was asked and never answered.
71
+ * Nobody can say whether the buyer was charged: the payment network was
72
+ * asked and never answered. The order may still be open — the goods may
73
+ * already be made — and a later read can still move. Closed is not what
74
+ * this word says.
73
75
  *
74
76
  * Deliberately not `rejected`, and this is the fifth gate in one value. An
75
77
  * agent told its purchase did not happen goes and buys the same thing
@@ -88,7 +90,18 @@ export const ORDER_STATUSES = Object.freeze([
88
90
  "expired",
89
91
  /** The merchant left, and orders still open closed with them. */
90
92
  "cancelled",
91
- /** The money moved and the delivery did not happen. */
93
+ /**
94
+ * The money moved and the goods have not come: the merchant owes the buyer
95
+ * the goods or the money back. Not an ending, and it carries no deadline of
96
+ * its own. Goods the merchant delivers after it still reach the buyer, settle
97
+ * the debt and make the order `delivered`.
98
+ *
99
+ * What it cannot say is whether the money has already gone back. The
100
+ * merchant pays a refund from their own wallet and the gateway has no way yet
101
+ * to record that they did, so until it has one nothing moves an order on to
102
+ * `refunded`, and a buyer the merchant has already paid back still reads
103
+ * this word.
104
+ */
92
105
  "refund_due",
93
106
  /** That debt has since been paid back to the buyer. */
94
107
  "refunded",
package/dist/results.js CHANGED
@@ -161,7 +161,8 @@ export const ProblemSchema = z
161
161
  * value, and it covers two kinds of finding that a merchant tells apart by
162
162
  * the words rather than by the shape: one about the whole of what was
163
163
  * sent, and one about the merchant sending it — their having set no name
164
- * for buyers to read, or no wallet for their sales to be paid into.
164
+ * for buyers to read, no wallet for their sales to be paid into, or no
165
+ * operator approval for the live catalogue.
165
166
  * Leaving the field out entirely would make an empty path
166
167
  * indistinguishable from a path nobody filled in.
167
168
  */
@@ -172,7 +173,7 @@ export const ProblemSchema = z
172
173
  message: z.string().regex(/\S/, "a finding carries an explanation a person can read"),
173
174
  })
174
175
  .meta({
175
- description: 'One thing wrong with what was sent: where it is, a code for the program that reads it, and the same finding in words for the person who has to fix it. The path names the field, innermost last — ["params", "email", "type"] — and an empty path is a statement rather than a missing value: the finding is about the whole of what was sent, or about the sender — a merchant with no name set for buyers, or no wallet set for their sales to be paid into, is refused with an empty path too — and not about any one field, which is also what a document that could not be read at all produces. The field is always present for that reason, because an absent path and an empty one would be indistinguishable. Findings never travel alone: they arrive as the problems list inside the error of a call that refused what it was handed — a card that was not published, a delivery that is not what its card declares, a body or a set of purchase parameters that did not fit.',
176
+ description: 'One thing wrong with what was sent: where it is, a code for the program that reads it, and the same finding in words for the person who has to fix it. The path names the field, innermost last — ["params", "email", "type"] — and an empty path is a statement rather than a missing value: the finding is about the whole of what was sent, or about the sender — a merchant with no name set for buyers, no wallet set for their sales to be paid into, or no operator approval for the live catalogue is refused with an empty path too — and not about any one field, which is also what a document that could not be read at all produces. The field is always present for that reason, because an absent path and an empty one would be indistinguishable. Findings never travel alone: they arrive as the problems list inside the error of a call that refused what it was handed — a card that was not published, a delivery that is not what its card declares, a body or a set of purchase parameters that did not fit.',
176
177
  });
177
178
  /**
178
179
  * Why a call did not go through: a code to branch on, a sentence to print, and
@@ -202,7 +203,7 @@ export const CallErrorSchema = z.strictObject({
202
203
  code: z.string().regex(/\S/, "an error carries a code").meta({
203
204
  // Same reason as the refusal code: the dictionary travels with the field
204
205
  // or it does not reach the reader the export exists for.
205
- description: 'Why the call did not go through. The set is open, and five are promised to mean one thing each — but not on the same calls, and which call a code can arrive on is part of what is promised about it. Publishing a card is refused with one word and no other: "card_rejected" (the card was not published, and every finding standing between it and the catalog is named in the error\'s problems — the fields at fault, and the merchant\'s own missing name or payout wallet where those are what is missing; it is never retryable, because the same card gets the same answer and what changes the outcome is fixing what the problems name). The calls that close an order — delivering, refusing, taking one on — are refused with the other four, and never with the first: "refund_already_settled" (the debt was paid back, so there is nothing left to deliver against). "order_already_closed" (the order reached an ending that no call reopens). "not_applicable_in_mode" (the call does not exist for this card\'s mode — refusing separately does not, in the synchronous one, where the handler\'s own answer is the refusal). "delivery_does_not_match_card" (the goods are not the ones the card for this order declares it delivers — nothing was written down, the problems name the fields that did not fit, and the message says whether the order still stands or has already ended). The last of those is retryable in a different sense from a lost connection: the call arrived and was understood, so sending the same goods again gives the same refusal, and what clears it is delivering what the card declares. It is not retryable at all where the order has already ended, because there is nothing left to deliver against.',
206
+ description: 'Why the call did not go through. The set is open, and five are promised to mean one thing each — but not on the same calls, and which call a code can arrive on is part of what is promised about it. Publishing a card is refused with one word and no other: "card_rejected" (the card was not published, and every finding standing between it and the catalog is named in the error\'s problems — the fields at fault, and the merchant\'s own missing name, payout wallet or live operator approval where those are what is missing; it is never retryable, because the same card gets the same answer and what changes the outcome is fixing what the problems name). The calls that close an order — delivering, refusing, taking one on — are refused with the other four, and never with the first: "refund_already_settled" (the debt was paid back, so there is nothing left to deliver against). "order_already_closed" (the order reached an ending that no call reopens). "not_applicable_in_mode" (the call does not exist for this card\'s mode — refusing separately does not, in the synchronous one, where the handler\'s own answer is the refusal). "delivery_does_not_match_card" (the goods are not the ones the card for this order declares it delivers — nothing was written down, the problems name the fields that did not fit, and the message says whether the order still stands or has already ended). The last of those is retryable in a different sense from a lost connection: the call arrived and was understood, so sending the same goods again gives the same refusal, and what clears it is delivering what the card declares. It is not retryable at all where the order has already ended, because there is nothing left to deliver against.',
206
207
  }),
207
208
  message: z.string().regex(/\S/, "an error carries an explanation a person can read"),
208
209
  retryable: z.boolean(),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nuanu-ai/agentify-contracts",
3
- "version": "0.3.2",
3
+ "version": "0.4.0",
4
4
  "type": "module",
5
5
  "description": "The Agentify wire contract as code: the schemas for cards, orders, price checks and receipts that the gateway and the merchant SDK both read.",
6
6
  "keywords": [
@@ -9,7 +9,7 @@
9
9
  "zod-schemas",
10
10
  "json-schema"
11
11
  ],
12
- "homepage": "https://app.agentify.ad/docs/",
12
+ "homepage": "https://agentify.ad/docs/",
13
13
  "license": "Apache-2.0",
14
14
  "repository": {
15
15
  "type": "git",