@danceiny/gotry 0.0.1-rc.9 → 0.2.0-rc.28

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 (533) hide show
  1. package/README.md +172 -219
  2. package/README.zh-CN.md +222 -0
  3. package/bin/gotry-backend.js +53 -0
  4. package/bin/gotry-booking-copilot.js +53 -0
  5. package/bin/gotry-bootstrap.js +1788 -0
  6. package/bin/gotry-inner.js +733 -83
  7. package/bin/gotry-process-liveness.d.ts +27 -0
  8. package/bin/gotry-process-liveness.js +97 -0
  9. package/bin/gotry-runtime-resolution.d.ts +27 -0
  10. package/bin/gotry-runtime-resolution.js +49 -0
  11. package/bin/gotry.js +1 -1
  12. package/client/client.js +203 -0
  13. package/cordis.gotry-patch.yml +80 -56
  14. package/data/airline-airports.json +39 -0
  15. package/data/stations-12306-verify.json +524 -0
  16. package/dist/capabilities/agent-reach-deep.js +45 -122
  17. package/dist/capabilities/agent-reach.js +101 -146
  18. package/dist/capabilities/anything.js +161 -94
  19. package/dist/capabilities/artifacts.js +370 -0
  20. package/dist/capabilities/channel-health.js +131 -0
  21. package/dist/capabilities/channel-registry.js +256 -0
  22. package/dist/capabilities/doctor.js +553 -0
  23. package/dist/capabilities/effect.js +394 -0
  24. package/dist/capabilities/external-event.js +149 -0
  25. package/dist/capabilities/fact-log.js +55 -0
  26. package/dist/capabilities/flyai-config.js +337 -0
  27. package/dist/capabilities/flyai.js +947 -110
  28. package/dist/capabilities/fx-contract.js +293 -0
  29. package/dist/capabilities/geo-atlas.js +246 -0
  30. package/dist/capabilities/ground-transfer.js +676 -0
  31. package/dist/capabilities/hbcli.js +260 -123
  32. package/dist/capabilities/hotelbyte-transaction.js +194 -0
  33. package/dist/capabilities/incident-log.js +131 -61
  34. package/dist/capabilities/itinerary-artifact.js +190 -0
  35. package/dist/capabilities/itinerary-deck-artifact.js +194 -0
  36. package/dist/capabilities/itinerary-deck-export.js +339 -0
  37. package/dist/capabilities/lavish-local.js +924 -0
  38. package/dist/capabilities/model-override.js +38 -0
  39. package/dist/capabilities/opensky.js +54 -43
  40. package/dist/capabilities/provider-detail-sanitize.js +64 -0
  41. package/dist/capabilities/resilience.js +191 -0
  42. package/dist/capabilities/route-provider-conformance.js +341 -0
  43. package/dist/capabilities/session/action-cache.js +50 -44
  44. package/dist/capabilities/session/adapters/ctrip-flight.js +120 -62
  45. package/dist/capabilities/session/adapters/ctrip-hotel.js +222 -0
  46. package/dist/capabilities/session/adapters/dida-portal.js +274 -0
  47. package/dist/capabilities/session/adapters/meituan-local.js +35 -54
  48. package/dist/capabilities/session/adapters/rail-12306.js +342 -0
  49. package/dist/capabilities/session/benchmark.js +189 -0
  50. package/dist/capabilities/session/bridge-ledger.js +224 -0
  51. package/dist/capabilities/session/extension-bridge.js +636 -0
  52. package/dist/capabilities/session/extension-channel.js +109 -0
  53. package/dist/capabilities/session/extension-distribution.js +230 -0
  54. package/dist/capabilities/session/extract.js +31 -21
  55. package/dist/capabilities/session/golden-score.js +114 -0
  56. package/dist/capabilities/session/health-watch.js +215 -0
  57. package/dist/capabilities/session/read-guard.js +75 -24
  58. package/dist/capabilities/session/static-flight-golden.js +150 -0
  59. package/dist/capabilities/session/transport.js +97 -83
  60. package/dist/capabilities/session/wizard.js +117 -0
  61. package/dist/capabilities/session-consent.js +178 -0
  62. package/dist/capabilities/session-login.js +170 -0
  63. package/dist/capabilities/session-search.js +635 -44
  64. package/dist/capabilities/spawn-bounded.js +203 -0
  65. package/dist/capabilities/sponsor-plugin.js +341 -0
  66. package/dist/capabilities/visa-policy.js +140 -0
  67. package/dist/capabilities/weather.js +243 -138
  68. package/dist/data/session-golden-20.json +25 -0
  69. package/dist/data/sf-golden-manifest.json +103 -0
  70. package/dist/data/sf-static-routes.json +91 -0
  71. package/dist/scripts/action-cache-tests.js +24 -59
  72. package/dist/scripts/agent-planning-turn-deadline-e2e.js +242 -0
  73. package/dist/scripts/agent-planning-turn-deadline-tests.js +185 -0
  74. package/dist/scripts/agent-reach-deep-tests.js +30 -40
  75. package/dist/scripts/agent-reach-error-tests.js +354 -0
  76. package/dist/scripts/agent-reach-tests.js +26 -18
  77. package/dist/scripts/agent-reach-wrapper-tests.js +50 -50
  78. package/dist/scripts/anything-path-measure-tests.js +133 -0
  79. package/dist/scripts/anything-path-measure.js +150 -0
  80. package/dist/scripts/anything-tests.js +250 -60
  81. package/dist/scripts/artifact-client-contract-tests.js +220 -0
  82. package/dist/scripts/artifacts-capability-tests.js +727 -0
  83. package/dist/scripts/async-collect.js +50 -11
  84. package/dist/scripts/benchmark-environment-bridge-e2e.js +741 -0
  85. package/dist/scripts/benchmark-environment-bridge-tests.js +1452 -0
  86. package/dist/scripts/booking-copilot-availability-ledger-binding-tests.js +126 -0
  87. package/dist/scripts/booking-copilot-availability-policy-tests.js +265 -0
  88. package/dist/scripts/booking-copilot-bin-proof-tests.js +66 -0
  89. package/dist/scripts/booking-copilot-cleanup-proof-helper.js +76 -0
  90. package/dist/scripts/booking-copilot-crossrepo-fixture-server.js +144 -0
  91. package/dist/scripts/booking-copilot-dsh-core-proof-tests.js +424 -0
  92. package/dist/scripts/booking-copilot-dsh-planner-proof-tests.js +2839 -0
  93. package/dist/scripts/booking-copilot-dsh-plugin-proof-tests.js +309 -0
  94. package/dist/scripts/booking-copilot-dsh-readiness-proof.js +238 -0
  95. package/dist/scripts/booking-copilot-dsh-warmer-proof.js +126 -0
  96. package/dist/scripts/booking-copilot-event-sequence-concurrency-proof-tests.js +156 -0
  97. package/dist/scripts/booking-copilot-gap-code-contract-proof-tests.js +70 -0
  98. package/dist/scripts/booking-copilot-intent-proof-tests.js +422 -0
  99. package/dist/scripts/booking-copilot-operation-ledger-concurrency-proof-tests.js +184 -0
  100. package/dist/scripts/booking-copilot-planner-live-probe.js +95 -0
  101. package/dist/scripts/booking-copilot-proof-runtime.js +42 -0
  102. package/dist/scripts/booking-copilot-receipt-ledger-concurrency-proof-tests.js +210 -0
  103. package/dist/scripts/booking-copilot-runtime-proof-tests.js +2349 -0
  104. package/dist/scripts/booking-copilot-server-proof-tests.js +784 -0
  105. package/dist/scripts/booking-copilot-startup-proof-tests.js +94 -0
  106. package/dist/scripts/booking-executor-tests.js +80 -0
  107. package/dist/scripts/booking-recovery-chain-tests.js +182 -0
  108. package/dist/scripts/booking-saga-tests.js +125 -0
  109. package/dist/scripts/booking-surface-contract-proof-tests.js +212 -0
  110. package/dist/scripts/bootstrap-tests.js +1549 -0
  111. package/dist/scripts/bridge-events-tests.js +239 -0
  112. package/dist/scripts/bridge-ledger-tests.js +428 -0
  113. package/dist/scripts/build-changelog.js +238 -0
  114. package/dist/scripts/build-metrics-report.js +331 -0
  115. package/dist/scripts/changelog-tests.js +118 -0
  116. package/dist/scripts/channel-probe-tests.js +103 -0
  117. package/dist/scripts/channel-probe.js +169 -0
  118. package/dist/scripts/channel-registry-tests.js +208 -0
  119. package/dist/scripts/city-scenario-tier-tests.js +234 -0
  120. package/dist/scripts/companion-tests.js +25 -70
  121. package/dist/scripts/dida-cookie-probe.js +87 -0
  122. package/dist/scripts/dida-runner-stop-tests.js +311 -0
  123. package/dist/scripts/dida-sw-probe.js +114 -0
  124. package/dist/scripts/diff-test.js +17 -12
  125. package/dist/scripts/doctor-tests.js +600 -0
  126. package/dist/scripts/drill-multiuser-ledger-tests.js +1076 -0
  127. package/dist/scripts/drill-sdk-descendant-cleanup-tests.js +606 -0
  128. package/dist/scripts/drill-w2a-sensor-tests.js +788 -0
  129. package/dist/scripts/dsh-artifact-e2e.js +279 -0
  130. package/dist/scripts/dsh-artifact-web-e2e.js +675 -0
  131. package/dist/scripts/dsh-http-proxy-sse-proof.js +90 -0
  132. package/dist/scripts/dsh-llm-tests.js +437 -0
  133. package/dist/scripts/dsh-runtime-closure-tests.js +182 -0
  134. package/dist/scripts/dsh-runtime-closure.js +162 -0
  135. package/dist/scripts/dsh-session-v3-migration-proof.js +109 -0
  136. package/dist/scripts/dsh-subprocess-local-proof.js +150 -0
  137. package/dist/scripts/dsh-target-closure-proof.js +178 -0
  138. package/dist/scripts/effect-tests.js +539 -0
  139. package/dist/scripts/engine-run.js +1 -3
  140. package/dist/scripts/engine-tests.js +16 -10
  141. package/dist/scripts/evaluation-cadence-tests.js +174 -0
  142. package/dist/scripts/evaluation-contract-tests.js +268 -0
  143. package/dist/scripts/extension-distribution-cli.js +39 -0
  144. package/dist/scripts/extension-distribution-tests.js +443 -0
  145. package/dist/scripts/extension-tests.js +988 -0
  146. package/dist/scripts/external-event-tests.js +350 -0
  147. package/dist/scripts/fact-gate-tests.js +869 -0
  148. package/dist/scripts/fixtures/extension-bridge-unref-child.mjs +21 -0
  149. package/dist/scripts/flight-hotel-anchor-363-registered-e2e.js +169 -0
  150. package/dist/scripts/flight-malformed-tests.js +159 -0
  151. package/dist/scripts/flyai-setup-tests.js +228 -0
  152. package/dist/scripts/flyai-setup-tool-tests.js +54 -0
  153. package/dist/scripts/flyai-tests.js +692 -0
  154. package/dist/scripts/flyai-tool-registration-contract-tests.js +91 -0
  155. package/dist/scripts/fx-contract-tests.js +201 -0
  156. package/dist/scripts/g5-guard-tests.js +150 -0
  157. package/dist/scripts/g5-guard.js +193 -0
  158. package/dist/scripts/gen-lunar-anchors.js +106 -0
  159. package/dist/scripts/geo-atlas-tests.js +283 -0
  160. package/dist/scripts/gotry-backend-kernel-tests.js +206 -0
  161. package/dist/scripts/gotry-try-demo-tests.js +79 -0
  162. package/dist/scripts/gotry-try-demo.js +49 -0
  163. package/dist/scripts/ground-transfer-tests.js +956 -0
  164. package/dist/scripts/hbcli-e2e-tests.js +159 -0
  165. package/dist/scripts/hbcli-live-optin-tests.js +96 -0
  166. package/dist/scripts/hbcli-release-contract-tests.js +122 -0
  167. package/dist/scripts/hbcli-tests.js +121 -69
  168. package/dist/scripts/health-watch-cli.js +73 -0
  169. package/dist/scripts/hotel-date-gate-tests.js +496 -0
  170. package/dist/scripts/hotelbyte-reconcile-tests.js +141 -0
  171. package/dist/scripts/hotelbyte-spawn-e2e-tests.js +373 -0
  172. package/dist/scripts/i18n-tests.js +41 -0
  173. package/dist/scripts/incident-tests.js +281 -87
  174. package/dist/scripts/issue-194-job-id-guard-tests.js +106 -0
  175. package/dist/scripts/issue-233-cancel-refund-commission-tests.js +392 -0
  176. package/dist/scripts/issue-271-liveness-tests.js +569 -0
  177. package/dist/scripts/issue-289-model-retry-real-tests.js +296 -0
  178. package/dist/scripts/issue-289-model-retry-tests.js +441 -0
  179. package/dist/scripts/issue-289-web-retry-e2e.js +630 -0
  180. package/dist/scripts/issue-338-home-city-e2e.js +577 -0
  181. package/dist/scripts/issue343-real-entry-e2e.js +160 -0
  182. package/dist/scripts/issue436-persisted-routing-e2e.js +247 -0
  183. package/dist/scripts/itinerary-artifact-tests.js +368 -0
  184. package/dist/scripts/itinerary-deck-artifact-tests.js +416 -0
  185. package/dist/scripts/itinerary-deck-export-tests.js +552 -0
  186. package/dist/scripts/itinerary-deck-tests.js +435 -0
  187. package/dist/scripts/itinerary-html-tests.js +426 -0
  188. package/dist/scripts/journey-tests.js +22 -27
  189. package/dist/scripts/kernel-manifest-evidence.js +109 -0
  190. package/dist/scripts/kernel-manifest-gate.js +126 -0
  191. package/dist/scripts/kernel-manifest-tests.js +212 -0
  192. package/dist/scripts/kernel-manifest-trace-entry.js +7 -0
  193. package/dist/scripts/kernel-manifest-trace-hook.mjs +28 -0
  194. package/dist/scripts/kernel-manifest.js +369 -0
  195. package/dist/scripts/lavish-local-tests.js +1226 -0
  196. package/dist/scripts/lavish-product-tools-tests.js +537 -0
  197. package/dist/scripts/ledger-repair-apply-tests.js +316 -0
  198. package/dist/scripts/ledger-repair-plan-tests.js +375 -0
  199. package/dist/scripts/ledger-tests.js +382 -246
  200. package/dist/scripts/ledger-workflow-crash.js +10 -20
  201. package/dist/scripts/m3-cohort-tests.js +714 -0
  202. package/dist/scripts/m3-cohort.js +310 -0
  203. package/dist/scripts/managed-dsh-cleanup-diagnostic-proof.js +184 -0
  204. package/dist/scripts/managed-dsh-close-failure-proof.js +172 -0
  205. package/dist/scripts/managed-dsh-run-port-proof.js +153 -0
  206. package/dist/scripts/managed-dsh-terminal-proof.js +252 -0
  207. package/dist/scripts/map-tools-vendor-package-proof.js +365 -0
  208. package/dist/scripts/memory-capture-tests.js +242 -61
  209. package/dist/scripts/memory-decay-tests.js +18 -52
  210. package/dist/scripts/memory-lifecycle-tests.js +657 -0
  211. package/dist/scripts/memory-lifecycle.js +196 -0
  212. package/dist/scripts/memory-metrics.js +24 -12
  213. package/dist/scripts/memory-value-report.js +631 -0
  214. package/dist/scripts/memory-value-tests.js +328 -0
  215. package/dist/scripts/metrics-report-tests.js +151 -0
  216. package/dist/scripts/model-override-e2e.js +137 -0
  217. package/dist/scripts/nightly-evidence-tests.js +203 -0
  218. package/dist/scripts/nightly-evidence.js +303 -0
  219. package/dist/scripts/nudge-digest.js +39 -28
  220. package/dist/scripts/observability-tests.js +381 -0
  221. package/dist/scripts/onboarding-tests.js +161 -0
  222. package/dist/scripts/opensky-check.js +18 -13
  223. package/dist/scripts/opensky-tests.js +28 -28
  224. package/dist/scripts/outcome-projection-tests.js +427 -0
  225. package/dist/scripts/persona-sim-tests.js +603 -0
  226. package/dist/scripts/persona-sim.js +1081 -0
  227. package/dist/scripts/persona-surface-guard-tests.js +49 -0
  228. package/dist/scripts/pnpm-dsh-closure-proof.js +17 -0
  229. package/dist/scripts/policy-anchor-359-registered-e2e.js +214 -0
  230. package/dist/scripts/price-drift-tests.js +340 -0
  231. package/dist/scripts/price-drift-watch.js +447 -0
  232. package/dist/scripts/probe-poi-tests.js +53 -45
  233. package/dist/scripts/product-metrics.js +483 -0
  234. package/dist/scripts/publish-preverify.js +110 -0
  235. package/dist/scripts/realtime-pricing-tests.js +76 -0
  236. package/dist/scripts/recall-tests.js +513 -0
  237. package/dist/scripts/replay-async.js +22 -18
  238. package/dist/scripts/replay-real.js +18 -18
  239. package/dist/scripts/replay.js +54 -82
  240. package/dist/scripts/route-provider-conformance-tests.js +391 -0
  241. package/dist/scripts/session-attach-diagnose.js +20 -20
  242. package/dist/scripts/session-attach-poc.js +34 -37
  243. package/dist/scripts/session-benchmark.js +180 -0
  244. package/dist/scripts/session-dida-live-e2e.js +199 -0
  245. package/dist/scripts/session-extract-tests.js +14 -35
  246. package/dist/scripts/session-link-tests.js +478 -0
  247. package/dist/scripts/session-login.js +27 -46
  248. package/dist/scripts/session-tests.js +796 -96
  249. package/dist/scripts/session-zone-crash.js +49 -0
  250. package/dist/scripts/session-zone-ledger-tests.js +432 -0
  251. package/dist/scripts/session-zone-observation-tests.js +492 -0
  252. package/dist/scripts/session-zone-observe.js +135 -0
  253. package/dist/scripts/session-zone-wiring-tests.js +566 -0
  254. package/dist/scripts/session-zones-tests.js +374 -0
  255. package/dist/scripts/sf-live-benchmark.js +367 -0
  256. package/dist/scripts/sf-live-challenge-stop-tests.js +453 -0
  257. package/dist/scripts/sf-live-cli-tests.js +92 -0
  258. package/dist/scripts/sf-live-options.js +46 -0
  259. package/dist/scripts/sf-manifest-tests.js +30 -0
  260. package/dist/scripts/sf-manifest.js +33 -0
  261. package/dist/scripts/sf-soft-score-tests.js +67 -0
  262. package/dist/scripts/sf-summary-tests.js +324 -0
  263. package/dist/scripts/sf-summary.js +525 -0
  264. package/dist/scripts/share-tests.js +432 -0
  265. package/dist/scripts/skeleton-check.js +16 -14
  266. package/dist/scripts/skeleton-integration-test.js +28 -11
  267. package/dist/scripts/skills-contract-tests.js +51 -46
  268. package/dist/scripts/smoke-session-gate-tests.js +21 -0
  269. package/dist/scripts/smoke.js +690 -246
  270. package/dist/scripts/spawn-bounded-abort-tests.js +244 -0
  271. package/dist/scripts/sponsor-reuse-tests.js +262 -0
  272. package/dist/scripts/state-cli-tests.js +226 -101
  273. package/dist/scripts/state-cli.js +565 -198
  274. package/dist/scripts/state-repair-cli.js +66 -0
  275. package/dist/scripts/state-repair-tests.js +140 -0
  276. package/dist/scripts/static-golden-tests.js +165 -0
  277. package/dist/scripts/time-eval-tests.js +212 -192
  278. package/dist/scripts/travel-timeline-tests.js +29 -93
  279. package/dist/scripts/turn-handoff-collect-tests.js +169 -0
  280. package/dist/scripts/turn-handoff-collect.js +161 -0
  281. package/dist/scripts/turn-policy-tests.js +55 -0
  282. package/dist/scripts/typed-contract-canary.js +176 -0
  283. package/dist/scripts/tz-resolver-sanity.js +50 -0
  284. package/dist/scripts/tz-resolver-tests.js +584 -0
  285. package/dist/scripts/unified-tests.js +60 -20
  286. package/dist/scripts/visa-policy-tests.js +62 -0
  287. package/dist/scripts/weather-tests.js +276 -41
  288. package/dist/scripts/wish-channel-gate-tests.js +54 -0
  289. package/dist/scripts/write-gate-tests.js +522 -0
  290. package/dist/scripts/z3-lifecycle-fault-tests.js +188 -0
  291. package/dist/scripts/z3-lifecycle-tests.js +170 -0
  292. package/dist/scripts/z3-race-repeat-tests.js +39 -0
  293. package/dist/scripts/z3-race-tests.js +46 -0
  294. package/dist/src/artifact-gate.js +829 -0
  295. package/dist/src/backend/kernel.js +91 -0
  296. package/dist/src/backend/modules/booking-copilot.js +92 -0
  297. package/dist/src/backend/modules/booking-executor.js +124 -0
  298. package/dist/src/backend/modules/session-search.js +551 -0
  299. package/dist/src/benchmark-agent-conformance.js +578 -0
  300. package/dist/src/benchmark-environment-bridge.js +515 -0
  301. package/dist/src/benchmark-headless-child-diagnostics.js +166 -0
  302. package/dist/src/benchmark-tool-isolation.js +151 -0
  303. package/dist/src/bookable-facts.js +533 -0
  304. package/dist/src/booking-saga.js +97 -0
  305. package/dist/src/booking-surface/availability-policy.js +697 -0
  306. package/dist/src/booking-surface/booking-intent.js +43 -0
  307. package/dist/src/booking-surface/cancel-refund-commission.js +379 -0
  308. package/dist/src/booking-surface/canonical-schema.js +116 -0
  309. package/dist/src/booking-surface/contracts.js +75 -0
  310. package/dist/src/booking-surface/dsh-planner.js +1854 -0
  311. package/dist/src/booking-surface/dsh-plugin.js +378 -0
  312. package/dist/src/booking-surface/dsh-worker.js +98 -0
  313. package/dist/src/booking-surface/error-codes.js +231 -0
  314. package/dist/src/booking-surface/index.js +9 -0
  315. package/dist/src/booking-surface/managed-dsh-cleanup-diagnostic.js +97 -0
  316. package/dist/src/booking-surface/managed-dsh-run-port.js +244 -0
  317. package/dist/src/booking-surface/profile.js +24 -0
  318. package/dist/src/booking-surface/recovery-chain.js +367 -0
  319. package/dist/src/booking-surface/runtime.js +1968 -0
  320. package/dist/src/booking-surface/server.js +674 -0
  321. package/dist/src/booking-surface/startup.js +168 -0
  322. package/dist/src/booking-surface/validation.js +261 -0
  323. package/dist/src/bridge.js +20 -13
  324. package/dist/src/city-scenario-tier.js +378 -0
  325. package/dist/src/companions.js +48 -74
  326. package/dist/src/contracts.js +21 -43
  327. package/dist/src/dsh-llm.js +171 -115
  328. package/dist/src/engine.js +276 -193
  329. package/dist/src/evaluation-cadence.js +97 -0
  330. package/dist/src/evaluation-contracts.js +283 -0
  331. package/dist/src/flight-pack-adapter.js +54 -0
  332. package/dist/src/flight-pack-contract.js +2 -0
  333. package/dist/src/flyai-setup-tool.js +70 -0
  334. package/dist/src/gotry-backend.js +125 -0
  335. package/dist/src/hotel-date-gate.js +118 -0
  336. package/dist/src/i18n.js +88 -0
  337. package/dist/src/index.js +2385 -881
  338. package/dist/src/itinerary-deck.js +139 -0
  339. package/dist/src/itinerary-doc-shared.js +661 -0
  340. package/dist/src/itinerary-html.js +131 -0
  341. package/dist/src/journey.js +155 -108
  342. package/dist/src/lavish-tools.js +400 -0
  343. package/dist/src/ledger-repair-apply.js +538 -0
  344. package/dist/src/ledger-repair-plan.js +463 -0
  345. package/dist/src/loop.js +331 -161
  346. package/dist/src/m3-cohort.js +1577 -0
  347. package/dist/src/memory-capture.js +180 -32
  348. package/dist/src/memory-decay.js +30 -14
  349. package/dist/src/memory-lifecycle.js +1310 -0
  350. package/dist/src/memory-utility.js +27 -40
  351. package/dist/src/mock-llm.js +36 -61
  352. package/dist/src/model.js +81 -36
  353. package/dist/src/outcome-projection.js +746 -0
  354. package/dist/src/realtime-pricing.js +103 -0
  355. package/dist/src/recall/card.js +74 -0
  356. package/dist/src/recall/evaluator.js +140 -0
  357. package/dist/src/recall/integration.js +17 -0
  358. package/dist/src/recall/tick.js +166 -0
  359. package/dist/src/session-link/plan-it-action.js +48 -0
  360. package/dist/src/session-link/session-link.js +248 -0
  361. package/dist/src/session-zone-ledger.js +312 -0
  362. package/dist/src/session-zone-observation.js +354 -0
  363. package/dist/src/session-zone-wiring.js +658 -0
  364. package/dist/src/session-zones.js +510 -0
  365. package/dist/src/share/adapters.js +51 -0
  366. package/dist/src/share/share-consent.js +76 -0
  367. package/dist/src/share/share-deck.js +58 -0
  368. package/dist/src/share/share-token.js +146 -0
  369. package/dist/src/slot-spec.js +84 -106
  370. package/dist/src/state-ledger.js +696 -524
  371. package/dist/src/state-repair.js +299 -0
  372. package/dist/src/subagent-job-id-guard.js +58 -0
  373. package/dist/src/time-anchor.js +231 -33
  374. package/dist/src/tool-packet.js +20 -8
  375. package/dist/src/travel-slots.js +58 -35
  376. package/dist/src/travel-timeline.js +44 -63
  377. package/dist/src/turn-deadline.js +287 -0
  378. package/dist/src/turn-policy.js +118 -0
  379. package/dist/src/tz-resolver.js +143 -0
  380. package/dist/src/unified.js +600 -360
  381. package/dist/src/wish-pool.js +42 -12
  382. package/dist/src/write-gate.js +495 -0
  383. package/dist/src/z3-shared.js +284 -0
  384. package/extension/README.md +21 -0
  385. package/extension/README.zh-CN.md +21 -0
  386. package/extension/background.js +463 -0
  387. package/extension/content-bridge.js +270 -0
  388. package/extension/content-main.js +111 -0
  389. package/extension/manifest.json +60 -0
  390. package/package.json +407 -14
  391. package/schemas/booking.intent.schema.json +193 -0
  392. package/schemas/booking.surface.schema.json +2622 -0
  393. package/ts/capabilities/agent-reach-deep.ts +114 -0
  394. package/ts/capabilities/agent-reach.ts +198 -0
  395. package/ts/capabilities/anything.ts +282 -0
  396. package/ts/capabilities/artifacts.ts +428 -0
  397. package/ts/capabilities/fact-log.ts +54 -0
  398. package/ts/capabilities/flyai-config.ts +388 -0
  399. package/ts/capabilities/flyai.ts +1274 -0
  400. package/ts/capabilities/hbcli.ts +253 -71
  401. package/ts/capabilities/incident-log.ts +88 -59
  402. package/ts/capabilities/itinerary-artifact.ts +214 -0
  403. package/ts/capabilities/itinerary-deck-artifact.ts +218 -0
  404. package/ts/capabilities/itinerary-deck-export.ts +378 -0
  405. package/ts/capabilities/opensky.ts +121 -0
  406. package/ts/capabilities/session/action-cache.ts +148 -0
  407. package/ts/capabilities/session/adapters/ctrip-flight.ts +181 -0
  408. package/ts/capabilities/session/adapters/ctrip-hotel.ts +238 -0
  409. package/ts/capabilities/session/adapters/dida-portal.ts +338 -0
  410. package/ts/capabilities/session/adapters/meituan-local.ts +70 -0
  411. package/ts/capabilities/session/adapters/rail-12306.ts +392 -0
  412. package/ts/capabilities/session/benchmark.ts +276 -0
  413. package/ts/capabilities/session/bridge-ledger.ts +333 -0
  414. package/ts/capabilities/session/extension-bridge.ts +794 -0
  415. package/ts/capabilities/session/extension-channel.ts +144 -0
  416. package/ts/capabilities/session/extension-distribution.ts +266 -0
  417. package/ts/capabilities/session/extract.ts +54 -0
  418. package/ts/capabilities/session/golden-score.ts +139 -0
  419. package/ts/capabilities/session/health-watch.ts +264 -0
  420. package/ts/capabilities/session/read-guard.ts +141 -0
  421. package/ts/capabilities/session/static-flight-golden.ts +209 -0
  422. package/ts/capabilities/session/transport.ts +146 -0
  423. package/ts/capabilities/session/wizard.ts +140 -0
  424. package/ts/capabilities/session-consent.ts +211 -0
  425. package/ts/capabilities/session-login.ts +208 -0
  426. package/ts/capabilities/session-search.ts +893 -0
  427. package/ts/capabilities/weather.ts +330 -0
  428. package/ts/dsh-runtime/vendor/README.md +68 -0
  429. package/ts/dsh-runtime/vendor/dsh-map-tools/LICENSE +21 -0
  430. package/ts/dsh-runtime/vendor/dsh-map-tools/README.en.md +405 -0
  431. package/ts/dsh-runtime/vendor/dsh-map-tools/README.md +404 -0
  432. package/ts/dsh-runtime/vendor/dsh-map-tools/client/client.js +1584 -0
  433. package/ts/dsh-runtime/vendor/dsh-map-tools/cordis.patch.yml +5 -0
  434. package/ts/dsh-runtime/vendor/dsh-map-tools/icon.svg +5 -0
  435. package/ts/dsh-runtime/vendor/dsh-map-tools/lib/clients/amap.js +595 -0
  436. package/ts/dsh-runtime/vendor/dsh-map-tools/lib/clients/nominatim.js +63 -0
  437. package/ts/dsh-runtime/vendor/dsh-map-tools/lib/clients/osrm.js +58 -0
  438. package/ts/dsh-runtime/vendor/dsh-map-tools/lib/clients/photon.js +55 -0
  439. package/ts/dsh-runtime/vendor/dsh-map-tools/lib/config-file.js +87 -0
  440. package/ts/dsh-runtime/vendor/dsh-map-tools/lib/config-route.js +131 -0
  441. package/ts/dsh-runtime/vendor/dsh-map-tools/lib/config.js +16 -0
  442. package/ts/dsh-runtime/vendor/dsh-map-tools/lib/geo.js +232 -0
  443. package/ts/dsh-runtime/vendor/dsh-map-tools/lib/index.js +120 -0
  444. package/ts/dsh-runtime/vendor/dsh-map-tools/lib/settings-ns.js +40 -0
  445. package/ts/dsh-runtime/vendor/dsh-map-tools/lib/staticmap-route.js +115 -0
  446. package/ts/dsh-runtime/vendor/dsh-map-tools/lib/tools/geocode.js +127 -0
  447. package/ts/dsh-runtime/vendor/dsh-map-tools/lib/tools/poi.js +84 -0
  448. package/ts/dsh-runtime/vendor/dsh-map-tools/lib/tools/routes.js +267 -0
  449. package/ts/dsh-runtime/vendor/dsh-map-tools/lib/types/clients/amap.d.ts +90 -0
  450. package/ts/dsh-runtime/vendor/dsh-map-tools/lib/types/clients/nominatim.d.ts +17 -0
  451. package/ts/dsh-runtime/vendor/dsh-map-tools/lib/types/clients/osrm.d.ts +15 -0
  452. package/ts/dsh-runtime/vendor/dsh-map-tools/lib/types/clients/photon.d.ts +22 -0
  453. package/ts/dsh-runtime/vendor/dsh-map-tools/lib/types/config-file.d.ts +33 -0
  454. package/ts/dsh-runtime/vendor/dsh-map-tools/lib/types/config-route.d.ts +23 -0
  455. package/ts/dsh-runtime/vendor/dsh-map-tools/lib/types/config.d.ts +23 -0
  456. package/ts/dsh-runtime/vendor/dsh-map-tools/lib/types/geo.d.ts +61 -0
  457. package/ts/dsh-runtime/vendor/dsh-map-tools/lib/types/index.d.ts +18 -0
  458. package/ts/dsh-runtime/vendor/dsh-map-tools/lib/types/settings-ns.d.ts +14 -0
  459. package/ts/dsh-runtime/vendor/dsh-map-tools/lib/types/staticmap-route.d.ts +31 -0
  460. package/ts/dsh-runtime/vendor/dsh-map-tools/lib/types/tools/geocode.d.ts +11 -0
  461. package/ts/dsh-runtime/vendor/dsh-map-tools/lib/types/tools/poi.d.ts +9 -0
  462. package/ts/dsh-runtime/vendor/dsh-map-tools/lib/types/tools/routes.d.ts +75 -0
  463. package/ts/dsh-runtime/vendor/dsh-map-tools/lib/types/types.d.ts +68 -0
  464. package/ts/dsh-runtime/vendor/dsh-map-tools/lib/types.js +16 -0
  465. package/ts/dsh-runtime/vendor/dsh-map-tools/package.json +97 -0
  466. package/ts/package.json +293 -3
  467. package/ts/scripts/async-collect.ts +91 -0
  468. package/ts/scripts/map-tools-vendor-package-proof.ts +404 -0
  469. package/ts/scripts/skeleton-check.ts +1 -1
  470. package/ts/scripts/skeleton-integration-test.ts +23 -1
  471. package/ts/scripts/state-cli.ts +586 -0
  472. package/ts/scripts/turn-handoff-collect.ts +178 -0
  473. package/ts/src/artifact-gate.ts +991 -0
  474. package/ts/src/benchmark-agent-conformance.ts +619 -0
  475. package/ts/src/benchmark-environment-bridge.ts +538 -0
  476. package/ts/src/benchmark-headless-child-diagnostics.ts +184 -0
  477. package/ts/src/benchmark-tool-isolation.ts +166 -0
  478. package/ts/src/bookable-facts.ts +837 -0
  479. package/ts/src/booking-saga.ts +133 -0
  480. package/ts/src/booking-surface/availability-policy.ts +522 -0
  481. package/ts/src/booking-surface/booking-intent.ts +86 -0
  482. package/ts/src/booking-surface/cancel-refund-commission.ts +488 -0
  483. package/ts/src/booking-surface/canonical-schema.js +116 -0
  484. package/ts/src/booking-surface/contracts.ts +475 -0
  485. package/ts/src/booking-surface/dsh-planner.ts +1949 -0
  486. package/ts/src/booking-surface/dsh-plugin.js +378 -0
  487. package/ts/src/booking-surface/dsh-worker.ts +110 -0
  488. package/ts/src/booking-surface/error-codes.ts +241 -0
  489. package/ts/src/booking-surface/index.ts +9 -0
  490. package/ts/src/booking-surface/managed-dsh-cleanup-diagnostic.ts +151 -0
  491. package/ts/src/booking-surface/managed-dsh-run-port.ts +273 -0
  492. package/ts/src/booking-surface/profile.ts +42 -0
  493. package/ts/src/booking-surface/recovery-chain.ts +409 -0
  494. package/ts/src/booking-surface/runtime.ts +1793 -0
  495. package/ts/src/booking-surface/server.ts +733 -0
  496. package/ts/src/booking-surface/startup.ts +201 -0
  497. package/ts/src/booking-surface/validation.ts +217 -0
  498. package/ts/src/companions.ts +113 -0
  499. package/ts/src/contracts.ts +17 -3
  500. package/ts/src/dsh-llm.ts +152 -17
  501. package/ts/src/flyai-setup-tool.ts +77 -0
  502. package/ts/src/index.ts +2123 -200
  503. package/ts/src/itinerary-deck.ts +189 -0
  504. package/ts/src/itinerary-doc-shared.ts +741 -0
  505. package/ts/src/itinerary-html.ts +171 -0
  506. package/ts/src/loop.ts +234 -26
  507. package/ts/src/memory-capture.ts +283 -0
  508. package/ts/src/memory-decay.ts +55 -0
  509. package/ts/src/memory-utility.ts +70 -0
  510. package/ts/src/mock-llm.ts +4 -8
  511. package/ts/src/model.ts +88 -2
  512. package/ts/src/recall/card.ts +106 -0
  513. package/ts/src/recall/evaluator.ts +170 -0
  514. package/ts/src/recall/integration.ts +35 -0
  515. package/ts/src/recall/tick.ts +213 -0
  516. package/ts/src/session-link/plan-it-action.ts +78 -0
  517. package/ts/src/session-link/session-link.ts +275 -0
  518. package/ts/src/share/adapters.ts +93 -0
  519. package/ts/src/share/share-consent.ts +105 -0
  520. package/ts/src/share/share-deck.ts +85 -0
  521. package/ts/src/share/share-token.ts +166 -0
  522. package/ts/src/slot-spec.ts +172 -0
  523. package/ts/src/state-ledger.ts +1166 -0
  524. package/ts/src/subagent-job-id-guard.ts +72 -0
  525. package/ts/src/time-anchor.ts +338 -0
  526. package/ts/src/tool-packet.ts +32 -0
  527. package/ts/src/travel-slots.ts +219 -0
  528. package/ts/src/travel-timeline.ts +83 -0
  529. package/ts/src/turn-deadline.ts +366 -0
  530. package/ts/src/turn-policy.ts +154 -0
  531. package/ts/src/unified.ts +444 -105
  532. package/ts/src/wish-pool.ts +79 -0
  533. package/dist/scripts/session-attach-wait.js +0 -41
@@ -0,0 +1,341 @@
1
+ /**
2
+ * D-39 live-route provider CONFORMANCE contract v1 (issue #429 contract slice,
3
+ * SIMULATED-TRIGGER DRILL — default OFF, zero callers, trigger flag frozen false,
4
+ * provider registry frozen EMPTY).
5
+ *
6
+ * ⚠ Evidence boundary: this is the conformance GATE any future live-route adapter
7
+ * must pass, exercised here against a MOCK adapter only. #429's trigger is, per
8
+ * path, "a named product use case + the actual data provider and access boundary +
9
+ * reviewable authority/freshness/coverage evidence"; it has NOT fired for any path.
10
+ * No real routing provider is contacted (`consultRouteProvider` refuses before
11
+ * touching an adapter while the trigger is false), no dependency is added, and the
12
+ * accepted narrow path of #341 (explicit-coordinate destination driving estimate
13
+ * with static price evidence) is untouched. Nothing here claims provider
14
+ * availability or an M4/M5/M6 Exit.
15
+ *
16
+ * What it owns: the single admission gate `admitRouteFact` — a provider outcome
17
+ * becomes a route fact only if the provider's OWN claims (mode, evidence class,
18
+ * echoed origin/destination, freshness, fare authority) match the declared use
19
+ * case. Every mismatch is a typed refusal whose detail is sanitized, and a refusal
20
+ * always leaves the static fallback and its original price label intact.
21
+ *
22
+ * Frozen upstream constraints (READ-ONLY reuse):
23
+ * - docs/architecture.md D-39 + §10: each wider path needs its own named use case,
24
+ * source, freshness contract, access boundary and real-data proof; read-only
25
+ * routing authorizes no write path;
26
+ * - ts/capabilities/ground-transfer.ts (#341/#364/#382): the accepted narrow shape
27
+ * — per-direction isolation, host observation time (never a provider publication
28
+ * timestamp), `trafficStatus: 'not-live-route-estimate'`, and the static
29
+ * `priceCny` + `[静态包:估算]` label that a route fact never replaces;
30
+ * - ts/capabilities/fx-contract.ts (#344): the trigger-gated, frozen-empty
31
+ * registry seam and the "stale/miss/error never masquerades as current" rule.
32
+ *
33
+ * Layering: this module performs zero network, cache, timer, clock or filesystem
34
+ * work, and its ONLY import is the pure sibling sanitizer
35
+ * `provider-detail-sanitize.ts` (shared with the live ground-transfer path so one
36
+ * implementation serves both). It imports nothing from the kernel evaluate/solve
37
+ * layer (`src/model.ts`, `src/unified.ts`), and no product file imports it. Any
38
+ * future adapter's network/cache work stays on the capability side of that line;
39
+ * the focused suite asserts the import surface mechanically.
40
+ *
41
+ * Only the real trigger can supply: the provider identity and licence, actual
42
+ * coverage/freshness measurements, a separately authoritative fare source, and an
43
+ * authorized minimal real path recorded at an exact source SHA.
44
+ *
45
+ * @module capabilities/route-provider-conformance
46
+ */
47
+ import { FAULT_DETAIL_MAX_CHARS, faultDetailLeak, sanitizeFaultDetail } from './provider-detail-sanitize.js';
48
+ /** Re-exported so the conformance gate stays the single API surface for callers. */
49
+ export { FAULT_DETAIL_MAX_CHARS, faultDetailLeak, sanitizeFaultDetail };
50
+ export const ROUTE_PROVIDER_CONFORMANCE_SCHEMA = 'gotry_route_provider_conformance.v1';
51
+ /**
52
+ * D-39 wider-path trigger gate, frozen false. Each path (live traffic, transit,
53
+ * rail, fare, address resolution) is admitted independently; flipping this is a
54
+ * per-path founder decision with a named use case and a real provider.
55
+ */
56
+ export const D39_LIVE_ROUTE_TRIGGER_FIRED = false;
57
+ /** Transport modes. A provider may never relabel one as another, in either direction. */
58
+ export const ROUTE_MODES = ['driving', 'transit', 'rail', 'walking', 'cycling'];
59
+ /** Evidence classes, weakest first. A declared class must match EXACTLY. */
60
+ export const ROUTE_EVIDENCE_CLASSES = ['static_estimate', 'route_estimate', 'live_traffic'];
61
+ /** Access boundaries. A read-only routing admission never implies a write path. */
62
+ export const ROUTE_ACCESS_BOUNDARIES = ['read_only_public', 'licensed_read_only', 'supplier_transaction'];
63
+ /** Fault modes every candidate provider must be probed against before admission. */
64
+ export const ROUTE_PROVIDER_FAULT_MODES = [
65
+ 'unavailable',
66
+ 'stale',
67
+ 'mismatched_direction',
68
+ 'mode_relabel',
69
+ 'estimate_as_live_traffic',
70
+ 'challenge',
71
+ 'rate_limited',
72
+ 'partial_result',
73
+ ];
74
+ /** Conformance clauses. A future adapter is admissible only if ALL of them pass. */
75
+ export const ROUTE_CONFORMANCE_CLAUSES = [
76
+ /** the response must echo the requested origin/destination; the swapped pair is a different fact */
77
+ 'direction_binding',
78
+ /** the provider's own mode claim must equal the use case's mode */
79
+ 'mode_isolation',
80
+ /** the provider's own evidence class must equal the use case's (no escalation, no shortfall) */
81
+ 'evidence_class_isolation',
82
+ /** a provider outside the freshness contract is stale, never current */
83
+ 'freshness_contract',
84
+ /** every admitted fact names its source identity and access boundary */
85
+ 'source_identity',
86
+ /** every fault mode fails closed with a typed code — never a silent degrade */
87
+ 'fault_fail_closed',
88
+ /** a refusal leaves the static fallback minutes, price and original label untouched */
89
+ 'static_fallback_preserved',
90
+ /** a route provider is never a fare authority unless the use case declares a separate one */
91
+ 'fare_authority_separate',
92
+ /** fault details are sanitized: no provider response body, markup, cookie or token */
93
+ 'fault_detail_sanitized',
94
+ ];
95
+ function fail(code, detail) {
96
+ return { ok: false, code, detail };
97
+ }
98
+ function pass(value) {
99
+ return { ok: true, value };
100
+ }
101
+ /** Runtime provider registry, frozen EMPTY. A non-empty value is a founder decision. */
102
+ export const ADMITTED_LIVE_ROUTE_PROVIDERS = [];
103
+ // ---------------------------------------------------------------------------
104
+ // Detail sanitization: see ./provider-detail-sanitize.ts (shared with the live
105
+ // ground-transfer path; re-exported above so this gate stays the single API).
106
+ // ---------------------------------------------------------------------------
107
+ // ---------------------------------------------------------------------------
108
+ // The admission gate
109
+ // ---------------------------------------------------------------------------
110
+ function parseInstant(value, label) {
111
+ if (typeof value !== 'string' || value.trim() === '')
112
+ return fail('bad_ts', `${label} must be a non-empty ISO-8601 instant, got ${JSON.stringify(value)}`);
113
+ if (/^\d{4}-\d{2}-\d{2}$/.test(value.trim()))
114
+ return fail('bad_ts', `${label} must carry a full time-of-day (date-only '${value}' cannot be aged)`);
115
+ const ms = Date.parse(value);
116
+ if (!Number.isFinite(ms))
117
+ return fail('bad_ts', `${label} is not a parseable ISO-8601 instant: ${JSON.stringify(value)}`);
118
+ return pass(new Date(ms).toISOString());
119
+ }
120
+ /** Map a provider fault to its typed refusal code (closed, total mapping). */
121
+ const FAULT_CODE = {
122
+ unavailable: 'unavailable',
123
+ stale: 'stale',
124
+ mismatched_direction: 'direction_mismatch',
125
+ mode_relabel: 'mode_mismatch',
126
+ estimate_as_live_traffic: 'evidence_class_escalation',
127
+ challenge: 'challenge',
128
+ rate_limited: 'rate_limited',
129
+ partial_result: 'partial_result',
130
+ };
131
+ /**
132
+ * The single admission gate: a provider outcome becomes a route fact only if every
133
+ * declared claim matches the named use case. Each refusal is typed and sanitized;
134
+ * no refusal ever degrades into a weaker-but-accepted fact.
135
+ */
136
+ export function admitRouteFact(useCase, descriptor, request, outcome, now) {
137
+ if (typeof useCase?.id !== 'string' || useCase.id.trim() === '')
138
+ return fail('binding_incomplete', 'use case id is mandatory: a path is admitted per NAMED product use case, never globally');
139
+ if (!ROUTE_MODES.includes(useCase.mode))
140
+ return fail('closed_set', `use case mode must be one of [${ROUTE_MODES.join('/')}], got ${JSON.stringify(useCase.mode)}`);
141
+ if (!ROUTE_EVIDENCE_CLASSES.includes(useCase.evidence_class))
142
+ return fail('closed_set', `use case evidence_class must be one of [${ROUTE_EVIDENCE_CLASSES.join('/')}], got ${JSON.stringify(useCase.evidence_class)}`);
143
+ if (!ROUTE_ACCESS_BOUNDARIES.includes(useCase.access_boundary))
144
+ return fail('closed_set', `use case access_boundary must be one of [${ROUTE_ACCESS_BOUNDARIES.join('/')}]`);
145
+ if (!Number.isFinite(useCase.freshness_max_age_s) || useCase.freshness_max_age_s <= 0)
146
+ return fail('binding_incomplete', 'use case freshness_max_age_s must be a positive number of seconds (a path without a freshness contract is not admitted)');
147
+ if (typeof descriptor?.id !== 'string' || descriptor.id.trim() === '')
148
+ return fail('binding_incomplete', 'provider descriptor id is mandatory (source identity)');
149
+ if (typeof descriptor.legal_basis !== 'string' || descriptor.legal_basis.trim() === '')
150
+ return fail('binding_incomplete', `provider ${descriptor.id} carries no legal_basis — admission requires a stated licence / access boundary`);
151
+ if (typeof descriptor.source_sha !== 'string' || descriptor.source_sha.trim() === '')
152
+ return fail('binding_incomplete', `provider ${descriptor.id} carries no source_sha — D-39 requires the exact reviewed source revision`);
153
+ if (descriptor.access_boundary !== useCase.access_boundary) {
154
+ return fail('closed_set', `provider ${descriptor.id} access boundary '${descriptor.access_boundary}' does not match use case '${useCase.id}' boundary '${useCase.access_boundary}' — a read-only routing admission never widens into a transaction boundary`);
155
+ }
156
+ if (typeof request?.origin !== 'string' || request.origin.trim() === '' || typeof request?.destination !== 'string' || request.destination.trim() === '') {
157
+ return fail('binding_incomplete', 'request origin and destination are mandatory (direction binding has nothing to bind otherwise)');
158
+ }
159
+ if (request.mode !== useCase.mode) {
160
+ return fail('mode_mismatch', `request mode '${request.mode}' contradicts use case '${useCase.id}' mode '${useCase.mode}'`);
161
+ }
162
+ if (!outcome?.ok) {
163
+ if (!ROUTE_PROVIDER_FAULT_MODES.includes(outcome?.fault)) {
164
+ return fail('closed_set', `provider fault must be one of [${ROUTE_PROVIDER_FAULT_MODES.join('/')}], got ${JSON.stringify(outcome?.fault)} — an unclassified failure is not a degrade licence`);
165
+ }
166
+ return fail(FAULT_CODE[outcome.fault], `provider ${descriptor.id} fault '${outcome.fault}': ${sanitizeFaultDetail(outcome.detail)}`);
167
+ }
168
+ const response = outcome.response;
169
+ if (typeof response?.provider_id !== 'string' || response.provider_id.trim() === '')
170
+ return fail('binding_incomplete', 'response provider_id is mandatory (source identity per fact)');
171
+ if (response.provider_id !== descriptor.id) {
172
+ return fail('binding_incomplete', `response provider_id '${response.provider_id}' does not match the admitted descriptor '${descriptor.id}' — a fact may not be attributed to a provider that did not produce it`);
173
+ }
174
+ if (!ROUTE_MODES.includes(response.mode)) {
175
+ return fail('closed_set', `response mode must be one of [${ROUTE_MODES.join('/')}], got ${JSON.stringify(response.mode)} — a response without an explicit mode claim may not be labelled by the request`);
176
+ }
177
+ if (response.mode !== useCase.mode) {
178
+ return fail('mode_mismatch', `provider ${descriptor.id} returned mode '${response.mode}' for a '${useCase.mode}' use case — ${response.mode} must never be relabelled as ${useCase.mode} (nor the reverse)`);
179
+ }
180
+ if (!ROUTE_EVIDENCE_CLASSES.includes(response.evidence_class)) {
181
+ return fail('closed_set', `response evidence_class must be one of [${ROUTE_EVIDENCE_CLASSES.join('/')}], got ${JSON.stringify(response.evidence_class)}`);
182
+ }
183
+ if (response.evidence_class !== useCase.evidence_class) {
184
+ const providerRank = ROUTE_EVIDENCE_CLASSES.indexOf(response.evidence_class);
185
+ const useCaseRank = ROUTE_EVIDENCE_CLASSES.indexOf(useCase.evidence_class);
186
+ return providerRank > useCaseRank
187
+ ? fail('evidence_class_escalation', `provider ${descriptor.id} claims '${response.evidence_class}' for a '${useCase.evidence_class}' use case — an estimate must never be presented as ${response.evidence_class}`)
188
+ : fail('evidence_class_shortfall', `provider ${descriptor.id} delivered '${response.evidence_class}' for a '${useCase.evidence_class}' use case — a weaker class may not fill a stronger promise`);
189
+ }
190
+ if (response.echoed_origin !== request.origin || response.echoed_destination !== request.destination) {
191
+ return fail('direction_mismatch', `provider ${descriptor.id} routed ${response.echoed_origin}→${response.echoed_destination} but the ${request.direction} request was ${request.origin}→${request.destination} — direction binding is verified against the RESPONSE, not assumed from the request`);
192
+ }
193
+ const distance = response.distance_m;
194
+ const duration = response.duration_s;
195
+ if (typeof distance !== 'number' || !Number.isFinite(distance) || distance < 0
196
+ || typeof duration !== 'number' || !Number.isFinite(duration) || duration < 0
197
+ || (distance > 0 && duration === 0)) {
198
+ return fail('partial_result', `provider ${descriptor.id} returned an incomplete or self-contradictory route (distance_m=${String(distance)}, duration_s=${String(duration)}); a positive distance cannot be covered in zero time`);
199
+ }
200
+ const nowParsed = parseInstant(now, 'gate clock now');
201
+ if (!nowParsed.ok)
202
+ return nowParsed;
203
+ const observedAt = parseInstant(response.observed_at, 'response observed_at (host observation instant)');
204
+ if (!observedAt.ok)
205
+ return observedAt;
206
+ if (observedAt.value > nowParsed.value) {
207
+ return fail('bad_ts', `observed_at ${observedAt.value} postdates the gate clock ${nowParsed.value} — a provider publication timestamp is not a host observation instant`);
208
+ }
209
+ const ageS = (Date.parse(nowParsed.value) - Date.parse(observedAt.value)) / 1000;
210
+ if (ageS > useCase.freshness_max_age_s) {
211
+ return fail('stale', `observation is ${ageS}s old, beyond the '${useCase.id}' freshness contract of ${useCase.freshness_max_age_s}s — stale never masquerades as current`);
212
+ }
213
+ let fare = null;
214
+ if (response.fare !== undefined) {
215
+ if (useCase.fare_authority === 'none') {
216
+ return fail('fare_not_authoritative', `provider ${descriptor.id} offered a fare for use case '${useCase.id}' which declares no fare authority — the static price and its original label stand until a separately authoritative fare exists`);
217
+ }
218
+ const f = response.fare;
219
+ if (typeof f.amount !== 'string' || f.amount.trim() === '' || typeof f.currency !== 'string' || f.currency.trim() === '' || typeof f.authority !== 'string' || f.authority.trim() === '') {
220
+ return fail('binding_incomplete', 'an admitted fare needs amount, currency and a named authority');
221
+ }
222
+ if (f.authority === descriptor.id || f.authority === response.provider_id) {
223
+ return fail('fare_not_authoritative', `a route provider ('${descriptor.id}') is never its own fare authority — '${useCase.id}' requires a separately authoritative fare source`);
224
+ }
225
+ fare = { amount: f.amount, currency: f.currency, authority: f.authority };
226
+ }
227
+ return pass(Object.freeze({
228
+ schema: ROUTE_PROVIDER_CONFORMANCE_SCHEMA,
229
+ use_case_id: useCase.id,
230
+ direction: request.direction,
231
+ origin: request.origin,
232
+ destination: request.destination,
233
+ mode: useCase.mode,
234
+ evidence_class: useCase.evidence_class,
235
+ provider_id: descriptor.id,
236
+ access_boundary: descriptor.access_boundary,
237
+ source_sha: descriptor.source_sha,
238
+ distance_m: distance,
239
+ duration_s: duration,
240
+ duration_min: Math.round(duration / 60),
241
+ observed_at: observedAt.value,
242
+ age_s: ageS,
243
+ fare,
244
+ }));
245
+ }
246
+ /**
247
+ * The only entry point to a live route adapter. While `D39_LIVE_ROUTE_TRIGGER_FIRED`
248
+ * is false this refuses BEFORE touching the adapter, so zero routing providers are
249
+ * contacted (the fetch-spy zero-call proof in run-all §87).
250
+ */
251
+ export async function consultRouteProvider(adapter, useCase, request,
252
+ /** `now` is MANDATORY: this module reads no clock, so the caller injects one. */
253
+ options) {
254
+ const triggerFired = options?.triggerFired ?? D39_LIVE_ROUTE_TRIGGER_FIRED;
255
+ if (!triggerFired) {
256
+ return fail('trigger_deferred', `D-39 path trigger has not fired for use case '${String(useCase?.id)}' (#429: a named product use case + the actual provider and access boundary + reviewable authority/freshness/coverage evidence); zero routing providers contacted, static fallback stands`);
257
+ }
258
+ const registry = options?.registry ?? ADMITTED_LIVE_ROUTE_PROVIDERS;
259
+ if (!registry.some(d => d.id === adapter?.descriptor?.id)) {
260
+ return fail('provider_not_admitted', `provider '${String(adapter?.descriptor?.id)}' is not in the admitted registry (admitted: [${registry.map(d => d.id).join('/') || 'none'}]); admitting one is a per-path founder decision with a legal_basis and source_sha`);
261
+ }
262
+ const outcome = await adapter.fetchRoute(request, { signal: options?.signal ?? new AbortController().signal });
263
+ return admitRouteFact(useCase, adapter.descriptor, request, outcome, options.now);
264
+ }
265
+ /**
266
+ * Mechanical check: after a refusal, the static fallback must be unchanged —
267
+ * same mode, same minutes, same price and the SAME original price label. Returns
268
+ * a violation string, or null.
269
+ */
270
+ export function staticFallbackViolation(before, after) {
271
+ if (before.mode !== after.mode)
272
+ return `static fallback mode changed '${before.mode}' → '${after.mode}'`;
273
+ if (before.minutes !== after.minutes)
274
+ return `static fallback minutes changed ${before.minutes} → ${after.minutes}: a refused route fact must not touch the static estimate`;
275
+ if (before.priceCny !== after.priceCny)
276
+ return `static fallback priceCny changed ${before.priceCny} → ${after.priceCny}: a route fact never supplies a price`;
277
+ if (before.priceEvidence !== after.priceEvidence)
278
+ return `static price label changed '${before.priceEvidence}' → '${after.priceEvidence}': the original label stands until a separately authoritative fare exists`;
279
+ return null;
280
+ }
281
+ /**
282
+ * Run the conformance probes and report per clause.
283
+ *
284
+ * `admissible` is true only when every clause in `ROUTE_CONFORMANCE_CLAUSES` was
285
+ * probed AND passed: an unprobed clause is reported as unprobed and blocks
286
+ * admission, because "we never tested that" is not evidence of conformance.
287
+ */
288
+ export function runRouteProviderConformance(useCase, descriptor, probes, now) {
289
+ const byClause = new Map();
290
+ for (const probe of probes) {
291
+ const slot = byClause.get(probe.clause) ?? { pass: true, count: 0, evidence: [] };
292
+ slot.count++;
293
+ const result = admitRouteFact(useCase, descriptor, probe.request, probe.outcome, now);
294
+ if (probe.expect === null) {
295
+ if (result.ok)
296
+ slot.evidence.push(`${probe.label}: admitted as expected`);
297
+ else {
298
+ slot.pass = false;
299
+ slot.evidence.push(`${probe.label}: expected admission, got refusal ${result.code} — ${result.detail}`);
300
+ }
301
+ }
302
+ else if (result.ok) {
303
+ slot.pass = false;
304
+ slot.evidence.push(`${probe.label}: expected refusal ${probe.expect}, got ADMISSION (a fault was silently accepted)`);
305
+ }
306
+ else if (result.code !== probe.expect) {
307
+ slot.pass = false;
308
+ slot.evidence.push(`${probe.label}: expected refusal ${probe.expect}, got ${result.code} — ${result.detail}`);
309
+ }
310
+ else {
311
+ const leak = faultDetailLeak(result.detail);
312
+ if (leak !== null) {
313
+ slot.pass = false;
314
+ slot.evidence.push(`${probe.label}: refused ${result.code} but the detail leaks — ${leak}`);
315
+ }
316
+ else {
317
+ slot.evidence.push(`${probe.label}: refused ${result.code} with a sanitized detail`);
318
+ }
319
+ }
320
+ byClause.set(probe.clause, slot);
321
+ }
322
+ const clauses = [];
323
+ const unprobed = [];
324
+ for (const clause of ROUTE_CONFORMANCE_CLAUSES) {
325
+ const slot = byClause.get(clause);
326
+ if (slot === undefined) {
327
+ unprobed.push(clause);
328
+ clauses.push({ clause, verdict: 'fail', probes: 0, evidence: ['clause was never probed — "untested" is not conformance'] });
329
+ continue;
330
+ }
331
+ clauses.push({ clause, verdict: slot.pass ? 'pass' : 'fail', probes: slot.count, evidence: Object.freeze([...slot.evidence]) });
332
+ }
333
+ return Object.freeze({
334
+ schema: ROUTE_PROVIDER_CONFORMANCE_SCHEMA,
335
+ use_case_id: useCase.id,
336
+ provider_id: descriptor.id,
337
+ admissible: unprobed.length === 0 && clauses.every(c => c.verdict === 'pass'),
338
+ clauses: Object.freeze([...clauses]),
339
+ unprobed: Object.freeze([...unprobed]),
340
+ });
341
+ }
@@ -1,23 +1,28 @@
1
+ /**
2
+ * action-cache 本地自愈层(RFC docs/rfc/user-session-data-rfc.md §3.2 / §2.3;Stagehand 云端缓存的本地化):
3
+ *
4
+ * 目的:会话检索的查询模式高度重复(同站点同类型搜索),首跑用 LLM/规则定位,后续走
5
+ * 缓存的确定性载荷零成本重放;站点改版 → DOM 指纹失配 → miss → 重新定位并回写。
6
+ *
7
+ * 设计原则(Stagehand「错误的缓存点击比慢更糟」的被动失效):
8
+ * - key = site + action + 参数模板(%from%/%to%/%date% 变量化,同型查询共享条目);
9
+ * - 每条目绑 domFingerprint(快照/接口形状的 sha256 指纹);lookup 时现场指纹与条目不符 = miss(即使 key 命中);
10
+ * - miss 即回写(记录新定位),过期(默认 48h)与容量(每 site 默认 50 条,LRU)被动淘汰;
11
+ * - 纯函数 + JSON 文件持久化(隔离 stateRoot;损坏文件按空缓存处理,永不抛错)。
12
+ *
13
+ * P2 切片:模块+确定性测试先行;消费方(P2 美团适配器/a11y 兜底)下一切片接线。
14
+ */
1
15
  import { createHash } from 'node:crypto';
2
- import { mkdirSync, readFileSync, writeFileSync, existsSync, rmSync } from 'node:fs';
16
+ import { mkdirSync, readFileSync, writeFileSync, existsSync } from 'node:fs';
3
17
  import { dirname, join } from 'node:path';
18
+ /** 把具体查询参数变量化为模板 key:日期→%date%,from/to 语义序在前,其余参数按字典序尾随 */
4
19
  export function templateKey(site, action, params) {
5
- const val = (k)=>k === 'date' ? '%date%' : (params[k] ?? '').trim();
6
- const head = [
7
- 'from',
8
- 'to',
9
- 'date'
10
- ].filter((k)=>k in params).map(val);
11
- const tail = Object.keys(params).filter((k)=>![
12
- 'from',
13
- 'to',
14
- 'date'
15
- ].includes(k)).sort().map(val);
16
- return `${site}:${action}:${[
17
- ...head,
18
- ...tail
19
- ].join('|')}`;
20
+ const val = (k) => (k === 'date' ? '%date%' : (params[k] ?? '').trim());
21
+ const head = ['from', 'to', 'date'].filter((k) => k in params).map(val);
22
+ const tail = Object.keys(params).filter((k) => !['from', 'to', 'date'].includes(k)).sort().map(val);
23
+ return `${site}:${action}:${[...head, ...tail].join('|')}`;
20
24
  }
25
+ /** 指纹:快照/接口形状文本 → sha256 前 16 位(微改版即失配——宁可 miss 不可错点) */
21
26
  export function fingerprint(shapeText) {
22
27
  return createHash('sha256').update(shapeText).digest('hex').slice(0, 16);
23
28
  }
@@ -28,76 +33,79 @@ export class ActionCache {
28
33
  ttlMs;
29
34
  maxPerSite;
30
35
  now;
31
- constructor(filePath, opts = {}){
36
+ constructor(filePath, opts = {}) {
32
37
  this.filePath = filePath;
33
38
  this.ttlMs = opts.ttlMs ?? 48 * 3600_000;
34
39
  this.maxPerSite = opts.maxEntriesPerSite ?? 50;
35
- this.now = opts.now ?? (()=>new Date());
40
+ this.now = opts.now ?? (() => new Date());
36
41
  }
37
42
  load() {
38
- if (this.loaded) return;
43
+ if (this.loaded)
44
+ return;
39
45
  this.loaded = true;
40
46
  try {
41
47
  if (existsSync(this.filePath)) {
42
48
  const raw = JSON.parse(readFileSync(this.filePath, 'utf8'));
43
- for (const e of raw){
44
- if (e?.key && e.domFingerprint && e.locator) this.entries.set(e.key, e);
49
+ for (const e of raw) {
50
+ if (e?.key && e.domFingerprint && e.locator)
51
+ this.entries.set(e.key, e);
45
52
  }
46
53
  }
47
- } catch {}
54
+ }
55
+ catch { /* 损坏文件按空缓存处理 */ }
48
56
  }
49
57
  persist() {
50
58
  try {
51
- mkdirSync(dirname(this.filePath), {
52
- recursive: true
53
- });
59
+ mkdirSync(dirname(this.filePath), { recursive: true });
54
60
  const tmp = this.filePath + '.tmp';
55
- writeFileSync(tmp, JSON.stringify([
56
- ...this.entries.values()
57
- ], null, 0), 'utf8');
61
+ writeFileSync(tmp, JSON.stringify([...this.entries.values()], null, 0), 'utf8');
58
62
  writeFileSync(this.filePath, readFileSync(tmp, 'utf8'), 'utf8');
59
63
  try {
60
64
  require('node:fs').rmSync(tmp);
61
- } catch {}
62
- } catch {}
65
+ }
66
+ catch { /* best effort */ }
67
+ }
68
+ catch { /* 持久化失败不阻塞内存路径 */ }
63
69
  }
70
+ /** 站点前缀条目数(LRU 淘汰用) */
64
71
  siteEntries(site) {
65
- return [
66
- ...this.entries.values()
67
- ].filter((e)=>e.key.startsWith(site + ':'));
72
+ return [...this.entries.values()].filter((e) => e.key.startsWith(site + ':'));
68
73
  }
74
+ /** 命中三条件:key 存在 + 未过期 + 指纹一致;命中计 hits 并惰性落盘 */
69
75
  lookup(key, domFingerprint, site) {
70
76
  this.load();
71
77
  const e = this.entries.get(key);
72
- if (!e) return null;
78
+ if (!e)
79
+ return null;
73
80
  if (this.now().getTime() - Date.parse(e.lastHitAt || e.createdAt) > this.ttlMs) {
74
81
  this.entries.delete(key);
75
82
  this.persist();
76
83
  return null;
77
84
  }
78
- if (e.domFingerprint !== domFingerprint) return null;
85
+ if (e.domFingerprint !== domFingerprint)
86
+ return null; // 改版:被动失效,等 record 回写
79
87
  e.hits += 1;
80
88
  e.lastHitAt = this.now().toISOString();
81
89
  this.persist();
82
90
  void site;
83
91
  return e;
84
92
  }
93
+ /** miss 后回写(重新定位的产物);同 key 覆盖;超容 LRU 淘汰最旧 */
85
94
  record(key, domFingerprint, locator, site) {
86
95
  this.load();
87
96
  const ts = this.now().toISOString();
88
97
  const prev = this.entries.get(key);
89
98
  this.entries.set(key, {
90
- key,
91
- domFingerprint,
92
- locator,
99
+ key, domFingerprint, locator,
93
100
  createdAt: prev?.createdAt ?? ts,
94
101
  lastHitAt: ts,
95
- hits: prev?.hits ?? 0
102
+ hits: prev?.hits ?? 0,
96
103
  });
97
104
  const siteList = this.siteEntries(site);
98
105
  if (siteList.length > this.maxPerSite) {
99
- const victim = siteList.sort((a, b)=>Date.parse(a.lastHitAt) - Date.parse(b.lastHitAt))[0];
100
- if (victim) this.entries.delete(victim.key);
106
+ const victim = siteList.sort((a, b) => Date.parse(a.lastHitAt) - Date.parse(b.lastHitAt))[0];
107
+ if (victim)
108
+ this.entries.delete(victim.key);
101
109
  }
102
110
  this.persist();
103
111
  return this.entries.get(key);
@@ -112,9 +120,7 @@ export class ActionCache {
112
120
  return site ? this.siteEntries(site).length : this.entries.size;
113
121
  }
114
122
  }
123
+ /** 便捷入口:隔离 stateRoot 下的缓存文件路径 */
115
124
  export function actionCachePath(stateRoot) {
116
125
  return join(stateRoot, 'session-action-cache.json');
117
126
  }
118
-
119
-
120
- //# sourceURL=/Users/bytedance/work/gotry/ts/capabilities/session/action-cache.ts