@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,162 +1,140 @@
1
+ /**
2
+ * onboarding UX 测试(issue #21 onboarding UX,§3.3 ADR-21 上架后重设,run-all §40)。
3
+ *
4
+ * 4 段全离线断言(wizard 2026-09-02 缩为 2 步纯 Node 端:扩展落位 + watch precheck):
5
+ * 1. wizard --dry-run:零网络零浏览器零 GUI spawn,exit 0,2 步齐全
6
+ * 2. health-watch 三时序:0ms ready(立即 timeout)/ 5s ready(中途 ready)/ 120s+1ms 超时
7
+ * 3. retry-after-watch:needs-extension → watch ready → 自动重放同 query_id 同参数
8
+ * 4. wizard 无强制 spawn:forcePlatform 参数彻底消失(GUI 跨平台降级退役)
9
+ *
10
+ * 离线纪律:不打真 Chrome、不发真请求;wizard 不需要 spawn 注入(stub 注入路径仍在但 dry-run 路径不调)。
11
+ */
1
12
  import assert from 'node:assert/strict';
2
- import { runOnboardingWizard, defaultExtensionDir, describeExtensionDir } from '../capabilities/session/wizard.js';
3
- import { startExtensionHealthWatch, withAutoRetryOnExtension, HEALTH_WATCH_INTERVAL_FLOOR_MS, HEALTH_WATCH_INTERVAL_CEIL_MS } from '../capabilities/session/health-watch.js';
13
+ import { runOnboardingWizard, defaultExtensionDir, describeExtensionDir, } from '../capabilities/session/wizard.js';
14
+ import { startExtensionHealthWatch, withAutoRetryOnExtension, HEALTH_WATCH_INTERVAL_FLOOR_MS, HEALTH_WATCH_INTERVAL_CEIL_MS, } from '../capabilities/session/health-watch.js';
4
15
  let passed = 0;
5
16
  function check(label, fn) {
6
- return Promise.resolve().then(fn).then(()=>{
7
- passed += 1;
8
- console.log(` ok - ${label}`);
9
- });
17
+ return Promise.resolve()
18
+ .then(fn)
19
+ .then(() => { passed += 1; console.log(` ok - ${label}`); });
10
20
  }
11
21
  function noopSpawn() {
12
22
  const { EventEmitter } = require('node:events');
13
23
  const child = new EventEmitter();
24
+ // 流对象 stub
14
25
  const stream = new EventEmitter();
15
26
  child.stdin = stream;
16
27
  child.stdout = null;
17
28
  child.stderr = null;
18
- child.unref = ()=>undefined;
29
+ child.unref = () => undefined;
19
30
  return child;
20
31
  }
21
32
  function captureSpawn() {
22
33
  const calls = [];
23
- const spawn = (bin, args = [])=>{
24
- calls.push({
25
- bin,
26
- args
27
- });
34
+ const spawn = ((bin, args = []) => {
35
+ calls.push({ bin, args });
28
36
  return noopSpawn();
29
- };
30
- return {
31
- spawn,
32
- calls
33
- };
37
+ });
38
+ return { spawn, calls };
34
39
  }
35
40
  async function asyncSleep(ms) {
36
- if (ms <= 0) return;
37
- await new Promise((resolve)=>setTimeout(resolve, ms));
41
+ if (ms <= 0)
42
+ return;
43
+ await new Promise((resolve) => setTimeout(resolve, ms));
38
44
  }
39
45
  console.log('ONBOARDING UX (§40)');
40
- await check('1. wizard --dry-run 零网络零浏览器零 GUI spawn,exit 0,2 步齐全', async ()=>{
41
- const result = await runOnboardingWizard({
42
- dryRun: true
43
- });
46
+ await check('1. wizard --dry-run 零网络零浏览器零 GUI spawn,exit 0,2 步齐全', async () => {
47
+ const result = await runOnboardingWizard({ dryRun: true });
44
48
  assert.equal(result.ok, true, `wizard ok 应 true,实际 ${JSON.stringify(result.steps)}`);
45
49
  assert.equal(result.steps.length, 2, `应有 2 步,实际 ${result.steps.length}`);
46
- const expected = [
47
- 'ensure-extension-files',
48
- 'watch-extension-ready'
49
- ];
50
- for(let i = 0; i < expected.length; i++){
50
+ const expected = ['ensure-extension-files', 'watch-extension-ready'];
51
+ for (let i = 0; i < expected.length; i++) {
51
52
  assert.equal(result.steps[i].step, expected[i]);
52
53
  assert.equal(result.steps[i].status, 'skip', `dry-run 每步应为 skip,${result.steps[i].step} 实为 ${result.steps[i].status}`);
53
54
  }
54
55
  });
55
- await check('2. health-watch 三时序:0ms / 中途 / 120s+1ms', async ()=>{
56
- const w0 = startExtensionHealthWatch({
57
- timeoutMs: 0,
58
- intervalMs: 10
59
- });
56
+ await check('2. health-watch 三时序:0ms / 中途 / 120s+1ms', async () => {
57
+ // (a) timeoutMs=0 → 立即 timeout
58
+ const w0 = startExtensionHealthWatch({ timeoutMs: 0, intervalMs: 10 });
60
59
  const o0 = await w0.waitReady();
61
60
  assert.equal(o0.ready, false);
62
61
  assert.equal(o0.reason, 'timeout');
62
+ // (b) 中途 ready:第一次 probe false,第二次 true(30ms 后)
63
63
  let probeCalls = 0;
64
64
  const wMid = startExtensionHealthWatch({
65
65
  timeoutMs: 500,
66
66
  intervalMs: 30,
67
- probe: async ()=>{
68
- probeCalls += 1;
69
- return probeCalls >= 2;
70
- }
67
+ probe: async () => { probeCalls += 1; return probeCalls >= 2; },
71
68
  });
72
69
  const oMid = await wMid.waitReady();
73
70
  assert.equal(oMid.ready, true, `中途 ready 实为 ${JSON.stringify(oMid)}`);
74
71
  assert.ok(oMid.attempts >= 2);
72
+ // (c) 永不 ready → timeout(用极小 timeoutMs+全 false probe 模拟)
75
73
  const wTimeout = startExtensionHealthWatch({
76
74
  timeoutMs: 60,
77
75
  intervalMs: 20,
78
- probe: async ()=>false
76
+ probe: async () => false,
79
77
  });
80
78
  const oTimeout = await wTimeout.waitReady();
81
79
  assert.equal(oTimeout.ready, false);
82
80
  assert.equal(oTimeout.reason, 'timeout');
83
81
  });
84
- await check('3. wizard 完全不调 spawn(GUI 面板/剪贴板/直开浏览器均已退役)', async ()=>{
82
+ await check('3. wizard 完全不调 spawn(GUI 面板/剪贴板/直开浏览器均已退役)', async () => {
83
+ // 2026-09-02 上架后:wizard 缩为 2 步纯 Node 端职责(扩展落位 + watch precheck),
84
+ // 不弹 osascript/zenity、不动 pbcopy/xclip/clip、不 open 浏览器。
85
+ // 这里只校验 dry-run 与无源目录 fail 路径都不产生 spawn 调用。
85
86
  const dry = captureSpawn();
86
- await runOnboardingWizard({
87
- dryRun: true,
88
- sourceDir: '/',
89
- extensionDir: '/tmp/none'
90
- });
87
+ await runOnboardingWizard({ dryRun: true, sourceDir: '/', extensionDir: '/tmp/none' });
91
88
  assert.equal(dry.calls.length, 0, `dry-run 不应 spawn 任何命令(实调 ${dry.calls.length})`);
92
89
  const fail = captureSpawn();
93
- await runOnboardingWizard({
94
- dryRun: false,
95
- sourceDir: '/nonexistent-source-dir-for-onboarding-tests',
96
- extensionDir: '/tmp/none-fail'
97
- });
90
+ // dryRun=false + 不存在的源目录 → ensure 会 fail,但应仍不产生 spawn 调用
91
+ await runOnboardingWizard({ dryRun: false, sourceDir: '/nonexistent-source-dir-for-onboarding-tests', extensionDir: '/tmp/none-fail' });
98
92
  assert.equal(fail.calls.length, 0, `fail 路径也不应 spawn(实调 ${fail.calls.length})`);
99
93
  });
100
- await check('4. retry-after-watch:needs-extension → watch ready → 自动重放同 query_id', async ()=>{
94
+ await check('4. retry-after-watch:needs-extension → watch ready → 自动重放同 query_id', async () => {
101
95
  let fetchCalls = 0;
102
96
  const queryId = 'sf-01';
103
- const fetch = async ()=>{
97
+ const fetch = async () => {
104
98
  fetchCalls += 1;
105
- return {
106
- query_id: queryId,
107
- verdict: 'needs-extension',
108
- needsExt: fetchCalls === 1
109
- };
99
+ return { query_id: queryId, verdict: 'needs-extension', needsExt: fetchCalls === 1 };
110
100
  };
101
+ // 第一次 → needs-extension,启 watch
111
102
  const first = await fetch();
112
103
  assert.equal(first.verdict, 'needs-extension');
113
104
  let probeCount = 0;
114
105
  const watch = startExtensionHealthWatch({
115
106
  timeoutMs: 1_000,
116
107
  intervalMs: 20,
117
- probe: async ()=>{
118
- probeCount += 1;
119
- return probeCount >= 2;
120
- }
108
+ probe: async () => { probeCount += 1; return probeCount >= 2; },
121
109
  });
122
110
  const outcome = await watch.waitReady();
123
111
  assert.equal(outcome.ready, true);
112
+ // watch ready → 自动重放同 query_id
124
113
  const retry = await fetch();
125
114
  assert.equal(retry.query_id, queryId, '同 query_id 必须保持');
126
115
  assert.equal(fetchCalls, 2, `应调用 fetch 两次(首次 + 重放),实 ${fetchCalls}`);
127
116
  });
128
- await check('5. wizard 不依赖 platform/panel 参数(GUI 跨平台降级退役)', async ()=>{
129
- const result = await runOnboardingWizard({
130
- dryRun: true,
131
- extensionDir: '/tmp/gotry-test-ext-2'
132
- });
117
+ await check('5. wizard 不依赖 platform/panel 参数(GUI 跨平台降级退役)', async () => {
118
+ // 2026-09-02 上架后:wizard 不再接 forcePlatform/spawn panel 参数,
119
+ // 任何对 wizard 的调用都是 2 步(ensure + watch precheck)。
120
+ const result = await runOnboardingWizard({ dryRun: true, extensionDir: '/tmp/gotry-test-ext-2' });
133
121
  assert.equal(result.steps.length, 2, `应 2 步,实 ${result.steps.length}`);
134
122
  assert.equal(result.steps[0].step, 'ensure-extension-files');
135
123
  assert.equal(result.steps[1].step, 'watch-extension-ready');
136
124
  assert.equal(result.platform, undefined, 'platform 字段应不再存在');
137
125
  });
138
- await check('6. withAutoRetryOnExtension 端到端:首次 needs-ext → 自动重放', async ()=>{
126
+ await check('6. withAutoRetryOnExtension 端到端:首次 needs-ext → 自动重放', async () => {
139
127
  let callCount = 0;
140
128
  let ready = false;
141
- setTimeout(()=>{
142
- ready = true;
143
- }, 30);
129
+ // watch 第一次 probe 后 30ms 标记 ready(模拟用户装完扩展)
130
+ setTimeout(() => { ready = true; }, 30);
144
131
  const args = {
145
- fetch: async ()=>{
132
+ fetch: async () => {
146
133
  callCount += 1;
147
- return callCount === 1 ? {
148
- needsExt: true
149
- } : {
150
- needsExt: false,
151
- hit: true
152
- };
134
+ return callCount === 1 ? { needsExt: true } : { needsExt: false, hit: true };
153
135
  },
154
- isExtensionNeeded: (r)=>r.needsExt === true,
155
- watch: {
156
- timeoutMs: 1_000,
157
- intervalMs: 20,
158
- probe: async ()=>ready
159
- }
136
+ isExtensionNeeded: (r) => r.needsExt === true,
137
+ watch: { timeoutMs: 1_000, intervalMs: 20, probe: async () => ready },
160
138
  };
161
139
  const out = await withAutoRetryOnExtension(args);
162
140
  assert.equal(out.retried, true, `应触发重放,实 retried=${out.retried}`);
@@ -165,15 +143,15 @@ await check('6. withAutoRetryOnExtension 端到端:首次 needs-ext → 自动
165
143
  assert.equal(out.result.hit, true);
166
144
  assert.equal(callCount, 2, `withAutoRetry 应调 2 次 fetch,实 ${callCount}`);
167
145
  });
168
- await check('7. health-watch interval 边界常量与 watch 契约对齐', ()=>{
146
+ await check('7. health-watch interval 边界常量与 watch 契约对齐', () => {
169
147
  assert.ok(HEALTH_WATCH_INTERVAL_FLOOR_MS >= 1_000, '下界不应让 watch 风暴');
170
148
  assert.ok(HEALTH_WATCH_INTERVAL_CEIL_MS <= 44_000, '上界应 < EXTENSION_CONNECTED_WINDOW_MS');
171
149
  });
172
- await check('8. defaultExtensionDir = ~/.gotry/extension(契约对齐 bootstrap 节)', ()=>{
150
+ await check('8. defaultExtensionDir = ~/.gotry/extension(契约对齐 bootstrap 节)', () => {
173
151
  const dir = defaultExtensionDir();
174
152
  assert.match(dir, /\.gotry[\\/]extension$/, `扩展目录形态应是 ~/.gotry/extension,实 ${dir}`);
175
153
  });
176
- await check('9. describeExtensionDir:不存在的目录不抛错,返回 exists:false', ()=>{
154
+ await check('9. describeExtensionDir:不存在的目录不抛错,返回 exists:false', () => {
177
155
  const desc = describeExtensionDir('/nonexistent/zzz');
178
156
  assert.equal(desc.exists, false);
179
157
  assert.equal(desc.fileCount, 0);
@@ -181,6 +159,3 @@ await check('9. describeExtensionDir:不存在的目录不抛错,返回 exists:f
181
159
  });
182
160
  await asyncSleep(0);
183
161
  console.log(`ONBOARDING UX (§40): ${passed} pass`);
184
-
185
-
186
- //# sourceURL=ts/scripts/onboarding-tests.ts
@@ -1,20 +1,25 @@
1
+ /**
2
+ * OpenSky 校验桥(M2 段 3 第一件,§7-1 免费路线的校验层):验证某航班真实执飞。
3
+ * 零新依赖:匿名 REST(400 credits/天),失败降级为「校验不可用」而非阻塞规划。
4
+ * 证据链:[实时API:opensky] + 抓取时间;查不到≠不存在(ADS-B 覆盖有限),只作正向印证。
5
+ * 运行:cd ts && npx tsx scripts/opensky-check.ts EK329
6
+ */
1
7
  const BASE = 'https://opensky-network.org/api';
2
8
  async function checkArrival(callsign, airport) {
9
+ // 匿名窗口只支持近 7 天;演示用最近的到达查询验证桥通不通
3
10
  const now = Math.floor(Date.now() / 1000);
4
- const url = airport ? `${BASE}/arrivals?airport=${airport}&begin=${now - 7 * 86400}&end=${now}` : `${BASE}/arrivals?airport=OMDB&begin=${now - 7 * 86400}&end=${now}`;
5
- const res = await fetch(url, {
6
- headers: {
7
- Accept: 'application/json'
8
- }
9
- });
10
- if (!res.ok) return `[校验不可用:opensky ${res.status}]`;
11
- const data = await res.json();
12
- const hit = data.find((a)=>(a.callsign ?? '').trim().toUpperCase().includes(callsign.toUpperCase()));
11
+ const url = airport
12
+ ? `${BASE}/arrivals?airport=${airport}&begin=${now - 7 * 86400}&end=${now}`
13
+ : `${BASE}/arrivals?airport=OMDB&begin=${now - 7 * 86400}&end=${now}`;
14
+ const res = await fetch(url, { headers: { Accept: 'application/json' } });
15
+ if (!res.ok)
16
+ return `[校验不可用:opensky ${res.status}]`;
17
+ const data = (await res.json());
18
+ const hit = data.find(a => (a.callsign ?? '').trim().toUpperCase().includes(callsign.toUpperCase()));
13
19
  const ts = new Date().toISOString();
14
- return hit ? `[实时API:opensky@${ts}] ✅ ${callsign} 近 7 天执飞记录:到达 ${hit.arrivalAirport ?? '?'}(callsign ${hit.callsign?.trim()})` : `[实时API:opensky@${ts}] ○ 近 7 天 ${airport ?? 'OMDB'} 到达列表未见 ${callsign}(ADS-B 覆盖有限,不作否定结论)`;
20
+ return hit
21
+ ? `[实时API:opensky@${ts}] ✅ ${callsign} 近 7 天执飞记录:到达 ${hit.arrivalAirport ?? '?'}(callsign ${hit.callsign?.trim()})`
22
+ : `[实时API:opensky@${ts}] ○ 近 7 天 ${airport ?? 'OMDB'} 到达列表未见 ${callsign}(ADS-B 覆盖有限,不作否定结论)`;
15
23
  }
16
24
  const target = process.argv[2] ?? 'EK329';
17
25
  console.log(await checkArrival(target, process.argv[3] ?? null));
18
-
19
-
20
- //# sourceURL=ts/scripts/opensky-check.ts
@@ -1,52 +1,52 @@
1
+ /**
2
+ * opensky 能力层测试(免费匿名 API):
3
+ * 1. 真实航班号(可能不是当前在飞)→ 命中时 observed,查空时 not_observed(三值语义)
4
+ * 2. 完全不在飞的小众号 → not_observed
5
+ * 3. 网络超时 → unavailable(降级不抛错)
6
+ * 4. 证据链:各 verdict 正确标注
7
+ *
8
+ * 注:OpenSky 当前 ADS-B 全球观测并非同一时间覆盖所有航班——EK329 一天
9
+ * 飞数十次但中间有「不在飞」的窗口。所以验 not_observed 也是有效路径。
10
+ *
11
+ * 运行: cd ts && npx tsx scripts/opensky-tests.ts
12
+ */
1
13
  import assert from 'node:assert/strict';
2
14
  import { verifyFlight } from '../capabilities/opensky.js';
3
- const live = await verifyFlight({
4
- callsign: 'EK329',
5
- airport: 'OMDB'
6
- });
15
+ // 1. 真实航班号 + 明确目的地机场(机场能筛掉部分不命中)
16
+ // EK329 是 LHR-DXB 路径。观察时段不命中时 verdict='not_observed',不是错误。
17
+ const live = await verifyFlight({ callsign: 'EK329', airport: 'OMDB' });
7
18
  assert.ok(live.sampleSize >= 0, 'sampleSize ≥ 0(空数组也合法)');
8
- assert.ok([
9
- 'observed',
10
- 'not_observed',
11
- 'unavailable'
12
- ].includes(live.verdict), `verdict 三值之一:${live.verdict}`);
19
+ assert.ok(['observed', 'not_observed', 'unavailable'].includes(live.verdict), `verdict 三值之一:${live.verdict}`);
13
20
  if (live.verdict === 'observed') {
14
21
  assert.ok((live.hits?.length ?? 0) > 0, 'observed 必须配 hits');
15
22
  const h = live.hits[0];
16
23
  assert.ok(typeof h.icao24 === 'string' && h.icao24.length > 0, 'icao24 存在');
17
24
  assert.match(live.evidence, /\[实时API:opensky@/, '证据链标注');
18
25
  console.log(`1. EK329 OMDB → ${live.verdict} (sample=${live.sampleSize}, hits=${live.hits?.length}) OK`);
19
- } else if (live.verdict === 'not_observed') {
26
+ }
27
+ else if (live.verdict === 'not_observed') {
20
28
  assert.match(live.evidence, /○|not_observed|未见/, 'not_observed 标注 ○');
21
29
  console.log(`1. EK329 OMDB → not_observed 当前观测窗没飞 (o) OK`);
22
- } else {
30
+ }
31
+ else {
32
+ // unavailable = API 限流/不可达,失败也合法
23
33
  assert.match(live.evidence, /error/, 'unavailable 标注 error');
24
34
  console.log(`1. EK329 OMDB → unavailable (API 异常,降级合法) OK`);
25
35
  }
26
- const fake = await verifyFlight({
27
- callsign: 'XXDODO1234',
28
- airport: 'OMDB'
29
- });
30
- assert.ok([
31
- 'not_observed',
32
- 'unavailable'
33
- ].includes(fake.verdict), `期望 not_observed/unavailable,实际 ${fake.verdict}`);
36
+ // 2. 完全不存在的航班号 not_observed 或 unavailable(API 限流 429 时走 unavailable)
37
+ const fake = await verifyFlight({ callsign: 'XXDODO1234', airport: 'OMDB' });
38
+ assert.ok(['not_observed', 'unavailable'].includes(fake.verdict), `期望 not_observed/unavailable,实际 ${fake.verdict}`);
34
39
  if (fake.verdict === 'not_observed') {
35
40
  assert.match(fake.evidence, /○/, 'not_observed 标 ○');
36
41
  console.log('2. XXDODO1234 OMDB → not_observed (○) OK');
37
- } else {
42
+ }
43
+ else {
38
44
  console.log('2. XXDODO1234 OMDB → unavailable (API 限流 OK) OK');
39
45
  }
46
+ // 3. 网络超时 → unavailable
40
47
  import { verifyFlight as vf } from '../capabilities/opensky.js';
41
- const to = await vf({
42
- callsign: 'EK329',
43
- airport: 'OMDB',
44
- timeoutMs: 1
45
- });
48
+ const to = await vf({ callsign: 'EK329', airport: 'OMDB', timeoutMs: 1 });
46
49
  assert.equal(to.verdict, 'unavailable', `timeout 应 unavailable,实际 ${to.verdict}`);
47
50
  assert.match(to.evidence, /error/, 'unavailable 证据带 error');
48
51
  console.log('3. timeout → unavailable OK');
49
52
  console.log('\nOPEN-SKY TESTS: 3/3 OK(免费匿名 OpenSky API)');
50
-
51
-
52
- //# sourceURL=ts/scripts/opensky-tests.ts
@@ -1,24 +1,49 @@
1
+ /**
2
+ * persona 表层护栏测试(issue #192/#2/#194 回归锚;2026-09-11 契约瘦身改锚,
3
+ * 全离线,只读仓根 patch):
4
+ * 1. (10) 域边界含表层规则句——gotry 能力一律是工具调用,绝不把 gotry_* 传给
5
+ * skill 加载器(dsh skill 面名合法域 ^[a-z0-9]+(-[a-z0-9]+)*$,下划线必抛
6
+ * invalid skill name,rc18 真实用户踩坑);
7
+ * 2. 行为契约 13 条编号完整(2026-09-11 瘦身 23→13,防后续编辑吞条目;窄域
8
+ * 细则归位工具描述/路由卡,persona 只留跨场景行为契约);
9
+ * 3. skill 失败后的行为指引存在(改回 tool call,不换名重试 skill);
10
+ * 4. (4) 候选时段示例枚举绑定锚点卡——澄清卡/访谈/选项不列已过节日
11
+ * (#2 rc18 真实复发:卡把已过的春节/清明/五一当「想用的时候」示例);
12
+ * 5. (13) 后台协作——子任务等待纪律(#194 rc19 实踩:子代理回执 id 不是
13
+ * job id,job_output 轮询子代理 = unknown job 硬错误)+ 永不宣称「工具
14
+ * 预算已耗尽」(ADR-24 v2:唯一边界是运行时时间闸);
15
+ * 6. 动态变量注入面完整——current_date/time_anchor_card/motivation_brief/
16
+ * channel_routing_card 四个引用缺一不可(瘦身不得吞注入面)。
17
+ *
18
+ * 运行: cd ts && npx tsx scripts/persona-surface-guard-tests.ts
19
+ */
1
20
  import assert from 'node:assert/strict';
2
21
  import { readFileSync } from 'node:fs';
3
22
  import { join } from 'node:path';
4
23
  const patch = readFileSync(join(process.cwd(), '..', 'cordis.gotry-patch.yml'), 'utf-8');
24
+ // 1. 表层规则句存在且仅一次
5
25
  const guard = '表层规则:gotry 的全部能力一律是【工具调用】';
6
26
  assert.equal((patch.match(new RegExp(guard, 'g')) ?? []).length, 1, '表层规则句应恰好出现一次');
7
27
  assert.ok(patch.includes('绝不把 gotry_* 名字传给 skill 加载器'), '应显式禁止 gotry_* 进 skill 加载器');
8
- const markers = new Set([
9
- ...patch.matchAll(/\((\d{1,2})\)/g)
10
- ].map((m)=>Number(m[1])));
11
- for(let i = 1; i <= 23; i += 1){
28
+ // 2. 行为契约 13 条编号完整(2026-09-11 瘦身 23→13)
29
+ const markers = new Set([...patch.matchAll(/\((\d{1,2})\)/g)].map((m) => Number(m[1])));
30
+ for (let i = 1; i <= 13; i += 1) {
12
31
  assert.ok(markers.has(i), `行为契约 (${i}) 应存在`);
13
32
  }
14
- assert.equal(markers.size, 23, `契约条目应恰为 23 条,实际 ${markers.size}`);
33
+ assert.equal(markers.size, 13, `契约条目应恰为 13 条,实际 ${markers.size}`);
34
+ // 3. skill 用错面后的行为指引
15
35
  assert.ok(patch.includes('改回 tool call'), '应指引失败后改回 tool call');
16
- assert.ok(patch.includes('澄清卡/访谈/选项里向用户列出的候选时段示例'), '#2 回归:候选时段示例条款应存在');
36
+ // 4. #2 复发回归锚:澄清卡示例枚举同样过锚点卡(契约 (4) 内部澄清)
37
+ assert.ok(patch.includes('候选时段示例'), '#2 回归:候选时段示例条款应存在');
17
38
  assert.ok(patch.includes('已过的节日不进示例枚举'), '应禁止已过节日进澄清卡示例枚举');
18
- assert.ok(patch.includes('(23)子任务等待纪律'), '#194 回归:子任务等待纪律条款应存在');
39
+ // 5. #194 回归锚:子任务等待纪律((13) 后台协作)
40
+ assert.ok(patch.includes('(13)后台协作'), '#194 回归:后台协作条款应存在');
19
41
  assert.ok(patch.includes('对子代理绝不调用 job_output/job_kill'), '应禁止对子代理调用 job_output/job_kill');
20
- assert.ok(patch.includes("job_output/job_kill 只用于"), '应限定 job_output/job_kill 的适用面');
21
- console.log('PERSONA SURFACE GUARD TESTS: 5/5 OK(表层规则句 / 23 条契约完整 / skill 失败行为指引 / 澄清卡示例过锚点卡 / 子任务等待纪律)');
22
-
23
-
24
- //# sourceURL=ts/scripts/persona-surface-guard-tests.ts
42
+ assert.ok(patch.includes('job_output/job_kill 只用于'), '应限定 job_output/job_kill 的适用面');
43
+ // ADR-24 v2:工具循环唯一边界是运行时时间闸
44
+ assert.ok(patch.includes('工具预算已耗尽'), 'ADR-24 v2:永不宣称工具预算耗尽的指引应存在');
45
+ // 6. 动态变量注入面完整(瘦身不得吞注入面)
46
+ for (const v of ['{{current_date}}', '{{time_anchor_card}}', '{{motivation_brief}}', '{{channel_routing_card}}']) {
47
+ assert.ok(patch.includes(v), `persona 应保留动态变量引用 ${v}`);
48
+ }
49
+ console.log('PERSONA SURFACE GUARD TESTS: 6/6 OK(表层规则句 / 13 条契约完整 / skill 失败行为指引 / 澄清卡示例过锚点卡 / 子任务等待纪律+预算话术 / 动态变量注入面)');
@@ -2,7 +2,7 @@ import assert from 'node:assert/strict';
2
2
  import { readFileSync } from 'node:fs';
3
3
  import { resolve } from 'node:path';
4
4
  import { REQUIRED_BENCHMARK_DSH_VERSION } from '../../bin/gotry-runtime-resolution.js';
5
- import { parsePnpmDshLock, REQUIRED_DSH_RUNTIME_PACKAGE_COUNT, validateDshRuntimeClosure } from './dsh-runtime-closure.js';
5
+ import { parsePnpmDshLock, REQUIRED_DSH_RUNTIME_PACKAGE_COUNT, validateDshRuntimeClosure, } from './dsh-runtime-closure.js';
6
6
  const consumerRoot = process.argv[2];
7
7
  assert.ok(consumerRoot, 'usage: pnpm-dsh-closure-proof.ts <clean-consumer-root>');
8
8
  const installedPackage = JSON.parse(readFileSync(resolve(consumerRoot, 'node_modules/@danceiny/gotry/package.json'), 'utf8'));
@@ -11,10 +11,7 @@ const closure = validateDshRuntimeClosure({
11
11
  dependencies: installedPackage.dependencies ?? {},
12
12
  lockPackages,
13
13
  runtimeVersion: REQUIRED_BENCHMARK_DSH_VERSION,
14
- expectedPackageCount: REQUIRED_DSH_RUNTIME_PACKAGE_COUNT
14
+ expectedPackageCount: REQUIRED_DSH_RUNTIME_PACKAGE_COUNT,
15
15
  });
16
16
  assert.equal(closure.names.length, REQUIRED_DSH_RUNTIME_PACKAGE_COUNT, 'clean pnpm consumer must resolve the complete Round 5 DSH closure');
17
17
  console.log(`PNPM DSH CLOSURE PROOF: ${closure.names.length} packages at ${closure.version}`);
18
-
19
-
20
- //# sourceURL=ts/scripts/pnpm-dsh-closure-proof.ts