@danceiny/gotry 0.0.1-rc.21 → 0.0.1-rc.24

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 (327) hide show
  1. package/README.md +102 -194
  2. package/README.zh-CN.md +115 -210
  3. package/bin/gotry-backend.js +53 -0
  4. package/bin/gotry-bootstrap.js +466 -35
  5. package/bin/gotry-inner.js +255 -36
  6. package/bin/gotry-process-liveness.d.ts +27 -0
  7. package/bin/gotry-process-liveness.js +97 -0
  8. package/bin/gotry-runtime-resolution.d.ts +1 -1
  9. package/bin/gotry-runtime-resolution.js +2 -2
  10. package/client/client.js +174 -0
  11. package/cordis.gotry-patch.yml +70 -93
  12. package/dist/capabilities/agent-reach-deep.js +45 -122
  13. package/dist/capabilities/agent-reach.js +63 -148
  14. package/dist/capabilities/anything.js +89 -75
  15. package/dist/capabilities/artifacts.js +123 -104
  16. package/dist/capabilities/channel-health.js +65 -45
  17. package/dist/capabilities/channel-registry.js +108 -87
  18. package/dist/capabilities/doctor.js +357 -235
  19. package/dist/capabilities/effect.js +223 -309
  20. package/dist/capabilities/fact-log.js +28 -14
  21. package/dist/capabilities/flyai.js +245 -156
  22. package/dist/capabilities/ground-transfer.js +509 -0
  23. package/dist/capabilities/hbcli.js +144 -148
  24. package/dist/capabilities/hotelbyte-transaction.js +194 -0
  25. package/dist/capabilities/incident-log.js +131 -61
  26. package/dist/capabilities/model-override.js +30 -10
  27. package/dist/capabilities/opensky.js +54 -43
  28. package/dist/capabilities/resilience.js +50 -32
  29. package/dist/capabilities/session/action-cache.js +50 -44
  30. package/dist/capabilities/session/adapters/ctrip-flight.js +119 -62
  31. package/dist/capabilities/session/adapters/ctrip-hotel.js +125 -110
  32. package/dist/capabilities/session/adapters/dida-portal.js +206 -0
  33. package/dist/capabilities/session/adapters/meituan-local.js +35 -54
  34. package/dist/capabilities/session/adapters/rail-12306.js +169 -112
  35. package/dist/capabilities/session/benchmark.js +85 -149
  36. package/dist/capabilities/session/extension-bridge.js +320 -259
  37. package/dist/capabilities/session/extension-channel.js +57 -76
  38. package/dist/capabilities/session/extension-distribution.js +115 -119
  39. package/dist/capabilities/session/extract.js +31 -21
  40. package/dist/capabilities/session/golden-score.js +55 -33
  41. package/dist/capabilities/session/health-watch.js +146 -154
  42. package/dist/capabilities/session/read-guard.js +55 -47
  43. package/dist/capabilities/session/static-flight-golden.js +49 -36
  44. package/dist/capabilities/session/transport.js +54 -61
  45. package/dist/capabilities/session/wizard.js +63 -93
  46. package/dist/capabilities/session-consent.js +143 -47
  47. package/dist/capabilities/session-login.js +95 -126
  48. package/dist/capabilities/session-search.js +391 -253
  49. package/dist/capabilities/sponsor-plugin.js +341 -0
  50. package/dist/capabilities/visa-policy.js +87 -73
  51. package/dist/capabilities/weather.js +163 -235
  52. package/dist/scripts/action-cache-tests.js +24 -59
  53. package/dist/scripts/agent-planning-turn-deadline-e2e.js +91 -142
  54. package/dist/scripts/agent-planning-turn-deadline-tests.js +80 -176
  55. package/dist/scripts/agent-reach-deep-tests.js +30 -40
  56. package/dist/scripts/agent-reach-tests.js +26 -18
  57. package/dist/scripts/agent-reach-wrapper-tests.js +46 -50
  58. package/dist/scripts/anything-tests.js +58 -62
  59. package/dist/scripts/artifact-client-contract-tests.js +69 -0
  60. package/dist/scripts/artifacts-capability-tests.js +235 -0
  61. package/dist/scripts/async-collect.js +26 -15
  62. package/dist/scripts/benchmark-environment-bridge-e2e.js +287 -684
  63. package/dist/scripts/benchmark-environment-bridge-tests.js +818 -3123
  64. package/dist/scripts/booking-copilot-availability-ledger-binding-tests.js +66 -279
  65. package/dist/scripts/booking-copilot-availability-policy-tests.js +153 -1257
  66. package/dist/scripts/booking-copilot-bin-proof-tests.js +22 -45
  67. package/dist/scripts/booking-copilot-crossrepo-fixture-server.js +64 -76
  68. package/dist/scripts/booking-copilot-dsh-core-proof-tests.js +69 -199
  69. package/dist/scripts/booking-copilot-dsh-planner-proof-tests.js +393 -759
  70. package/dist/scripts/booking-copilot-dsh-plugin-proof-tests.js +33 -75
  71. package/dist/scripts/booking-copilot-event-sequence-concurrency-proof-tests.js +60 -110
  72. package/dist/scripts/booking-copilot-gap-code-contract-proof-tests.js +28 -66
  73. package/dist/scripts/booking-copilot-operation-ledger-concurrency-proof-tests.js +72 -271
  74. package/dist/scripts/booking-copilot-receipt-ledger-concurrency-proof-tests.js +73 -275
  75. package/dist/scripts/booking-copilot-runtime-proof-tests.js +784 -3398
  76. package/dist/scripts/booking-copilot-server-proof-tests.js +63 -168
  77. package/dist/scripts/booking-copilot-startup-proof-tests.js +38 -124
  78. package/dist/scripts/booking-executor-tests.js +80 -0
  79. package/dist/scripts/booking-recovery-chain-tests.js +182 -0
  80. package/dist/scripts/booking-saga-tests.js +61 -123
  81. package/dist/scripts/booking-surface-contract-proof-tests.js +152 -1167
  82. package/dist/scripts/bootstrap-tests.js +1383 -128
  83. package/dist/scripts/build-changelog.js +89 -130
  84. package/dist/scripts/build-metrics-report.js +135 -143
  85. package/dist/scripts/changelog-tests.js +35 -82
  86. package/dist/scripts/channel-probe-tests.js +44 -116
  87. package/dist/scripts/channel-probe.js +84 -167
  88. package/dist/scripts/channel-registry-tests.js +97 -185
  89. package/dist/scripts/companion-tests.js +25 -70
  90. package/dist/scripts/dida-cookie-probe.js +87 -0
  91. package/dist/scripts/dida-sw-probe.js +114 -0
  92. package/dist/scripts/diff-test.js +17 -12
  93. package/dist/scripts/doctor-tests.js +428 -120
  94. package/dist/scripts/dsh-artifact-e2e.js +150 -0
  95. package/dist/scripts/dsh-artifact-web-e2e.js +443 -0
  96. package/dist/scripts/dsh-http-proxy-sse-proof.js +90 -0
  97. package/dist/scripts/dsh-runtime-closure-tests.js +110 -153
  98. package/dist/scripts/dsh-runtime-closure.js +75 -63
  99. package/dist/scripts/dsh-session-v3-migration-proof.js +106 -0
  100. package/dist/scripts/dsh-subprocess-local-proof.js +149 -0
  101. package/dist/scripts/dsh-target-closure-proof.js +178 -0
  102. package/dist/scripts/effect-tests.js +165 -552
  103. package/dist/scripts/engine-run.js +1 -3
  104. package/dist/scripts/engine-tests.js +16 -10
  105. package/dist/scripts/evaluation-cadence-tests.js +69 -242
  106. package/dist/scripts/evaluation-contract-tests.js +193 -499
  107. package/dist/scripts/extension-distribution-cli.js +19 -15
  108. package/dist/scripts/extension-distribution-tests.js +98 -211
  109. package/dist/scripts/extension-tests.js +366 -389
  110. package/dist/scripts/fact-gate-tests.js +725 -263
  111. package/dist/scripts/fixtures/extension-bridge-unref-child.mjs +21 -0
  112. package/dist/scripts/flight-hotel-anchor-363-registered-e2e.js +169 -0
  113. package/dist/scripts/flight-malformed-tests.js +159 -0
  114. package/dist/scripts/flyai-tests.js +325 -68
  115. package/dist/scripts/g5-guard-tests.js +131 -0
  116. package/dist/scripts/g5-guard.js +189 -0
  117. package/dist/scripts/gen-lunar-anchors.js +106 -0
  118. package/dist/scripts/gotry-backend-kernel-tests.js +79 -0
  119. package/dist/scripts/ground-transfer-tests.js +956 -0
  120. package/dist/scripts/hbcli-e2e-tests.js +71 -90
  121. package/dist/scripts/hbcli-live-optin-tests.js +96 -0
  122. package/dist/scripts/hbcli-release-contract-tests.js +122 -0
  123. package/dist/scripts/hbcli-tests.js +41 -115
  124. package/dist/scripts/health-watch-cli.js +42 -28
  125. package/dist/scripts/hotel-date-gate-tests.js +496 -0
  126. package/dist/scripts/hotelbyte-reconcile-tests.js +141 -0
  127. package/dist/scripts/hotelbyte-spawn-e2e-tests.js +373 -0
  128. package/dist/scripts/i18n-tests.js +16 -9
  129. package/dist/scripts/incident-tests.js +281 -87
  130. package/dist/scripts/issue-194-job-id-guard-tests.js +106 -0
  131. package/dist/scripts/issue-233-cancel-refund-commission-tests.js +392 -0
  132. package/dist/scripts/issue-271-liveness-tests.js +547 -0
  133. package/dist/scripts/issue-289-model-retry-real-tests.js +296 -0
  134. package/dist/scripts/issue-289-model-retry-tests.js +441 -0
  135. package/dist/scripts/issue-289-web-retry-e2e.js +630 -0
  136. package/dist/scripts/issue-338-home-city-e2e.js +577 -0
  137. package/dist/scripts/issue343-real-entry-e2e.js +160 -0
  138. package/dist/scripts/journey-tests.js +22 -27
  139. package/dist/scripts/kernel-manifest-evidence.js +109 -0
  140. package/dist/scripts/kernel-manifest-gate.js +126 -0
  141. package/dist/scripts/kernel-manifest-tests.js +212 -0
  142. package/dist/scripts/kernel-manifest-trace-entry.js +7 -0
  143. package/dist/scripts/kernel-manifest-trace-hook.mjs +28 -0
  144. package/dist/scripts/kernel-manifest.js +369 -0
  145. package/dist/scripts/ledger-repair-apply-tests.js +316 -0
  146. package/dist/scripts/ledger-repair-plan-tests.js +375 -0
  147. package/dist/scripts/ledger-tests.js +325 -340
  148. package/dist/scripts/ledger-workflow-crash.js +10 -20
  149. package/dist/scripts/map-tools-vendor-package-proof.js +206 -134
  150. package/dist/scripts/memory-capture-tests.js +242 -61
  151. package/dist/scripts/memory-decay-tests.js +18 -52
  152. package/dist/scripts/memory-lifecycle-tests.js +657 -0
  153. package/dist/scripts/memory-lifecycle.js +196 -0
  154. package/dist/scripts/memory-metrics.js +24 -12
  155. package/dist/scripts/memory-value-report.js +474 -222
  156. package/dist/scripts/memory-value-tests.js +328 -0
  157. package/dist/scripts/metrics-report-tests.js +62 -199
  158. package/dist/scripts/model-override-e2e.js +66 -105
  159. package/dist/scripts/nightly-evidence-tests.js +64 -89
  160. package/dist/scripts/nightly-evidence.js +108 -111
  161. package/dist/scripts/nudge-digest.js +39 -28
  162. package/dist/scripts/onboarding-tests.js +63 -88
  163. package/dist/scripts/opensky-check.js +18 -13
  164. package/dist/scripts/opensky-tests.js +28 -28
  165. package/dist/scripts/persona-surface-guard-tests.js +37 -12
  166. package/dist/scripts/pnpm-dsh-closure-proof.js +2 -5
  167. package/dist/scripts/policy-anchor-359-registered-e2e.js +214 -0
  168. package/dist/scripts/price-drift-tests.js +126 -227
  169. package/dist/scripts/price-drift-watch.js +209 -253
  170. package/dist/scripts/probe-poi-tests.js +52 -45
  171. package/dist/scripts/product-metrics.js +187 -273
  172. package/dist/scripts/publish-preverify.js +47 -41
  173. package/dist/scripts/realtime-pricing-tests.js +37 -76
  174. package/dist/scripts/replay-async.js +20 -18
  175. package/dist/scripts/replay-real.js +16 -18
  176. package/dist/scripts/replay.js +52 -82
  177. package/dist/scripts/session-attach-diagnose.js +16 -12
  178. package/dist/scripts/session-attach-poc.js +34 -37
  179. package/dist/scripts/session-benchmark.js +66 -147
  180. package/dist/scripts/session-dida-live-e2e.js +151 -0
  181. package/dist/scripts/session-extract-tests.js +14 -35
  182. package/dist/scripts/session-login.js +14 -13
  183. package/dist/scripts/session-tests.js +545 -583
  184. package/dist/scripts/sf-live-benchmark.js +92 -110
  185. package/dist/scripts/sf-live-cli-tests.js +2 -9
  186. package/dist/scripts/sf-soft-score-tests.js +19 -60
  187. package/dist/scripts/sf-summary-tests.js +149 -0
  188. package/dist/scripts/sf-summary.js +466 -84
  189. package/dist/scripts/skeleton-check.js +16 -14
  190. package/dist/scripts/skeleton-integration-test.js +11 -10
  191. package/dist/scripts/skills-contract-tests.js +51 -46
  192. package/dist/scripts/smoke-session-gate-tests.js +12 -20
  193. package/dist/scripts/smoke.js +541 -422
  194. package/dist/scripts/sponsor-reuse-tests.js +262 -0
  195. package/dist/scripts/state-cli-tests.js +226 -101
  196. package/dist/scripts/state-cli.js +549 -212
  197. package/dist/scripts/static-golden-tests.js +46 -180
  198. package/dist/scripts/time-eval-tests.js +210 -192
  199. package/dist/scripts/travel-timeline-tests.js +29 -93
  200. package/dist/scripts/turn-handoff-collect-tests.js +46 -93
  201. package/dist/scripts/turn-handoff-collect.js +71 -99
  202. package/dist/scripts/turn-policy-tests.js +28 -29
  203. package/dist/scripts/typed-contract-canary.js +77 -162
  204. package/dist/scripts/tz-resolver-sanity.js +50 -0
  205. package/dist/scripts/tz-resolver-tests.js +584 -0
  206. package/dist/scripts/unified-tests.js +23 -19
  207. package/dist/scripts/visa-policy-tests.js +31 -44
  208. package/dist/scripts/weather-tests.js +121 -543
  209. package/dist/scripts/wish-channel-gate-tests.js +29 -86
  210. package/dist/scripts/write-gate-tests.js +522 -0
  211. package/dist/scripts/z3-lifecycle-fault-tests.js +188 -0
  212. package/dist/scripts/z3-lifecycle-tests.js +170 -0
  213. package/dist/scripts/z3-race-repeat-tests.js +39 -0
  214. package/dist/scripts/z3-race-tests.js +18 -12
  215. package/dist/src/artifact-gate.js +652 -221
  216. package/dist/src/backend/kernel.js +91 -0
  217. package/dist/src/backend/modules/booking-copilot.js +55 -0
  218. package/dist/src/backend/modules/booking-executor.js +124 -0
  219. package/dist/src/backend/modules/session-search.js +194 -0
  220. package/dist/src/benchmark-agent-conformance.js +296 -262
  221. package/dist/src/benchmark-environment-bridge.js +298 -413
  222. package/dist/src/benchmark-headless-child-diagnostics.js +93 -100
  223. package/dist/src/benchmark-tool-isolation.js +94 -67
  224. package/dist/src/bookable-facts.js +299 -174
  225. package/dist/src/booking-saga.js +64 -120
  226. package/dist/src/booking-surface/availability-policy.js +443 -576
  227. package/dist/src/booking-surface/cancel-refund-commission.js +379 -0
  228. package/dist/src/booking-surface/contracts.js +24 -80
  229. package/dist/src/booking-surface/dsh-planner.js +510 -281
  230. package/dist/src/booking-surface/dsh-plugin.js +17 -1
  231. package/dist/src/booking-surface/error-codes.js +82 -10
  232. package/dist/src/booking-surface/index.js +0 -3
  233. package/dist/src/booking-surface/profile.js +10 -54
  234. package/dist/src/booking-surface/recovery-chain.js +367 -0
  235. package/dist/src/booking-surface/runtime.js +765 -891
  236. package/dist/src/booking-surface/server.js +200 -251
  237. package/dist/src/booking-surface/startup.js +58 -54
  238. package/dist/src/booking-surface/validation.js +150 -218
  239. package/dist/src/bridge.js +20 -13
  240. package/dist/src/companions.js +48 -74
  241. package/dist/src/contracts.js +21 -43
  242. package/dist/src/dsh-llm.js +82 -120
  243. package/dist/src/engine.js +253 -239
  244. package/dist/src/evaluation-cadence.js +72 -209
  245. package/dist/src/evaluation-contracts.js +220 -843
  246. package/dist/src/flight-pack-adapter.js +54 -0
  247. package/dist/src/flight-pack-contract.js +2 -0
  248. package/dist/src/gotry-backend.js +70 -0
  249. package/dist/src/hotel-date-gate.js +118 -0
  250. package/dist/src/i18n.js +18 -7
  251. package/dist/src/index.js +1425 -1629
  252. package/dist/src/journey.js +132 -81
  253. package/dist/src/ledger-repair-apply.js +538 -0
  254. package/dist/src/ledger-repair-plan.js +463 -0
  255. package/dist/src/loop.js +257 -166
  256. package/dist/src/memory-capture.js +180 -32
  257. package/dist/src/memory-decay.js +30 -14
  258. package/dist/src/memory-lifecycle.js +1310 -0
  259. package/dist/src/memory-utility.js +27 -40
  260. package/dist/src/mock-llm.js +36 -61
  261. package/dist/src/model.js +81 -36
  262. package/dist/src/realtime-pricing.js +63 -72
  263. package/dist/src/slot-spec.js +84 -106
  264. package/dist/src/state-ledger.js +310 -471
  265. package/dist/src/subagent-job-id-guard.js +58 -0
  266. package/dist/src/time-anchor.js +231 -33
  267. package/dist/src/tool-packet.js +20 -8
  268. package/dist/src/travel-slots.js +58 -35
  269. package/dist/src/travel-timeline.js +44 -63
  270. package/dist/src/turn-deadline.js +121 -127
  271. package/dist/src/turn-policy.js +61 -89
  272. package/dist/src/tz-resolver.js +143 -0
  273. package/dist/src/unified.js +504 -381
  274. package/dist/src/wish-pool.js +39 -14
  275. package/dist/src/write-gate.js +495 -0
  276. package/dist/src/z3-shared.js +273 -7
  277. package/extension/README.md +4 -3
  278. package/extension/background.js +125 -14
  279. package/extension/content-bridge.js +23 -1
  280. package/extension/content-main.js +15 -4
  281. package/extension/manifest.json +16 -8
  282. package/package.json +251 -220
  283. package/ts/capabilities/agent-reach.ts +4 -4
  284. package/ts/capabilities/anything.ts +1 -1
  285. package/ts/capabilities/artifacts.ts +46 -9
  286. package/ts/capabilities/flyai.ts +156 -37
  287. package/ts/capabilities/hbcli.ts +1 -1
  288. package/ts/capabilities/incident-log.ts +88 -59
  289. package/ts/capabilities/session/adapters/ctrip-flight.ts +99 -36
  290. package/ts/capabilities/session/adapters/dida-portal.ts +250 -0
  291. package/ts/capabilities/session/adapters/rail-12306.ts +123 -24
  292. package/ts/capabilities/session/extension-bridge.ts +226 -101
  293. package/ts/capabilities/session/extension-channel.ts +22 -9
  294. package/ts/capabilities/session/wizard.ts +2 -2
  295. package/ts/capabilities/session-consent.ts +98 -14
  296. package/ts/capabilities/session-login.ts +1 -0
  297. package/ts/capabilities/session-search.ts +315 -31
  298. package/ts/dsh-runtime/vendor/README.md +8 -4
  299. package/ts/dsh-runtime/vendor/dsh-map-tools/README.en.md +7 -1
  300. package/ts/dsh-runtime/vendor/dsh-map-tools/README.md +5 -3
  301. package/ts/dsh-runtime/vendor/dsh-map-tools/lib/settings-ns.js +1 -1
  302. package/ts/dsh-runtime/vendor/dsh-map-tools/lib/types/settings-ns.d.ts +1 -1
  303. package/ts/dsh-runtime/vendor/dsh-map-tools/package.json +6 -6
  304. package/ts/package.json +236 -16
  305. package/ts/scripts/map-tools-vendor-package-proof.ts +152 -31
  306. package/ts/scripts/state-cli.ts +418 -51
  307. package/ts/src/artifact-gate.ts +561 -15
  308. package/ts/src/benchmark-environment-bridge.ts +37 -20
  309. package/ts/src/bookable-facts.ts +183 -7
  310. package/ts/src/booking-surface/cancel-refund-commission.ts +488 -0
  311. package/ts/src/booking-surface/dsh-planner.ts +240 -32
  312. package/ts/src/booking-surface/dsh-plugin.js +17 -1
  313. package/ts/src/booking-surface/error-codes.ts +75 -0
  314. package/ts/src/booking-surface/recovery-chain.ts +409 -0
  315. package/ts/src/booking-surface/server.ts +84 -51
  316. package/ts/src/booking-surface/validation.ts +2 -0
  317. package/ts/src/contracts.ts +12 -2
  318. package/ts/src/dsh-llm.ts +4 -8
  319. package/ts/src/index.ts +609 -90
  320. package/ts/src/loop.ts +116 -7
  321. package/ts/src/memory-capture.ts +227 -3
  322. package/ts/src/mock-llm.ts +4 -8
  323. package/ts/src/model.ts +88 -2
  324. package/ts/src/state-ledger.ts +47 -29
  325. package/ts/src/subagent-job-id-guard.ts +72 -0
  326. package/ts/src/time-anchor.ts +217 -13
  327. package/ts/src/unified.ts +316 -54
@@ -1,3 +1,4 @@
1
+ // TS 引擎直接跑洱海金标准用例,打印与 Python 相同结构的结果
1
2
  import { readFile } from 'node:fs/promises';
2
3
  import { join } from 'node:path';
3
4
  import { parseCandidate, parseRequest } from '../src/model.js';
@@ -9,6 +10,3 @@ const t0 = Date.now();
9
10
  const result = await solve(req, candidates);
10
11
  console.log(`(TS 引擎总耗时含 WASM init: ${Date.now() - t0}ms, recommended=${result['recommended']})\n`);
11
12
  console.log(result['answer_md']);
12
-
13
-
14
- //# sourceURL=ts/scripts/engine-run.ts
@@ -1,3 +1,7 @@
1
+ /**
2
+ * TS 引擎金标准断言(与 py/tests/test_engine.py 同一套洱海用例)。
3
+ * 运行(在 ts/ 下):npx tsx scripts/engine-tests.ts
4
+ */
1
5
  import assert from 'node:assert/strict';
2
6
  import { readFile } from 'node:fs/promises';
3
7
  import { join } from 'node:path';
@@ -7,39 +11,41 @@ const payload = JSON.parse(await readFile(join('..', 'data', 'golden_erhai.json'
7
11
  const req = parseRequest(payload['request']);
8
12
  const candidates = payload['candidates'].map(parseCandidate);
9
13
  const result = await solve(req, candidates);
10
- const verdicts = Object.fromEntries(result.verdicts.map((v)=>[
11
- v['candidate_id'],
12
- v
13
- ]));
14
+ const verdicts = Object.fromEntries(result.verdicts.map(v => [v['candidate_id'], v]));
15
+ // 1. 洱海在周末窗口不可行,unsat core 必须点名 duration
14
16
  assert.equal(verdicts['dali']['feasible'], false);
15
17
  assert.ok(verdicts['dali']['unsat_core'].includes('duration'));
18
+ // 2. 憧憬不被拒绝:进 wish pool,带成行条件
16
19
  const wp = verdicts['dali']['wish_pool'];
17
20
  assert.ok(wp, 'dali wish pool exists');
18
21
  assert.ok(wp['conditions']['days'] >= 5);
19
22
  assert.ok('budget_cny' in wp['conditions']);
20
23
  assert.ok(wp['conditions']['best_months'].length > 0);
24
+ // 3. 最小修改建议必须写明代价
21
25
  assert.ok(verdicts['dali']['suggestions'].length > 0);
22
- assert.ok(verdicts['dali']['suggestions'].some((s)=>s['text'].includes('天')));
26
+ assert.ok(verdicts['dali']['suggestions'].some((s) => s['text'].includes('天')));
27
+ // 4. 千岛湖可行且被推荐
23
28
  assert.equal(verdicts['qiandao']['feasible'], true);
24
29
  assert.equal(result.recommended, 'qiandao');
30
+ // 5. 全成本六要素齐全
25
31
  const t = verdicts['qiandao']['true_cost'];
26
32
  assert.ok(t['money_cny'] <= 3000);
27
33
  assert.ok(Number(String(t['wake']).replace(':', '')) >= 630);
28
34
  assert.ok(t['energy_arrival_pct'] >= 40);
29
35
  assert.ok(t['usable_hours'] >= requiredUsableHours(req.motivation));
36
+ // 6. 太湖也可行且更便宜(同一可行口径内)
30
37
  assert.equal(verdicts['taihu']['feasible'], true);
31
38
  assert.ok(verdicts['taihu']['true_cost']['money_cny'] <= verdicts['qiandao']['true_cost']['money_cny']);
39
+ // 7. 回答不空手而归
32
40
  assert.ok(result.answer_md.includes('千岛湖'));
33
41
  assert.ok(result.answer_md.includes('下一次出发'));
34
42
  assert.ok(result.answer_md.includes('待你决定的两个问题'));
43
+ // 8. 预算差一口气的场景:报告差额而非拒绝
35
44
  const tight = structuredClone(payload);
36
45
  tight['request']['budget_cny'] = 900;
37
46
  const tightReq = parseRequest(tight['request']);
38
- const v = await solveCandidate(candidates.find((c)=>c.id === 'qiandao'), tightReq);
47
+ const v = await solveCandidate(candidates.find(c => c.id === 'qiandao'), tightReq);
39
48
  assert.equal(v.feasible, false);
40
49
  assert.ok(v.unsatCore.includes('budget'));
41
- assert.ok(v.suggestions.some((s)=>s.text.includes('预算提高到')));
50
+ assert.ok(v.suggestions.some(s => s.text.includes('预算提高到')));
42
51
  console.log('TS ENGINE TESTS: 8/8 OK');
43
-
44
-
45
- //# sourceURL=ts/scripts/engine-tests.ts
@@ -1,10 +1,15 @@
1
+ /**
2
+ * Contract tests for the evaluation cadence policy and planner.
3
+ * Run from ts/: npx tsx scripts/evaluation-cadence-tests.ts
4
+ */
1
5
  import { readFile } from 'node:fs/promises';
2
6
  import { join } from 'node:path';
3
7
  import assert from 'node:assert/strict';
4
- import { parseEvaluationCadencePolicy, planEvaluationCadence } from '../src/evaluation-cadence.js';
8
+ import { parseEvaluationCadencePolicy, planEvaluationCadence, } from '../src/evaluation-cadence.js';
5
9
  import { assertPublicArtifactSafe } from '../src/evaluation-contracts.js';
6
10
  const policyPath = join(process.cwd(), 'data', 'evaluation', 'cadence-policy.json');
7
11
  async function loadPolicyFixture() {
12
+ // This must remain a real fixture load: policy behavior is not tested with an inline mock.
8
13
  return JSON.parse(await readFile(policyPath, 'utf8'));
9
14
  }
10
15
  function expectThrows(fn, message) {
@@ -14,66 +19,16 @@ async function testCanonicalPolicyAndHealthyWeeklyPlan() {
14
19
  const raw = await loadPolicyFixture();
15
20
  const policy = parseEvaluationCadencePolicy(raw);
16
21
  assertPublicArtifactSafe(policy, 'test policy safety');
17
- assert.deepEqual(policy.levels.map((level)=>level.cadence), [
18
- 'pr',
19
- 'nightly',
20
- 'weekly',
21
- 'milestone'
22
- ]);
23
- assert.deepEqual(policy.levels.map((level)=>level.pass_k), [
24
- 1,
25
- 2,
26
- 3,
27
- 5
28
- ]);
29
- assert.deepEqual(policy.levels.map((level)=>level.max_cost_usd), [
30
- 0,
31
- 2,
32
- 10,
33
- 50
34
- ]);
35
- assert.deepEqual(policy.levels.map((level)=>level.max_wall_minutes), [
36
- 20,
37
- 90,
38
- 360,
39
- 1440
40
- ]);
41
- assert.deepEqual(policy.levels.map((level)=>level.max_tool_calls_per_case), [
42
- 18,
43
- 18,
44
- 18,
45
- 18
46
- ]);
47
- assert.deepEqual(policy.levels.map((level)=>[
48
- level.human_calibration.required,
49
- level.human_calibration.min_samples
50
- ]), [
51
- [
52
- false,
53
- 0
54
- ],
55
- [
56
- false,
57
- 0
58
- ],
59
- [
60
- true,
61
- 10
62
- ],
63
- [
64
- true,
65
- 30
66
- ]
67
- ]);
22
+ assert.deepEqual(policy.levels.map((level) => level.cadence), ['pr', 'nightly', 'weekly', 'milestone']);
23
+ assert.deepEqual(policy.levels.map((level) => level.pass_k), [1, 2, 3, 5]);
24
+ assert.deepEqual(policy.levels.map((level) => level.max_cost_usd), [0, 2, 10, 50]);
25
+ assert.deepEqual(policy.levels.map((level) => level.max_wall_minutes), [20, 90, 360, 1440]);
26
+ assert.deepEqual(policy.levels.map((level) => level.max_tool_calls_per_case), [18, 18, 18, 18]);
27
+ assert.deepEqual(policy.levels.map((level) => [level.human_calibration.required, level.human_calibration.min_samples]), [[false, 0], [false, 0], [true, 10], [true, 30]]);
68
28
  const decision = planEvaluationCadence(policy, {
69
29
  cadence: 'weekly',
70
30
  signals: [],
71
- recent_optimization_prs: [
72
- 81,
73
- 84,
74
- 87,
75
- 89
76
- ]
31
+ recent_optimization_prs: [81, 84, 87, 89],
77
32
  });
78
33
  assert.deepEqual(decision, {
79
34
  cadence: 'weekly',
@@ -85,24 +40,15 @@ async function testCanonicalPolicyAndHealthyWeeklyPlan() {
85
40
  max_cost_usd: 10,
86
41
  max_wall_minutes: 360,
87
42
  max_tool_calls_per_case: 18,
88
- human_calibration: {
89
- required: true,
90
- min_samples: 10
91
- },
92
- cross_benchmark_window: {
93
- min_prs: 3,
94
- max_prs: 5
95
- },
43
+ human_calibration: { required: true, min_samples: 10 },
44
+ cross_benchmark_window: { min_prs: 3, max_prs: 5 },
96
45
  performance_tradeoff_disclosure_threshold: 0.2,
97
46
  delivery: {
98
47
  exactly_one_gotry_pr: true,
99
48
  exactly_one_discussion_78_comment: true,
100
- update_existing_comment: true
49
+ update_existing_comment: true,
101
50
  },
102
- cross_benchmark_synthesis: {
103
- required: true,
104
- overdue: false
105
- }
51
+ cross_benchmark_synthesis: { required: true, overdue: false },
106
52
  });
107
53
  assertPublicArtifactSafe(decision, 'test decision safety');
108
54
  }
@@ -110,214 +56,98 @@ async function testStopSignalsDenyAdmissionAndRegisterFailures() {
110
56
  const policy = parseEvaluationCadencePolicy(await loadPolicyFixture());
111
57
  const decision = planEvaluationCadence(policy, {
112
58
  cadence: 'weekly',
113
- signals: [
114
- 'source_revision_drift',
115
- 'hard_violation'
116
- ],
117
- recent_optimization_prs: [
118
- 81,
119
- 84,
120
- 87
121
- ]
59
+ signals: ['source_revision_drift', 'hard_violation'],
60
+ recent_optimization_prs: [81, 84, 87],
122
61
  });
123
62
  assert.equal(decision.admission, false);
124
- assert.deepEqual(decision.stop_signals, [
125
- 'source_revision_drift',
126
- 'hard_violation'
127
- ]);
63
+ assert.deepEqual(decision.stop_signals, ['source_revision_drift', 'hard_violation']);
128
64
  assert.equal(decision.failure_registry, true);
129
65
  const nonRegistry = planEvaluationCadence(policy, {
130
66
  cadence: 'weekly',
131
- signals: [
132
- 'license_unresolved'
133
- ],
134
- recent_optimization_prs: [
135
- 81,
136
- 84,
137
- 87
138
- ]
67
+ signals: ['license_unresolved'],
68
+ recent_optimization_prs: [81, 84, 87],
139
69
  });
140
70
  assert.equal(nonRegistry.admission, false);
141
71
  assert.equal(nonRegistry.failure_registry, false);
142
72
  const allSignals = planEvaluationCadence(policy, {
143
73
  cadence: 'weekly',
144
- signals: [
145
- 'source_revision_drift',
146
- 'license_unresolved',
147
- 'scorer_ceiling_invalid',
148
- 'known_bad_no_longer_fails',
149
- 'hard_violation',
150
- 'matched_regression',
151
- 'variance_breach',
152
- 'budget_breach'
153
- ],
154
- recent_optimization_prs: []
74
+ signals: ['source_revision_drift', 'license_unresolved', 'scorer_ceiling_invalid', 'known_bad_no_longer_fails', 'hard_violation', 'matched_regression', 'variance_breach', 'budget_breach'],
75
+ recent_optimization_prs: [],
155
76
  });
156
77
  assert.equal(allSignals.admission, false);
157
78
  assert.equal(allSignals.failure_registry, true);
158
- const duplicatePrs = {
159
- cadence: 'weekly',
160
- signals: [],
161
- recent_optimization_prs: [
162
- 81,
163
- 81,
164
- 82
165
- ]
166
- };
167
- expectThrows(()=>planEvaluationCadence(policy, duplicatePrs), 'duplicate optimization PR IDs must fail closed');
79
+ const duplicatePrs = { cadence: 'weekly', signals: [], recent_optimization_prs: [81, 81, 82] };
80
+ expectThrows(() => planEvaluationCadence(policy, duplicatePrs), 'duplicate optimization PR IDs must fail closed');
168
81
  const sparsePrs = [];
169
82
  sparsePrs[2] = 81;
170
- expectThrows(()=>planEvaluationCadence(policy, {
171
- cadence: 'weekly',
172
- signals: [],
173
- recent_optimization_prs: sparsePrs
174
- }), 'sparse optimization PR IDs must fail closed');
175
- expectThrows(()=>planEvaluationCadence(policy, {
176
- cadence: 'weekly',
177
- signals: [],
178
- recent_optimization_prs: [
179
- 0
180
- ]
181
- }), 'non-positive optimization PR IDs must fail closed');
182
- expectThrows(()=>planEvaluationCadence(policy, {
183
- cadence: 'weekly',
184
- signals: [],
185
- recent_optimization_prs: [
186
- 1.5
187
- ]
188
- }), 'fractional optimization PR IDs must fail closed');
83
+ expectThrows(() => planEvaluationCadence(policy, { cadence: 'weekly', signals: [], recent_optimization_prs: sparsePrs }), 'sparse optimization PR IDs must fail closed');
84
+ expectThrows(() => planEvaluationCadence(policy, { cadence: 'weekly', signals: [], recent_optimization_prs: [0] }), 'non-positive optimization PR IDs must fail closed');
85
+ expectThrows(() => planEvaluationCadence(policy, { cadence: 'weekly', signals: [], recent_optimization_prs: [1.5] }), 'fractional optimization PR IDs must fail closed');
189
86
  }
190
87
  async function testRoundDeliveryAndMilestoneCalibration() {
191
88
  const policy = parseEvaluationCadencePolicy(await loadPolicyFixture());
192
89
  const milestone = planEvaluationCadence(policy, {
193
90
  cadence: 'milestone',
194
91
  signals: [],
195
- recent_optimization_prs: [
196
- 81,
197
- 84,
198
- 87,
199
- 89,
200
- 91
201
- ]
92
+ recent_optimization_prs: [81, 84, 87, 89, 91],
202
93
  });
203
94
  assert.equal(milestone.admission, true);
204
95
  assert.equal(milestone.pass_k, 5);
205
- assert.deepEqual(milestone.human_calibration, {
206
- required: true,
207
- min_samples: 30
208
- });
209
- assert.deepEqual(milestone.cross_benchmark_window, {
210
- min_prs: 3,
211
- max_prs: 5
212
- });
96
+ assert.deepEqual(milestone.human_calibration, { required: true, min_samples: 30 });
97
+ assert.deepEqual(milestone.cross_benchmark_window, { min_prs: 3, max_prs: 5 });
213
98
  assert.equal(milestone.performance_tradeoff_disclosure_threshold, 0.2);
214
99
  assert.deepEqual(milestone.delivery, {
215
100
  exactly_one_gotry_pr: true,
216
101
  exactly_one_discussion_78_comment: true,
217
- update_existing_comment: true
218
- });
219
- assert.deepEqual(milestone.cross_benchmark_synthesis, {
220
- required: true,
221
- overdue: false
222
- });
223
- assert.deepEqual(planEvaluationCadence(policy, {
224
- cadence: 'weekly',
225
- signals: [],
226
- recent_optimization_prs: []
227
- }).cross_benchmark_synthesis, {
228
- required: false,
229
- overdue: false
230
- });
231
- assert.deepEqual(planEvaluationCadence(policy, {
232
- cadence: 'weekly',
233
- signals: [],
234
- recent_optimization_prs: [
235
- 81,
236
- 82,
237
- 83,
238
- 84,
239
- 85,
240
- 86
241
- ]
242
- }).cross_benchmark_synthesis, {
243
- required: true,
244
- overdue: true
102
+ update_existing_comment: true,
245
103
  });
104
+ assert.deepEqual(milestone.cross_benchmark_synthesis, { required: true, overdue: false });
105
+ assert.deepEqual(planEvaluationCadence(policy, { cadence: 'weekly', signals: [], recent_optimization_prs: [] }).cross_benchmark_synthesis, { required: false, overdue: false });
106
+ assert.deepEqual(planEvaluationCadence(policy, { cadence: 'weekly', signals: [], recent_optimization_prs: [81, 82, 83, 84, 85, 86] }).cross_benchmark_synthesis, { required: true, overdue: true });
246
107
  }
247
108
  async function testMalformedPolicyFailsClosed() {
248
109
  const fixture = await loadPolicyFixture();
249
- const malformed = (change)=>{
110
+ const malformed = (change) => {
250
111
  const copy = structuredClone(fixture);
251
112
  change(copy);
252
- expectThrows(()=>parseEvaluationCadencePolicy(copy), 'malformed policy must fail closed');
113
+ expectThrows(() => parseEvaluationCadencePolicy(copy), 'malformed policy must fail closed');
253
114
  };
254
- malformed((copy)=>{
255
- copy.unknown_key = true;
256
- });
257
- malformed((copy)=>{
258
- copy.levels[0].cadence = 'hourly';
259
- });
260
- malformed((copy)=>{
261
- copy.levels[0].pass_k = -1;
262
- });
263
- malformed((copy)=>{
264
- copy.levels[0].pass_k = 1.5;
265
- });
266
- malformed((copy)=>{
267
- copy.levels = [
268
- ...copy.levels
269
- ].reverse();
270
- });
271
- malformed((copy)=>{
272
- const sparse = [];
273
- sparse[3] = copy.levels[3];
274
- copy.levels = sparse;
275
- });
276
- malformed((copy)=>{
277
- delete copy.stop_signals;
278
- });
115
+ malformed((copy) => { copy.unknown_key = true; });
116
+ malformed((copy) => { copy.levels[0].cadence = 'hourly'; });
117
+ malformed((copy) => { copy.levels[0].pass_k = -1; });
118
+ malformed((copy) => { copy.levels[0].pass_k = 1.5; });
119
+ malformed((copy) => { copy.levels = [...copy.levels].reverse(); });
120
+ malformed((copy) => { const sparse = []; sparse[3] = copy.levels[3]; copy.levels = sparse; });
121
+ malformed((copy) => { delete copy.stop_signals; });
279
122
  const policy = parseEvaluationCadencePolicy(fixture);
280
123
  const tamperedPolicy = structuredClone(policy);
281
124
  tamperedPolicy.levels[2].max_cost_usd = 999;
282
- expectThrows(()=>planEvaluationCadence(tamperedPolicy, {
283
- cadence: 'weekly',
284
- signals: [],
285
- recent_optimization_prs: []
286
- }), 'tampered policy budget must fail closed');
125
+ expectThrows(() => planEvaluationCadence(tamperedPolicy, { cadence: 'weekly', signals: [], recent_optimization_prs: [] }), 'tampered policy budget must fail closed');
287
126
  const tamperedDelivery = structuredClone(policy);
288
127
  tamperedDelivery.round_delivery.exactly_one_gotry_pr = false;
289
- expectThrows(()=>planEvaluationCadence(tamperedDelivery, {
290
- cadence: 'weekly',
291
- signals: [],
292
- recent_optimization_prs: []
293
- }), 'tampered policy delivery must fail closed');
294
- expectThrows(()=>planEvaluationCadence(policy, {
295
- cadence: 'hourly',
296
- signals: [],
297
- recent_optimization_prs: []
298
- }), 'unknown cadence must fail closed');
299
- expectThrows(()=>planEvaluationCadence(policy, {
300
- cadence: 'weekly',
301
- signals: [
302
- 'unknown_signal'
303
- ],
304
- recent_optimization_prs: []
305
- }), 'unknown stop signal must fail closed');
306
- expectThrows(()=>planEvaluationCadence(policy, {
307
- cadence: 'weekly',
308
- signals: [
309
- 'hard_violation',
310
- 'hard_violation'
311
- ],
312
- recent_optimization_prs: []
313
- }), 'duplicate stop signals must fail closed');
128
+ expectThrows(() => planEvaluationCadence(tamperedDelivery, { cadence: 'weekly', signals: [], recent_optimization_prs: [] }), 'tampered policy delivery must fail closed');
129
+ expectThrows(() => planEvaluationCadence(policy, {
130
+ cadence: 'hourly',
131
+ signals: [],
132
+ recent_optimization_prs: [],
133
+ }), 'unknown cadence must fail closed');
134
+ expectThrows(() => planEvaluationCadence(policy, {
135
+ cadence: 'weekly',
136
+ signals: ['unknown_signal'],
137
+ recent_optimization_prs: [],
138
+ }), 'unknown stop signal must fail closed');
139
+ expectThrows(() => planEvaluationCadence(policy, {
140
+ cadence: 'weekly',
141
+ signals: ['hard_violation', 'hard_violation'],
142
+ recent_optimization_prs: [],
143
+ }), 'duplicate stop signals must fail closed');
314
144
  const sparseSignals = [];
315
145
  sparseSignals[1] = 'hard_violation';
316
- expectThrows(()=>planEvaluationCadence(policy, {
317
- cadence: 'weekly',
318
- signals: sparseSignals,
319
- recent_optimization_prs: []
320
- }), 'sparse stop signals must fail closed');
146
+ expectThrows(() => planEvaluationCadence(policy, {
147
+ cadence: 'weekly',
148
+ signals: sparseSignals,
149
+ recent_optimization_prs: [],
150
+ }), 'sparse stop signals must fail closed');
321
151
  }
322
152
  async function testPolicyPublicSafety() {
323
153
  const policy = parseEvaluationCadencePolicy(await loadPolicyFixture());
@@ -326,7 +156,7 @@ async function testPolicyPublicSafety() {
326
156
  contains_third_party_prompt: false,
327
157
  contains_gold: false,
328
158
  contains_oracle: false,
329
- contains_private_data: false
159
+ contains_private_data: false,
330
160
  });
331
161
  }
332
162
  async function main() {
@@ -337,11 +167,8 @@ async function main() {
337
167
  await testPolicyPublicSafety();
338
168
  console.log('evaluation cadence tests: PASS');
339
169
  }
340
- main().catch((error)=>{
170
+ main().catch((error) => {
341
171
  console.error('evaluation cadence tests: FAIL');
342
172
  console.error(error);
343
173
  process.exitCode = 1;
344
174
  });
345
-
346
-
347
- //# sourceURL=ts/scripts/evaluation-cadence-tests.ts