@harrylabsj/kiwi 0.6.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.
Files changed (636) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +150 -0
  3. package/contracts/candidate-agent-dto-1.0.README.md +39 -0
  4. package/contracts/candidate-agent-dto-1.0.schema.json +172 -0
  5. package/contracts/interop/kiwi-buyer-message-send.json +43 -0
  6. package/contracts/interop/knp-data-part-examples.json +243 -0
  7. package/contracts/kiwi-catalog/1.0/agent-record.schema.json +78 -0
  8. package/contracts/kiwi-catalog/1.0/listing-record.schema.json +88 -0
  9. package/contracts/kiwi-catalog/1.0/listing-search-result.schema.json +60 -0
  10. package/contracts/negotiation/1.0/schema.json +501 -0
  11. package/contracts/shopping.negotiation/0.1/capabilities.schema.json +47 -0
  12. package/contracts/shopping.negotiation/0.1/decision.schema.json +120 -0
  13. package/contracts/shopping.negotiation/0.1/policy-result.schema.json +52 -0
  14. package/contracts/shopping.negotiation/0.1/snapshot.schema.json +172 -0
  15. package/dist/a2a/client/client.d.ts +33 -0
  16. package/dist/a2a/client/client.js +161 -0
  17. package/dist/a2a/client/client.js.map +1 -0
  18. package/dist/a2a/client/error.d.ts +35 -0
  19. package/dist/a2a/client/error.js +34 -0
  20. package/dist/a2a/client/error.js.map +1 -0
  21. package/dist/a2a/client/index.d.ts +29 -0
  22. package/dist/a2a/client/index.js +26 -0
  23. package/dist/a2a/client/index.js.map +1 -0
  24. package/dist/a2a/client/jsonrpc.d.ts +49 -0
  25. package/dist/a2a/client/jsonrpc.js +85 -0
  26. package/dist/a2a/client/jsonrpc.js.map +1 -0
  27. package/dist/a2a/client/parse.d.ts +18 -0
  28. package/dist/a2a/client/parse.js +134 -0
  29. package/dist/a2a/client/parse.js.map +1 -0
  30. package/dist/a2a/client/types.d.ts +102 -0
  31. package/dist/a2a/client/types.js +26 -0
  32. package/dist/a2a/client/types.js.map +1 -0
  33. package/dist/a2a/client/url-policy.d.ts +44 -0
  34. package/dist/a2a/client/url-policy.js +242 -0
  35. package/dist/a2a/client/url-policy.js.map +1 -0
  36. package/dist/a2a/negotiate.d.ts +68 -0
  37. package/dist/a2a/negotiate.js +288 -0
  38. package/dist/a2a/negotiate.js.map +1 -0
  39. package/dist/a2a/node.d.ts +37 -0
  40. package/dist/a2a/node.js +155 -0
  41. package/dist/a2a/node.js.map +1 -0
  42. package/dist/a2a/server/auth.d.ts +38 -0
  43. package/dist/a2a/server/auth.js +112 -0
  44. package/dist/a2a/server/auth.js.map +1 -0
  45. package/dist/a2a/server/card.d.ts +19 -0
  46. package/dist/a2a/server/card.js +81 -0
  47. package/dist/a2a/server/card.js.map +1 -0
  48. package/dist/a2a/server/errors.d.ts +109 -0
  49. package/dist/a2a/server/errors.js +178 -0
  50. package/dist/a2a/server/errors.js.map +1 -0
  51. package/dist/a2a/server/handler.d.ts +22 -0
  52. package/dist/a2a/server/handler.js +57 -0
  53. package/dist/a2a/server/handler.js.map +1 -0
  54. package/dist/a2a/server/inbound-message.d.ts +37 -0
  55. package/dist/a2a/server/inbound-message.js +104 -0
  56. package/dist/a2a/server/inbound-message.js.map +1 -0
  57. package/dist/a2a/server/index.d.ts +43 -0
  58. package/dist/a2a/server/index.js +42 -0
  59. package/dist/a2a/server/index.js.map +1 -0
  60. package/dist/a2a/server/merchant-handler.d.ts +69 -0
  61. package/dist/a2a/server/merchant-handler.js +316 -0
  62. package/dist/a2a/server/merchant-handler.js.map +1 -0
  63. package/dist/a2a/server/pipeline.d.ts +69 -0
  64. package/dist/a2a/server/pipeline.js +329 -0
  65. package/dist/a2a/server/pipeline.js.map +1 -0
  66. package/dist/a2a/server/server.d.ts +64 -0
  67. package/dist/a2a/server/server.js +420 -0
  68. package/dist/a2a/server/server.js.map +1 -0
  69. package/dist/a2a/server/task-registry.d.ts +31 -0
  70. package/dist/a2a/server/task-registry.js +67 -0
  71. package/dist/a2a/server/task-registry.js.map +1 -0
  72. package/dist/a2a/server/throttle.d.ts +154 -0
  73. package/dist/a2a/server/throttle.js +289 -0
  74. package/dist/a2a/server/throttle.js.map +1 -0
  75. package/dist/a2a/server/types.d.ts +191 -0
  76. package/dist/a2a/server/types.js +17 -0
  77. package/dist/a2a/server/types.js.map +1 -0
  78. package/dist/a2a/server/ucp.d.ts +49 -0
  79. package/dist/a2a/server/ucp.js +85 -0
  80. package/dist/a2a/server/ucp.js.map +1 -0
  81. package/dist/a2a/task/index.d.ts +24 -0
  82. package/dist/a2a/task/index.js +22 -0
  83. package/dist/a2a/task/index.js.map +1 -0
  84. package/dist/a2a/task/ledger.d.ts +48 -0
  85. package/dist/a2a/task/ledger.js +65 -0
  86. package/dist/a2a/task/ledger.js.map +1 -0
  87. package/dist/a2a/task/poller.d.ts +93 -0
  88. package/dist/a2a/task/poller.js +184 -0
  89. package/dist/a2a/task/poller.js.map +1 -0
  90. package/dist/a2a/task/state.d.ts +72 -0
  91. package/dist/a2a/task/state.js +119 -0
  92. package/dist/a2a/task/state.js.map +1 -0
  93. package/dist/a2a/ucp-agent.d.ts +49 -0
  94. package/dist/a2a/ucp-agent.js +78 -0
  95. package/dist/a2a/ucp-agent.js.map +1 -0
  96. package/dist/agent/agent-db.d.ts +31 -0
  97. package/dist/agent/agent-db.js +91 -0
  98. package/dist/agent/agent-db.js.map +1 -0
  99. package/dist/agent/buyer/buyer-tools.d.ts +70 -0
  100. package/dist/agent/buyer/buyer-tools.js +1353 -0
  101. package/dist/agent/buyer/buyer-tools.js.map +1 -0
  102. package/dist/agent/buyer/ranker.d.ts +53 -0
  103. package/dist/agent/buyer/ranker.js +153 -0
  104. package/dist/agent/buyer/ranker.js.map +1 -0
  105. package/dist/agent/buyer/scheduler.d.ts +58 -0
  106. package/dist/agent/buyer/scheduler.js +317 -0
  107. package/dist/agent/buyer/scheduler.js.map +1 -0
  108. package/dist/agent/buyer/search-loop.d.ts +42 -0
  109. package/dist/agent/buyer/search-loop.js +280 -0
  110. package/dist/agent/buyer/search-loop.js.map +1 -0
  111. package/dist/agent/buyer/task-store.d.ts +178 -0
  112. package/dist/agent/buyer/task-store.js +637 -0
  113. package/dist/agent/buyer/task-store.js.map +1 -0
  114. package/dist/agent/buyer/types.d.ts +222 -0
  115. package/dist/agent/buyer/types.js +124 -0
  116. package/dist/agent/buyer/types.js.map +1 -0
  117. package/dist/agent/chat-tools.d.ts +41 -0
  118. package/dist/agent/chat-tools.js +193 -0
  119. package/dist/agent/chat-tools.js.map +1 -0
  120. package/dist/agent/chat-tui.d.ts +49 -0
  121. package/dist/agent/chat-tui.js +314 -0
  122. package/dist/agent/chat-tui.js.map +1 -0
  123. package/dist/agent/connector/fake-connector.d.ts +50 -0
  124. package/dist/agent/connector/fake-connector.js +138 -0
  125. package/dist/agent/connector/fake-connector.js.map +1 -0
  126. package/dist/agent/connector/http-connector.d.ts +49 -0
  127. package/dist/agent/connector/http-connector.js +208 -0
  128. package/dist/agent/connector/http-connector.js.map +1 -0
  129. package/dist/agent/connector/types.d.ts +103 -0
  130. package/dist/agent/connector/types.js +97 -0
  131. package/dist/agent/connector/types.js.map +1 -0
  132. package/dist/agent/fake-chat-model.d.ts +22 -0
  133. package/dist/agent/fake-chat-model.js +134 -0
  134. package/dist/agent/fake-chat-model.js.map +1 -0
  135. package/dist/agent/kernel.d.ts +258 -0
  136. package/dist/agent/kernel.js +1099 -0
  137. package/dist/agent/kernel.js.map +1 -0
  138. package/dist/agent/memory/schema.d.ts +32 -0
  139. package/dist/agent/memory/schema.js +291 -0
  140. package/dist/agent/memory/schema.js.map +1 -0
  141. package/dist/agent/memory/store.d.ts +193 -0
  142. package/dist/agent/memory/store.js +881 -0
  143. package/dist/agent/memory/store.js.map +1 -0
  144. package/dist/agent/memory/types.d.ts +139 -0
  145. package/dist/agent/memory/types.js +119 -0
  146. package/dist/agent/memory/types.js.map +1 -0
  147. package/dist/agent/memory/vault.d.ts +49 -0
  148. package/dist/agent/memory/vault.js +125 -0
  149. package/dist/agent/memory/vault.js.map +1 -0
  150. package/dist/agent/merchant/action-candidate.d.ts +106 -0
  151. package/dist/agent/merchant/action-candidate.js +241 -0
  152. package/dist/agent/merchant/action-candidate.js.map +1 -0
  153. package/dist/agent/merchant/credential-broker.d.ts +67 -0
  154. package/dist/agent/merchant/credential-broker.js +76 -0
  155. package/dist/agent/merchant/credential-broker.js.map +1 -0
  156. package/dist/agent/merchant/fake-merchant-client.d.ts +47 -0
  157. package/dist/agent/merchant/fake-merchant-client.js +143 -0
  158. package/dist/agent/merchant/fake-merchant-client.js.map +1 -0
  159. package/dist/agent/merchant/merchant-client.d.ts +49 -0
  160. package/dist/agent/merchant/merchant-client.js +186 -0
  161. package/dist/agent/merchant/merchant-client.js.map +1 -0
  162. package/dist/agent/merchant/merchant-tools.d.ts +74 -0
  163. package/dist/agent/merchant/merchant-tools.js +582 -0
  164. package/dist/agent/merchant/merchant-tools.js.map +1 -0
  165. package/dist/agent/merchant/types.d.ts +119 -0
  166. package/dist/agent/merchant/types.js +133 -0
  167. package/dist/agent/merchant/types.js.map +1 -0
  168. package/dist/agent/mode.d.ts +32 -0
  169. package/dist/agent/mode.js +34 -0
  170. package/dist/agent/mode.js.map +1 -0
  171. package/dist/agent/negotiation-chat.d.ts +81 -0
  172. package/dist/agent/negotiation-chat.js +330 -0
  173. package/dist/agent/negotiation-chat.js.map +1 -0
  174. package/dist/agent/session.d.ts +22 -0
  175. package/dist/agent/session.js +164 -0
  176. package/dist/agent/session.js.map +1 -0
  177. package/dist/agent/system-prompt.d.ts +26 -0
  178. package/dist/agent/system-prompt.js +77 -0
  179. package/dist/agent/system-prompt.js.map +1 -0
  180. package/dist/agent/write-gate.d.ts +98 -0
  181. package/dist/agent/write-gate.js +76 -0
  182. package/dist/agent/write-gate.js.map +1 -0
  183. package/dist/cli.d.ts +18 -0
  184. package/dist/cli.js +1139 -0
  185. package/dist/cli.js.map +1 -0
  186. package/dist/commerce/data-source.d.ts +88 -0
  187. package/dist/commerce/data-source.js +25 -0
  188. package/dist/commerce/data-source.js.map +1 -0
  189. package/dist/commerce/erp-source.d.ts +51 -0
  190. package/dist/commerce/erp-source.js +184 -0
  191. package/dist/commerce/erp-source.js.map +1 -0
  192. package/dist/commerce/fake-client.d.ts +167 -0
  193. package/dist/commerce/fake-client.js +549 -0
  194. package/dist/commerce/fake-client.js.map +1 -0
  195. package/dist/commerce/http-client.d.ts +73 -0
  196. package/dist/commerce/http-client.js +284 -0
  197. package/dist/commerce/http-client.js.map +1 -0
  198. package/dist/commerce/local-db-source.d.ts +50 -0
  199. package/dist/commerce/local-db-source.js +162 -0
  200. package/dist/commerce/local-db-source.js.map +1 -0
  201. package/dist/commerce/shopping-cli-source.d.ts +57 -0
  202. package/dist/commerce/shopping-cli-source.js +206 -0
  203. package/dist/commerce/shopping-cli-source.js.map +1 -0
  204. package/dist/commerce/types.d.ts +146 -0
  205. package/dist/commerce/types.js +31 -0
  206. package/dist/commerce/types.js.map +1 -0
  207. package/dist/config/profile.d.ts +122 -0
  208. package/dist/config/profile.js +386 -0
  209. package/dist/config/profile.js.map +1 -0
  210. package/dist/contracts/negotiation-schema.d.ts +28 -0
  211. package/dist/contracts/negotiation-schema.js +101 -0
  212. package/dist/contracts/negotiation-schema.js.map +1 -0
  213. package/dist/contracts/schemas.d.ts +31 -0
  214. package/dist/contracts/schemas.js +122 -0
  215. package/dist/contracts/schemas.js.map +1 -0
  216. package/dist/counterparty/a2a-direct/index.d.ts +41 -0
  217. package/dist/counterparty/a2a-direct/index.js +330 -0
  218. package/dist/counterparty/a2a-direct/index.js.map +1 -0
  219. package/dist/counterparty/channel.d.ts +200 -0
  220. package/dist/counterparty/channel.js +61 -0
  221. package/dist/counterparty/channel.js.map +1 -0
  222. package/dist/counterparty/index.d.ts +28 -0
  223. package/dist/counterparty/index.js +24 -0
  224. package/dist/counterparty/index.js.map +1 -0
  225. package/dist/counterparty/platform-api/index.d.ts +41 -0
  226. package/dist/counterparty/platform-api/index.js +65 -0
  227. package/dist/counterparty/platform-api/index.js.map +1 -0
  228. package/dist/counterparty/registry.d.ts +51 -0
  229. package/dist/counterparty/registry.js +71 -0
  230. package/dist/counterparty/registry.js.map +1 -0
  231. package/dist/counterparty/shopping-cli-hosted/index.d.ts +36 -0
  232. package/dist/counterparty/shopping-cli-hosted/index.js +337 -0
  233. package/dist/counterparty/shopping-cli-hosted/index.js.map +1 -0
  234. package/dist/discovery/agent-card/error.d.ts +28 -0
  235. package/dist/discovery/agent-card/error.js +31 -0
  236. package/dist/discovery/agent-card/error.js.map +1 -0
  237. package/dist/discovery/agent-card/extensions.d.ts +20 -0
  238. package/dist/discovery/agent-card/extensions.js +59 -0
  239. package/dist/discovery/agent-card/extensions.js.map +1 -0
  240. package/dist/discovery/agent-card/index.d.ts +29 -0
  241. package/dist/discovery/agent-card/index.js +38 -0
  242. package/dist/discovery/agent-card/index.js.map +1 -0
  243. package/dist/discovery/agent-card/secrets.d.ts +30 -0
  244. package/dist/discovery/agent-card/secrets.js +240 -0
  245. package/dist/discovery/agent-card/secrets.js.map +1 -0
  246. package/dist/discovery/agent-card/types.d.ts +110 -0
  247. package/dist/discovery/agent-card/types.js +37 -0
  248. package/dist/discovery/agent-card/types.js.map +1 -0
  249. package/dist/discovery/agent-card/validate.d.ts +31 -0
  250. package/dist/discovery/agent-card/validate.js +210 -0
  251. package/dist/discovery/agent-card/validate.js.map +1 -0
  252. package/dist/discovery/capability/error.d.ts +23 -0
  253. package/dist/discovery/capability/error.js +28 -0
  254. package/dist/discovery/capability/error.js.map +1 -0
  255. package/dist/discovery/capability/index.d.ts +21 -0
  256. package/dist/discovery/capability/index.js +21 -0
  257. package/dist/discovery/capability/index.js.map +1 -0
  258. package/dist/discovery/capability/intersect.d.ts +56 -0
  259. package/dist/discovery/capability/intersect.js +137 -0
  260. package/dist/discovery/capability/intersect.js.map +1 -0
  261. package/dist/discovery/catalog-source/errors.d.ts +32 -0
  262. package/dist/discovery/catalog-source/errors.js +41 -0
  263. package/dist/discovery/catalog-source/errors.js.map +1 -0
  264. package/dist/discovery/catalog-source/index.d.ts +30 -0
  265. package/dist/discovery/catalog-source/index.js +29 -0
  266. package/dist/discovery/catalog-source/index.js.map +1 -0
  267. package/dist/discovery/catalog-source/kiwi-record.d.ts +183 -0
  268. package/dist/discovery/catalog-source/kiwi-record.js +72 -0
  269. package/dist/discovery/catalog-source/kiwi-record.js.map +1 -0
  270. package/dist/discovery/catalog-source/kiwi-schema.d.ts +33 -0
  271. package/dist/discovery/catalog-source/kiwi-schema.js +106 -0
  272. package/dist/discovery/catalog-source/kiwi-schema.js.map +1 -0
  273. package/dist/discovery/catalog-source/kiwi-source.d.ts +38 -0
  274. package/dist/discovery/catalog-source/kiwi-source.js +318 -0
  275. package/dist/discovery/catalog-source/kiwi-source.js.map +1 -0
  276. package/dist/discovery/catalog-source/register.d.ts +48 -0
  277. package/dist/discovery/catalog-source/register.js +83 -0
  278. package/dist/discovery/catalog-source/register.js.map +1 -0
  279. package/dist/discovery/catalog-source/schema.d.ts +21 -0
  280. package/dist/discovery/catalog-source/schema.js +63 -0
  281. package/dist/discovery/catalog-source/schema.js.map +1 -0
  282. package/dist/discovery/catalog-source/source.d.ts +45 -0
  283. package/dist/discovery/catalog-source/source.js +197 -0
  284. package/dist/discovery/catalog-source/source.js.map +1 -0
  285. package/dist/discovery/catalog-source/types.d.ts +122 -0
  286. package/dist/discovery/catalog-source/types.js +30 -0
  287. package/dist/discovery/catalog-source/types.js.map +1 -0
  288. package/dist/discovery/index.d.ts +25 -0
  289. package/dist/discovery/index.js +25 -0
  290. package/dist/discovery/index.js.map +1 -0
  291. package/dist/discovery/resolve.d.ts +175 -0
  292. package/dist/discovery/resolve.js +367 -0
  293. package/dist/discovery/resolve.js.map +1 -0
  294. package/dist/discovery/ucp/error.d.ts +25 -0
  295. package/dist/discovery/ucp/error.js +27 -0
  296. package/dist/discovery/ucp/error.js.map +1 -0
  297. package/dist/discovery/ucp/index.d.ts +33 -0
  298. package/dist/discovery/ucp/index.js +28 -0
  299. package/dist/discovery/ucp/index.js.map +1 -0
  300. package/dist/discovery/ucp/intersect.d.ts +148 -0
  301. package/dist/discovery/ucp/intersect.js +312 -0
  302. package/dist/discovery/ucp/intersect.js.map +1 -0
  303. package/dist/discovery/ucp/resolver.d.ts +62 -0
  304. package/dist/discovery/ucp/resolver.js +214 -0
  305. package/dist/discovery/ucp/resolver.js.map +1 -0
  306. package/dist/discovery/ucp/types.d.ts +97 -0
  307. package/dist/discovery/ucp/types.js +103 -0
  308. package/dist/discovery/ucp/types.js.map +1 -0
  309. package/dist/discovery/ucp/validate.d.ts +38 -0
  310. package/dist/discovery/ucp/validate.js +232 -0
  311. package/dist/discovery/ucp/validate.js.map +1 -0
  312. package/dist/discovery/ucp/vendor.d.ts +60 -0
  313. package/dist/discovery/ucp/vendor.js +61 -0
  314. package/dist/discovery/ucp/vendor.js.map +1 -0
  315. package/dist/doctor.d.ts +26 -0
  316. package/dist/doctor.js +113 -0
  317. package/dist/doctor.js.map +1 -0
  318. package/dist/exit-codes.d.ts +26 -0
  319. package/dist/exit-codes.js +27 -0
  320. package/dist/exit-codes.js.map +1 -0
  321. package/dist/fanout/disclosure.d.ts +138 -0
  322. package/dist/fanout/disclosure.js +188 -0
  323. package/dist/fanout/disclosure.js.map +1 -0
  324. package/dist/fanout/index.d.ts +32 -0
  325. package/dist/fanout/index.js +30 -0
  326. package/dist/fanout/index.js.map +1 -0
  327. package/dist/fanout/orchestrator.d.ts +153 -0
  328. package/dist/fanout/orchestrator.js +439 -0
  329. package/dist/fanout/orchestrator.js.map +1 -0
  330. package/dist/fanout/policy.d.ts +128 -0
  331. package/dist/fanout/policy.js +130 -0
  332. package/dist/fanout/policy.js.map +1 -0
  333. package/dist/handoff/acp-commerce.d.ts +58 -0
  334. package/dist/handoff/acp-commerce.js +69 -0
  335. package/dist/handoff/acp-commerce.js.map +1 -0
  336. package/dist/handoff/authorization.d.ts +127 -0
  337. package/dist/handoff/authorization.js +107 -0
  338. package/dist/handoff/authorization.js.map +1 -0
  339. package/dist/handoff/candidate.d.ts +94 -0
  340. package/dist/handoff/candidate.js +172 -0
  341. package/dist/handoff/candidate.js.map +1 -0
  342. package/dist/handoff/channel.d.ts +88 -0
  343. package/dist/handoff/channel.js +189 -0
  344. package/dist/handoff/channel.js.map +1 -0
  345. package/dist/handoff/completion.d.ts +44 -0
  346. package/dist/handoff/completion.js +136 -0
  347. package/dist/handoff/completion.js.map +1 -0
  348. package/dist/handoff/delivery.d.ts +59 -0
  349. package/dist/handoff/delivery.js +185 -0
  350. package/dist/handoff/delivery.js.map +1 -0
  351. package/dist/handoff/destination.d.ts +39 -0
  352. package/dist/handoff/destination.js +99 -0
  353. package/dist/handoff/destination.js.map +1 -0
  354. package/dist/handoff/errors.d.ts +34 -0
  355. package/dist/handoff/errors.js +47 -0
  356. package/dist/handoff/errors.js.map +1 -0
  357. package/dist/handoff/idempotency.d.ts +51 -0
  358. package/dist/handoff/idempotency.js +168 -0
  359. package/dist/handoff/idempotency.js.map +1 -0
  360. package/dist/handoff/index.d.ts +46 -0
  361. package/dist/handoff/index.js +48 -0
  362. package/dist/handoff/index.js.map +1 -0
  363. package/dist/handoff/ledger.d.ts +94 -0
  364. package/dist/handoff/ledger.js +195 -0
  365. package/dist/handoff/ledger.js.map +1 -0
  366. package/dist/handoff/lifecycle.d.ts +29 -0
  367. package/dist/handoff/lifecycle.js +102 -0
  368. package/dist/handoff/lifecycle.js.map +1 -0
  369. package/dist/handoff/metrics.d.ts +56 -0
  370. package/dist/handoff/metrics.js +78 -0
  371. package/dist/handoff/metrics.js.map +1 -0
  372. package/dist/handoff/operator-approval.d.ts +143 -0
  373. package/dist/handoff/operator-approval.js +287 -0
  374. package/dist/handoff/operator-approval.js.map +1 -0
  375. package/dist/handoff/order-record.d.ts +104 -0
  376. package/dist/handoff/order-record.js +235 -0
  377. package/dist/handoff/order-record.js.map +1 -0
  378. package/dist/handoff/package.d.ts +102 -0
  379. package/dist/handoff/package.js +132 -0
  380. package/dist/handoff/package.js.map +1 -0
  381. package/dist/handoff/transaction.d.ts +96 -0
  382. package/dist/handoff/transaction.js +263 -0
  383. package/dist/handoff/transaction.js.map +1 -0
  384. package/dist/handoff/ucp-checkout/cart-channel.d.ts +111 -0
  385. package/dist/handoff/ucp-checkout/cart-channel.js +370 -0
  386. package/dist/handoff/ucp-checkout/cart-channel.js.map +1 -0
  387. package/dist/handoff/ucp-checkout/cart-parse.d.ts +22 -0
  388. package/dist/handoff/ucp-checkout/cart-parse.js +102 -0
  389. package/dist/handoff/ucp-checkout/cart-parse.js.map +1 -0
  390. package/dist/handoff/ucp-checkout/cart-types.d.ts +93 -0
  391. package/dist/handoff/ucp-checkout/cart-types.js +38 -0
  392. package/dist/handoff/ucp-checkout/cart-types.js.map +1 -0
  393. package/dist/handoff/ucp-checkout/channel.d.ts +159 -0
  394. package/dist/handoff/ucp-checkout/channel.js +636 -0
  395. package/dist/handoff/ucp-checkout/channel.js.map +1 -0
  396. package/dist/handoff/ucp-checkout/client.d.ts +88 -0
  397. package/dist/handoff/ucp-checkout/client.js +228 -0
  398. package/dist/handoff/ucp-checkout/client.js.map +1 -0
  399. package/dist/handoff/ucp-checkout/endpoint.d.ts +36 -0
  400. package/dist/handoff/ucp-checkout/endpoint.js +145 -0
  401. package/dist/handoff/ucp-checkout/endpoint.js.map +1 -0
  402. package/dist/handoff/ucp-checkout/index.d.ts +35 -0
  403. package/dist/handoff/ucp-checkout/index.js +36 -0
  404. package/dist/handoff/ucp-checkout/index.js.map +1 -0
  405. package/dist/handoff/ucp-checkout/parse.d.ts +71 -0
  406. package/dist/handoff/ucp-checkout/parse.js +349 -0
  407. package/dist/handoff/ucp-checkout/parse.js.map +1 -0
  408. package/dist/handoff/ucp-checkout/totals.d.ts +41 -0
  409. package/dist/handoff/ucp-checkout/totals.js +36 -0
  410. package/dist/handoff/ucp-checkout/totals.js.map +1 -0
  411. package/dist/handoff/ucp-checkout/types.d.ts +149 -0
  412. package/dist/handoff/ucp-checkout/types.js +58 -0
  413. package/dist/handoff/ucp-checkout/types.js.map +1 -0
  414. package/dist/handoff/url-safety.d.ts +44 -0
  415. package/dist/handoff/url-safety.js +121 -0
  416. package/dist/handoff/url-safety.js.map +1 -0
  417. package/dist/i18n.d.ts +24 -0
  418. package/dist/i18n.js +27 -0
  419. package/dist/i18n.js.map +1 -0
  420. package/dist/negotiation/action-candidate.d.ts +97 -0
  421. package/dist/negotiation/action-candidate.js +160 -0
  422. package/dist/negotiation/action-candidate.js.map +1 -0
  423. package/dist/negotiation/condition/evaluator.d.ts +36 -0
  424. package/dist/negotiation/condition/evaluator.js +123 -0
  425. package/dist/negotiation/condition/evaluator.js.map +1 -0
  426. package/dist/negotiation/context-map/index.d.ts +23 -0
  427. package/dist/negotiation/context-map/index.js +22 -0
  428. package/dist/negotiation/context-map/index.js.map +1 -0
  429. package/dist/negotiation/context-map/store.d.ts +51 -0
  430. package/dist/negotiation/context-map/store.js +186 -0
  431. package/dist/negotiation/context-map/store.js.map +1 -0
  432. package/dist/negotiation/context-map/types.d.ts +29 -0
  433. package/dist/negotiation/context-map/types.js +57 -0
  434. package/dist/negotiation/context-map/types.js.map +1 -0
  435. package/dist/negotiation/domain/common.d.ts +95 -0
  436. package/dist/negotiation/domain/common.js +216 -0
  437. package/dist/negotiation/domain/common.js.map +1 -0
  438. package/dist/negotiation/domain/envelope.d.ts +55 -0
  439. package/dist/negotiation/domain/envelope.js +110 -0
  440. package/dist/negotiation/domain/envelope.js.map +1 -0
  441. package/dist/negotiation/domain/identifiers.d.ts +65 -0
  442. package/dist/negotiation/domain/identifiers.js +130 -0
  443. package/dist/negotiation/domain/identifiers.js.map +1 -0
  444. package/dist/negotiation/domain/objects.d.ts +149 -0
  445. package/dist/negotiation/domain/objects.js +335 -0
  446. package/dist/negotiation/domain/objects.js.map +1 -0
  447. package/dist/negotiation/idempotency/index.d.ts +26 -0
  448. package/dist/negotiation/idempotency/index.js +25 -0
  449. package/dist/negotiation/idempotency/index.js.map +1 -0
  450. package/dist/negotiation/idempotency/store.d.ts +52 -0
  451. package/dist/negotiation/idempotency/store.js +189 -0
  452. package/dist/negotiation/idempotency/store.js.map +1 -0
  453. package/dist/negotiation/idempotency/types.d.ts +102 -0
  454. package/dist/negotiation/idempotency/types.js +47 -0
  455. package/dist/negotiation/idempotency/types.js.map +1 -0
  456. package/dist/negotiation/jcs.d.ts +21 -0
  457. package/dist/negotiation/jcs.js +114 -0
  458. package/dist/negotiation/jcs.js.map +1 -0
  459. package/dist/negotiation/ledger/event.d.ts +142 -0
  460. package/dist/negotiation/ledger/event.js +206 -0
  461. package/dist/negotiation/ledger/event.js.map +1 -0
  462. package/dist/negotiation/ledger/index.d.ts +26 -0
  463. package/dist/negotiation/ledger/index.js +25 -0
  464. package/dist/negotiation/ledger/index.js.map +1 -0
  465. package/dist/negotiation/ledger/store.d.ts +97 -0
  466. package/dist/negotiation/ledger/store.js +338 -0
  467. package/dist/negotiation/ledger/store.js.map +1 -0
  468. package/dist/negotiation/prompt.d.ts +34 -0
  469. package/dist/negotiation/prompt.js +113 -0
  470. package/dist/negotiation/prompt.js.map +1 -0
  471. package/dist/negotiation/recovery/index.d.ts +26 -0
  472. package/dist/negotiation/recovery/index.js +24 -0
  473. package/dist/negotiation/recovery/index.js.map +1 -0
  474. package/dist/negotiation/recovery/outbound.d.ts +49 -0
  475. package/dist/negotiation/recovery/outbound.js +34 -0
  476. package/dist/negotiation/recovery/outbound.js.map +1 -0
  477. package/dist/negotiation/recovery/recover.d.ts +59 -0
  478. package/dist/negotiation/recovery/recover.js +486 -0
  479. package/dist/negotiation/recovery/recover.js.map +1 -0
  480. package/dist/negotiation/recovery/types.d.ts +85 -0
  481. package/dist/negotiation/recovery/types.js +17 -0
  482. package/dist/negotiation/recovery/types.js.map +1 -0
  483. package/dist/negotiation/state/phase.d.ts +70 -0
  484. package/dist/negotiation/state/phase.js +200 -0
  485. package/dist/negotiation/state/phase.js.map +1 -0
  486. package/dist/negotiation/types.d.ts +139 -0
  487. package/dist/negotiation/types.js +24 -0
  488. package/dist/negotiation/types.js.map +1 -0
  489. package/dist/net/safe-http.d.ts +54 -0
  490. package/dist/net/safe-http.js +116 -0
  491. package/dist/net/safe-http.js.map +1 -0
  492. package/dist/operator/controller.d.ts +181 -0
  493. package/dist/operator/controller.js +784 -0
  494. package/dist/operator/controller.js.map +1 -0
  495. package/dist/operator/runner.d.ts +128 -0
  496. package/dist/operator/runner.js +248 -0
  497. package/dist/operator/runner.js.map +1 -0
  498. package/dist/operator/store.d.ts +39 -0
  499. package/dist/operator/store.js +169 -0
  500. package/dist/operator/store.js.map +1 -0
  501. package/dist/operator/strategy.d.ts +54 -0
  502. package/dist/operator/strategy.js +249 -0
  503. package/dist/operator/strategy.js.map +1 -0
  504. package/dist/operator/tui.d.ts +27 -0
  505. package/dist/operator/tui.js +395 -0
  506. package/dist/operator/tui.js.map +1 -0
  507. package/dist/operator/types.d.ts +224 -0
  508. package/dist/operator/types.js +17 -0
  509. package/dist/operator/types.js.map +1 -0
  510. package/dist/product-buyer.d.ts +74 -0
  511. package/dist/product-buyer.js +161 -0
  512. package/dist/product-buyer.js.map +1 -0
  513. package/dist/product-cli.d.ts +56 -0
  514. package/dist/product-cli.js +175 -0
  515. package/dist/product-cli.js.map +1 -0
  516. package/dist/product-compat.d.ts +50 -0
  517. package/dist/product-compat.js +63 -0
  518. package/dist/product-compat.js.map +1 -0
  519. package/dist/product-init.d.ts +73 -0
  520. package/dist/product-init.js +203 -0
  521. package/dist/product-init.js.map +1 -0
  522. package/dist/product-publish.d.ts +85 -0
  523. package/dist/product-publish.js +216 -0
  524. package/dist/product-publish.js.map +1 -0
  525. package/dist/protocol/legacy-shopping-negotiation/adapter.d.ts +42 -0
  526. package/dist/protocol/legacy-shopping-negotiation/adapter.js +561 -0
  527. package/dist/protocol/legacy-shopping-negotiation/adapter.js.map +1 -0
  528. package/dist/protocol/legacy-shopping-negotiation/mapping.d.ts +78 -0
  529. package/dist/protocol/legacy-shopping-negotiation/mapping.js +321 -0
  530. package/dist/protocol/legacy-shopping-negotiation/mapping.js.map +1 -0
  531. package/dist/protocol/legacy-shopping-negotiation/money.d.ts +49 -0
  532. package/dist/protocol/legacy-shopping-negotiation/money.js +70 -0
  533. package/dist/protocol/legacy-shopping-negotiation/money.js.map +1 -0
  534. package/dist/protocol/legacy-shopping-negotiation/types.d.ts +107 -0
  535. package/dist/protocol/legacy-shopping-negotiation/types.js +34 -0
  536. package/dist/protocol/legacy-shopping-negotiation/types.js.map +1 -0
  537. package/dist/runtime/buyer-policy.d.ts +58 -0
  538. package/dist/runtime/buyer-policy.js +89 -0
  539. package/dist/runtime/buyer-policy.js.map +1 -0
  540. package/dist/runtime/fake-model.d.ts +77 -0
  541. package/dist/runtime/fake-model.js +307 -0
  542. package/dist/runtime/fake-model.js.map +1 -0
  543. package/dist/runtime/foreground.d.ts +56 -0
  544. package/dist/runtime/foreground.js +97 -0
  545. package/dist/runtime/foreground.js.map +1 -0
  546. package/dist/runtime/heartbeat.d.ts +36 -0
  547. package/dist/runtime/heartbeat.js +49 -0
  548. package/dist/runtime/heartbeat.js.map +1 -0
  549. package/dist/runtime/merchant-turn.d.ts +35 -0
  550. package/dist/runtime/merchant-turn.js +20 -0
  551. package/dist/runtime/merchant-turn.js.map +1 -0
  552. package/dist/runtime/model.d.ts +40 -0
  553. package/dist/runtime/model.js +86 -0
  554. package/dist/runtime/model.js.map +1 -0
  555. package/dist/runtime/negotiation-turn.d.ts +101 -0
  556. package/dist/runtime/negotiation-turn.js +317 -0
  557. package/dist/runtime/negotiation-turn.js.map +1 -0
  558. package/dist/runtime/tools.d.ts +64 -0
  559. package/dist/runtime/tools.js +236 -0
  560. package/dist/runtime/tools.js.map +1 -0
  561. package/dist/supervisor/init.d.ts +31 -0
  562. package/dist/supervisor/init.js +222 -0
  563. package/dist/supervisor/init.js.map +1 -0
  564. package/dist/supervisor/logs.d.ts +28 -0
  565. package/dist/supervisor/logs.js +101 -0
  566. package/dist/supervisor/logs.js.map +1 -0
  567. package/dist/supervisor/manage.d.ts +72 -0
  568. package/dist/supervisor/manage.js +419 -0
  569. package/dist/supervisor/manage.js.map +1 -0
  570. package/dist/supervisor/manifest.d.ts +69 -0
  571. package/dist/supervisor/manifest.js +209 -0
  572. package/dist/supervisor/manifest.js.map +1 -0
  573. package/dist/supervisor/stack-config.d.ts +79 -0
  574. package/dist/supervisor/stack-config.js +262 -0
  575. package/dist/supervisor/stack-config.js.map +1 -0
  576. package/dist/supervisor/wrapper.d.ts +17 -0
  577. package/dist/supervisor/wrapper.js +138 -0
  578. package/dist/supervisor/wrapper.js.map +1 -0
  579. package/dist/trust/identity/auth-verifier.d.ts +96 -0
  580. package/dist/trust/identity/auth-verifier.js +166 -0
  581. package/dist/trust/identity/auth-verifier.js.map +1 -0
  582. package/dist/trust/identity/identity-binding.d.ts +63 -0
  583. package/dist/trust/identity/identity-binding.js +59 -0
  584. package/dist/trust/identity/identity-binding.js.map +1 -0
  585. package/dist/trust/identity/index.d.ts +38 -0
  586. package/dist/trust/identity/index.js +31 -0
  587. package/dist/trust/identity/index.js.map +1 -0
  588. package/dist/trust/identity/jws.d.ts +64 -0
  589. package/dist/trust/identity/jws.js +178 -0
  590. package/dist/trust/identity/jws.js.map +1 -0
  591. package/dist/trust/identity/keys.d.ts +71 -0
  592. package/dist/trust/identity/keys.js +118 -0
  593. package/dist/trust/identity/keys.js.map +1 -0
  594. package/dist/trust/identity/message-signature.d.ts +105 -0
  595. package/dist/trust/identity/message-signature.js +297 -0
  596. package/dist/trust/identity/message-signature.js.map +1 -0
  597. package/dist/trust/identity/nonce.d.ts +45 -0
  598. package/dist/trust/identity/nonce.js +50 -0
  599. package/dist/trust/identity/nonce.js.map +1 -0
  600. package/dist/trust/identity/signature-base.d.ts +84 -0
  601. package/dist/trust/identity/signature-base.js +261 -0
  602. package/dist/trust/identity/signature-base.js.map +1 -0
  603. package/dist/trust/identity/trust-policy.d.ts +92 -0
  604. package/dist/trust/identity/trust-policy.js +95 -0
  605. package/dist/trust/identity/trust-policy.js.map +1 -0
  606. package/dist/trust/index.d.ts +21 -0
  607. package/dist/trust/index.js +22 -0
  608. package/dist/trust/index.js.map +1 -0
  609. package/dist/trust/records/evaluator.d.ts +76 -0
  610. package/dist/trust/records/evaluator.js +122 -0
  611. package/dist/trust/records/evaluator.js.map +1 -0
  612. package/dist/trust/records/index.d.ts +28 -0
  613. package/dist/trust/records/index.js +26 -0
  614. package/dist/trust/records/index.js.map +1 -0
  615. package/dist/trust/records/store.d.ts +75 -0
  616. package/dist/trust/records/store.js +339 -0
  617. package/dist/trust/records/store.js.map +1 -0
  618. package/dist/trust/records/types.d.ts +159 -0
  619. package/dist/trust/records/types.js +40 -0
  620. package/dist/trust/records/types.js.map +1 -0
  621. package/dist/tui/banner.d.ts +46 -0
  622. package/dist/tui/banner.js +99 -0
  623. package/dist/tui/banner.js.map +1 -0
  624. package/dist/tui/styles.d.ts +70 -0
  625. package/dist/tui/styles.js +197 -0
  626. package/dist/tui/styles.js.map +1 -0
  627. package/dist/tui/theme.d.ts +63 -0
  628. package/dist/tui/theme.js +136 -0
  629. package/dist/tui/theme.js.map +1 -0
  630. package/examples/profiles/buyer.deepseek.yaml +34 -0
  631. package/examples/profiles/buyer.fake.yaml +36 -0
  632. package/examples/profiles/buyer.local.yaml +40 -0
  633. package/examples/profiles/merchant.deepseek.yaml +32 -0
  634. package/examples/profiles/merchant.fake.yaml +31 -0
  635. package/examples/profiles/merchant.local.yaml +34 -0
  636. package/package.json +55 -0
@@ -0,0 +1,168 @@
1
+ /**
2
+ * Copyright 2026 harrylabsj
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+ /**
17
+ * HandoffIdempotencyStore —— 执行域幂等(KTH rev0.3 §10.1)。
18
+ *
19
+ * 幂等键:(source_candidate_id, source_candidate_digest)。与 negotiation
20
+ * 的 `(sender_identity, message_id)` 协议域幂等**不混用**——handoff 重试
21
+ * 窗口比 24h 长(候选可能存活数天),保留期缺省 ≥ 7 天。
22
+ *
23
+ * 存储:JSONL(`<dir>/handoff-idempotency.jsonl`,目录 0700),追加式 +
24
+ * 惰性清理过期行。lookup 命中 → 返回已交付的 handoff_id(重试不重复交付)。
25
+ */
26
+ import { chmodSync, closeSync, existsSync, fsyncSync, mkdirSync, openSync, readFileSync, renameSync, statSync, unlinkSync, writeFileSync, writeSync, } from "node:fs";
27
+ import path from "node:path";
28
+ import { HandoffError } from "./errors.js";
29
+ const DEFAULT_RETENTION_DAYS = 7;
30
+ const DEFAULT_LOCK_TIMEOUT_MS = 120_000;
31
+ const LOCK_POLL_MS = 25;
32
+ /** 陈旧锁阈值:持锁超此即视为崩溃残留(executeHandoff 锁持有上限 = 锁超时
33
+ * + URL 探测,10 分钟对正常操作是安全上限)。 */
34
+ const LOCK_STALE_MS = 10 * 60 * 1000;
35
+ export class HandoffIdempotencyStore {
36
+ dir;
37
+ filePath;
38
+ retentionMs;
39
+ now;
40
+ lockTimeoutMs;
41
+ constructor(options) {
42
+ mkdirSync(options.dir, { recursive: true, mode: 0o700 });
43
+ chmodSync(options.dir, 0o700);
44
+ this.dir = options.dir;
45
+ this.filePath = path.join(options.dir, "handoff-idempotency.jsonl");
46
+ this.retentionMs = (options.retentionDays ?? DEFAULT_RETENTION_DAYS) * 24 * 60 * 60 * 1000;
47
+ this.lockTimeoutMs = options.lockTimeoutMs ?? DEFAULT_LOCK_TIMEOUT_MS;
48
+ this.now = options.now ?? (() => new Date().toISOString());
49
+ }
50
+ /**
51
+ * 以候选为粒度的互斥(§10.1 幂等的并发保护):executeHandoff 的
52
+ * lookup→(多次 await)→record 是 check-then-act,两个并发执行会双双通过
53
+ * 幂等检查、同一候选交付两次。锁文件用 `openSync("wx")` 原子创建——
54
+ * 单进程内 async 交错与跨进程共享 dir 两个场景都互斥;持锁期间崩溃由
55
+ * 等待方超时(fail-closed:抛 HandoffError,绝不并发执行)。
56
+ */
57
+ async withCandidateLock(candidateId, fn) {
58
+ const lockDir = path.join(this.dir, "locks");
59
+ mkdirSync(lockDir, { recursive: true, mode: 0o700 });
60
+ const safeId = candidateId.replace(/[^A-Za-z0-9_-]/g, "_");
61
+ const lockPath = path.join(lockDir, `${safeId}.lock`);
62
+ const deadline = Date.now() + this.lockTimeoutMs;
63
+ for (;;) {
64
+ try {
65
+ const fd = openSync(lockPath, "wx");
66
+ closeSync(fd);
67
+ break;
68
+ }
69
+ catch (err) {
70
+ if (err.code !== "EEXIST")
71
+ throw err;
72
+ // 陈旧锁自愈(评审项 B2):持锁进程崩溃(finally 未执行)→ 锁文件
73
+ // 永久残留,该候选永远 concurrency_lock_timeout(每次等满超时)。
74
+ // mtime 超 LOCK_STALE_MS 即视为残留删除重试。
75
+ try {
76
+ const st = statSync(lockPath);
77
+ if (Date.now() - st.mtimeMs > LOCK_STALE_MS) {
78
+ unlinkSync(lockPath);
79
+ continue;
80
+ }
81
+ }
82
+ catch {
83
+ // 锁文件刚被释放 → 重试
84
+ continue;
85
+ }
86
+ if (Date.now() >= deadline) {
87
+ throw new HandoffError("concurrency_lock_timeout", `handoff candidate ${candidateId} is locked by another executor (waited ${this.lockTimeoutMs}ms); refusing concurrent execution`);
88
+ }
89
+ await new Promise((resolve) => setTimeout(resolve, LOCK_POLL_MS));
90
+ }
91
+ }
92
+ try {
93
+ return await fn();
94
+ }
95
+ finally {
96
+ try {
97
+ unlinkSync(lockPath);
98
+ }
99
+ catch {
100
+ // 锁文件已不存在(异常清理)则忽略。
101
+ }
102
+ }
103
+ }
104
+ /** 幂等查询:同候选同 digest 已交付 → 返回 handoff_id。 */
105
+ lookup(candidateId, candidateDigest) {
106
+ for (const row of this.rows()) {
107
+ if (row.candidate_id === candidateId && row.candidate_digest === candidateDigest) {
108
+ return { handoff_id: row.handoff_id };
109
+ }
110
+ }
111
+ return undefined;
112
+ }
113
+ /** 记录一次成功交付(幂等键 → handoff_id)。 */
114
+ record(candidateId, candidateDigest, handoffId) {
115
+ const row = {
116
+ candidate_id: candidateId,
117
+ candidate_digest: candidateDigest,
118
+ handoff_id: handoffId,
119
+ recorded_at: this.now(),
120
+ };
121
+ // 追加 + fsync(评审项 B2):此前纯追加无 fsync,崩溃时最后一行可能
122
+ // 撕裂——rows() 容忍撕裂行(跳过)→ 同候选再次执行会重复交付。fsync
123
+ // 后成功返回即持久,重试路径可依赖幂等表。
124
+ const fd = openSync(this.filePath, "a", 0o600);
125
+ try {
126
+ writeSync(fd, `${JSON.stringify(row)}\n`);
127
+ fsyncSync(fd);
128
+ }
129
+ finally {
130
+ closeSync(fd);
131
+ }
132
+ }
133
+ /** 惰性清理:删除超过保留期的行(重写文件,原子 rename)。 */
134
+ prune() {
135
+ const cutoff = Date.parse(this.now()) - this.retentionMs;
136
+ const rows = this.rows();
137
+ const fresh = rows.filter((row) => Date.parse(row.recorded_at) >= cutoff);
138
+ if (fresh.length === rows.length)
139
+ return 0;
140
+ const tmp = `${this.filePath}.tmp`;
141
+ writeFileSync(tmp, fresh.map((r) => JSON.stringify(r)).join("\n") + (fresh.length > 0 ? "\n" : ""), {
142
+ mode: 0o600,
143
+ });
144
+ renameSync(tmp, this.filePath);
145
+ return rows.length - fresh.length;
146
+ }
147
+ rows() {
148
+ if (!existsSync(this.filePath))
149
+ return [];
150
+ const raw = readFileSync(this.filePath, "utf-8");
151
+ const rows = [];
152
+ for (const line of raw.split("\n")) {
153
+ if (line.length === 0)
154
+ continue;
155
+ try {
156
+ const parsed = JSON.parse(line);
157
+ if (typeof parsed.candidate_id === "string" && typeof parsed.handoff_id === "string") {
158
+ rows.push(parsed);
159
+ }
160
+ }
161
+ catch {
162
+ // 撕裂行跳过(审计由 Ledger 承担;幂等表容忍最后一行撕裂)。
163
+ }
164
+ }
165
+ return rows;
166
+ }
167
+ }
168
+ //# sourceMappingURL=idempotency.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"idempotency.js","sourceRoot":"","sources":["../../src/handoff/idempotency.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,46 @@
1
+ /**
2
+ * Copyright 2026 harrylabsj
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+ /**
17
+ * Kiwi v0.7.0 Transaction Handoff(WP1)—— 域模型与授权接缝。
18
+ *
19
+ * 基线 §3.4 / §43:订单/支付发生在外部交易系统(UCP Checkout,business 是
20
+ * Merchant of Record);Kiwi 只做「非绑定共识 → 交易系统」的安全交接。本包只
21
+ * 提供交接工件、交易系统适配接缝、AP2 授权接缝与完成门禁,不创建订单、不处理
22
+ * 原始支付凭据、不实现真实 UCP Checkout / AP2(分别属于 WP2 / 外部系统)。
23
+ *
24
+ * 两层关系(术语对齐决策,KTH rev0.3):
25
+ * 外层 —— KTH 候选链:Agreement → HandoffCandidate(candidate.ts,
26
+ * 不可变 + event-sourced 生命周期 lifecycle.ts/ledger.ts)→ 交付观察
27
+ * (delivery 状态,Phase 2)。
28
+ * 内层 —— UCP checkout session 适配:HandoffPackage/HandoffSession/
29
+ * HandoffChannel(package.ts/channel.ts,v0.6.0 WP1 工件,不重命名保留)。
30
+ * `ucp_checkout`/`ucp_order` 目的地走内层;URL/PO/quote/contact 目的地
31
+ * 走外层交付。
32
+ */
33
+ export { HandoffError, HANDOFF_ERROR_CODES, type HandoffErrorCode, } from "./errors.js";
34
+ export { HANDOFF_PACKAGE_VERSION, createHandoffPackage, verifyHandoffPackageDigest, isHandoffPackage, type HandoffIdentitySnapshot, type HandoffPackage, type HandoffPackageInput, } from "./package.js";
35
+ export { HANDOFF_SESSION_STATUSES, ManualHandoffChannel, type HandoffChannel, type HandoffResult, type HandoffSession, type HandoffSessionStatus, type ManualHandoffChannelOptions, } from "./channel.js";
36
+ export { CONFIRMATION_EVIDENCE_KINDS, FailClosedAuthorizationProvider, createPaymentAuthorization, createUserConfirmationEvidence, digestTerms, newAuthorizationId, type AuthorizeCheckoutInput, type AuthorizeCheckoutResult, type AuthorizationProvider, type ConfirmationEvidenceKind, type CreateIntentMandateInput, type CreateIntentMandateResult, type PaymentAuthorization, type PaymentAuthorizationInput, type UserConfirmationEvidence, type UserConfirmationEvidenceInput, type VerifyIntentMandateInput, type VerifyIntentMandateResult, } from "./authorization.js";
37
+ export { COMPLETION_GATE_FAILURE_CODES, evaluateCompletionGate, isStructurallyValidAuthorization, type CompletionGateContext, type CompletionGateDecision, type CompletionGateFailureCode, } from "./completion.js";
38
+ export { DESTINATION_TYPES, isDestinationType, isUrlDestinationType, validateDestination, type Destination, type DestinationType, } from "./destination.js";
39
+ export { computeCandidateDigest, createHandoffCandidate, isHandoffCandidate, validateHandoffCandidate, verifyHandoffCandidateDigest, type HandoffCandidate, type HandoffCandidateInput, type HandoffDisplaySummary, } from "./candidate.js";
40
+ export { HANDOFF_CANDIDATE_EVENT_KINDS, HANDOFF_CANDIDATE_LIFECYCLE_STATES, foldCandidateLifecycle, isHandoffCandidateEventKind, isTerminalLifecycleState, transitionCandidateLifecycle, type HandoffCandidateEventKind, type HandoffCandidateLifecycleState, } from "./lifecycle.js";
41
+ export { HANDOFF_DELIVERY_EVENT_KINDS, HandoffEventStore, type HandoffDeliveryEventKind, type HandoffEventInput, type HandoffEventStoreOptions, } from "./ledger.js";
42
+ export { HANDOFF_DELIVERY_STATES, OPEN_EVIDENCE_KINDS, deliveryState, isHandoffDeliveryEventKind, recordLaunch, recordOpenEvidence, recordRevoked, validateOpenEvidence, type HandoffDeliveryState, type OpenEvidence, type OpenEvidenceKind, } from "./delivery.js";
43
+ export { executeHandoff, defaultUrlSafety, type AgreementReadResult, type ExecuteHandoffInput, type ExecuteHandoffResult, type TransactionHandoff, } from "./transaction.js";
44
+ export { HandoffIdempotencyStore, type HandoffIdempotencyStoreOptions } from "./idempotency.js";
45
+ export { validateExternalDestinationUrl, type SafeDestinationUrl, type UrlSafetyOptions, } from "./url-safety.js";
46
+ export { computeHandoffMetrics, type HandoffMetrics } from "./metrics.js";
@@ -0,0 +1,48 @@
1
+ /**
2
+ * Copyright 2026 harrylabsj
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+ /**
17
+ * Kiwi v0.7.0 Transaction Handoff(WP1)—— 域模型与授权接缝。
18
+ *
19
+ * 基线 §3.4 / §43:订单/支付发生在外部交易系统(UCP Checkout,business 是
20
+ * Merchant of Record);Kiwi 只做「非绑定共识 → 交易系统」的安全交接。本包只
21
+ * 提供交接工件、交易系统适配接缝、AP2 授权接缝与完成门禁,不创建订单、不处理
22
+ * 原始支付凭据、不实现真实 UCP Checkout / AP2(分别属于 WP2 / 外部系统)。
23
+ *
24
+ * 两层关系(术语对齐决策,KTH rev0.3):
25
+ * 外层 —— KTH 候选链:Agreement → HandoffCandidate(candidate.ts,
26
+ * 不可变 + event-sourced 生命周期 lifecycle.ts/ledger.ts)→ 交付观察
27
+ * (delivery 状态,Phase 2)。
28
+ * 内层 —— UCP checkout session 适配:HandoffPackage/HandoffSession/
29
+ * HandoffChannel(package.ts/channel.ts,v0.6.0 WP1 工件,不重命名保留)。
30
+ * `ucp_checkout`/`ucp_order` 目的地走内层;URL/PO/quote/contact 目的地
31
+ * 走外层交付。
32
+ */
33
+ export { HandoffError, HANDOFF_ERROR_CODES, } from "./errors.js";
34
+ export { HANDOFF_PACKAGE_VERSION, createHandoffPackage, verifyHandoffPackageDigest, isHandoffPackage, } from "./package.js";
35
+ export { HANDOFF_SESSION_STATUSES, ManualHandoffChannel, } from "./channel.js";
36
+ export { CONFIRMATION_EVIDENCE_KINDS, FailClosedAuthorizationProvider, createPaymentAuthorization, createUserConfirmationEvidence, digestTerms, newAuthorizationId, } from "./authorization.js";
37
+ export { COMPLETION_GATE_FAILURE_CODES, evaluateCompletionGate, isStructurallyValidAuthorization, } from "./completion.js";
38
+ // ── KTH/0.1 rev0.3(v0.7.0 WP-C1)──────────────────────────────────────────
39
+ export { DESTINATION_TYPES, isDestinationType, isUrlDestinationType, validateDestination, } from "./destination.js";
40
+ export { computeCandidateDigest, createHandoffCandidate, isHandoffCandidate, validateHandoffCandidate, verifyHandoffCandidateDigest, } from "./candidate.js";
41
+ export { HANDOFF_CANDIDATE_EVENT_KINDS, HANDOFF_CANDIDATE_LIFECYCLE_STATES, foldCandidateLifecycle, isHandoffCandidateEventKind, isTerminalLifecycleState, transitionCandidateLifecycle, } from "./lifecycle.js";
42
+ export { HANDOFF_DELIVERY_EVENT_KINDS, HandoffEventStore, } from "./ledger.js";
43
+ export { HANDOFF_DELIVERY_STATES, OPEN_EVIDENCE_KINDS, deliveryState, isHandoffDeliveryEventKind, recordLaunch, recordOpenEvidence, recordRevoked, validateOpenEvidence, } from "./delivery.js";
44
+ export { executeHandoff, defaultUrlSafety, } from "./transaction.js";
45
+ export { HandoffIdempotencyStore } from "./idempotency.js";
46
+ export { validateExternalDestinationUrl, } from "./url-safety.js";
47
+ export { computeHandoffMetrics } from "./metrics.js";
48
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/handoff/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EACL,YAAY,EACZ,mBAAmB,GAEpB,MAAM,aAAa,CAAC;AAErB,OAAO,EACL,uBAAuB,EACvB,oBAAoB,EACpB,0BAA0B,EAC1B,gBAAgB,GAIjB,MAAM,cAAc,CAAC;AAEtB,OAAO,EACL,wBAAwB,EACxB,oBAAoB,GAMrB,MAAM,cAAc,CAAC;AAEtB,OAAO,EACL,2BAA2B,EAC3B,+BAA+B,EAC/B,0BAA0B,EAC1B,8BAA8B,EAC9B,WAAW,EACX,kBAAkB,GAanB,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EACL,6BAA6B,EAC7B,sBAAsB,EACtB,gCAAgC,GAIjC,MAAM,iBAAiB,CAAC;AAEzB,4EAA4E;AAE5E,OAAO,EACL,iBAAiB,EACjB,iBAAiB,EACjB,oBAAoB,EACpB,mBAAmB,GAGpB,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EACL,sBAAsB,EACtB,sBAAsB,EACtB,kBAAkB,EAClB,wBAAwB,EACxB,4BAA4B,GAI7B,MAAM,gBAAgB,CAAC;AAExB,OAAO,EACL,6BAA6B,EAC7B,kCAAkC,EAClC,sBAAsB,EACtB,2BAA2B,EAC3B,wBAAwB,EACxB,4BAA4B,GAG7B,MAAM,gBAAgB,CAAC;AAExB,OAAO,EACL,4BAA4B,EAC5B,iBAAiB,GAIlB,MAAM,aAAa,CAAC;AAErB,OAAO,EACL,uBAAuB,EACvB,mBAAmB,EACnB,aAAa,EACb,0BAA0B,EAC1B,YAAY,EACZ,kBAAkB,EAClB,aAAa,EACb,oBAAoB,GAIrB,MAAM,eAAe,CAAC;AAEvB,OAAO,EACL,cAAc,EACd,gBAAgB,GAKjB,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EAAE,uBAAuB,EAAuC,MAAM,kBAAkB,CAAC;AAEhG,OAAO,EACL,8BAA8B,GAG/B,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EAAE,qBAAqB,EAAuB,MAAM,cAAc,CAAC"}
@@ -0,0 +1,94 @@
1
+ /**
2
+ * Copyright 2026 harrylabsj
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+ /**
17
+ * HandoffEventStore —— 复用 `LedgerStore` 引擎(append-only / hash-linked /
18
+ * verifyChain / 禁词扫描全部继承)的 KTH 事件存储。
19
+ *
20
+ * 链 key:negotiation_id(来自候选的 agreement 溯源)——handoff 事件落在
21
+ * 产生它的 negotiation 的审计链上;`eventsForCandidate` / `eventsForHandoff`
22
+ * 在链内按 id 过滤。候选生命周期状态由 events 投影(KTH rev0.3 §5.1,
23
+ * 完成定义 #18 Ledger 可审计 Handoff created/delivered/opened/expired)。
24
+ */
25
+ import { type LedgerCapabilitySnapshot, type LedgerEvent, type LedgerIdentitySnapshot, type LedgerOutcome, type LedgerVerifyResult } from "../negotiation/ledger/event.js";
26
+ import type { HandoffCandidate } from "./candidate.js";
27
+ import { type HandoffCandidateEventKind } from "./lifecycle.js";
28
+ /** 交付观察事件 kind(KTH rev0.3 §9;不伪装外部成交,§36-27/28)。 */
29
+ export declare const HANDOFF_DELIVERY_EVENT_KINDS: readonly ["handoff_delivered", "handoff_launched", "handoff_opened_confirmed", "handoff_expired", "handoff_revoked", "handoff_delivery_failed"];
30
+ export type HandoffDeliveryEventKind = (typeof HANDOFF_DELIVERY_EVENT_KINDS)[number];
31
+ export interface HandoffEventStoreOptions {
32
+ /** 基础数据目录;事件落在 `<dir>/ledger/`(与 negotiation 同目录布局)。 */
33
+ dir: string;
34
+ /** 可注入时钟(RFC 3339);缺省 new Date().toISOString()。 */
35
+ now?: () => string;
36
+ }
37
+ export interface HandoffEventInput {
38
+ kind: HandoffCandidateEventKind | HandoffDeliveryEventKind;
39
+ /** 溯源候选。 */
40
+ candidate: HandoffCandidate;
41
+ /** 交付事件绑定 handoff_id(candidate 事件省略)。 */
42
+ handoff_id?: string;
43
+ identity: LedgerIdentitySnapshot;
44
+ capability: LedgerCapabilitySnapshot;
45
+ /** 可归属证据(OPENED_CONFIRMED 必需;其余可选)。 */
46
+ evidence?: Record<string, unknown>;
47
+ /** 目的地快照(最小化、非秘密)。 */
48
+ destination?: Record<string, unknown>;
49
+ outcome?: LedgerOutcome;
50
+ occurred_at?: string;
51
+ }
52
+ /** KTH 事件存储(LedgerStore 引擎复用)。 */
53
+ export declare class HandoffEventStore {
54
+ private readonly store;
55
+ private readonly now;
56
+ constructor(options: HandoffEventStoreOptions);
57
+ /** 追加一条 handoff 事件(candidate 生命周期或交付观察)。 */
58
+ append(input: HandoffEventInput): LedgerEvent;
59
+ /** 候选生命周期事件(kind 限定 candidate 域)。 */
60
+ appendCandidateEvent(input: Omit<HandoffEventInput, "kind"> & {
61
+ kind: HandoffCandidateEventKind;
62
+ }): LedgerEvent;
63
+ /**
64
+ * 交付观察事件(kind 限定 delivery 域)。
65
+ *
66
+ * 落链前做交付状态机迁移校验(delivery.ts 的 DELIVERY_TRANSITIONS,
67
+ * 与 candidate lifecycle 的迁移校验对称):交付事件必须绑定 handoff_id,
68
+ * 且 (none)→DELIVERED 必须是首个事件;REVOKED/EXPIRED/OPENED_CONFIRMED
69
+ * 之后不再接受任何事件。校验按同 handoff_id 折叠(同一 negotiation 链上
70
+ * 可并存多个 handoff 的交付事件,互不干扰)。
71
+ */
72
+ appendDeliveryEvent(input: Omit<HandoffEventInput, "kind"> & {
73
+ kind: HandoffDeliveryEventKind;
74
+ }): LedgerEvent;
75
+ /** 某 negotiation 链上的全部事件。 */
76
+ events(negotiationId: string): LedgerEvent[];
77
+ /** 全部已落账的 negotiation_id(/handoff 列表用)。 */
78
+ listNegotiations(): string[];
79
+ /** 某候选的全部生命周期 + 交付事件(按记录时间序;链 key = negotiation_id)。 */
80
+ eventsForCandidate(negotiationId: string, candidateId: string): LedgerEvent[];
81
+ /** 某 handoff 的交付观察事件。 */
82
+ eventsForHandoff(negotiationId: string, handoffId: string): LedgerEvent[];
83
+ /** 链完整性校验(篡改 / 断链 / 重复检出)。 */
84
+ verifyChain(negotiationId: string): LedgerVerifyResult;
85
+ /**
86
+ * 惰性过期清扫(评审项 L1):handoff_candidate_expired 此前只在
87
+ * executeHandoff 的过期门内落链——到期未执行的候选在 TUI /handoff 列表
88
+ * 永远显示 PROPOSED/READY"从未获批/从未执行",指标失真。本方法遍历全部
89
+ * 链,对未终态且 expires_at 已过的候选落 expired 事件。幂等:已终态
90
+ * (EXPIRED/REJECTED/STALE/CONSUMED)候选不重复处理。调用方挂载在 kernel
91
+ * 的周期性入口(schedulerTick)与 /handoff 渲染前。
92
+ */
93
+ sweepExpiredCandidates(now: string): number;
94
+ }
@@ -0,0 +1,195 @@
1
+ /**
2
+ * Copyright 2026 harrylabsj
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+ /**
17
+ * HandoffEventStore —— 复用 `LedgerStore` 引擎(append-only / hash-linked /
18
+ * verifyChain / 禁词扫描全部继承)的 KTH 事件存储。
19
+ *
20
+ * 链 key:negotiation_id(来自候选的 agreement 溯源)——handoff 事件落在
21
+ * 产生它的 negotiation 的审计链上;`eventsForCandidate` / `eventsForHandoff`
22
+ * 在链内按 id 过滤。候选生命周期状态由 events 投影(KTH rev0.3 §5.1,
23
+ * 完成定义 #18 Ledger 可审计 Handoff created/delivered/opened/expired)。
24
+ */
25
+ import { assertNoForbiddenContent, } from "../negotiation/ledger/event.js";
26
+ import { LedgerStore } from "../negotiation/ledger/store.js";
27
+ import { HANDOFF_CANDIDATE_EVENT_KINDS, } from "./lifecycle.js";
28
+ import { deliveryState, transitionDeliveryState } from "./delivery.js";
29
+ import { isTerminalLifecycleState, foldCandidateLifecycle } from "./lifecycle.js";
30
+ import { HandoffError } from "./errors.js";
31
+ /** 交付观察事件 kind(KTH rev0.3 §9;不伪装外部成交,§36-27/28)。 */
32
+ export const HANDOFF_DELIVERY_EVENT_KINDS = [
33
+ "handoff_delivered",
34
+ "handoff_launched",
35
+ "handoff_opened_confirmed",
36
+ "handoff_expired",
37
+ "handoff_revoked",
38
+ "handoff_delivery_failed",
39
+ ];
40
+ /** 从目的地补充字段中剥离候选身份字段(type/ref 属于候选,不可被覆盖)。 */
41
+ function stripDestinationIdentityFields(destination) {
42
+ const rest = { ...destination };
43
+ delete rest.type;
44
+ delete rest.ref;
45
+ return rest;
46
+ }
47
+ /** KTH 事件存储(LedgerStore 引擎复用)。 */
48
+ export class HandoffEventStore {
49
+ store;
50
+ now;
51
+ constructor(options) {
52
+ this.store = new LedgerStore({ dir: options.dir, now: options.now });
53
+ this.now = options.now ?? (() => new Date().toISOString());
54
+ }
55
+ /** 追加一条 handoff 事件(candidate 生命周期或交付观察)。 */
56
+ append(input) {
57
+ // evidence / destination 是自由对象字段(LedgerStore 的禁词扫描只覆盖
58
+ // wire_payload / outcome.result)——本地补扫,保证秘密永不落链(§36-5)。
59
+ if (input.evidence !== undefined)
60
+ assertNoForbiddenContent(input.evidence, "evidence");
61
+ if (input.destination !== undefined)
62
+ assertNoForbiddenContent(input.destination, "destination");
63
+ const isCandidateEvent = HANDOFF_CANDIDATE_EVENT_KINDS.includes(input.kind);
64
+ const content = {
65
+ event_kind: input.kind,
66
+ negotiation_id: input.candidate.negotiation_id,
67
+ handoff_candidate_id: input.candidate.handoff_candidate_id,
68
+ ...(input.handoff_id !== undefined ? { handoff_id: input.handoff_id } : {}),
69
+ agreement_id: input.candidate.agreement_id,
70
+ terms_digest: input.candidate.terms_digest,
71
+ ...(input.destination !== undefined
72
+ ? {
73
+ destination: {
74
+ type: input.candidate.destination_type,
75
+ ref: input.candidate.destination_ref,
76
+ // 调用方只可补充展示字段(如 final_url);type/ref 是候选的审计
77
+ // 事实,不得被覆盖(否则落链目的地与候选内容不一致)。
78
+ ...stripDestinationIdentityFields(input.destination),
79
+ },
80
+ }
81
+ : {}),
82
+ ...(input.evidence !== undefined ? { evidence: input.evidence } : {}),
83
+ identity: input.identity,
84
+ capability: input.capability,
85
+ // 候选生命周期事件携带完整候选文档(KTH rev0.3 §5.1/§18-13:
86
+ // lifecycle 从事件重建且不 mutate 候选内容)。
87
+ outcome: input.outcome ??
88
+ (isCandidateEvent
89
+ ? { kind: "ok", result: { candidate: input.candidate } }
90
+ : { kind: "ok", result: {} }),
91
+ occurred_at: input.occurred_at ?? this.now(),
92
+ };
93
+ return this.store.append(content);
94
+ }
95
+ /** 候选生命周期事件(kind 限定 candidate 域)。 */
96
+ appendCandidateEvent(input) {
97
+ return this.append(input);
98
+ }
99
+ /**
100
+ * 交付观察事件(kind 限定 delivery 域)。
101
+ *
102
+ * 落链前做交付状态机迁移校验(delivery.ts 的 DELIVERY_TRANSITIONS,
103
+ * 与 candidate lifecycle 的迁移校验对称):交付事件必须绑定 handoff_id,
104
+ * 且 (none)→DELIVERED 必须是首个事件;REVOKED/EXPIRED/OPENED_CONFIRMED
105
+ * 之后不再接受任何事件。校验按同 handoff_id 折叠(同一 negotiation 链上
106
+ * 可并存多个 handoff 的交付事件,互不干扰)。
107
+ */
108
+ appendDeliveryEvent(input) {
109
+ if (input.handoff_id === undefined) {
110
+ throw new HandoffError("invalid_input", "delivery event requires handoff_id", "handoff_id");
111
+ }
112
+ const chain = this.store.events(input.candidate.negotiation_id);
113
+ const current = deliveryState(chain.filter((e) => e.handoff_id === input.handoff_id));
114
+ transitionDeliveryState(current, input.kind);
115
+ return this.append(input);
116
+ }
117
+ /** 某 negotiation 链上的全部事件。 */
118
+ events(negotiationId) {
119
+ return this.store.events(negotiationId);
120
+ }
121
+ /** 全部已落账的 negotiation_id(/handoff 列表用)。 */
122
+ listNegotiations() {
123
+ return this.store.listNegotiations();
124
+ }
125
+ /** 某候选的全部生命周期 + 交付事件(按记录时间序;链 key = negotiation_id)。 */
126
+ eventsForCandidate(negotiationId, candidateId) {
127
+ return this.store
128
+ .events(negotiationId)
129
+ .filter((e) => e.handoff_candidate_id === candidateId);
130
+ }
131
+ /** 某 handoff 的交付观察事件。 */
132
+ eventsForHandoff(negotiationId, handoffId) {
133
+ return this.store.events(negotiationId).filter((e) => e.handoff_id === handoffId);
134
+ }
135
+ /** 链完整性校验(篡改 / 断链 / 重复检出)。 */
136
+ verifyChain(negotiationId) {
137
+ return this.store.verifyChain(negotiationId);
138
+ }
139
+ /**
140
+ * 惰性过期清扫(评审项 L1):handoff_candidate_expired 此前只在
141
+ * executeHandoff 的过期门内落链——到期未执行的候选在 TUI /handoff 列表
142
+ * 永远显示 PROPOSED/READY"从未获批/从未执行",指标失真。本方法遍历全部
143
+ * 链,对未终态且 expires_at 已过的候选落 expired 事件。幂等:已终态
144
+ * (EXPIRED/REJECTED/STALE/CONSUMED)候选不重复处理。调用方挂载在 kernel
145
+ * 的周期性入口(schedulerTick)与 /handoff 渲染前。
146
+ */
147
+ sweepExpiredCandidates(now) {
148
+ let swept = 0;
149
+ for (const negotiationId of this.store.listNegotiations()) {
150
+ const events = this.store.events(negotiationId);
151
+ const seen = new Set();
152
+ for (const event of events) {
153
+ const candidateId = event.handoff_candidate_id;
154
+ if (candidateId === undefined || seen.has(candidateId))
155
+ continue;
156
+ seen.add(candidateId);
157
+ const candidateEvents = events.filter((e) => e.handoff_candidate_id === candidateId);
158
+ const state = foldCandidateLifecycle(candidateEvents);
159
+ if (state === undefined || isTerminalLifecycleState(state))
160
+ continue;
161
+ // 过期判定:候选内嵌文档的 expires_at(created 事件携带完整候选)。
162
+ const created = candidateEvents.find((e) => e.event_kind === "handoff_candidate_created");
163
+ const embedded = created?.outcome.kind === "ok"
164
+ ? created.outcome.result?.candidate
165
+ : undefined;
166
+ const expiresAt = typeof embedded?.expires_at === "string" ? embedded.expires_at : "";
167
+ // NaN 防护与 executeHandoff 的过期门一致:不可解析视为未过期(不误杀)。
168
+ if (expiresAt === "" || !Number.isFinite(Date.parse(expiresAt)))
169
+ continue;
170
+ if (Date.parse(expiresAt) >= Date.parse(now))
171
+ continue;
172
+ const candidate = created?.outcome.kind === "ok"
173
+ ? created.outcome.result?.candidate
174
+ : undefined;
175
+ if (candidate === undefined)
176
+ continue;
177
+ try {
178
+ this.appendCandidateEvent({
179
+ kind: "handoff_candidate_expired",
180
+ candidate,
181
+ identity: { sender_identity: candidate.buyer_identity_ref, counterparty_identity: candidate.merchant_identity_ref, actor: "buyer" },
182
+ capability: { capability: "com.harrylabsj.kiwi.shopping.negotiation", protocol_version: "1.0" },
183
+ occurred_at: now,
184
+ });
185
+ swept += 1;
186
+ }
187
+ catch {
188
+ // 单候选失败不影响整体清扫(fail-closed 但继续其他链)。
189
+ }
190
+ }
191
+ }
192
+ return swept;
193
+ }
194
+ }
195
+ //# sourceMappingURL=ledger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ledger.js","sourceRoot":"","sources":["../../src/handoff/ledger.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Copyright 2026 harrylabsj
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+ import type { LedgerEvent, LedgerEventKind } from "../negotiation/ledger/event.js";
17
+ export declare const HANDOFF_CANDIDATE_LIFECYCLE_STATES: readonly ["PROPOSED", "READY", "REJECTED", "STALE", "EXPIRED", "CONSUMED"];
18
+ export type HandoffCandidateLifecycleState = (typeof HANDOFF_CANDIDATE_LIFECYCLE_STATES)[number];
19
+ /** candidate 生命周期事件 kind(与 LEDGER_EVENT_KINDS 的 handoff_candidate_* 对齐)。 */
20
+ export declare const HANDOFF_CANDIDATE_EVENT_KINDS: readonly ["handoff_candidate_created", "handoff_candidate_ready", "handoff_candidate_rejected", "handoff_candidate_stale", "handoff_candidate_expired", "handoff_candidate_consumed"];
21
+ export type HandoffCandidateEventKind = (typeof HANDOFF_CANDIDATE_EVENT_KINDS)[number];
22
+ /** 事件 kind 是否 candidate 生命周期事件。 */
23
+ export declare function isHandoffCandidateEventKind(kind: LedgerEventKind): kind is HandoffCandidateEventKind;
24
+ /** 从 Ledger 事件序列投影 candidate 生命周期状态(纯函数,最后事件胜出)。 */
25
+ export declare function foldCandidateLifecycle(events: readonly Pick<LedgerEvent, "event_kind" | "event_id" | "recorded_at">[]): HandoffCandidateLifecycleState | undefined;
26
+ /** 迁移校验:返回 target 或抛 schemaError(fail-closed)。 */
27
+ export declare function transitionCandidateLifecycle(current: HandoffCandidateLifecycleState | undefined, eventKind: HandoffCandidateEventKind): HandoffCandidateLifecycleState;
28
+ /** 终态判定:终态候选不可 revive,必须新建候选(带 supersedes_candidate_id)。 */
29
+ export declare function isTerminalLifecycleState(state: HandoffCandidateLifecycleState): boolean;