@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.
- package/README.md +102 -194
- package/README.zh-CN.md +115 -210
- package/bin/gotry-backend.js +53 -0
- package/bin/gotry-bootstrap.js +466 -35
- package/bin/gotry-inner.js +255 -36
- package/bin/gotry-process-liveness.d.ts +27 -0
- package/bin/gotry-process-liveness.js +97 -0
- package/bin/gotry-runtime-resolution.d.ts +1 -1
- package/bin/gotry-runtime-resolution.js +2 -2
- package/client/client.js +174 -0
- package/cordis.gotry-patch.yml +70 -93
- package/dist/capabilities/agent-reach-deep.js +45 -122
- package/dist/capabilities/agent-reach.js +63 -148
- package/dist/capabilities/anything.js +89 -75
- package/dist/capabilities/artifacts.js +123 -104
- package/dist/capabilities/channel-health.js +65 -45
- package/dist/capabilities/channel-registry.js +108 -87
- package/dist/capabilities/doctor.js +357 -235
- package/dist/capabilities/effect.js +223 -309
- package/dist/capabilities/fact-log.js +28 -14
- package/dist/capabilities/flyai.js +245 -156
- package/dist/capabilities/ground-transfer.js +509 -0
- package/dist/capabilities/hbcli.js +144 -148
- package/dist/capabilities/hotelbyte-transaction.js +194 -0
- package/dist/capabilities/incident-log.js +131 -61
- package/dist/capabilities/model-override.js +30 -10
- package/dist/capabilities/opensky.js +54 -43
- package/dist/capabilities/resilience.js +50 -32
- package/dist/capabilities/session/action-cache.js +50 -44
- package/dist/capabilities/session/adapters/ctrip-flight.js +119 -62
- package/dist/capabilities/session/adapters/ctrip-hotel.js +125 -110
- package/dist/capabilities/session/adapters/dida-portal.js +206 -0
- package/dist/capabilities/session/adapters/meituan-local.js +35 -54
- package/dist/capabilities/session/adapters/rail-12306.js +169 -112
- package/dist/capabilities/session/benchmark.js +85 -149
- package/dist/capabilities/session/extension-bridge.js +320 -259
- package/dist/capabilities/session/extension-channel.js +57 -76
- package/dist/capabilities/session/extension-distribution.js +115 -119
- package/dist/capabilities/session/extract.js +31 -21
- package/dist/capabilities/session/golden-score.js +55 -33
- package/dist/capabilities/session/health-watch.js +146 -154
- package/dist/capabilities/session/read-guard.js +55 -47
- package/dist/capabilities/session/static-flight-golden.js +49 -36
- package/dist/capabilities/session/transport.js +54 -61
- package/dist/capabilities/session/wizard.js +63 -93
- package/dist/capabilities/session-consent.js +143 -47
- package/dist/capabilities/session-login.js +95 -126
- package/dist/capabilities/session-search.js +391 -253
- package/dist/capabilities/sponsor-plugin.js +341 -0
- package/dist/capabilities/visa-policy.js +87 -73
- package/dist/capabilities/weather.js +163 -235
- package/dist/scripts/action-cache-tests.js +24 -59
- package/dist/scripts/agent-planning-turn-deadline-e2e.js +91 -142
- package/dist/scripts/agent-planning-turn-deadline-tests.js +80 -176
- package/dist/scripts/agent-reach-deep-tests.js +30 -40
- package/dist/scripts/agent-reach-tests.js +26 -18
- package/dist/scripts/agent-reach-wrapper-tests.js +46 -50
- package/dist/scripts/anything-tests.js +58 -62
- package/dist/scripts/artifact-client-contract-tests.js +69 -0
- package/dist/scripts/artifacts-capability-tests.js +235 -0
- package/dist/scripts/async-collect.js +26 -15
- package/dist/scripts/benchmark-environment-bridge-e2e.js +287 -684
- package/dist/scripts/benchmark-environment-bridge-tests.js +818 -3123
- package/dist/scripts/booking-copilot-availability-ledger-binding-tests.js +66 -279
- package/dist/scripts/booking-copilot-availability-policy-tests.js +153 -1257
- package/dist/scripts/booking-copilot-bin-proof-tests.js +22 -45
- package/dist/scripts/booking-copilot-crossrepo-fixture-server.js +64 -76
- package/dist/scripts/booking-copilot-dsh-core-proof-tests.js +69 -199
- package/dist/scripts/booking-copilot-dsh-planner-proof-tests.js +393 -759
- package/dist/scripts/booking-copilot-dsh-plugin-proof-tests.js +33 -75
- package/dist/scripts/booking-copilot-event-sequence-concurrency-proof-tests.js +60 -110
- package/dist/scripts/booking-copilot-gap-code-contract-proof-tests.js +28 -66
- package/dist/scripts/booking-copilot-operation-ledger-concurrency-proof-tests.js +72 -271
- package/dist/scripts/booking-copilot-receipt-ledger-concurrency-proof-tests.js +73 -275
- package/dist/scripts/booking-copilot-runtime-proof-tests.js +784 -3398
- package/dist/scripts/booking-copilot-server-proof-tests.js +63 -168
- package/dist/scripts/booking-copilot-startup-proof-tests.js +38 -124
- package/dist/scripts/booking-executor-tests.js +80 -0
- package/dist/scripts/booking-recovery-chain-tests.js +182 -0
- package/dist/scripts/booking-saga-tests.js +61 -123
- package/dist/scripts/booking-surface-contract-proof-tests.js +152 -1167
- package/dist/scripts/bootstrap-tests.js +1383 -128
- package/dist/scripts/build-changelog.js +89 -130
- package/dist/scripts/build-metrics-report.js +135 -143
- package/dist/scripts/changelog-tests.js +35 -82
- package/dist/scripts/channel-probe-tests.js +44 -116
- package/dist/scripts/channel-probe.js +84 -167
- package/dist/scripts/channel-registry-tests.js +97 -185
- package/dist/scripts/companion-tests.js +25 -70
- package/dist/scripts/dida-cookie-probe.js +87 -0
- package/dist/scripts/dida-sw-probe.js +114 -0
- package/dist/scripts/diff-test.js +17 -12
- package/dist/scripts/doctor-tests.js +428 -120
- package/dist/scripts/dsh-artifact-e2e.js +150 -0
- package/dist/scripts/dsh-artifact-web-e2e.js +443 -0
- package/dist/scripts/dsh-http-proxy-sse-proof.js +90 -0
- package/dist/scripts/dsh-runtime-closure-tests.js +110 -153
- package/dist/scripts/dsh-runtime-closure.js +75 -63
- package/dist/scripts/dsh-session-v3-migration-proof.js +106 -0
- package/dist/scripts/dsh-subprocess-local-proof.js +149 -0
- package/dist/scripts/dsh-target-closure-proof.js +178 -0
- package/dist/scripts/effect-tests.js +165 -552
- package/dist/scripts/engine-run.js +1 -3
- package/dist/scripts/engine-tests.js +16 -10
- package/dist/scripts/evaluation-cadence-tests.js +69 -242
- package/dist/scripts/evaluation-contract-tests.js +193 -499
- package/dist/scripts/extension-distribution-cli.js +19 -15
- package/dist/scripts/extension-distribution-tests.js +98 -211
- package/dist/scripts/extension-tests.js +366 -389
- package/dist/scripts/fact-gate-tests.js +725 -263
- package/dist/scripts/fixtures/extension-bridge-unref-child.mjs +21 -0
- package/dist/scripts/flight-hotel-anchor-363-registered-e2e.js +169 -0
- package/dist/scripts/flight-malformed-tests.js +159 -0
- package/dist/scripts/flyai-tests.js +325 -68
- package/dist/scripts/g5-guard-tests.js +131 -0
- package/dist/scripts/g5-guard.js +189 -0
- package/dist/scripts/gen-lunar-anchors.js +106 -0
- package/dist/scripts/gotry-backend-kernel-tests.js +79 -0
- package/dist/scripts/ground-transfer-tests.js +956 -0
- package/dist/scripts/hbcli-e2e-tests.js +71 -90
- package/dist/scripts/hbcli-live-optin-tests.js +96 -0
- package/dist/scripts/hbcli-release-contract-tests.js +122 -0
- package/dist/scripts/hbcli-tests.js +41 -115
- package/dist/scripts/health-watch-cli.js +42 -28
- package/dist/scripts/hotel-date-gate-tests.js +496 -0
- package/dist/scripts/hotelbyte-reconcile-tests.js +141 -0
- package/dist/scripts/hotelbyte-spawn-e2e-tests.js +373 -0
- package/dist/scripts/i18n-tests.js +16 -9
- package/dist/scripts/incident-tests.js +281 -87
- package/dist/scripts/issue-194-job-id-guard-tests.js +106 -0
- package/dist/scripts/issue-233-cancel-refund-commission-tests.js +392 -0
- package/dist/scripts/issue-271-liveness-tests.js +547 -0
- package/dist/scripts/issue-289-model-retry-real-tests.js +296 -0
- package/dist/scripts/issue-289-model-retry-tests.js +441 -0
- package/dist/scripts/issue-289-web-retry-e2e.js +630 -0
- package/dist/scripts/issue-338-home-city-e2e.js +577 -0
- package/dist/scripts/issue343-real-entry-e2e.js +160 -0
- package/dist/scripts/journey-tests.js +22 -27
- package/dist/scripts/kernel-manifest-evidence.js +109 -0
- package/dist/scripts/kernel-manifest-gate.js +126 -0
- package/dist/scripts/kernel-manifest-tests.js +212 -0
- package/dist/scripts/kernel-manifest-trace-entry.js +7 -0
- package/dist/scripts/kernel-manifest-trace-hook.mjs +28 -0
- package/dist/scripts/kernel-manifest.js +369 -0
- package/dist/scripts/ledger-repair-apply-tests.js +316 -0
- package/dist/scripts/ledger-repair-plan-tests.js +375 -0
- package/dist/scripts/ledger-tests.js +325 -340
- package/dist/scripts/ledger-workflow-crash.js +10 -20
- package/dist/scripts/map-tools-vendor-package-proof.js +206 -134
- package/dist/scripts/memory-capture-tests.js +242 -61
- package/dist/scripts/memory-decay-tests.js +18 -52
- package/dist/scripts/memory-lifecycle-tests.js +657 -0
- package/dist/scripts/memory-lifecycle.js +196 -0
- package/dist/scripts/memory-metrics.js +24 -12
- package/dist/scripts/memory-value-report.js +474 -222
- package/dist/scripts/memory-value-tests.js +328 -0
- package/dist/scripts/metrics-report-tests.js +62 -199
- package/dist/scripts/model-override-e2e.js +66 -105
- package/dist/scripts/nightly-evidence-tests.js +64 -89
- package/dist/scripts/nightly-evidence.js +108 -111
- package/dist/scripts/nudge-digest.js +39 -28
- package/dist/scripts/onboarding-tests.js +63 -88
- package/dist/scripts/opensky-check.js +18 -13
- package/dist/scripts/opensky-tests.js +28 -28
- package/dist/scripts/persona-surface-guard-tests.js +37 -12
- package/dist/scripts/pnpm-dsh-closure-proof.js +2 -5
- package/dist/scripts/policy-anchor-359-registered-e2e.js +214 -0
- package/dist/scripts/price-drift-tests.js +126 -227
- package/dist/scripts/price-drift-watch.js +209 -253
- package/dist/scripts/probe-poi-tests.js +52 -45
- package/dist/scripts/product-metrics.js +187 -273
- package/dist/scripts/publish-preverify.js +47 -41
- package/dist/scripts/realtime-pricing-tests.js +37 -76
- package/dist/scripts/replay-async.js +20 -18
- package/dist/scripts/replay-real.js +16 -18
- package/dist/scripts/replay.js +52 -82
- package/dist/scripts/session-attach-diagnose.js +16 -12
- package/dist/scripts/session-attach-poc.js +34 -37
- package/dist/scripts/session-benchmark.js +66 -147
- package/dist/scripts/session-dida-live-e2e.js +151 -0
- package/dist/scripts/session-extract-tests.js +14 -35
- package/dist/scripts/session-login.js +14 -13
- package/dist/scripts/session-tests.js +545 -583
- package/dist/scripts/sf-live-benchmark.js +92 -110
- package/dist/scripts/sf-live-cli-tests.js +2 -9
- package/dist/scripts/sf-soft-score-tests.js +19 -60
- package/dist/scripts/sf-summary-tests.js +149 -0
- package/dist/scripts/sf-summary.js +466 -84
- package/dist/scripts/skeleton-check.js +16 -14
- package/dist/scripts/skeleton-integration-test.js +11 -10
- package/dist/scripts/skills-contract-tests.js +51 -46
- package/dist/scripts/smoke-session-gate-tests.js +12 -20
- package/dist/scripts/smoke.js +541 -422
- package/dist/scripts/sponsor-reuse-tests.js +262 -0
- package/dist/scripts/state-cli-tests.js +226 -101
- package/dist/scripts/state-cli.js +549 -212
- package/dist/scripts/static-golden-tests.js +46 -180
- package/dist/scripts/time-eval-tests.js +210 -192
- package/dist/scripts/travel-timeline-tests.js +29 -93
- package/dist/scripts/turn-handoff-collect-tests.js +46 -93
- package/dist/scripts/turn-handoff-collect.js +71 -99
- package/dist/scripts/turn-policy-tests.js +28 -29
- package/dist/scripts/typed-contract-canary.js +77 -162
- package/dist/scripts/tz-resolver-sanity.js +50 -0
- package/dist/scripts/tz-resolver-tests.js +584 -0
- package/dist/scripts/unified-tests.js +23 -19
- package/dist/scripts/visa-policy-tests.js +31 -44
- package/dist/scripts/weather-tests.js +121 -543
- package/dist/scripts/wish-channel-gate-tests.js +29 -86
- package/dist/scripts/write-gate-tests.js +522 -0
- package/dist/scripts/z3-lifecycle-fault-tests.js +188 -0
- package/dist/scripts/z3-lifecycle-tests.js +170 -0
- package/dist/scripts/z3-race-repeat-tests.js +39 -0
- package/dist/scripts/z3-race-tests.js +18 -12
- package/dist/src/artifact-gate.js +652 -221
- package/dist/src/backend/kernel.js +91 -0
- package/dist/src/backend/modules/booking-copilot.js +55 -0
- package/dist/src/backend/modules/booking-executor.js +124 -0
- package/dist/src/backend/modules/session-search.js +194 -0
- package/dist/src/benchmark-agent-conformance.js +296 -262
- package/dist/src/benchmark-environment-bridge.js +298 -413
- package/dist/src/benchmark-headless-child-diagnostics.js +93 -100
- package/dist/src/benchmark-tool-isolation.js +94 -67
- package/dist/src/bookable-facts.js +299 -174
- package/dist/src/booking-saga.js +64 -120
- package/dist/src/booking-surface/availability-policy.js +443 -576
- package/dist/src/booking-surface/cancel-refund-commission.js +379 -0
- package/dist/src/booking-surface/contracts.js +24 -80
- package/dist/src/booking-surface/dsh-planner.js +510 -281
- package/dist/src/booking-surface/dsh-plugin.js +17 -1
- package/dist/src/booking-surface/error-codes.js +82 -10
- package/dist/src/booking-surface/index.js +0 -3
- package/dist/src/booking-surface/profile.js +10 -54
- package/dist/src/booking-surface/recovery-chain.js +367 -0
- package/dist/src/booking-surface/runtime.js +765 -891
- package/dist/src/booking-surface/server.js +200 -251
- package/dist/src/booking-surface/startup.js +58 -54
- package/dist/src/booking-surface/validation.js +150 -218
- package/dist/src/bridge.js +20 -13
- package/dist/src/companions.js +48 -74
- package/dist/src/contracts.js +21 -43
- package/dist/src/dsh-llm.js +82 -120
- package/dist/src/engine.js +253 -239
- package/dist/src/evaluation-cadence.js +72 -209
- package/dist/src/evaluation-contracts.js +220 -843
- package/dist/src/flight-pack-adapter.js +54 -0
- package/dist/src/flight-pack-contract.js +2 -0
- package/dist/src/gotry-backend.js +70 -0
- package/dist/src/hotel-date-gate.js +118 -0
- package/dist/src/i18n.js +18 -7
- package/dist/src/index.js +1425 -1629
- package/dist/src/journey.js +132 -81
- package/dist/src/ledger-repair-apply.js +538 -0
- package/dist/src/ledger-repair-plan.js +463 -0
- package/dist/src/loop.js +257 -166
- package/dist/src/memory-capture.js +180 -32
- package/dist/src/memory-decay.js +30 -14
- package/dist/src/memory-lifecycle.js +1310 -0
- package/dist/src/memory-utility.js +27 -40
- package/dist/src/mock-llm.js +36 -61
- package/dist/src/model.js +81 -36
- package/dist/src/realtime-pricing.js +63 -72
- package/dist/src/slot-spec.js +84 -106
- package/dist/src/state-ledger.js +310 -471
- package/dist/src/subagent-job-id-guard.js +58 -0
- package/dist/src/time-anchor.js +231 -33
- package/dist/src/tool-packet.js +20 -8
- package/dist/src/travel-slots.js +58 -35
- package/dist/src/travel-timeline.js +44 -63
- package/dist/src/turn-deadline.js +121 -127
- package/dist/src/turn-policy.js +61 -89
- package/dist/src/tz-resolver.js +143 -0
- package/dist/src/unified.js +504 -381
- package/dist/src/wish-pool.js +39 -14
- package/dist/src/write-gate.js +495 -0
- package/dist/src/z3-shared.js +273 -7
- package/extension/README.md +4 -3
- package/extension/background.js +125 -14
- package/extension/content-bridge.js +23 -1
- package/extension/content-main.js +15 -4
- package/extension/manifest.json +16 -8
- package/package.json +251 -220
- package/ts/capabilities/agent-reach.ts +4 -4
- package/ts/capabilities/anything.ts +1 -1
- package/ts/capabilities/artifacts.ts +46 -9
- package/ts/capabilities/flyai.ts +156 -37
- package/ts/capabilities/hbcli.ts +1 -1
- package/ts/capabilities/incident-log.ts +88 -59
- package/ts/capabilities/session/adapters/ctrip-flight.ts +99 -36
- package/ts/capabilities/session/adapters/dida-portal.ts +250 -0
- package/ts/capabilities/session/adapters/rail-12306.ts +123 -24
- package/ts/capabilities/session/extension-bridge.ts +226 -101
- package/ts/capabilities/session/extension-channel.ts +22 -9
- package/ts/capabilities/session/wizard.ts +2 -2
- package/ts/capabilities/session-consent.ts +98 -14
- package/ts/capabilities/session-login.ts +1 -0
- package/ts/capabilities/session-search.ts +315 -31
- package/ts/dsh-runtime/vendor/README.md +8 -4
- package/ts/dsh-runtime/vendor/dsh-map-tools/README.en.md +7 -1
- package/ts/dsh-runtime/vendor/dsh-map-tools/README.md +5 -3
- package/ts/dsh-runtime/vendor/dsh-map-tools/lib/settings-ns.js +1 -1
- package/ts/dsh-runtime/vendor/dsh-map-tools/lib/types/settings-ns.d.ts +1 -1
- package/ts/dsh-runtime/vendor/dsh-map-tools/package.json +6 -6
- package/ts/package.json +236 -16
- package/ts/scripts/map-tools-vendor-package-proof.ts +152 -31
- package/ts/scripts/state-cli.ts +418 -51
- package/ts/src/artifact-gate.ts +561 -15
- package/ts/src/benchmark-environment-bridge.ts +37 -20
- package/ts/src/bookable-facts.ts +183 -7
- package/ts/src/booking-surface/cancel-refund-commission.ts +488 -0
- package/ts/src/booking-surface/dsh-planner.ts +240 -32
- package/ts/src/booking-surface/dsh-plugin.js +17 -1
- package/ts/src/booking-surface/error-codes.ts +75 -0
- package/ts/src/booking-surface/recovery-chain.ts +409 -0
- package/ts/src/booking-surface/server.ts +84 -51
- package/ts/src/booking-surface/validation.ts +2 -0
- package/ts/src/contracts.ts +12 -2
- package/ts/src/dsh-llm.ts +4 -8
- package/ts/src/index.ts +609 -90
- package/ts/src/loop.ts +116 -7
- package/ts/src/memory-capture.ts +227 -3
- package/ts/src/mock-llm.ts +4 -8
- package/ts/src/model.ts +88 -2
- package/ts/src/state-ledger.ts +47 -29
- package/ts/src/subagent-job-id-guard.ts +72 -0
- package/ts/src/time-anchor.ts +217 -13
- 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();
|