@harrylabsj/kiwi 0.6.0 → 0.6.2

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 (167) hide show
  1. package/README.md +21 -0
  2. package/contracts/candidate-agent-dto-1.0.README.md +12 -8
  3. package/contracts/conformance/python-service/README.md +19 -0
  4. package/contracts/conformance/python-service/run.py +134 -0
  5. package/contracts/kiwi-catalog/1.0/listing-record.schema.json +11 -1
  6. package/contracts/kiwi-contracts.lock.json +7 -0
  7. package/contracts/manifest.json +61 -0
  8. package/contracts/vectors/candidate-agent.invalid-private-field.json +7 -0
  9. package/contracts/vectors/candidate-agent.valid.json +26 -0
  10. package/dist/a2a/client/client.js +39 -34
  11. package/dist/a2a/client/client.js.map +1 -1
  12. package/dist/a2a/client/url-policy.d.ts +8 -1
  13. package/dist/a2a/client/url-policy.js +18 -2
  14. package/dist/a2a/client/url-policy.js.map +1 -1
  15. package/dist/a2a/clock.d.ts +30 -0
  16. package/dist/a2a/clock.js +39 -0
  17. package/dist/a2a/clock.js.map +1 -0
  18. package/dist/a2a/negotiate.d.ts +6 -0
  19. package/dist/a2a/negotiate.js +10 -12
  20. package/dist/a2a/negotiate.js.map +1 -1
  21. package/dist/a2a/node.d.ts +23 -3
  22. package/dist/a2a/node.js +128 -18
  23. package/dist/a2a/node.js.map +1 -1
  24. package/dist/a2a/server/merchant-handler.d.ts +4 -0
  25. package/dist/a2a/server/merchant-handler.js +238 -25
  26. package/dist/a2a/server/merchant-handler.js.map +1 -1
  27. package/dist/a2a/server/pipeline.d.ts +17 -0
  28. package/dist/a2a/server/pipeline.js +89 -1
  29. package/dist/a2a/server/pipeline.js.map +1 -1
  30. package/dist/a2a/server/ucp.d.ts +30 -2
  31. package/dist/a2a/server/ucp.js +23 -14
  32. package/dist/a2a/server/ucp.js.map +1 -1
  33. package/dist/agent/agent-db.js +5 -0
  34. package/dist/agent/agent-db.js.map +1 -1
  35. package/dist/agent/buyer/buyer-tools.d.ts +5 -0
  36. package/dist/agent/buyer/buyer-tools.js +8 -1
  37. package/dist/agent/buyer/buyer-tools.js.map +1 -1
  38. package/dist/agent/buyer/types.d.ts +0 -25
  39. package/dist/agent/buyer/types.js.map +1 -1
  40. package/dist/agent/kernel-builder.d.ts +27 -0
  41. package/dist/agent/kernel-builder.js +180 -0
  42. package/dist/agent/kernel-builder.js.map +1 -0
  43. package/dist/agent/kernel.d.ts +6 -0
  44. package/dist/agent/kernel.js +95 -8
  45. package/dist/agent/kernel.js.map +1 -1
  46. package/dist/agent/memory/store.d.ts +5 -0
  47. package/dist/agent/memory/store.js +29 -1
  48. package/dist/agent/memory/store.js.map +1 -1
  49. package/dist/agent/merchant/action-candidate.js +15 -1
  50. package/dist/agent/merchant/action-candidate.js.map +1 -1
  51. package/dist/agent/merchant/merchant-client.js +22 -4
  52. package/dist/agent/merchant/merchant-client.js.map +1 -1
  53. package/dist/agent/merchant/types.d.ts +5 -2
  54. package/dist/agent/merchant/types.js +6 -2
  55. package/dist/agent/merchant/types.js.map +1 -1
  56. package/dist/agent/negotiation-chat.js +34 -14
  57. package/dist/agent/negotiation-chat.js.map +1 -1
  58. package/dist/cli.d.ts +56 -0
  59. package/dist/cli.js +141 -156
  60. package/dist/cli.js.map +1 -1
  61. package/dist/commerce/data-source.d.ts +7 -3
  62. package/dist/commerce/data-source.js.map +1 -1
  63. package/dist/commerce/http-client.js +35 -31
  64. package/dist/commerce/http-client.js.map +1 -1
  65. package/dist/commerce/shopping-cli-source.js +66 -48
  66. package/dist/commerce/shopping-cli-source.js.map +1 -1
  67. package/dist/config/profile.d.ts +7 -0
  68. package/dist/config/profile.js +23 -0
  69. package/dist/config/profile.js.map +1 -1
  70. package/dist/counterparty/a2a-direct/index.d.ts +5 -0
  71. package/dist/counterparty/a2a-direct/index.js +24 -0
  72. package/dist/counterparty/a2a-direct/index.js.map +1 -1
  73. package/dist/counterparty/shopping-cli-hosted/index.js +52 -19
  74. package/dist/counterparty/shopping-cli-hosted/index.js.map +1 -1
  75. package/dist/discovery/catalog-source/kiwi-record.d.ts +3 -0
  76. package/dist/discovery/catalog-source/kiwi-record.js.map +1 -1
  77. package/dist/discovery/catalog-source/kiwi-source.js +46 -36
  78. package/dist/discovery/catalog-source/kiwi-source.js.map +1 -1
  79. package/dist/discovery/catalog-source/register.d.ts +6 -0
  80. package/dist/discovery/catalog-source/register.js +27 -8
  81. package/dist/discovery/catalog-source/register.js.map +1 -1
  82. package/dist/discovery/catalog-source/source.js +39 -35
  83. package/dist/discovery/catalog-source/source.js.map +1 -1
  84. package/dist/discovery/resolve.d.ts +15 -0
  85. package/dist/discovery/resolve.js +59 -35
  86. package/dist/discovery/resolve.js.map +1 -1
  87. package/dist/discovery/ucp/index.d.ts +1 -1
  88. package/dist/discovery/ucp/index.js +1 -1
  89. package/dist/discovery/ucp/index.js.map +1 -1
  90. package/dist/discovery/ucp/resolver.d.ts +5 -0
  91. package/dist/discovery/ucp/resolver.js +65 -38
  92. package/dist/discovery/ucp/resolver.js.map +1 -1
  93. package/dist/discovery/ucp/vendor.d.ts +1 -1
  94. package/dist/discovery/ucp/vendor.js +1 -1
  95. package/dist/handoff/delivery.d.ts +4 -2
  96. package/dist/handoff/delivery.js +6 -1
  97. package/dist/handoff/delivery.js.map +1 -1
  98. package/dist/handoff/errors.d.ts +1 -1
  99. package/dist/handoff/errors.js +1 -0
  100. package/dist/handoff/errors.js.map +1 -1
  101. package/dist/handoff/idempotency.d.ts +10 -1
  102. package/dist/handoff/idempotency.js +13 -3
  103. package/dist/handoff/idempotency.js.map +1 -1
  104. package/dist/handoff/index.d.ts +1 -1
  105. package/dist/handoff/index.js +1 -1
  106. package/dist/handoff/index.js.map +1 -1
  107. package/dist/handoff/ledger.d.ts +9 -0
  108. package/dist/handoff/ledger.js +66 -0
  109. package/dist/handoff/ledger.js.map +1 -1
  110. package/dist/handoff/transaction.d.ts +21 -3
  111. package/dist/handoff/transaction.js +50 -11
  112. package/dist/handoff/transaction.js.map +1 -1
  113. package/dist/handoff/ucp-checkout/channel.js +15 -10
  114. package/dist/handoff/ucp-checkout/channel.js.map +1 -1
  115. package/dist/negotiation/jcs.js +11 -8
  116. package/dist/negotiation/jcs.js.map +1 -1
  117. package/dist/negotiation/lease/store.d.ts +25 -0
  118. package/dist/negotiation/lease/store.js +101 -0
  119. package/dist/negotiation/lease/store.js.map +1 -0
  120. package/dist/negotiation/recovery/recover.js +25 -1
  121. package/dist/negotiation/recovery/recover.js.map +1 -1
  122. package/dist/negotiation/state/phase.js +12 -4
  123. package/dist/negotiation/state/phase.js.map +1 -1
  124. package/dist/operator/runner.d.ts +11 -0
  125. package/dist/operator/runner.js +20 -1
  126. package/dist/operator/runner.js.map +1 -1
  127. package/dist/product-catalog.d.ts +43 -0
  128. package/dist/product-catalog.js +60 -0
  129. package/dist/product-catalog.js.map +1 -0
  130. package/dist/product-cli.d.ts +1 -1
  131. package/dist/product-cli.js +1 -1
  132. package/dist/product-publish.d.ts +15 -17
  133. package/dist/product-publish.js +279 -46
  134. package/dist/product-publish.js.map +1 -1
  135. package/dist/supervisor/stack-config.d.ts +6 -1
  136. package/dist/supervisor/stack-config.js +11 -3
  137. package/dist/supervisor/stack-config.js.map +1 -1
  138. package/dist/trust/identity/message-signature.js +17 -0
  139. package/dist/trust/identity/message-signature.js.map +1 -1
  140. package/dist/weixin/channel.d.ts +89 -0
  141. package/dist/weixin/channel.js +370 -0
  142. package/dist/weixin/channel.js.map +1 -0
  143. package/dist/weixin/cli-weixin.d.ts +29 -0
  144. package/dist/weixin/cli-weixin.js +130 -0
  145. package/dist/weixin/cli-weixin.js.map +1 -0
  146. package/dist/weixin/credentials.d.ts +33 -0
  147. package/dist/weixin/credentials.js +107 -0
  148. package/dist/weixin/credentials.js.map +1 -0
  149. package/dist/weixin/ilink-client.d.ts +44 -0
  150. package/dist/weixin/ilink-client.js +287 -0
  151. package/dist/weixin/ilink-client.js.map +1 -0
  152. package/dist/weixin/login.d.ts +37 -0
  153. package/dist/weixin/login.js +93 -0
  154. package/dist/weixin/login.js.map +1 -0
  155. package/dist/weixin/qr.d.ts +26 -0
  156. package/dist/weixin/qr.js +525 -0
  157. package/dist/weixin/qr.js.map +1 -0
  158. package/dist/weixin/types.d.ts +114 -0
  159. package/dist/weixin/types.js +48 -0
  160. package/dist/weixin/types.js.map +1 -0
  161. package/package.json +12 -2
  162. package/dist/commerce/erp-source.d.ts +0 -51
  163. package/dist/commerce/erp-source.js +0 -184
  164. package/dist/commerce/erp-source.js.map +0 -1
  165. package/dist/commerce/local-db-source.d.ts +0 -50
  166. package/dist/commerce/local-db-source.js +0 -162
  167. package/dist/commerce/local-db-source.js.map +0 -1
@@ -18,6 +18,8 @@ import { newAgreementId, newExchangeId, newMessageId, newOfferId, } from "../../
18
18
  import { finalizeEnvelope } from "../../negotiation/domain/envelope.js";
19
19
  import { contentDigest } from "../../negotiation/jcs.js";
20
20
  import { evaluateConditionalOffer } from "../../negotiation/condition/evaluator.js";
21
+ import { toMinorUnits as losslessToMinorUnits } from "../../protocol/legacy-shopping-negotiation/money.js";
22
+ import { createNegotiationPhase, isTerminalPhase, transitionPhase, } from "../../negotiation/state/phase.js";
21
23
  export const MERCHANT_CAPABILITY = "com.harrylabsj.kiwi.shopping.negotiation";
22
24
  export const MERCHANT_SKU = "SKU-001";
23
25
  export const MERCHANT_CURRENCY = "CNY";
@@ -55,7 +57,11 @@ function seedEnvelope(seed) {
55
57
  ...seed,
56
58
  });
57
59
  }
58
- function offerTerms(opts) {
60
+ /** offer 有效期(审查 P3:此前 valid_until 硬编码 2099——§11 "Offer with
61
+ * valid_until MUST NOT be accepted after that timestamp" 永不生效,陈旧
62
+ * 报价可被无限期接受)。24h 窗口,accept 时校验(offer_expired 拒绝)。 */
63
+ export const OFFER_VALIDITY_MS = 24 * 60 * 60 * 1000;
64
+ function offerTerms(opts, now) {
59
65
  return {
60
66
  items: [
61
67
  {
@@ -65,7 +71,7 @@ function offerTerms(opts) {
65
71
  },
66
72
  ],
67
73
  fulfillment_terms: { delivery_before: MERCHANT_DELIVERY_BEFORE },
68
- valid_until: "2099-12-31T23:59:59Z",
74
+ valid_until: new Date(Date.parse(now) + OFFER_VALIDITY_MS).toISOString(),
69
75
  };
70
76
  }
71
77
  function buildAgreement(input) {
@@ -95,6 +101,13 @@ const textReply = (text, taskState = "working") => ({
95
101
  messageId: newMessageId(),
96
102
  },
97
103
  });
104
+ /** 商业拒绝(offer 未知/已关闭/terms_digest 不匹配/终态重开)。
105
+ * decline 消息由 pipeline 按 reason_code 自动构造。 */
106
+ const declineReply = (reasonCode = "state_conflict") => ({
107
+ kind: "declined",
108
+ reasonCode,
109
+ taskState: "completed",
110
+ });
98
111
  const envelopeReply = (reply) => ({
99
112
  kind: "accepted",
100
113
  taskState: "working",
@@ -109,6 +122,88 @@ export function createMerchantHandler(options) {
109
122
  const { ledger, now, sender, counterparty } = options;
110
123
  const offerPriceMinor = options.offerPriceMinor ?? MERCHANT_OFFER_PRICE_MINOR;
111
124
  const conditionalByNegotiation = new Map();
125
+ // 审查 P2-D:终态(AGREEMENT_REACHED / WITHDRAWN / DECLINED / CANCELLED)
126
+ // 不得以同一 negotiation_id 重开(§17.4/§21.2)——运行时此前无任何终态
127
+ // 守卫:连发两份 accept 可产出两份 agreement、withdraw 后可再次成交。
128
+ const closedNegotiations = new Set();
129
+ // 每 negotiation 的相位机状态(审查 BUG-10:完整状态含 active_offer_id /
130
+ // resume_phase——此前只记 OPEN→终态的最小轨迹,中间相位由
131
+ // conditionalByNegotiation 隐式表达,规范转换表不是接收消息的权威门)。
132
+ const phaseStateByNegotiation = new Map();
133
+ // 产生商业承诺的动作:终态后一律拒绝;text-only(clarification)放行。
134
+ const COMMERCIAL_ACTIONS = new Set([
135
+ "inquiry",
136
+ "rfq",
137
+ "offer",
138
+ "counter_offer",
139
+ "conditional_offer",
140
+ "accept_nonbinding",
141
+ ]);
142
+ /** 审查 BUG-10:把入站 action 映射到相位机事件并推进;非法转换(不在
143
+ * 转换表内的组合)fail-closed 返回 false(调用方 decline state_conflict)。
144
+ * clarification 是文本应答即恢复:同轮 apply clarification_response,
145
+ * 相位净不变。相位变化(含中间相位 OFFER_OPEN)落 state_transition 事件,
146
+ * 重启可完整重建。 */
147
+ const advancePhase = async (negotiationId, event) => {
148
+ const state = phaseStateByNegotiation.get(negotiationId) ?? createNegotiationPhase(negotiationId);
149
+ let next;
150
+ try {
151
+ next = transitionPhase(state, event);
152
+ }
153
+ catch {
154
+ return false;
155
+ }
156
+ phaseStateByNegotiation.set(negotiationId, next);
157
+ if (next.phase !== state.phase) {
158
+ await appendPhaseTransition(negotiationId, next.phase, state.phase);
159
+ }
160
+ return true;
161
+ };
162
+ /** 入站 action → 相位机事件(inquiry/rfq 是起始动作,无转换)。 */
163
+ const actionToPhaseEvent = (envelope) => {
164
+ const offerId = String(envelope.payload?.offer_id ?? "");
165
+ switch (envelope.action) {
166
+ case "offer":
167
+ return { type: "offer", offer_id: offerId };
168
+ case "counter_offer":
169
+ return { type: "counter_offer", offer_id: offerId };
170
+ case "conditional_offer":
171
+ return { type: "conditional_offer", offer_id: offerId };
172
+ case "clarification":
173
+ return { type: "clarification" };
174
+ case "accept_nonbinding":
175
+ return { type: "accept_nonbinding", offer_id: offerId };
176
+ case "withdraw":
177
+ return { type: "withdraw", scope: envelope.payload?.scope === "negotiation" ? "negotiation" : "offer" };
178
+ case "decline":
179
+ return { type: "decline", scope: envelope.payload?.scope === "negotiation" ? "negotiation" : "offer" };
180
+ case "cancel":
181
+ return { type: "cancel" };
182
+ default:
183
+ return undefined;
184
+ }
185
+ };
186
+ /** 落 state_transition 事件并推进本机相位(recovery.deriveLocalPhase 消费)。
187
+ * fromPhase 必须显式传入——调用方若已把 next 写入 map 再读,from 会变成
188
+ * 已推进的值(审查 BUG-10 实现注记)。 */
189
+ const appendPhaseTransition = async (negotiationId, toPhase, fromPhase) => {
190
+ const current = phaseStateByNegotiation.get(negotiationId);
191
+ const effectiveFrom = fromPhase ?? current?.phase ?? "OPEN";
192
+ phaseStateByNegotiation.set(negotiationId, { ...(current ?? createNegotiationPhase(negotiationId)), phase: toPhase });
193
+ await ledger.append({
194
+ event_kind: "state_transition",
195
+ negotiation_id: negotiationId,
196
+ state_transition: { from_phase: effectiveFrom, to_phase: toPhase },
197
+ identity: {
198
+ sender_identity: sender,
199
+ counterparty_identity: counterparty,
200
+ actor: "merchant",
201
+ },
202
+ capability: { capability: MERCHANT_CAPABILITY, protocol_version: "1.0" },
203
+ outcome: { kind: "ok" },
204
+ occurred_at: now(),
205
+ });
206
+ };
112
207
  // 每 negotiation 已解析的真实商品价(sku → {priceMinor, currency}),带
113
208
  // TTL(评审项 L3:此前永久累积、价格永不刷新——长驻 merchant 节点内存
114
209
  // 单调增长且价目陈旧)。
@@ -125,8 +220,16 @@ export function createMerchantHandler(options) {
125
220
  if (options.productSource !== undefined) {
126
221
  try {
127
222
  const product = await options.productSource.getProduct(sku);
223
+ // 审查 BUG-04:major→minor 必须 lossless——Math.round 会把 19.995
224
+ // 静默改写为 1999/2000 进入报价(P2-P 已修数据源路径,此处是生产
225
+ // merchant handler 的剩余舍入点)。无法精确表达 → fail-closed
226
+ // (抛错 → resolveProduct 回退演示价并注记)。
227
+ const converted = losslessToMinorUnits(product.price, 2);
228
+ if (!converted.lossless) {
229
+ throw new Error(`商品源价格 ${product.price} 超出 ${MERCHANT_CURRENCY} 两位小数精度(lossy)`);
230
+ }
128
231
  const resolved = {
129
- priceMinor: Math.round(product.price * 100),
232
+ priceMinor: converted.amount_minor,
130
233
  currency: product.currency,
131
234
  at: Date.parse(now()),
132
235
  };
@@ -167,12 +270,72 @@ export function createMerchantHandler(options) {
167
270
  occurred_at: reply.created_at,
168
271
  });
169
272
  };
273
+ // 审查 BUG-03:从持久 Ledger 恢复状态(必须在 return 之前执行)——重启后
274
+ // 终态不得重开、已发出的 conditional offer 必须继续可被接受(此前
275
+ // conditionalByNegotiation / closedNegotiations / phaseStateByNegotiation 纯内存,
276
+ // 重启全丢:已终态 negotiation 可重新打开、已发 offer 返回 offer_unknown)。
277
+ for (const negotiationId of ledger.listNegotiations()) {
278
+ const events = ledger.events(negotiationId);
279
+ let phase = "OPEN";
280
+ for (const event of events) {
281
+ if (event.state_transition?.to_phase !== undefined) {
282
+ phase = event.state_transition.to_phase;
283
+ }
284
+ }
285
+ // 审查 P1-07(跨重启残留,独立验收发现):终态相位同样必须恢复——相位
286
+ // 取自链上 state_transition 事实(非臆造)。否则 cancel/withdraw/decline
287
+ // 不在 COMMERCIAL_ACTIONS、重启后 advancePhase 从全新 OPEN 状态推进:
288
+ // 重放的 cancel 被当作新动作接受,并落 from_phase 伪造为 OPEN 的幻影
289
+ // 终态转换。恢复后由相位机 fail-closed(state_conflict),与进程内一致。
290
+ phaseStateByNegotiation.set(negotiationId, {
291
+ negotiation_id: negotiationId,
292
+ phase,
293
+ });
294
+ if (isTerminalPhase(phase)) {
295
+ closedNegotiations.add(negotiationId);
296
+ continue; // 终态后 conditional 已删除,不恢复
297
+ }
298
+ // 恢复最后发出的 conditional_offer(message_sent 事件携带完整 envelope)
299
+ let lastConditional;
300
+ for (const event of events) {
301
+ if (event.event_kind !== "message_sent")
302
+ continue;
303
+ const envelope = event.wire_payload;
304
+ if (envelope?.action !== "conditional_offer")
305
+ continue;
306
+ const payload = envelope.payload;
307
+ if (payload?.offer_id === undefined)
308
+ continue;
309
+ lastConditional = {
310
+ conditional: envelope.payload,
311
+ quantity: payload.base_terms?.items?.[0]?.quantity?.value ?? MERCHANT_QUANTITY,
312
+ };
313
+ }
314
+ if (lastConditional !== undefined) {
315
+ conditionalByNegotiation.set(negotiationId, lastConditional);
316
+ }
317
+ }
170
318
  return {
171
319
  name: "kiwi-agent-serve-merchant",
172
320
  async handle(ctx) {
173
321
  const envelope = ctx.envelope;
174
322
  const negotiationId = envelope.negotiation_id;
175
323
  const inReplyTo = envelope.message_id;
324
+ // 审查 P2-D:终态不得以同一 negotiation_id 重开(§17.4/§21.2)。
325
+ if (closedNegotiations.has(negotiationId) && COMMERCIAL_ACTIONS.has(envelope.action)) {
326
+ return declineReply("state_conflict");
327
+ }
328
+ // 审查 BUG-10:每个入站 action 经规范转换表推进相位——非法转换
329
+ // fail-closed(state_conflict)。accept 的推进在 §15 校验通过后
330
+ // (见 accept 分支:被拒的 accept 不得进入 AGREEMENT_REACHED)。
331
+ const phaseEvent = actionToPhaseEvent(envelope);
332
+ const isAcceptAction = envelope.action === "accept_nonbinding";
333
+ if (phaseEvent !== undefined && !isAcceptAction) {
334
+ const advanced = await advancePhase(negotiationId, phaseEvent);
335
+ if (!advanced) {
336
+ return declineReply("state_conflict");
337
+ }
338
+ }
176
339
  switch (envelope.action) {
177
340
  case "inquiry": {
178
341
  // 入站消息由 A2A pipeline 统一落 message_received(§22);这里不再
@@ -194,10 +357,16 @@ export function createMerchantHandler(options) {
194
357
  payload: {
195
358
  type: "offer",
196
359
  offer_id: newOfferId(),
197
- terms: offerTerms({ sku, priceMinor, quantity, currency }),
360
+ terms: offerTerms({ sku, priceMinor, quantity, currency }, now()),
198
361
  },
199
362
  ...(note !== undefined ? { public_message: note } : {}),
200
363
  });
364
+ // 审查 BUG-10:merchant 侧相位由自己的出站动作推进——rfq 的 offer
365
+ // 回复是 OPEN→OFFER_OPEN 的边(入站侧 rfq 是起始动作无事件)。
366
+ await advancePhase(negotiationId, {
367
+ type: "offer",
368
+ offer_id: String(reply.payload.offer_id ?? ""),
369
+ });
201
370
  await appendSent(reply);
202
371
  return envelopeReply(reply);
203
372
  }
@@ -217,10 +386,14 @@ export function createMerchantHandler(options) {
217
386
  type: "counter_offer",
218
387
  offer_id: newOfferId(),
219
388
  responding_to_offer_id: buyerOffer.offer_id ?? "",
220
- proposed_terms: offerTerms({ sku, priceMinor, quantity, currency }),
389
+ proposed_terms: offerTerms({ sku, priceMinor, quantity, currency }, now()),
221
390
  },
222
391
  ...(note !== undefined ? { public_message: note } : {}),
223
392
  });
393
+ await advancePhase(negotiationId, {
394
+ type: "counter_offer",
395
+ offer_id: String(reply.payload.offer_id ?? ""),
396
+ });
224
397
  await appendSent(reply);
225
398
  return envelopeReply(reply);
226
399
  }
@@ -242,11 +415,11 @@ export function createMerchantHandler(options) {
242
415
  type: "conditional_offer",
243
416
  offer_id: newOfferId(),
244
417
  responding_to_offer_id: counter.offer_id,
245
- base_terms: offerTerms({ sku, priceMinor, quantity, currency }),
418
+ base_terms: offerTerms({ sku, priceMinor, quantity, currency }, now()),
246
419
  conditions: [
247
420
  {
248
421
  when: { all: [{ field: "aggregate.total_quantity", op: "gte", value: 100 }] },
249
- then_terms: offerTerms({ sku, priceMinor: dealPriceMinor, quantity, currency }),
422
+ then_terms: offerTerms({ sku, priceMinor: dealPriceMinor, quantity, currency }, now()),
250
423
  },
251
424
  ],
252
425
  },
@@ -256,6 +429,10 @@ export function createMerchantHandler(options) {
256
429
  conditional: reply.payload,
257
430
  quantity,
258
431
  });
432
+ await advancePhase(negotiationId, {
433
+ type: "conditional_offer",
434
+ offer_id: String(reply.payload.offer_id ?? ""),
435
+ });
259
436
  await appendSent(reply);
260
437
  return envelopeReply(reply);
261
438
  }
@@ -265,26 +442,42 @@ export function createMerchantHandler(options) {
265
442
  }
266
443
  case "accept_nonbinding": {
267
444
  const stored = conditionalByNegotiation.get(negotiationId);
268
- const acceptedOfferId = envelope.payload.offer_id ?? "";
445
+ const acceptPayload = envelope.payload;
446
+ const acceptedOfferId = acceptPayload.offer_id ?? "";
269
447
  // 成交价必须来自本磋商已发出的 conditional_offer:无前置 conditional
270
- // 或 accept 的 offer_id 与所存 conditional 不匹配 → 用基础价成交
271
- // (无折扣),绝不发 DEAL 价。此前无前置时直接给 DEAL 价,任何 buyer
272
- // conditional_offer 之前发 accept 即可拿到折扣价。
448
+ // 或 accept 的 offer_id 与所存 conditional 不匹配 → 拒绝成交。此前
449
+ // 无前置时回退基础价照样产出 agreement,从未发出的 offer_id 也照样
450
+ // 成交(agreement 指向不存在的 offer,审计溯源断裂)。
273
451
  const storedOfferId = stored?.conditional?.offer_id ?? "";
274
452
  const acceptedConditional = stored !== undefined && acceptedOfferId !== "" && acceptedOfferId === storedOfferId
275
453
  ? stored
276
454
  : undefined;
277
- const agreedTerms = acceptedConditional === undefined
278
- ? offerTerms({
279
- priceMinor: (await resolveProduct(MERCHANT_SKU)).priceMinor,
280
- quantity: MERCHANT_QUANTITY,
281
- })
282
- : evaluateConditionalOffer(acceptedConditional.conditional, {
283
- "aggregate.total_quantity": acceptedConditional.quantity,
284
- });
455
+ if (acceptedConditional === undefined) {
456
+ return declineReply("offer_unknown");
457
+ }
458
+ // KNP §15(审查 P2-C,实验复现):terms_digest 必须是 agreed terms
459
+ // 的 canonical digest——错误 digest 此前也产出 agreement。任一检查
460
+ // 失败都不得创建 agreement。
461
+ const agreedTerms = evaluateConditionalOffer(acceptedConditional.conditional, {
462
+ "aggregate.total_quantity": acceptedConditional.quantity,
463
+ });
464
+ // 审查 P3:§11 offer 过期校验——valid_until 已过 → 拒绝(此前
465
+ // valid_until 硬编码 2099 永不生效,陈旧报价可被无限期接受)。
466
+ const validUntil = agreedTerms?.valid_until;
467
+ if (validUntil !== undefined) {
468
+ const validUntilMs = Date.parse(validUntil);
469
+ const nowMs = Date.parse(now());
470
+ if (!Number.isFinite(validUntilMs) || !Number.isFinite(nowMs) || validUntilMs < nowMs) {
471
+ return declineReply("offer_expired");
472
+ }
473
+ }
474
+ const presentedDigest = acceptPayload.terms_digest ?? "";
475
+ if (presentedDigest === "" || presentedDigest !== contentDigest(agreedTerms)) {
476
+ return declineReply("terms_digest_mismatch");
477
+ }
285
478
  const agreement = buildAgreement({
286
479
  negotiation_id: negotiationId,
287
- accepted_offer_id: envelope.payload.offer_id,
480
+ accepted_offer_id: acceptedOfferId,
288
481
  agreed_terms: agreedTerms,
289
482
  created_at: now(),
290
483
  });
@@ -294,18 +487,38 @@ export function createMerchantHandler(options) {
294
487
  parts: [{ kind: "text", text: "Agreement reached (nonbinding)." }],
295
488
  messageId: newMessageId(),
296
489
  };
297
- // 协商终态:conditional 不再需要(评审项 L3:此前永久累积)
490
+ // 协商终态:conditional 不再需要(评审项 L3:此前永久累积);
491
+ // 审查 BUG-10:accept 的相位推进在 §15 校验通过后(被拒的 accept
492
+ // 不得进入 AGREEMENT_REACHED)。
298
493
  conditionalByNegotiation.delete(negotiationId);
494
+ closedNegotiations.add(negotiationId);
495
+ await advancePhase(negotiationId, { type: "accept_nonbinding", offer_id: acceptedOfferId });
299
496
  return { kind: "accepted", taskState: "completed", artifactParts: [artifactPart], message };
300
497
  }
301
- case "withdraw":
498
+ case "withdraw": {
499
+ const scope = envelope.payload.scope ?? "offer";
302
500
  conditionalByNegotiation.delete(negotiationId);
303
- return textReply(`Withdrawn (scope=${envelope.payload.scope ?? "offer"}).`);
304
- case "decline":
501
+ // scope=offer 只关 offer 不终局(相位机 OFFER_OPEN→OPEN);scope=
502
+ // negotiation 才进入 WITHDRAWN 终态。
503
+ if (scope !== "offer") {
504
+ closedNegotiations.add(negotiationId);
505
+ await advancePhase(negotiationId, { type: "withdraw", scope: "negotiation" });
506
+ }
507
+ return textReply(`Withdrawn (scope=${scope}).`);
508
+ }
509
+ case "decline": {
510
+ const scope = envelope.payload.scope ?? "offer";
305
511
  conditionalByNegotiation.delete(negotiationId);
306
- return textReply(`Declined (scope=${envelope.payload.scope ?? "offer"}).`);
512
+ if (scope !== "offer") {
513
+ closedNegotiations.add(negotiationId);
514
+ await advancePhase(negotiationId, { type: "decline", scope: "negotiation" });
515
+ }
516
+ return textReply(`Declined (scope=${scope}).`);
517
+ }
307
518
  case "cancel":
308
519
  conditionalByNegotiation.delete(negotiationId);
520
+ closedNegotiations.add(negotiationId);
521
+ await advancePhase(negotiationId, { type: "cancel" });
309
522
  return textReply("Negotiation cancelled.");
310
523
  default:
311
524
  return { kind: "declined", reasonCode: "unsupported_action" };
@@ -1 +1 @@
1
- {"version":3,"file":"merchant-handler.js","sourceRoot":"","sources":["../../../src/a2a/server/merchant-handler.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"merchant-handler.js","sourceRoot":"","sources":["../../../src/a2a/server/merchant-handler.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAeH,OAAO,EAAE,WAAW,EAAE,MAAM,mCAAmC,CAAC;AAChE,OAAO,EACL,cAAc,EACd,aAAa,EACb,YAAY,EACZ,UAAU,GACX,MAAM,yCAAyC,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,sCAAsC,CAAC;AACxE,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AACzD,OAAO,EAAE,wBAAwB,EAAE,MAAM,0CAA0C,CAAC;AACpF,OAAO,EAAE,YAAY,IAAI,oBAAoB,EAAE,MAAM,qDAAqD,CAAC;AAC3G,OAAO,EACL,sBAAsB,EACtB,eAAe,EACf,eAAe,GAIhB,MAAM,kCAAkC,CAAC;AAS1C,MAAM,CAAC,MAAM,mBAAmB,GAAG,0CAA0C,CAAC;AAC9E,MAAM,CAAC,MAAM,YAAY,GAAG,SAAS,CAAC;AACtC,MAAM,CAAC,MAAM,iBAAiB,GAAG,KAAK,CAAC;AACvC,MAAM,CAAC,MAAM,0BAA0B,GAAG,MAAM,CAAC,CAAC,aAAa;AAC/D,MAAM,CAAC,MAAM,yBAAyB,GAAG,MAAM,CAAC,CAAC,aAAa;AAC9D,MAAM,CAAC,MAAM,iBAAiB,GAAG,GAAG,CAAC;AACrC,MAAM,CAAC,MAAM,wBAAwB,GAAG,sBAAsB,CAAC;AA0B/D;;;;GAIG;AACH,MAAM,UAAU,uBAAuB,CACrC,UAA8B;IAE9B,OAAO;QACL,KAAK,CAAC,UAAU,CAAC,GAAW;YAC1B,MAAM,IAAI,GAAG,MAAM,UAAU,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;YAC9C,IAAI,IAAI,KAAK,SAAS,IAAI,IAAI,CAAC,WAAW,KAAK,SAAS,IAAI,IAAI,CAAC,QAAQ,KAAK,SAAS,EAAE,CAAC;gBACxF,MAAM,IAAI,KAAK,CAAC,uCAAuC,GAAG,EAAE,CAAC,CAAC;YAChE,CAAC;YACD,OAAO;gBACL,KAAK,EAAE,IAAI,CAAC,WAAW,GAAG,GAAG;gBAC7B,QAAQ,EAAE,IAAI,CAAC,QAAQ;gBACvB,GAAG,CAAC,IAAI,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBAC1D,GAAG,CAAC,IAAI,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aAC3D,CAAC;QACJ,CAAC;KACF,CAAC;AACJ,CAAC;AAQD,SAAS,YAAY,CAAC,IAAkB;IACtC,OAAO,gBAAgB,CAAC;QACtB,UAAU,EAAE,mBAAmB;QAC/B,gBAAgB,EAAE,KAAK;QACvB,WAAW,EAAE,IAAI,CAAC,WAAW,IAAI,aAAa,EAAE;QAChD,UAAU,EAAE,IAAI,CAAC,UAAU,IAAI,YAAY,EAAE;QAC7C,GAAG,IAAI;KACR,CAAC,CAAC;AACL,CAAC;AAED;;qDAEqD;AACrD,MAAM,CAAC,MAAM,iBAAiB,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;AAErD,SAAS,UAAU,CACjB,IAA+E,EAC/E,GAAW;IAEX,OAAO;QACL,KAAK,EAAE;YACL;gBACE,GAAG,EAAE,IAAI,CAAC,GAAG,IAAI,YAAY;gBAC7B,QAAQ,EAAE,EAAE,KAAK,EAAE,IAAI,CAAC,QAAQ,EAAE,IAAI,EAAE,OAAO,EAAE;gBACjD,UAAU,EAAE,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,IAAI,iBAAiB,EAAE,YAAY,EAAE,IAAI,CAAC,UAAU,EAAE;aAC5F;SACF;QACD,iBAAiB,EAAE,EAAE,eAAe,EAAE,wBAAwB,EAAE;QAChE,WAAW,EAAE,IAAI,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,iBAAiB,CAAC,CAAC,WAAW,EAAE;KACzE,CAAC;AACJ,CAAC;AAED,SAAS,cAAc,CAAC,KAKvB;IACC,OAAO;QACL,IAAI,EAAE,+BAA+B;QACrC,YAAY,EAAE,cAAc,EAAE;QAC9B,cAAc,EAAE,KAAK,CAAC,cAAc;QACpC,iBAAiB,EAAE,KAAK,CAAC,iBAAiB;QAC1C,YAAY,EAAE,KAAK,CAAC,YAAY;QAChC,YAAY,EAAE,aAAa,CAAC,KAAK,CAAC,YAAqB,CAAC;QACxD,WAAW,EAAE,CAAC,OAAO,EAAE,UAAU,CAAC;QAClC,UAAU,EAAE,KAAK,CAAC,UAAU;QAC5B,cAAc,EAAE,YAAY;QAC5B,aAAa,EAAE,KAAK;QACpB,kBAAkB,EAAE,KAAK;QACzB,kBAAkB,EAAE,KAAK;KAC1B,CAAC;AACJ,CAAC;AAED,MAAM,SAAS,GAAG,CAAC,IAAY,EAAE,YAAqC,SAAS,EAA4B,EAAE,CAAC,CAAC;IAC7G,IAAI,EAAE,UAAU;IAChB,SAAS;IACT,OAAO,EAAE;QACP,IAAI,EAAE,OAAO;QACb,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;QAC/B,sDAAsD;QACtD,+BAA+B;QAC/B,SAAS,EAAE,YAAY,EAAE;KAC1B;CACF,CAAC,CAAC;AAEH;8CAC8C;AAC9C,MAAM,YAAY,GAAG,CAAC,aAAgC,gBAAgB,EAA4B,EAAE,CAAC,CAAC;IACpG,IAAI,EAAE,UAAU;IAChB,UAAU;IACV,SAAS,EAAE,WAAW;CACvB,CAAC,CAAC;AAEH,MAAM,aAAa,GAAG,CAAC,KAA0C,EAA4B,EAAE,CAAC,CAAC;IAC/F,IAAI,EAAE,UAAU;IAChB,SAAS,EAAE,SAAS;IACpB,OAAO,EAAE;QACP,IAAI,EAAE,OAAO;QACb,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,YAAY,EAAE,KAAK,EAAE,EAAE,CAAC;QACxD,SAAS,EAAE,KAAK,CAAC,UAAU;KAC5B;CACF,CAAC,CAAC;AAEH,iCAAiC;AACjC,MAAM,UAAU,qBAAqB,CACnC,OAA+B;IAE/B,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,YAAY,EAAE,GAAG,OAAO,CAAC;IACtD,MAAM,eAAe,GAAG,OAAO,CAAC,eAAe,IAAI,0BAA0B,CAAC;IAC9E,MAAM,wBAAwB,GAAG,IAAI,GAAG,EAAsE,CAAC;IAC/G,mEAAmE;IACnE,mDAAmD;IACnD,kDAAkD;IAClD,MAAM,kBAAkB,GAAG,IAAI,GAAG,EAAU,CAAC;IAC7C,yDAAyD;IACzD,wCAAwC;IACxC,kDAAkD;IAClD,MAAM,uBAAuB,GAAG,IAAI,GAAG,EAAiC,CAAC;IACzE,gDAAgD;IAChD,MAAM,kBAAkB,GAAG,IAAI,GAAG,CAAC;QACjC,SAAS;QACT,KAAK;QACL,OAAO;QACP,eAAe;QACf,mBAAmB;QACnB,mBAAmB;KACpB,CAAC,CAAC;IAEH;;;;mBAIe;IACf,MAAM,YAAY,GAAG,KAAK,EACxB,aAAqB,EACrB,KAA4B,EACV,EAAE;QACpB,MAAM,KAAK,GAAG,uBAAuB,CAAC,GAAG,CAAC,aAAa,CAAC,IAAI,sBAAsB,CAAC,aAAa,CAAC,CAAC;QAClG,IAAI,IAA2B,CAAC;QAChC,IAAI,CAAC;YACH,IAAI,GAAG,eAAe,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;QACvC,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,KAAK,CAAC;QACf,CAAC;QACD,uBAAuB,CAAC,GAAG,CAAC,aAAa,EAAE,IAAI,CAAC,CAAC;QACjD,IAAI,IAAI,CAAC,KAAK,KAAK,KAAK,CAAC,KAAK,EAAE,CAAC;YAC/B,MAAM,qBAAqB,CAAC,aAAa,EAAE,IAAI,CAAC,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC;QACtE,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC,CAAC;IAEF,gDAAgD;IAChD,MAAM,kBAAkB,GAAG,CACzB,QAA+C,EACZ,EAAE;QACrC,MAAM,OAAO,GAAG,MAAM,CAAE,QAAQ,CAAC,OAA8C,EAAE,QAAQ,IAAI,EAAE,CAAC,CAAC;QACjG,QAAQ,QAAQ,CAAC,MAAM,EAAE,CAAC;YACxB,KAAK,OAAO;gBACV,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC;YAC9C,KAAK,eAAe;gBAClB,OAAO,EAAE,IAAI,EAAE,eAAe,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC;YACtD,KAAK,mBAAmB;gBACtB,OAAO,EAAE,IAAI,EAAE,mBAAmB,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC;YAC1D,KAAK,eAAe;gBAClB,OAAO,EAAE,IAAI,EAAE,eAAe,EAAE,CAAC;YACnC,KAAK,mBAAmB;gBACtB,OAAO,EAAE,IAAI,EAAE,mBAAmB,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC;YAC1D,KAAK,UAAU;gBACb,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,KAAK,EAAG,QAAQ,CAAC,OAA0C,EAAE,KAAK,KAAK,aAAa,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC;YAC9I,KAAK,SAAS;gBACZ,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAG,QAAQ,CAAC,OAA0C,EAAE,KAAK,KAAK,aAAa,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC;YAC7I,KAAK,QAAQ;gBACX,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;YAC5B;gBACE,OAAO,SAAS,CAAC;QACrB,CAAC;IACH,CAAC,CAAC;IAEF;;iCAE6B;IAC7B,MAAM,qBAAqB,GAAG,KAAK,EACjC,aAAqB,EACrB,OAAyB,EACzB,SAA4B,EACb,EAAE;QACjB,MAAM,OAAO,GAAG,uBAAuB,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;QAC3D,MAAM,aAAa,GAAG,SAAS,IAAI,OAAO,EAAE,KAAK,IAAI,MAAM,CAAC;QAC5D,uBAAuB,CAAC,GAAG,CAAC,aAAa,EAAE,EAAE,GAAG,CAAC,OAAO,IAAI,sBAAsB,CAAC,aAAa,CAAC,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,CAAC;QACtH,MAAM,MAAM,CAAC,MAAM,CAAC;YAClB,UAAU,EAAE,kBAAkB;YAC9B,cAAc,EAAE,aAAa;YAC7B,gBAAgB,EAAE,EAAE,UAAU,EAAE,aAAa,EAAE,QAAQ,EAAE,OAAO,EAAE;YAClE,QAAQ,EAAE;gBACR,eAAe,EAAE,MAAM;gBACvB,qBAAqB,EAAE,YAAY;gBACnC,KAAK,EAAE,UAAU;aAClB;YACD,UAAU,EAAE,EAAE,UAAU,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,KAAK,EAAE;YACxE,OAAO,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE;YACvB,WAAW,EAAE,GAAG,EAAE;SACnB,CAAC,CAAC;IACL,CAAC,CAAC;IACF,0DAA0D;IAC1D,6CAA6C;IAC7C,cAAc;IACd,MAAM,kBAAkB,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;IAC1C,MAAM,UAAU,GAAG,IAAI,GAAG,EAAgE,CAAC;IAE3F,2CAA2C;IAC3C,MAAM,cAAc,GAAG,KAAK,EAC1B,GAAW,EACuD,EAAE;QACpE,MAAM,MAAM,GAAG,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACnC,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;YACzB,IAAI,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,GAAG,MAAM,CAAC,EAAE,IAAI,kBAAkB;gBAAE,OAAO,MAAM,CAAC;YACvE,UAAU,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,oBAAoB;QAC9C,CAAC;QACD,IAAI,OAAO,CAAC,aAAa,KAAK,SAAS,EAAE,CAAC;YACxC,IAAI,CAAC;gBACH,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,aAAa,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;gBAC5D,0DAA0D;gBAC1D,0CAA0C;gBAC1C,gDAAgD;gBAChD,kCAAkC;gBAClC,MAAM,SAAS,GAAG,oBAAoB,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;gBACzD,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,CAAC;oBACxB,MAAM,IAAI,KAAK,CACb,SAAS,OAAO,CAAC,KAAK,OAAO,iBAAiB,gBAAgB,CAC/D,CAAC;gBACJ,CAAC;gBACD,MAAM,QAAQ,GAAG;oBACf,UAAU,EAAE,SAAS,CAAC,YAAY;oBAClC,QAAQ,EAAE,OAAO,CAAC,QAAQ;oBAC1B,EAAE,EAAE,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC;iBACtB,CAAC;gBACF,UAAU,CAAC,GAAG,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;gBAC9B,OAAO,QAAQ,CAAC;YAClB,CAAC;YAAC,MAAM,CAAC;gBACP,uCAAuC;gBACvC,oCAAoC;gBACpC,OAAO;oBACL,UAAU,EAAE,eAAe;oBAC3B,QAAQ,EAAE,iBAAiB;oBAC3B,IAAI,EAAE,UAAU,GAAG,YAAY;iBAChC,CAAC;YACJ,CAAC;QACH,CAAC;QACD,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,QAAQ,EAAE,iBAAiB,EAAE,CAAC;IACtE,CAAC,CAAC;IAEF,MAAM,UAAU,GAAG,KAAK,EAAE,KAA0C,EAAiB,EAAE;QACrF,MAAM,MAAM,CAAC,MAAM,CAAC;YAClB,UAAU,EAAE,cAAc;YAC1B,cAAc,EAAE,KAAK,CAAC,cAAc;YACpC,WAAW,EAAE,KAAK,CAAC,WAAW;YAC9B,UAAU,EAAE,KAAK,CAAC,UAAU;YAC5B,WAAW,EAAE,KAAK,CAAC,WAAW;YAC9B,QAAQ,EAAE;gBACR,eAAe,EAAE,MAAM;gBACvB,qBAAqB,EAAE,YAAY;gBACnC,KAAK,EAAE,KAAK,CAAC,KAAK;aACnB;YACD,UAAU,EAAE;gBACV,UAAU,EAAE,KAAK,CAAC,UAAU;gBAC5B,gBAAgB,EAAE,KAAK,CAAC,gBAAgB;aACzC;YACD,WAAW,EAAE,KAAK,CAAC,MAAM;YACzB,YAAY,EAAE,KAA2C;YACzD,OAAO,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE;YACvB,WAAW,EAAE,KAAK,CAAC,UAAU;SAC9B,CAAC,CAAC;IACL,CAAC,CAAC;IAEF,kDAAkD;IAClD,4CAA4C;IAC5C,+EAA+E;IAC/E,yDAAyD;IACzD,KAAK,MAAM,aAAa,IAAI,MAAM,CAAC,gBAAgB,EAAE,EAAE,CAAC;QACtD,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC;QAC5C,IAAI,KAAK,GAAqB,MAAM,CAAC;QACrC,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;YAC3B,IAAI,KAAK,CAAC,gBAAgB,EAAE,QAAQ,KAAK,SAAS,EAAE,CAAC;gBACnD,KAAK,GAAG,KAAK,CAAC,gBAAgB,CAAC,QAAQ,CAAC;YAC1C,CAAC;QACH,CAAC;QACD,wCAAwC;QACxC,2DAA2D;QAC3D,wDAAwD;QACxD,iDAAiD;QACjD,mDAAmD;QACnD,uBAAuB,CAAC,GAAG,CAAC,aAAa,EAAE;YACzC,cAAc,EAAE,aAAa;YAC7B,KAAK;SACN,CAAC,CAAC;QACH,IAAI,eAAe,CAAC,KAAK,CAAC,EAAE,CAAC;YAC3B,kBAAkB,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;YACtC,SAAS,CAAC,0BAA0B;QACtC,CAAC;QACD,0DAA0D;QAC1D,IAAI,eAAuF,CAAC;QAC5F,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;YAC3B,IAAI,KAAK,CAAC,UAAU,KAAK,cAAc;gBAAE,SAAS;YAClD,MAAM,QAAQ,GAAG,KAAK,CAAC,YAEV,CAAC;YACd,IAAI,QAAQ,EAAE,MAAM,KAAK,mBAAmB;gBAAE,SAAS;YACvD,MAAM,OAAO,GAAG,QAAQ,CAAC,OAKZ,CAAC;YACd,IAAI,OAAO,EAAE,QAAQ,KAAK,SAAS;gBAAE,SAAS;YAC9C,eAAe,GAAG;gBAChB,WAAW,EAAE,QAAQ,CAAC,OAAkC;gBACxD,QAAQ,EAAE,OAAO,CAAC,UAAU,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,KAAK,IAAI,iBAAiB;aAC/E,CAAC;QACJ,CAAC;QACD,IAAI,eAAe,KAAK,SAAS,EAAE,CAAC;YAClC,wBAAwB,CAAC,GAAG,CAAC,aAAa,EAAE,eAAe,CAAC,CAAC;QAC/D,CAAC;IACH,CAAC;IACD,OAAO;QACL,IAAI,EAAE,2BAA2B;QACjC,KAAK,CAAC,MAAM,CAAC,GAA8B;YACzC,MAAM,QAAQ,GAAG,GAAG,CAAC,QAAQ,CAAC;YAC9B,MAAM,aAAa,GAAG,QAAQ,CAAC,cAAc,CAAC;YAC9C,MAAM,SAAS,GAAG,QAAQ,CAAC,UAAU,CAAC;YAEtC,kDAAkD;YAClD,IAAI,kBAAkB,CAAC,GAAG,CAAC,aAAa,CAAC,IAAI,kBAAkB,CAAC,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;gBACrF,OAAO,YAAY,CAAC,gBAAgB,CAAC,CAAC;YACxC,CAAC;YAED,yCAAyC;YACzC,oDAAoD;YACpD,mDAAmD;YACnD,MAAM,UAAU,GAAG,kBAAkB,CAAC,QAAQ,CAAC,CAAC;YAChD,MAAM,cAAc,GAAG,QAAQ,CAAC,MAAM,KAAK,mBAAmB,CAAC;YAC/D,IAAI,UAAU,KAAK,SAAS,IAAI,CAAC,cAAc,EAAE,CAAC;gBAChD,MAAM,QAAQ,GAAG,MAAM,YAAY,CAAC,aAAa,EAAE,UAAU,CAAC,CAAC;gBAC/D,IAAI,CAAC,QAAQ,EAAE,CAAC;oBACd,OAAO,YAAY,CAAC,gBAAgB,CAAC,CAAC;gBACxC,CAAC;YACH,CAAC;YAED,QAAQ,QAAQ,CAAC,MAAM,EAAE,CAAC;gBACxB,KAAK,SAAS,CAAC,CAAC,CAAC;oBACf,oDAAoD;oBACpD,yDAAyD;oBACzD,qCAAqC;oBACrC,OAAO,SAAS,CACd,YAAY,YAAY,OAAO,CAAC,eAAe,GAAG,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,iBAAiB,mCAAmC,CAC1H,CAAC;gBACJ,CAAC;gBACD,KAAK,KAAK,CAAC,CAAC,CAAC;oBACX,MAAM,OAAO,GAAG,QAAQ,CAAC,OAExB,CAAC;oBACF,MAAM,GAAG,GAAG,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,GAAG,IAAI,YAAY,CAAC;oBACpD,MAAM,QAAQ,GAAG,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,KAAK,IAAI,iBAAiB,CAAC;oBAC1E,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,IAAI,EAAE,GAAG,MAAM,cAAc,CAAC,GAAG,CAAC,CAAC;oBACjE,MAAM,KAAK,GAAG,YAAY,CAAC;wBACzB,cAAc,EAAE,aAAa;wBAC7B,WAAW,EAAE,SAAS;wBACtB,KAAK,EAAE,UAAU;wBACjB,MAAM,EAAE,OAAO;wBACf,UAAU,EAAE,GAAG,EAAE;wBACjB,OAAO,EAAE;4BACP,IAAI,EAAE,OAAO;4BACb,QAAQ,EAAE,UAAU,EAAE;4BACtB,KAAK,EAAE,UAAU,CAAC,EAAE,GAAG,EAAE,UAAU,EAAE,QAAQ,EAAE,QAAQ,EAAE,EAAE,GAAG,EAAE,CAAC;yBAClE;wBACD,GAAG,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,cAAc,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;qBACxD,CAAC,CAAC;oBACH,gDAAgD;oBAChD,4CAA4C;oBAC5C,MAAM,YAAY,CAAC,aAAa,EAAE;wBAChC,IAAI,EAAE,OAAO;wBACb,QAAQ,EAAE,MAAM,CAAE,KAAK,CAAC,OAAkC,CAAC,QAAQ,IAAI,EAAE,CAAC;qBAC3E,CAAC,CAAC;oBACH,MAAM,UAAU,CAAC,KAAK,CAAC,CAAC;oBACxB,OAAO,aAAa,CAAC,KAAK,CAAC,CAAC;gBAC9B,CAAC;gBACD,KAAK,OAAO,CAAC,CAAC,CAAC;oBACb,+CAA+C;oBAC/C,MAAM,UAAU,GAAG,QAAQ,CAAC,OAAuG,CAAC;oBACpI,MAAM,GAAG,GAAG,UAAU,CAAC,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,GAAG,IAAI,YAAY,CAAC;oBAC9D,MAAM,QAAQ,GAAG,UAAU,CAAC,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,KAAK,IAAI,iBAAiB,CAAC;oBACpF,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,IAAI,EAAE,GAAG,MAAM,cAAc,CAAC,GAAG,CAAC,CAAC;oBACjE,MAAM,KAAK,GAAG,YAAY,CAAC;wBACzB,cAAc,EAAE,aAAa;wBAC7B,WAAW,EAAE,SAAS;wBACtB,KAAK,EAAE,UAAU;wBACjB,MAAM,EAAE,eAAe;wBACvB,UAAU,EAAE,GAAG,EAAE;wBACjB,OAAO,EAAE;4BACP,IAAI,EAAE,eAAe;4BACrB,QAAQ,EAAE,UAAU,EAAE;4BACtB,sBAAsB,EAAE,UAAU,CAAC,QAAQ,IAAI,EAAE;4BACjD,cAAc,EAAE,UAAU,CAAC,EAAE,GAAG,EAAE,UAAU,EAAE,QAAQ,EAAE,QAAQ,EAAE,EAAE,GAAG,EAAE,CAAC;yBAC3E;wBACD,GAAG,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,cAAc,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;qBACxD,CAAC,CAAC;oBACH,MAAM,YAAY,CAAC,aAAa,EAAE;wBAChC,IAAI,EAAE,eAAe;wBACrB,QAAQ,EAAE,MAAM,CAAE,KAAK,CAAC,OAAkC,CAAC,QAAQ,IAAI,EAAE,CAAC;qBAC3E,CAAC,CAAC;oBACH,MAAM,UAAU,CAAC,KAAK,CAAC,CAAC;oBACxB,OAAO,aAAa,CAAC,KAAK,CAAC,CAAC;gBAC9B,CAAC;gBACD,KAAK,eAAe,CAAC,CAAC,CAAC;oBACrB,MAAM,OAAO,GAAG,QAAQ,CAAC,OAGxB,CAAC;oBACF,MAAM,GAAG,GAAG,OAAO,CAAC,cAAc,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,GAAG,IAAI,YAAY,CAAC;oBACpE,MAAM,QAAQ,GAAG,OAAO,CAAC,cAAc,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,KAAK,IAAI,iBAAiB,CAAC;oBAC1F,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,IAAI,EAAE,GAAG,MAAM,cAAc,CAAC,GAAG,CAAC,CAAC;oBACjE,oCAAoC;oBACpC,MAAM,eAAe,GAAG,OAAO,CAAC,mBAAmB,IAAI,CAAC,CAAC;oBACzD,MAAM,cAAc,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,UAAU,GAAG,CAAC,GAAG,GAAG,eAAe,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC;oBAChF,MAAM,KAAK,GAAG,YAAY,CAAC;wBACzB,cAAc,EAAE,aAAa;wBAC7B,WAAW,EAAE,SAAS;wBACtB,KAAK,EAAE,UAAU;wBACjB,MAAM,EAAE,mBAAmB;wBAC3B,UAAU,EAAE,GAAG,EAAE;wBACjB,OAAO,EAAE;4BACP,IAAI,EAAE,mBAAmB;4BACzB,QAAQ,EAAE,UAAU,EAAE;4BACtB,sBAAsB,EAAE,OAAO,CAAC,QAAQ;4BACxC,UAAU,EAAE,UAAU,CAAC,EAAE,GAAG,EAAE,UAAU,EAAE,QAAQ,EAAE,QAAQ,EAAE,EAAE,GAAG,EAAE,CAAC;4BACtE,UAAU,EAAE;gCACV;oCACE,IAAI,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE,KAAK,EAAE,0BAA0B,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,EAAE;oCAC7E,UAAU,EAAE,UAAU,CAAC,EAAE,GAAG,EAAE,UAAU,EAAE,cAAc,EAAE,QAAQ,EAAE,QAAQ,EAAE,EAAE,GAAG,EAAE,CAAC;iCACvF;6BACF;yBACF;wBACD,GAAG,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,cAAc,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;qBACxD,CAAC,CAAC;oBACH,wBAAwB,CAAC,GAAG,CAAC,aAAa,EAAE;wBAC1C,WAAW,EAAE,KAAK,CAAC,OAA6C;wBAChE,QAAQ;qBACT,CAAC,CAAC;oBACH,MAAM,YAAY,CAAC,aAAa,EAAE;wBAChC,IAAI,EAAE,mBAAmB;wBACzB,QAAQ,EAAE,MAAM,CAAE,KAAK,CAAC,OAAkC,CAAC,QAAQ,IAAI,EAAE,CAAC;qBAC3E,CAAC,CAAC;oBACH,MAAM,UAAU,CAAC,KAAK,CAAC,CAAC;oBACxB,OAAO,aAAa,CAAC,KAAK,CAAC,CAAC;gBAC9B,CAAC;gBACD,KAAK,eAAe,CAAC,CAAC,CAAC;oBACrB,MAAM,KAAK,GAAI,QAAQ,CAAC,OAAgD,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC;oBAC/F,OAAO,SAAS,CACd,cAAc,KAAK,IAAI,GAAG,sBAAsB,wBAAwB,0CAA0C,CACnH,CAAC;gBACJ,CAAC;gBACD,KAAK,mBAAmB,CAAC,CAAC,CAAC;oBACzB,MAAM,MAAM,GAAG,wBAAwB,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;oBAC3D,MAAM,aAAa,GAAG,QAAQ,CAAC,OAAuD,CAAC;oBACvF,MAAM,eAAe,GAAG,aAAa,CAAC,QAAQ,IAAI,EAAE,CAAC;oBACrD,mDAAmD;oBACnD,oDAAoD;oBACpD,6CAA6C;oBAC7C,qCAAqC;oBACrC,MAAM,aAAa,GAAI,MAAM,EAAE,WAAiD,EAAE,QAAQ,IAAI,EAAE,CAAC;oBACjG,MAAM,mBAAmB,GACvB,MAAM,KAAK,SAAS,IAAI,eAAe,KAAK,EAAE,IAAI,eAAe,KAAK,aAAa;wBACjF,CAAC,CAAC,MAAM;wBACR,CAAC,CAAC,SAAS,CAAC;oBAChB,IAAI,mBAAmB,KAAK,SAAS,EAAE,CAAC;wBACtC,OAAO,YAAY,CAAC,eAAe,CAAC,CAAC;oBACvC,CAAC;oBACD,sDAAsD;oBACtD,qDAAqD;oBACrD,qBAAqB;oBACrB,MAAM,WAAW,GAAG,wBAAwB,CAAC,mBAAmB,CAAC,WAAoB,EAAE;wBACrF,0BAA0B,EAAE,mBAAmB,CAAC,QAAQ;qBACzD,CAAC,CAAC;oBACH,+CAA+C;oBAC/C,0CAA0C;oBAC1C,MAAM,UAAU,GAAI,WAAoD,EAAE,WAAW,CAAC;oBACtF,IAAI,UAAU,KAAK,SAAS,EAAE,CAAC;wBAC7B,MAAM,YAAY,GAAG,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;wBAC5C,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC;wBAChC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,YAAY,GAAG,KAAK,EAAE,CAAC;4BACtF,OAAO,YAAY,CAAC,eAAe,CAAC,CAAC;wBACvC,CAAC;oBACH,CAAC;oBACD,MAAM,eAAe,GAAG,aAAa,CAAC,YAAY,IAAI,EAAE,CAAC;oBACzD,IAAI,eAAe,KAAK,EAAE,IAAI,eAAe,KAAK,aAAa,CAAC,WAAoB,CAAC,EAAE,CAAC;wBACtF,OAAO,YAAY,CAAC,uBAAuB,CAAC,CAAC;oBAC/C,CAAC;oBACD,MAAM,SAAS,GAAG,cAAc,CAAC;wBAC/B,cAAc,EAAE,aAAa;wBAC7B,iBAAiB,EAAE,eAAe;wBAClC,YAAY,EAAE,WAAW;wBACzB,UAAU,EAAE,GAAG,EAAE;qBAClB,CAAC,CAAC;oBACH,MAAM,YAAY,GAAY,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,SAAS,EAAE,EAAE,CAAC;oBACpE,MAAM,OAAO,GAAe;wBAC1B,IAAI,EAAE,OAAO;wBACb,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,iCAAiC,EAAE,CAAC;wBAClE,SAAS,EAAE,YAAY,EAAE;qBAC1B,CAAC;oBACF,wCAAwC;oBACxC,+CAA+C;oBAC/C,2BAA2B;oBAC3B,wBAAwB,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC;oBAC/C,kBAAkB,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;oBACtC,MAAM,YAAY,CAAC,aAAa,EAAE,EAAE,IAAI,EAAE,mBAAmB,EAAE,QAAQ,EAAE,eAAe,EAAE,CAAC,CAAC;oBAC5F,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,SAAS,EAAE,WAAW,EAAE,aAAa,EAAE,CAAC,YAAY,CAAC,EAAE,OAAO,EAAE,CAAC;gBAC9F,CAAC;gBACD,KAAK,UAAU,CAAC,CAAC,CAAC;oBAChB,MAAM,KAAK,GAAI,QAAQ,CAAC,OAA8B,CAAC,KAAK,IAAI,OAAO,CAAC;oBACxE,wBAAwB,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC;oBAC/C,uDAAuD;oBACvD,gCAAgC;oBAChC,IAAI,KAAK,KAAK,OAAO,EAAE,CAAC;wBACtB,kBAAkB,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;wBACtC,MAAM,YAAY,CAAC,aAAa,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,aAAa,EAAE,CAAC,CAAC;oBAChF,CAAC;oBACD,OAAO,SAAS,CAAC,oBAAoB,KAAK,IAAI,CAAC,CAAC;gBAClD,CAAC;gBACD,KAAK,SAAS,CAAC,CAAC,CAAC;oBACf,MAAM,KAAK,GAAI,QAAQ,CAAC,OAA8B,CAAC,KAAK,IAAI,OAAO,CAAC;oBACxE,wBAAwB,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC;oBAC/C,IAAI,KAAK,KAAK,OAAO,EAAE,CAAC;wBACtB,kBAAkB,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;wBACtC,MAAM,YAAY,CAAC,aAAa,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,aAAa,EAAE,CAAC,CAAC;oBAC/E,CAAC;oBACD,OAAO,SAAS,CAAC,mBAAmB,KAAK,IAAI,CAAC,CAAC;gBACjD,CAAC;gBACD,KAAK,QAAQ;oBACX,wBAAwB,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC;oBAC/C,kBAAkB,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;oBACtC,MAAM,YAAY,CAAC,aAAa,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC;oBACtD,OAAO,SAAS,CAAC,wBAAwB,CAAC,CAAC;gBAC7C;oBACE,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,UAAU,EAAE,oBAAoB,EAAE,CAAC;YAClE,CAAC;QACH,CAAC;KACF,CAAC;AAEJ,CAAC"}
@@ -62,6 +62,23 @@ export declare class InboundPipeline {
62
62
  private readonly throttle;
63
63
  constructor(options: InboundPipelineOptions);
64
64
  private toThrottleRequest;
65
+ /** 从已落账 message_received 事件还原最小 A2ATask(P1-05 恢复路径)。
66
+ * 事件携带 remote_task_id + outcome.task_state(§24.5);消息正文不落账,
67
+ * 恢复的任务不含 message(与幂等重放路径的完整 task 不同,可接受)。 */
68
+ private taskFromLedgerEvent;
69
+ /**
70
+ * 审查 P1-05:以 Ledger 为持久事实的幂等恢复——消息已落账(message_received)
71
+ * 但幂等未 commit(commit 失败 / append 与 commit 之间崩溃的窗口)时,重试
72
+ * 必须**不重复执行 handler**(至多一次)。三个调用点:
73
+ * - 幂等 check 返回 "new" 但 Ledger 已有同 message_id → 恢复(不跑 handler);
74
+ * - ledger.append 成功后 commit 失败 → 从刚落账的事件恢复并返回稳定响应;
75
+ * - ledger.append 抛 ledger_duplicate_content(P2-E,首次落账成功)→ 恢复。
76
+ *
77
+ * digest 必须与链上证据一致:同 message_id 异 digest = 恶意重放 → conflict
78
+ * fail-closed。补 commit 是 best-effort(失败不阻断恢复响应,ledger 仍是持久
79
+ * 事实,下一次重试仍走本条恢复路径)。
80
+ */
81
+ private recoverFromLedgerEvidence;
65
82
  /** message/send 入站处理(限流 → 校验 → 幂等 → handler → Ledger → 幂等 commit)。 */
66
83
  sendMessage(input: SendMessageInput, caller: SendMessageCaller): Promise<SendMessageResult>;
67
84
  /** tasks/get:内存优先,miss 时回退 Ledger 视图(§23 恢复第 4 步)。 */
@@ -158,6 +158,63 @@ export class InboundPipeline {
158
158
  fingerprintChanged: caller.fingerprintChanged,
159
159
  };
160
160
  }
161
+ /** 从已落账 message_received 事件还原最小 A2ATask(P1-05 恢复路径)。
162
+ * 事件携带 remote_task_id + outcome.task_state(§24.5);消息正文不落账,
163
+ * 恢复的任务不含 message(与幂等重放路径的完整 task 不同,可接受)。 */
164
+ taskFromLedgerEvent(event) {
165
+ const taskId = event.remote_task_id;
166
+ if (typeof taskId !== "string" || taskId.length === 0)
167
+ return null;
168
+ const result = event.outcome.kind === "ok" ? event.outcome.result : undefined;
169
+ const state = result === undefined ? undefined : result["task_state"];
170
+ if (!isKnownTaskState(state))
171
+ return null;
172
+ return { id: taskId, status: { state } };
173
+ }
174
+ /**
175
+ * 审查 P1-05:以 Ledger 为持久事实的幂等恢复——消息已落账(message_received)
176
+ * 但幂等未 commit(commit 失败 / append 与 commit 之间崩溃的窗口)时,重试
177
+ * 必须**不重复执行 handler**(至多一次)。三个调用点:
178
+ * - 幂等 check 返回 "new" 但 Ledger 已有同 message_id → 恢复(不跑 handler);
179
+ * - ledger.append 成功后 commit 失败 → 从刚落账的事件恢复并返回稳定响应;
180
+ * - ledger.append 抛 ledger_duplicate_content(P2-E,首次落账成功)→ 恢复。
181
+ *
182
+ * digest 必须与链上证据一致:同 message_id 异 digest = 恶意重放 → conflict
183
+ * fail-closed。补 commit 是 best-effort(失败不阻断恢复响应,ledger 仍是持久
184
+ * 事实,下一次重试仍走本条恢复路径)。
185
+ */
186
+ recoverFromLedgerEvidence(senderIdentity, envelope, prior, taskOverride) {
187
+ // 防御性 sender 一致性(fail-closed):链上证据必须归属当前 sender——幂等
188
+ // 主键是 (sender_identity, message_id),他人消息的证据不得被当作自己的。
189
+ // 调用点已按 sender 过滤;此处兜底。
190
+ if (prior.event.identity.sender_identity !== senderIdentity) {
191
+ throw internalServerError();
192
+ }
193
+ if (prior.event.wire_digest !== envelope.digest) {
194
+ throw protocolError("idempotency_conflict", `message_id ${envelope.message_id} already processed with a different digest (ledger evidence, §20.3)`);
195
+ }
196
+ // taskOverride:commit 失败恢复路径传入本回合完整 task(含 message);
197
+ // ledger 守卫/duplicate 恢复路径无内存 task,按事件 remote_task_id 还原最小 task。
198
+ const task = taskOverride ?? this.taskFromLedgerEvent(prior.event);
199
+ if (task === null) {
200
+ throw internalServerError();
201
+ }
202
+ try {
203
+ this.idempotency.commit({
204
+ sender_identity: senderIdentity,
205
+ message_id: envelope.message_id,
206
+ digest: envelope.digest,
207
+ negotiation_id: envelope.negotiation_id,
208
+ outcome: { kind: "ok", result: { task } },
209
+ ledger_event_id: prior.event.event_id,
210
+ ledger_event_digest: prior.event.event_digest,
211
+ });
212
+ }
213
+ catch (commitErr) {
214
+ this.logError("idempotency commit failed during ledger recovery", commitErr);
215
+ }
216
+ return { task, ledgerEvent: prior.event };
217
+ }
161
218
  /** message/send 入站处理(限流 → 校验 → 幂等 → handler → Ledger → 幂等 commit)。 */
162
219
  async sendMessage(input, caller) {
163
220
  // 惰性清理(评审项 L2):negotiation 幂等文件的 sweep 此前无调用方,
@@ -215,6 +272,15 @@ export class InboundPipeline {
215
272
  if (decision.status === "conflict") {
216
273
  throw protocolError("idempotency_conflict", `message_id ${envelope.message_id} already processed with a different digest (replay conflict, §20.3)`);
217
274
  }
275
+ // 审查 P1-05:幂等索引无记录但 Ledger 已落账同 (sender, message_id)(commit
276
+ // 失败 / append 与 commit 之间崩溃的窗口)→ 以 Ledger 为持久事实恢复,
277
+ // handler 不重复执行(至多一次)。**按 sender 过滤**:幂等主键是
278
+ // (sender_identity, message_id)(§20),不同 sender 用同 message_id 是
279
+ // 独立消息(sender 隔离),不得被他人消息的证据短路。
280
+ const priorOnLedger = this.ledger.findByMessageId(envelope.message_id);
281
+ if (priorOnLedger !== null && priorOnLedger.event.identity.sender_identity === senderIdentity) {
282
+ return this.recoverFromLedgerEvidence(senderIdentity, envelope, priorOnLedger);
283
+ }
218
284
  // 6. 路由给 NegotiationHandler。
219
285
  const taskId = newTaskId();
220
286
  const handlerCtx = {
@@ -275,6 +341,22 @@ export class InboundPipeline {
275
341
  // 内容策略违规:envelope 携带 ledger 不得记录的保留键(§28/§36-5)。
276
342
  throw schemaInvalid("envelope contains reserved content that must not be recorded");
277
343
  }
344
+ if (err instanceof LedgerError && err.code === "ledger_duplicate_content") {
345
+ // 审查 P2-E + P1-05:append 成功、幂等 commit 前崩溃的窗口。重试时
346
+ // 消息内容已落链(首次运行的处理结果),但幂等未 commit——此前走
347
+ // internalServerError 且永不 commit,消息永久卡死;且恢复路径用
348
+ // 本轮新 taskId 查 remote_task_id 恒 miss(事件携带首次的 taskId)。
349
+ // 统一走 ledger 恢复(digest 校验 + 按事件 remote_task_id 还原任务 +
350
+ // 补 commit):客户端拿到稳定响应,后续重试直接命中幂等短接或 ledger
351
+ // 守卫,handler 至多一次。真实恶意重放(同 message_id 异 digest)在
352
+ // digest 校验层 fail-closed(idempotency_conflict)。
353
+ const prior = this.ledger.findByMessageId(envelope.message_id);
354
+ if (prior === null) {
355
+ this.logError("ledger duplicate but prior event unrecoverable", err);
356
+ throw internalServerError();
357
+ }
358
+ return this.recoverFromLedgerEvidence(senderIdentity, envelope, prior);
359
+ }
278
360
  this.logError("ledger append failed", err);
279
361
  throw internalServerError();
280
362
  }
@@ -294,7 +376,13 @@ export class InboundPipeline {
294
376
  if (err instanceof IdempotencyConflictError) {
295
377
  throw protocolError("idempotency_conflict", `message_id ${envelope.message_id} already processed with a different digest`);
296
378
  }
297
- throw err;
379
+ // 审查 P1-05:commit 失败(非冲突,磁盘/瞬时)——message_received 已
380
+ // 落账。从 ledger 恢复并补 commit(best-effort),返回稳定响应而不是
381
+ // 抛错:否则客户端重试时幂等索引仍无记录 → handler 重复执行(双份
382
+ // agreement)。taskOverride 传本回合完整 task(含 message)。ledger
383
+ // 守卫兜底:即使客户端重试,也命中恢复路径。
384
+ this.logError("idempotency commit failed; recovering from ledger evidence", err);
385
+ return this.recoverFromLedgerEvidence(senderIdentity, envelope, { event: ledgerEvent }, task);
298
386
  }
299
387
  return { task, ledgerEvent };
300
388
  });