@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
@@ -0,0 +1,189 @@
1
+ /**
2
+ * G5 内部差旅桥机械闸(issue #348;governance/复用矩阵纪律的机械化,不是新政策)。
3
+ *
4
+ * 背景:G5 = 「内部差旅工具桥(T 系统侧,脱敏)」的创始人审批门,当前关闭
5
+ * (docs/gotry-master-outline.md 决策门表 + #348)。复用矩阵纪律:内部资产只能
6
+ * bridge/reference,桥接前必须有创始人显式授权。本脚本把该约束落成机械检查:
7
+ * 1. 扫描全部 git-tracked 文件(排除第三方/生成物/创始人私有 state)中
8
+ * 「G5 桥接引用」形状的标识符/配置/文案;
9
+ * 2. 命中时要求 docs/g5-authorization-ledger.md 存在覆盖该路径的 GRANT 条目
10
+ * (含 issue/决策链接);没有 → exit 1,输出可操作指引。
11
+ *
12
+ * 边界(诚实声明):本闸只证明「无授权记录 → 桥接引用不落地」;
13
+ * GRANT 条目只能由创始人侧维护,agent 自助授权不被本闸承认(作者身份靠
14
+ * git review,机械不可证)。真实 G5 授权本身仍是创始人决策(#348)。
15
+ *
16
+ * 命名面豁免(NAMING_SURFACES):门定义/授权台账/guard 自身必须能「提到」
17
+ * 这条关闭中的 lane,否则 tracker 无法描述自己的门。除此之外一律要求 GRANT。
18
+ *
19
+ * 用法:cd ts && npx tsx scripts/g5-guard.ts [--root <dir>]
20
+ * 退出码:0 = 通过;1 = 存在未授权引用;2 = 闸自身无法运行(缺台账/git 失败)。
21
+ * 自测:cd ts && npx tsx scripts/g5-guard-tests.ts(全离线,临时 fixture)。
22
+ */
23
+ import { spawnSync } from 'node:child_process';
24
+ import { existsSync, readFileSync } from 'node:fs';
25
+ import { dirname, join, resolve } from 'node:path';
26
+ import { fileURLToPath } from 'node:url';
27
+ export const LEDGER_REL = 'docs/g5-authorization-ledger.md';
28
+ export const ISSUE_348_URL = 'https://github.com/Danceiny/gotry/issues/348';
29
+ /**
30
+ * 「G5 桥接引用」的机械形状:标识符/配置键/插件名/中英文邻接短语。
31
+ * 边界用显式 lookaround 而非 `\b`:下划线是 word char,`\b` 会漏掉
32
+ * snake_case(G5_BRIDGE_*)与 camelCase(G5Bridge)相邻形状。
33
+ */
34
+ export const G5_BRIDGE_PATTERNS = [
35
+ { name: 'g5-adjacent-bridge-identifier', regex: /(?<![a-z0-9])g5[\s_-]{0,2}(bridge|bridged|bridging|adapter|adaptor|mcp)/i },
36
+ { name: 'bridge-adjacent-g5-identifier', regex: /(?<![a-z0-9])(bridge|bridged|bridging|adapter|adaptor)[\s_-]{0,2}g5(?![0-9])/i },
37
+ { name: 'internal-travel-mcp-plugin-id', regex: /\bcapability-travel-mcp\b/i },
38
+ { name: 't-system-bridge-identifier', regex: /(?<![a-z0-9])t[-_ ]?system[\s_-]{0,2}(bridge|bridged|bridging|adapter|adaptor|mcp)/i },
39
+ { name: 'bridge-adjacent-t-system', regex: /(?<![a-z0-9])(bridge|bridged|bridging|adapter|adaptor)[\s_-]{0,2}t[-_ ]?system/i },
40
+ { name: 'chinese-g5-bridge-adjacency', regex: /g5\s*桥|桥\s*g5/i },
41
+ { name: 'chinese-t-system-bridge-adjacency', regex: /T\s*系统\s*(桥|适配|接入)|(桥接|接入)\s*T\s*系统/ },
42
+ ];
43
+ /**
44
+ * 命名面豁免:这些文件被允许「提到」G5 lane(定义它/授权它/检测它),
45
+ * 它们不是授权——真实桥接落在其它任何文件都仍需台账 GRANT。
46
+ * - master-outline 对:G5 门定义 + 复用矩阵 T 系统行(tracker 本体);
47
+ * - 授权台账对:授权面自身;
48
+ * - guard + 自测:检测器必须含有自己的检测串。
49
+ */
50
+ export const NAMING_SURFACES = new Set([
51
+ 'docs/gotry-master-outline.md',
52
+ 'docs/gotry-master-outline.zh-CN.md',
53
+ 'docs/g5-authorization-ledger.md',
54
+ 'docs/g5-authorization-ledger.zh-CN.md',
55
+ 'ts/scripts/g5-guard.ts',
56
+ 'ts/scripts/g5-guard-tests.ts',
57
+ ]);
58
+ /** 排除段:第三方闭包/生成物/创始人私有产品数据(只读红线目录也不扫)。 */
59
+ const EXCLUDED_SEGMENTS = ['node_modules', 'vendor', 'dist', '.git', 'dsh-runtime', 'gotry-state'];
60
+ const LOCKFILE_BASENAMES = new Set(['package-lock.json', 'pnpm-lock.yaml', 'uv.lock', 'bun.lock', 'bun.lockb', 'npm-shrinkwrap.json']);
61
+ const BINARY_EXTENSIONS = new Set([
62
+ '.png', '.jpg', '.jpeg', '.gif', '.ico', '.webp', '.woff', '.woff2', '.ttf', '.otf', '.eot',
63
+ '.mp4', '.mov', '.zip', '.gz', '.tgz', '.bz2', '.7z', '.pdf', '.wasm', '.node', '.dylib', '.so', '.bin', '.icns',
64
+ ]);
65
+ export function isExcludedPath(relPath) {
66
+ const segments = relPath.split('/');
67
+ if (segments.some((s) => EXCLUDED_SEGMENTS.includes(s)))
68
+ return true;
69
+ const base = segments[segments.length - 1];
70
+ if (LOCKFILE_BASENAMES.has(base))
71
+ return true;
72
+ const dot = base.lastIndexOf('.');
73
+ if (dot >= 0 && BINARY_EXTENSIONS.has(base.slice(dot).toLowerCase()))
74
+ return true;
75
+ return false;
76
+ }
77
+ /** 单文件内容扫描:返回全部命中行(文件级,供 collectHits 逐文件调用)。 */
78
+ export function scanContent(relPath, content) {
79
+ const hits = [];
80
+ const lines = content.split('\n');
81
+ for (let i = 0; i < lines.length; i += 1) {
82
+ const line = lines[i];
83
+ for (const { name, regex } of G5_BRIDGE_PATTERNS) {
84
+ if (regex.test(line)) {
85
+ hits.push({ path: relPath, line: i + 1, pattern: name, text: line.trim().slice(0, 160) });
86
+ break; // 一行一次足矣,避免同 pattern 行内重复刷屏
87
+ }
88
+ }
89
+ }
90
+ return hits;
91
+ }
92
+ /** 台账 GRANT 行:`- GRANT: <glob> — <说明,必须含 issue/决策链接>`;code fence 内的行(模板/示例)不算数。 */
93
+ export function parseGrants(ledgerText) {
94
+ const grants = [];
95
+ let malformed = 0;
96
+ let inFence = false;
97
+ for (const rawLine of ledgerText.split('\n')) {
98
+ if (/^`{3,}/.test(rawLine.trim())) {
99
+ inFence = !inFence;
100
+ continue;
101
+ }
102
+ if (inFence)
103
+ continue;
104
+ const match = rawLine.match(/^-\s*GRANT:\s*(\S+)\s+—\s+(.+)$/);
105
+ if (!match)
106
+ continue;
107
+ // 无 issue/决策链接的 GRANT 视为不成立(fail closed),单独计数以便报错指引
108
+ if (!/#\d+|https?:\/\//.test(match[2])) {
109
+ malformed += 1;
110
+ continue;
111
+ }
112
+ grants.push({ glob: match[1], description: match[2].trim() });
113
+ }
114
+ return { grants, malformed };
115
+ }
116
+ /** glob → 路径正则:`**` 跨段,`*` 单段内,`?` 单字符。 */
117
+ export function globToRegExp(glob) {
118
+ const escaped = glob
119
+ .replace(/[.+^${}()|[\]\\]/g, '\\$&')
120
+ .replace(/\*\*/g, '\u0000')
121
+ .replace(/\*/g, '[^/]*')
122
+ .replace(/\?/g, '[^/]')
123
+ .replace(/\u0000/g, '.*');
124
+ return new RegExp(`^${escaped}$`);
125
+ }
126
+ export function grantCovers(grant, relPath) {
127
+ return globToRegExp(grant.glob).test(relPath);
128
+ }
129
+ function listTrackedFiles(root) {
130
+ const result = spawnSync('git', ['ls-files', '-z'], { cwd: root, encoding: 'buffer' });
131
+ if (result.error || result.status !== 0) {
132
+ console.error(`G5 GUARD: 无法枚举 git-tracked 文件(需要 git 仓库): ${result.error?.message ?? result.stderr?.toString().trim()}`);
133
+ process.exit(2);
134
+ }
135
+ return result.stdout.toString().split('\0').filter(Boolean);
136
+ }
137
+ function main() {
138
+ const args = process.argv.slice(2);
139
+ const rootIndex = args.indexOf('--root');
140
+ const root = rootIndex >= 0 ? resolve(args[rootIndex + 1]) : resolve(dirname(fileURLToPath(import.meta.url)), '..', '..');
141
+ const ledgerPath = join(root, LEDGER_REL);
142
+ if (!existsSync(ledgerPath)) {
143
+ console.error(`G5 GUARD: 授权台账不存在: ${LEDGER_REL}(闸配置错误,exit 2;台账由创始人侧维护)`);
144
+ process.exit(2);
145
+ }
146
+ const ledger = parseGrants(readFileSync(ledgerPath, 'utf8'));
147
+ const hits = [];
148
+ let scanned = 0;
149
+ for (const relPath of listTrackedFiles(root)) {
150
+ if (isExcludedPath(relPath))
151
+ continue;
152
+ if (NAMING_SURFACES.has(relPath))
153
+ continue;
154
+ const abs = join(root, relPath);
155
+ let content;
156
+ try {
157
+ content = readFileSync(abs, 'utf8');
158
+ }
159
+ catch {
160
+ continue; // 不可读(权限/符号链接悬空):跳过,不属于闸的裁决面
161
+ }
162
+ if (content.includes('\0'))
163
+ continue; // 二进制内容:跳过
164
+ scanned += 1;
165
+ hits.push(...scanContent(relPath, content));
166
+ }
167
+ if (hits.length === 0) {
168
+ console.log(`G5 GUARD: OK — ${scanned} 个 tracked 文件中无未授权 G5 桥引用;台账 GRANT: ${ledger.grants.length}${ledger.malformed ? `(另有 ${ledger.malformed} 条缺 issue/决策链接的 GRANT 被拒)` : ''}`);
169
+ process.exit(0);
170
+ }
171
+ const uncovered = hits.filter((hit) => !ledger.grants.some((grant) => grantCovers(grant, hit.path)));
172
+ for (const hit of hits) {
173
+ const covered = ledger.grants.some((grant) => grantCovers(grant, hit.path));
174
+ console.error(` ${hit.path}:${hit.line} [${hit.pattern}]${covered ? ' (已授权)' : ''} ${hit.text}`);
175
+ }
176
+ if (uncovered.length === 0) {
177
+ console.log(`G5 GUARD: OK — ${hits.length} 处 G5 桥引用均被台账 GRANT 覆盖`);
178
+ process.exit(0);
179
+ }
180
+ console.error(`G5 GUARD: FAIL — ${uncovered.length} 处未授权的 G5 内部差旅桥引用(共扫描 ${scanned} 个文件):`);
181
+ console.error('G5 门当前关闭:桥接内部旅行系统(T 系统)前必须获得创始人显式授权,可执行其一:');
182
+ console.error(` 1. 由创始人在 ${LEDGER_REL} 增加覆盖上述路径的 GRANT 条目(含 issue/决策链接;仅创始人侧维护,agent 不得自助授权);`);
183
+ console.error(' 2. 或移除引用,保持外部供应商路径(公共 MIT hotelbyte-cli 进程桥)。');
184
+ console.error(`Tracker: ${ISSUE_348_URL}(复用矩阵:内部资产只能 bridge/reference,禁止代码/schema 搬运)`);
185
+ process.exit(1);
186
+ }
187
+ const isDirectRun = process.argv[1] && resolve(process.argv[1]) === fileURLToPath(import.meta.url);
188
+ if (isDirectRun)
189
+ main();
@@ -0,0 +1,106 @@
1
+ /**
2
+ * 春节锚点表生成器(issue #274,D-9 清偿:手抄常量表已被否决——「换个日子的同款债务」)。
3
+ *
4
+ * 用 lunar-typescript(devDependency,MIT,零传递依赖,不进 runtime bundle)在构建期把
5
+ * 正月初一锚点机械生成到 SPRING_FESTIVAL 表,回写 ../src/time-anchor.ts 的生成块
6
+ * ([gen:lunar-anchors:begin/end] 标记之间);首次运行会把旧手抄表原位迁移为生成块。
7
+ * 扩表/换库 = 重跑本命令;表未变则为无 diff 幂等(生成时间只在表真变时刷新)。
8
+ *
9
+ * 运行(在 ts/ 下):
10
+ * npx tsx scripts/gen-lunar-anchors.ts # 生成并回写(全离线,不访问网络)
11
+ * npx tsx scripts/gen-lunar-anchors.ts --check # 只比对不写:表/库版本漂移即非零退出
12
+ * # (挂 run-all-tests.sh §58 漂移闸)
13
+ *
14
+ * 交叉验证不在这里做:2026-2031 旧表 6 条 + 港天文台 2032-2040 核实 9 条已固化为
15
+ * time-eval §7 的双 oracle 断言(红→绿:生成前 oracle B 必红)。
16
+ */
17
+ import { readFileSync, writeFileSync } from 'node:fs';
18
+ import { join } from 'node:path';
19
+ import { Lunar } from 'lunar-typescript';
20
+ const TARGET = join(import.meta.dirname, '..', 'src', 'time-anchor.ts');
21
+ const BEGIN = '// [gen:lunar-anchors:begin] 生成块起点——手改会被下次生成覆盖';
22
+ const END = '// [gen:lunar-anchors:end]';
23
+ const START_YEAR = 2026;
24
+ const END_YEAR = 2099;
25
+ /** 正月初一 → 公历 YYYY-MM-DD(lunar-typescript:农历年 y 正月初一 的 Solar)。 */
26
+ function springFestivalOf(lunarYear) {
27
+ return Lunar.fromYmd(lunarYear, 1, 1).getSolar().toYmd();
28
+ }
29
+ function buildTable() {
30
+ const table = {};
31
+ for (let y = START_YEAR; y <= END_YEAR; y++)
32
+ table[y] = springFestivalOf(y);
33
+ return table;
34
+ }
35
+ function libVersion() {
36
+ const pkg = JSON.parse(readFileSync(join(import.meta.dirname, '..', 'node_modules', 'lunar-typescript', 'package.json'), 'utf-8'));
37
+ return pkg.version;
38
+ }
39
+ function renderBlock(table, generatedAt) {
40
+ const entries = Object.keys(table).map(y => ` ${y}: '${table[Number(y)]}',`).join('\n');
41
+ return `/**
42
+ * 春节锚点表(正月初一;仅此节日漂移大,故表驱动;元旦/国庆固定月日按「下一次发生」算)。
43
+ * 本块由构建期生成器机械生成,禁止手改(issue #274:手抄常量表=换个日子的同款债务,已否决)。
44
+ * provenance:lunar-typescript@${libVersion()}(MIT,零传递依赖,devDependency 不进 runtime)· 生成时间 ${generatedAt}
45
+ * 命令:cd ts && npx tsx scripts/gen-lunar-anchors.ts(扩表/换库=重跑;--check=漂移闸,run-all §58)
46
+ * 交叉验证:2026-2031 旧表 6 条 + 港天文台 2032-2040 核实 9 条逐条一致(time-eval §7 双 oracle)。
47
+ * 到期守卫:springFestivalHorizonOk——最晚锚点年份 < 当前年+3 测试即红(临近耗尽先红于静默缺失)。
48
+ */
49
+ ${BEGIN}
50
+ export const SPRING_FESTIVAL: Record<number, string> = {
51
+ ${entries}
52
+ }
53
+ ${END}`;
54
+ }
55
+ /** 提取文件中现有生成块;无标记则匹配旧手抄声明(含其上一行单行 doc 注释)原位迁移。 */
56
+ function extractExisting(src) {
57
+ const b = src.indexOf(BEGIN);
58
+ const e = src.indexOf(END);
59
+ if (b !== -1 && e !== -1) {
60
+ const end = e + END.length;
61
+ return { block: src.slice(b, end), replaceFrom: next => src.slice(0, b) + next + src.slice(end) };
62
+ }
63
+ const legacy = src.match(/(?:\/\*\*[^\n]*\*\/\n)?(?:export )?const SPRING_FESTIVAL: Record<number, string> = \{\n(?: \d{4}: '\d{4}-\d{2}-\d{2}',\n)+\}/);
64
+ if (!legacy)
65
+ throw new Error('未找到 SPRING_FESTIVAL 表(既无生成标记也无手抄声明)');
66
+ const m = legacy[0];
67
+ return { block: null, replaceFrom: next => src.replace(m, next) };
68
+ }
69
+ /** 从块文本解析 年→日期 映射(--check 与幂等判定用,生成时间/库版本不参与比较)。 */
70
+ function parseTable(block) {
71
+ const table = {};
72
+ if (!block)
73
+ return table;
74
+ for (const m of block.matchAll(/(\d{4}): '(\d{4}-\d{2}-\d{2})'/g))
75
+ table[Number(m[1])] = m[2];
76
+ return table;
77
+ }
78
+ function tablesEqual(a, b) {
79
+ const ka = Object.keys(a);
80
+ const kb = Object.keys(b);
81
+ return ka.length === kb.length && ka.every(k => a[Number(k)] === b[Number(k)]);
82
+ }
83
+ const check = process.argv.includes('--check');
84
+ const table = buildTable();
85
+ const src = readFileSync(TARGET, 'utf-8');
86
+ const { block, replaceFrom } = extractExisting(src);
87
+ if (block && tablesEqual(parseTable(block), table)) {
88
+ console.log(`lunar-anchors:表已是最新(${START_YEAR}-${END_YEAR},共 ${Object.keys(table).length} 条),无 diff`);
89
+ process.exit(0);
90
+ }
91
+ const next = renderBlock(table, new Date().toISOString());
92
+ if (check) {
93
+ console.error(`lunar-anchors:漂移!${TARGET} 与生成器输出不一致(表内容或生成块缺失),应重跑:cd ts && npx tsx scripts/gen-lunar-anchors.ts`);
94
+ if (block) {
95
+ const have = parseTable(block);
96
+ const want = table;
97
+ for (let y = Math.min(START_YEAR, ...Object.keys(have).map(Number)); y <= END_YEAR; y++) {
98
+ if (have[y] !== want[y])
99
+ console.error(` ${y}: 文件=${have[y] ?? '(缺)'} 生成=${want[y] ?? '(缺)'}`);
100
+ }
101
+ }
102
+ process.exit(1);
103
+ }
104
+ writeFileSync(TARGET, replaceFrom(next));
105
+ const diffYears = Object.keys(table).filter(y => !block || parseTable(block)[Number(y)] !== table[Number(y)]);
106
+ console.log(`lunar-anchors:已回写 ${TARGET}(覆盖 ${START_YEAR}-${END_YEAR},共 ${Object.keys(table).length} 条;本次新增/变更 ${diffYears.length} 条)`);
@@ -0,0 +1,79 @@
1
+ import { closeBackend, createBackendServer } from '../src/backend/kernel.js';
2
+ import { startSessionSearchModule } from '../src/backend/modules/session-search.js';
3
+ const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
4
+ let pass = 0;
5
+ let fail = 0;
6
+ const check = (cond, label) => {
7
+ if (cond) {
8
+ pass += 1;
9
+ console.log(` ok - ${label}`);
10
+ }
11
+ else {
12
+ fail += 1;
13
+ console.log(` FAIL - ${label}`);
14
+ }
15
+ };
16
+ async function jfetch(url, init) {
17
+ const r = await fetch(url, init);
18
+ let body = null;
19
+ try {
20
+ body = await r.json();
21
+ }
22
+ catch { /* 空体 */ }
23
+ return { status: r.status, body };
24
+ }
25
+ async function main() {
26
+ // M1 内核:路由精确分发 + 未知 404 + 异常隔离 500(进程不倒)
27
+ const okModule = {
28
+ name: 'fake-ok',
29
+ routes: [{ method: 'GET', path: '/m1/ping', handle: (_req, res) => { res.setHeader('content-type', 'application/json'); res.end(JSON.stringify({ pong: true })); } }],
30
+ };
31
+ const boomModule = {
32
+ name: 'fake-boom',
33
+ routes: [{ method: 'GET', path: '/m2/boom', handle: async () => { throw new Error('boom'); } }],
34
+ };
35
+ const session = startSessionSearchModule({
36
+ apiKey: () => 'test-key',
37
+ search: async () => ({
38
+ ok: true, via: 'session-dida-portal', evidence: '[会话:dida-portal@test]', latencyMs: 1, verdict: 'hit',
39
+ rates: [{ hotelName: 'T', roomName: 'R', ratePlanId: 'RP', price: 100, currency: 'CNY', referenceNo: 'REF' }],
40
+ }),
41
+ });
42
+ const handle = await createBackendServer({ modules: [okModule, boomModule, session], port: 0 });
43
+ const base = `http://127.0.0.1:${handle.port}`;
44
+ try {
45
+ const ping = await jfetch(`${base}/m1/ping`);
46
+ check(ping.status === 200 && ping.body.pong === true, '模块路由精确分发');
47
+ const nf = await jfetch(`${base}/nope`);
48
+ check(nf.status === 404 && nf.body.error?.code === 'not_found', '未知路由 404');
49
+ const boom = await jfetch(`${base}/m2/boom`);
50
+ check(boom.status === 500 && boom.body.error?.code === 'gotry_backend_module_error', '模块异常隔离 500(服务面不倒)');
51
+ const afterBoom = await jfetch(`${base}/m1/ping`);
52
+ check(afterBoom.status === 200, '异常后服务面存活');
53
+ check(handle.moduleNames.includes('session-search') && handle.moduleNames.includes('fake-ok'), '模块注册表名单');
54
+ // M2 session-search 模块:鉴权 fail-closed + 注入 fake 检索合同
55
+ const noAuth = await jfetch(`${base}/v1/session/search`, { method: 'POST', body: '{"supplier":"dida-portal"}' });
56
+ check(noAuth.status === 403, '无 token 403');
57
+ const badSupplier = await jfetch(`${base}/v1/session/search`, {
58
+ method: 'POST',
59
+ headers: { authorization: 'Bearer test-key', 'content-type': 'application/json' },
60
+ body: '{"supplier":"ctrip-flight"}',
61
+ });
62
+ check(badSupplier.status === 400, '未知供应商通道 400');
63
+ const hit = await jfetch(`${base}/v1/session/search`, {
64
+ method: 'POST',
65
+ headers: { authorization: 'Bearer test-key', 'content-type': 'application/json' },
66
+ body: '{"supplier":"dida-portal"}',
67
+ });
68
+ const hitBody = hit.body;
69
+ check(hit.status === 200 && hitBody.verdict === 'hit' && hitBody.rates?.[0]?.ratePlanId === 'RP', '注入 fake 检索:结果合同透传');
70
+ }
71
+ finally {
72
+ await closeBackend(handle, [okModule, boomModule, session]).catch(() => { });
73
+ }
74
+ await sleep(50);
75
+ console.log(`\nGOTRY BACKEND KERNEL: ${pass} pass, ${fail} fail`);
76
+ if (fail > 0)
77
+ process.exitCode = 1;
78
+ }
79
+ void main();