@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
|
@@ -1,39 +1,36 @@
|
|
|
1
|
+
/** Closed dsh capability-tool registration proof (no dsh runtime required). */
|
|
1
2
|
import assert from 'node:assert/strict';
|
|
2
3
|
import { Ajv2020 } from 'ajv/dist/2020.js';
|
|
4
|
+
// @ts-expect-error Runtime dsh plugins are JavaScript modules registered by path.
|
|
3
5
|
import { apply, embeddedBookingToolDefinitions } from '../src/booking-surface/dsh-plugin.js';
|
|
4
6
|
const registered = [];
|
|
5
7
|
apply({
|
|
6
8
|
tools: {
|
|
7
|
-
register (tool)
|
|
8
|
-
|
|
9
|
-
}
|
|
10
|
-
}
|
|
9
|
+
register(tool) { registered.push(tool); },
|
|
10
|
+
},
|
|
11
11
|
});
|
|
12
12
|
assert.equal(registered.length, 6);
|
|
13
|
-
assert.deepEqual(registered.map((tool)=>tool.name), [
|
|
13
|
+
assert.deepEqual(registered.map((tool) => tool.name), [
|
|
14
14
|
'booking_search_hotels',
|
|
15
15
|
'booking_refine_results',
|
|
16
16
|
'booking_find_room_offers',
|
|
17
17
|
'booking_compare_offers',
|
|
18
18
|
'booking_prepare_booking',
|
|
19
|
-
'booking_observe_booking'
|
|
19
|
+
'booking_observe_booking',
|
|
20
20
|
]);
|
|
21
21
|
assert.deepEqual(registered, embeddedBookingToolDefinitions);
|
|
22
|
-
assert.ok(!registered.some((tool)
|
|
23
|
-
assert.ok(registered.every((tool)=>{
|
|
22
|
+
assert.ok(!registered.some((tool) => /gotry_book|trade|payment/i.test(String(tool.name))));
|
|
23
|
+
assert.ok(registered.every((tool) => {
|
|
24
24
|
const parameters = tool.parameters;
|
|
25
25
|
return parameters.additionalProperties === false && Object.keys(parameters.properties ?? {}).join(',') === 'decision';
|
|
26
26
|
}), 'every model-facing tool accepts only one typed decision envelope');
|
|
27
|
-
const prepare = registered.find((tool)=>tool.name === 'booking_prepare_booking');
|
|
27
|
+
const prepare = registered.find((tool) => tool.name === 'booking_prepare_booking');
|
|
28
28
|
const prepareParameters = prepare.parameters;
|
|
29
29
|
const operationBranches = prepareParameters.properties.decision.oneOf[0]?.properties?.action?.oneOf ?? [];
|
|
30
30
|
assert.equal(operationBranches.length, 2, 'prepare-booking exposes offer.check + checkout.prepare only');
|
|
31
31
|
assert.ok(!JSON.stringify(prepare.parameters).includes('book"'), 'schema has no Book discriminator');
|
|
32
|
-
const search = registered.find((tool)=>tool.name === 'booking_search_hotels');
|
|
33
|
-
const validateSearchTool = new Ajv2020({
|
|
34
|
-
allErrors: true,
|
|
35
|
-
strict: true
|
|
36
|
-
}).compile(search.parameters);
|
|
32
|
+
const search = registered.find((tool) => tool.name === 'booking_search_hotels');
|
|
33
|
+
const validateSearchTool = new Ajv2020({ allErrors: true, strict: true }).compile(search.parameters);
|
|
37
34
|
const validSearchDecision = {
|
|
38
35
|
decision: {
|
|
39
36
|
kind: 'operation',
|
|
@@ -49,51 +46,27 @@ const validSearchDecision = {
|
|
|
49
46
|
patch: {
|
|
50
47
|
budget: {
|
|
51
48
|
strength: 'must',
|
|
52
|
-
value: {
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
}
|
|
49
|
+
value: { max: { amount: '1000', currency: 'AED', sourceFactRef: 'fact-budget-1' } },
|
|
50
|
+
},
|
|
51
|
+
},
|
|
52
|
+
},
|
|
53
|
+
},
|
|
54
|
+
},
|
|
64
55
|
};
|
|
65
56
|
assert.equal(validateSearchTool(validSearchDecision), true, JSON.stringify(validateSearchTool.errors));
|
|
66
|
-
assert.equal(validateSearchTool({
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
schemaVersion: 'booking.surface',
|
|
71
|
-
kind: 'search.run',
|
|
72
|
-
actionId: 'action-model-v2',
|
|
73
|
-
contextRef: 'ctx-model-1',
|
|
74
|
-
expectedRevision: 0,
|
|
75
|
-
reason: 'Run the authoritative workspace search.',
|
|
76
|
-
factRefs: [],
|
|
77
|
-
input: {}
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
}), true, JSON.stringify(validateSearchTool.errors));
|
|
57
|
+
assert.equal(validateSearchTool({ decision: { kind: 'operation', action: {
|
|
58
|
+
schemaVersion: 'booking.surface', kind: 'search.run', actionId: 'action-model-v2', contextRef: 'ctx-model-1', expectedRevision: 0,
|
|
59
|
+
reason: 'Run the authoritative workspace search.', factRefs: [], input: {},
|
|
60
|
+
} } }), true, JSON.stringify(validateSearchTool.errors));
|
|
81
61
|
assert.equal(validateSearchTool({
|
|
82
62
|
...validSearchDecision,
|
|
83
63
|
decision: {
|
|
84
64
|
...validSearchDecision.decision,
|
|
85
65
|
action: {
|
|
86
66
|
...validSearchDecision.decision.action,
|
|
87
|
-
input: {
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
strength: 'must',
|
|
91
|
-
value: true
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
}
|
|
67
|
+
input: { patch: { unknownCriterion: { strength: 'must', value: true } } },
|
|
68
|
+
},
|
|
69
|
+
},
|
|
97
70
|
}), false, 'model-facing tool schema closes nested search criteria');
|
|
98
71
|
assert.equal(validateSearchTool({
|
|
99
72
|
...validSearchDecision,
|
|
@@ -105,18 +78,12 @@ assert.equal(validateSearchTool({
|
|
|
105
78
|
patch: {
|
|
106
79
|
budget: {
|
|
107
80
|
strength: 'must',
|
|
108
|
-
value: {
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
}
|
|
81
|
+
value: { max: { amount: 1000, currency: 'AED', sourceFactRef: 'fact-budget-1' } },
|
|
82
|
+
},
|
|
83
|
+
},
|
|
84
|
+
},
|
|
85
|
+
},
|
|
86
|
+
},
|
|
120
87
|
}), false, 'model-facing Money.amount rejects numbers');
|
|
121
88
|
assert.equal(validateSearchTool({
|
|
122
89
|
...validSearchDecision,
|
|
@@ -124,17 +91,8 @@ assert.equal(validateSearchTool({
|
|
|
124
91
|
...validSearchDecision.decision,
|
|
125
92
|
action: {
|
|
126
93
|
...validSearchDecision.decision.action,
|
|
127
|
-
input: {
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
email: 'x@example.com'
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
}
|
|
94
|
+
input: { patch: { holder: { email: 'x@example.com' } } },
|
|
95
|
+
},
|
|
96
|
+
},
|
|
136
97
|
}), false, 'model-facing tool schema rejects nested holder data');
|
|
137
98
|
console.log('BOOKING COPILOT DSH PLUGIN PROOF: exact six typed tools/no Book OK');
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
//# sourceURL=ts/scripts/booking-copilot-dsh-plugin-proof-tests.ts
|
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Real multi-process proof for task-scoped Booking Copilot event sequencing.
|
|
3
|
+
*
|
|
4
|
+
* Run from the repository root with Node 24:
|
|
5
|
+
* npx tsx ts/scripts/booking-copilot-event-sequence-concurrency-proof-tests.ts
|
|
6
|
+
*/
|
|
1
7
|
import assert from 'node:assert/strict';
|
|
2
8
|
import { existsSync, mkdirSync, mkdtempSync, rmSync, writeFileSync } from 'node:fs';
|
|
3
9
|
import { spawn } from 'node:child_process';
|
|
@@ -8,35 +14,14 @@ import { ensureLedger } from '../src/state-ledger.js';
|
|
|
8
14
|
import { BookingCopilotTaskRuntime } from '../src/booking-surface/runtime.js';
|
|
9
15
|
const taskId = 'task-event-sequence-atomicity';
|
|
10
16
|
const workspace = {
|
|
11
|
-
schemaVersion: 'booking.surface',
|
|
12
|
-
|
|
13
|
-
surface: 'tenant',
|
|
14
|
-
revision: 0,
|
|
15
|
-
locale: 'en-US',
|
|
16
|
-
currency: 'AED',
|
|
17
|
-
searchDraft: {},
|
|
18
|
-
results: {
|
|
19
|
-
status: 'idle'
|
|
20
|
-
},
|
|
21
|
-
visibleHotels: [],
|
|
22
|
-
loadedOffers: [],
|
|
23
|
-
shortlistedOfferRefs: [],
|
|
24
|
-
capabilities: {
|
|
25
|
-
surface: 'tenant',
|
|
26
|
-
allowedActions: [
|
|
27
|
-
'search.run'
|
|
28
|
-
]
|
|
29
|
-
}
|
|
17
|
+
schemaVersion: 'booking.surface', contextRef: 'ctx-event-sequence-atomicity', surface: 'tenant', revision: 0,
|
|
18
|
+
locale: 'en-US', currency: 'AED', searchDraft: {}, results: { status: 'idle' }, visibleHotels: [], loadedOffers: [], shortlistedOfferRefs: [],
|
|
19
|
+
capabilities: { surface: 'tenant', allowedActions: ['search.run'] },
|
|
30
20
|
};
|
|
31
21
|
const turn = {
|
|
32
|
-
schemaVersion: 'booking.surface',
|
|
33
|
-
kind: 'user.turn',
|
|
34
|
-
taskId,
|
|
22
|
+
schemaVersion: 'booking.surface', kind: 'user.turn', taskId,
|
|
35
23
|
turnId: 'seq-anchor-turn',
|
|
36
|
-
workspace,
|
|
37
|
-
request: {
|
|
38
|
-
text: 'opaque user turn'
|
|
39
|
-
}
|
|
24
|
+
workspace, request: { text: 'opaque user turn' },
|
|
40
25
|
};
|
|
41
26
|
const childIndex = process.argv.indexOf('--child');
|
|
42
27
|
const child = childIndex >= 0;
|
|
@@ -45,17 +30,20 @@ const childMode = child ? process.argv[childIndex + 2] : undefined;
|
|
|
45
30
|
const childVariant = child ? process.argv[childIndex + 3] : undefined;
|
|
46
31
|
function sleepWhile(predicate, timeoutMs = 10_000) {
|
|
47
32
|
const deadline = Date.now() + timeoutMs;
|
|
48
|
-
while(!predicate()){
|
|
49
|
-
if (Date.now() > deadline)
|
|
33
|
+
while (!predicate()) {
|
|
34
|
+
if (Date.now() > deadline)
|
|
35
|
+
throw new Error('proof_barrier_timeout');
|
|
50
36
|
Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, 5);
|
|
51
37
|
}
|
|
52
38
|
}
|
|
53
39
|
function waitForFile(path, timeoutMs = 10_000) {
|
|
54
|
-
return new Promise((resolve, reject)=>{
|
|
40
|
+
return new Promise((resolve, reject) => {
|
|
55
41
|
const deadline = Date.now() + timeoutMs;
|
|
56
|
-
const poll = ()=>{
|
|
57
|
-
if (existsSync(path))
|
|
58
|
-
|
|
42
|
+
const poll = () => {
|
|
43
|
+
if (existsSync(path))
|
|
44
|
+
return resolve();
|
|
45
|
+
if (Date.now() > deadline)
|
|
46
|
+
return reject(new Error(`proof_file_timeout:${path}`));
|
|
59
47
|
setTimeout(poll, 5);
|
|
60
48
|
};
|
|
61
49
|
poll();
|
|
@@ -64,39 +52,25 @@ function waitForFile(path, timeoutMs = 10_000) {
|
|
|
64
52
|
function runChild(root, mode, variant) {
|
|
65
53
|
const script = fileURLToPath(import.meta.url);
|
|
66
54
|
const tsx = fileURLToPath(new URL('../node_modules/tsx/dist/cli.mjs', import.meta.url));
|
|
67
|
-
const processChild = spawn(process.execPath, [
|
|
68
|
-
|
|
69
|
-
script,
|
|
70
|
-
'--child',
|
|
71
|
-
root,
|
|
72
|
-
mode,
|
|
73
|
-
variant
|
|
74
|
-
], {
|
|
75
|
-
cwd: process.cwd(),
|
|
76
|
-
stdio: [
|
|
77
|
-
'ignore',
|
|
78
|
-
'pipe',
|
|
79
|
-
'pipe'
|
|
80
|
-
]
|
|
55
|
+
const processChild = spawn(process.execPath, [tsx, script, '--child', root, mode, variant], {
|
|
56
|
+
cwd: process.cwd(), stdio: ['ignore', 'pipe', 'pipe'],
|
|
81
57
|
});
|
|
82
58
|
let output = '';
|
|
83
|
-
processChild.stdout.on('data', (chunk)=>{
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
output += chunk.toString();
|
|
88
|
-
});
|
|
89
|
-
return new Promise((resolve, reject)=>{
|
|
90
|
-
const timer = setTimeout(()=>{
|
|
59
|
+
processChild.stdout.on('data', (chunk) => { output += chunk.toString(); });
|
|
60
|
+
processChild.stderr.on('data', (chunk) => { output += chunk.toString(); });
|
|
61
|
+
return new Promise((resolve, reject) => {
|
|
62
|
+
const timer = setTimeout(() => {
|
|
91
63
|
processChild.kill('SIGKILL');
|
|
92
64
|
reject(new Error(`child_timeout:${mode}:${variant}:${output}`));
|
|
93
65
|
}, 15_000);
|
|
94
|
-
processChild.on('exit', (code)=>{
|
|
66
|
+
processChild.on('exit', (code) => {
|
|
95
67
|
clearTimeout(timer);
|
|
96
|
-
if (code !== 0)
|
|
68
|
+
if (code !== 0)
|
|
69
|
+
return reject(new Error(`child_exit_${code}:${mode}:${variant}:${output}`));
|
|
97
70
|
try {
|
|
98
71
|
resolve(JSON.parse(output.trim().split('\n').at(-1)));
|
|
99
|
-
}
|
|
72
|
+
}
|
|
73
|
+
catch (error) {
|
|
100
74
|
reject(new Error(`child_output_invalid:${mode}:${variant}:${output}:${error}`));
|
|
101
75
|
}
|
|
102
76
|
});
|
|
@@ -109,98 +83,74 @@ if (child) {
|
|
|
109
83
|
const ledger = ensureLedger(root);
|
|
110
84
|
const runtime = new BookingCopilotTaskRuntime(ledger);
|
|
111
85
|
writeFileSync(join(root, `started-${mode}-${variant}`), 'started');
|
|
112
|
-
sleepWhile(()=>existsSync(join(root, 'start')));
|
|
86
|
+
sleepWhile(() => existsSync(join(root, 'start')));
|
|
87
|
+
// The old implementation read the task outside its write transaction. This
|
|
88
|
+
// barrier makes both workers hold the same stale fold before either append;
|
|
89
|
+
// an immediate transaction permits only one worker to reach this point.
|
|
113
90
|
const originalResume = runtime.resumeTask.bind(runtime);
|
|
114
91
|
let firstRead = true;
|
|
115
|
-
runtime.resumeTask = (id)=>{
|
|
92
|
+
runtime.resumeTask = (id) => {
|
|
116
93
|
const state = originalResume(id);
|
|
117
94
|
if (firstRead && state) {
|
|
118
95
|
firstRead = false;
|
|
119
96
|
writeFileSync(join(root, `ready-${mode}-${variant}`), 'ready');
|
|
120
|
-
sleepWhile(()=>existsSync(join(root, 'release')));
|
|
97
|
+
sleepWhile(() => existsSync(join(root, 'release')));
|
|
121
98
|
}
|
|
122
99
|
return state;
|
|
123
100
|
};
|
|
124
101
|
try {
|
|
125
|
-
if (mode === 'user-turn')
|
|
126
|
-
...turn,
|
|
127
|
-
|
|
128
|
-
});
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
});
|
|
133
|
-
console.log(JSON.stringify({
|
|
134
|
-
event: {
|
|
135
|
-
sequence: event.sequence
|
|
136
|
-
}
|
|
137
|
-
}));
|
|
138
|
-
} catch (error) {
|
|
139
|
-
console.log(JSON.stringify({
|
|
140
|
-
error: error instanceof Error ? error.message : String(error)
|
|
141
|
-
}));
|
|
102
|
+
if (mode === 'user-turn')
|
|
103
|
+
runtime.startTask({ ...turn, turnId: `seq-${variant}-turn` });
|
|
104
|
+
const event = runtime.emitEvent(taskId, { kind: 'status', status: 'working' });
|
|
105
|
+
console.log(JSON.stringify({ event: { sequence: event.sequence } }));
|
|
106
|
+
}
|
|
107
|
+
catch (error) {
|
|
108
|
+
console.log(JSON.stringify({ error: error instanceof Error ? error.message : String(error) }));
|
|
142
109
|
process.exitCode = 1;
|
|
143
|
-
}
|
|
110
|
+
}
|
|
111
|
+
finally {
|
|
144
112
|
ledger.close();
|
|
145
113
|
}
|
|
146
|
-
}
|
|
114
|
+
}
|
|
115
|
+
else {
|
|
147
116
|
async function run(mode) {
|
|
148
117
|
const root = mkdtempSync(join(tmpdir(), `gotry-event-sequence-${mode}-`));
|
|
149
|
-
mkdirSync(root, {
|
|
150
|
-
recursive: true
|
|
151
|
-
});
|
|
118
|
+
mkdirSync(root, { recursive: true });
|
|
152
119
|
const ledger = ensureLedger(root);
|
|
153
120
|
new BookingCopilotTaskRuntime(ledger).startTask(turn);
|
|
154
121
|
ledger.close();
|
|
155
|
-
const children = [
|
|
156
|
-
runChild(root, mode, 'left'),
|
|
157
|
-
runChild(root, mode, 'right')
|
|
158
|
-
];
|
|
122
|
+
const children = [runChild(root, mode, 'left'), runChild(root, mode, 'right')];
|
|
159
123
|
try {
|
|
160
124
|
await Promise.all([
|
|
161
125
|
waitForFile(join(root, `started-${mode}-left`)),
|
|
162
|
-
waitForFile(join(root, `started-${mode}-right`))
|
|
126
|
+
waitForFile(join(root, `started-${mode}-right`)),
|
|
163
127
|
]);
|
|
164
128
|
writeFileSync(join(root, 'start'), 'start');
|
|
165
129
|
await Promise.race([
|
|
166
130
|
waitForFile(join(root, `ready-${mode}-left`)),
|
|
167
|
-
waitForFile(join(root, `ready-${mode}-right`))
|
|
131
|
+
waitForFile(join(root, `ready-${mode}-right`)),
|
|
168
132
|
]);
|
|
169
|
-
await new Promise((resolve)=>setTimeout(resolve, 250));
|
|
133
|
+
await new Promise((resolve) => setTimeout(resolve, 250));
|
|
170
134
|
assert.equal(existsSync(join(root, `ready-${mode}-left`)) && existsSync(join(root, `ready-${mode}-right`)), false, `${mode} workers both derived state before the first transaction committed`);
|
|
171
135
|
writeFileSync(join(root, 'release'), 'release');
|
|
172
136
|
const results = await Promise.all(children);
|
|
173
|
-
assert.deepEqual(results.map((result)=>result.error), [
|
|
174
|
-
undefined,
|
|
175
|
-
undefined
|
|
176
|
-
]);
|
|
137
|
+
assert.deepEqual(results.map((result) => result.error), [undefined, undefined]);
|
|
177
138
|
const check = ensureLedger(root);
|
|
178
139
|
const rows = check.db.prepare("SELECT payload FROM events WHERE tenant_id = ? AND run_id = ? AND kind = 'booking.copilot.event.emitted' ORDER BY seq").all(check.tenant, taskId);
|
|
179
|
-
const sequences = rows.map((row)=>JSON.parse(row.payload).sequence);
|
|
180
|
-
assert.deepEqual(sequences, [
|
|
181
|
-
|
|
182
|
-
2
|
|
183
|
-
], `${mode} durable event sequences must be unique and strictly monotonic`);
|
|
184
|
-
assert.deepEqual(results.map((result)=>result.event?.sequence).sort((a, b)=>a - b), [
|
|
185
|
-
1,
|
|
186
|
-
2
|
|
187
|
-
]);
|
|
140
|
+
const sequences = rows.map((row) => JSON.parse(row.payload).sequence);
|
|
141
|
+
assert.deepEqual(sequences, [1, 2], `${mode} durable event sequences must be unique and strictly monotonic`);
|
|
142
|
+
assert.deepEqual(results.map((result) => result.event?.sequence).sort((a, b) => a - b), [1, 2]);
|
|
188
143
|
if (mode === 'user-turn') {
|
|
189
144
|
const userTurns = check.db.prepare("SELECT COUNT(*) AS n FROM events WHERE tenant_id = ? AND run_id = ? AND kind = 'booking.copilot.user.turn.observed'").get(check.tenant, taskId);
|
|
190
145
|
assert.equal(userTurns.n, 3, 'initial plus two concurrent user turns must all be durable');
|
|
191
146
|
}
|
|
192
147
|
check.close();
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
force: true
|
|
197
|
-
});
|
|
148
|
+
}
|
|
149
|
+
finally {
|
|
150
|
+
rmSync(root, { recursive: true, force: true });
|
|
198
151
|
}
|
|
199
152
|
}
|
|
200
153
|
await run('emit');
|
|
201
154
|
await run('user-turn');
|
|
202
155
|
console.log('BOOKING COPILOT EVENT SEQUENCE CONCURRENCY PROOF: emit/user-turn multi-process sequence unique and strictly monotonic');
|
|
203
156
|
}
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
//# sourceURL=ts/scripts/booking-copilot-event-sequence-concurrency-proof-tests.ts
|
|
@@ -1,3 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cross-repository proof for the Portal sequential HotelRates gap contract.
|
|
3
|
+
*
|
|
4
|
+
* The Portal keeps the hotel identity in opaque factRefs while emitting only
|
|
5
|
+
* fixed safe identifiers in resultContract.gapCodes. This proof calls the
|
|
6
|
+
* actual GoTry receipt validator so a dynamic legacy code cannot cross the
|
|
7
|
+
* contract boundary.
|
|
8
|
+
*
|
|
9
|
+
* Run from the repository root with Node 24:
|
|
10
|
+
* npx tsx ts/scripts/booking-copilot-gap-code-contract-proof-tests.ts
|
|
11
|
+
*/
|
|
1
12
|
import assert from 'node:assert/strict';
|
|
2
13
|
import { validateBookingSurface } from '../src/booking-surface/validation.js';
|
|
3
14
|
const receiptBase = {
|
|
@@ -5,104 +16,55 @@ const receiptBase = {
|
|
|
5
16
|
kind: 'action.receipt',
|
|
6
17
|
actionId: 'offers-query-gap-contract',
|
|
7
18
|
contextRef: 'ctx-gap-contract',
|
|
8
|
-
revision: 1
|
|
19
|
+
revision: 1,
|
|
9
20
|
};
|
|
10
21
|
const ratesFailedResult = {
|
|
11
22
|
outcome: 'partial',
|
|
12
23
|
requestedCount: 1,
|
|
13
24
|
actualCount: 1,
|
|
14
25
|
hardCriteriaMet: true,
|
|
15
|
-
factRefs: [
|
|
16
|
-
'hotel:hotel-1',
|
|
17
|
-
'hotel:hotel-2',
|
|
18
|
-
'offer:breakfast'
|
|
19
|
-
]
|
|
26
|
+
factRefs: ['hotel:hotel-1', 'hotel:hotel-2', 'offer:breakfast'],
|
|
20
27
|
};
|
|
21
28
|
const ratesFailedObservation = {
|
|
22
29
|
kind: 'offers.state',
|
|
23
|
-
hotelRefs: [
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
offerRefs: [
|
|
27
|
-
'breakfast'
|
|
28
|
-
],
|
|
29
|
-
loadedHotelCount: 1
|
|
30
|
+
hotelRefs: ['hotel-2'],
|
|
31
|
+
offerRefs: ['breakfast'],
|
|
32
|
+
loadedHotelCount: 1,
|
|
30
33
|
};
|
|
31
34
|
const oldRatesFailedReceipt = {
|
|
32
35
|
...receiptBase,
|
|
33
36
|
status: 'partial',
|
|
34
37
|
observation: ratesFailedObservation,
|
|
35
|
-
resultContract: {
|
|
36
|
-
...ratesFailedResult,
|
|
37
|
-
gapCodes: [
|
|
38
|
-
'hotel_rates_failed:hotel-1'
|
|
39
|
-
],
|
|
40
|
-
blockers: [],
|
|
41
|
-
relaxationsApplied: []
|
|
42
|
-
}
|
|
38
|
+
resultContract: { ...ratesFailedResult, gapCodes: ['hotel_rates_failed:hotel-1'], blockers: [], relaxationsApplied: [] },
|
|
43
39
|
};
|
|
44
40
|
const newRatesFailedReceipt = {
|
|
45
41
|
...oldRatesFailedReceipt,
|
|
46
|
-
resultContract: {
|
|
47
|
-
...ratesFailedResult,
|
|
48
|
-
gapCodes: [
|
|
49
|
-
'hotel_rates_failed'
|
|
50
|
-
],
|
|
51
|
-
blockers: [],
|
|
52
|
-
relaxationsApplied: []
|
|
53
|
-
}
|
|
42
|
+
resultContract: { ...ratesFailedResult, gapCodes: ['hotel_rates_failed'], blockers: [], relaxationsApplied: [] },
|
|
54
43
|
};
|
|
55
44
|
assert.equal(validateBookingSurface(oldRatesFailedReceipt).ok, false, 'legacy dynamic supplier gap code must fail validation');
|
|
56
|
-
assert.deepEqual(validateBookingSurface(newRatesFailedReceipt), {
|
|
57
|
-
|
|
58
|
-
}, 'fixed supplier gap code with hotel fact ref must validate');
|
|
59
|
-
assert.deepEqual(newRatesFailedReceipt.resultContract.factRefs, [
|
|
60
|
-
'hotel:hotel-1',
|
|
61
|
-
'hotel:hotel-2',
|
|
62
|
-
'offer:breakfast'
|
|
63
|
-
]);
|
|
45
|
+
assert.deepEqual(validateBookingSurface(newRatesFailedReceipt), { ok: true }, 'fixed supplier gap code with hotel fact ref must validate');
|
|
46
|
+
assert.deepEqual(newRatesFailedReceipt.resultContract.factRefs, ['hotel:hotel-1', 'hotel:hotel-2', 'offer:breakfast']);
|
|
64
47
|
const oldNotVisibleReceipt = {
|
|
65
48
|
...receiptBase,
|
|
66
49
|
actionId: 'offers-query-hidden-hotel-gap-contract',
|
|
67
50
|
status: 'no_match',
|
|
68
|
-
observation: {
|
|
69
|
-
kind: 'offers.state',
|
|
70
|
-
hotelRefs: [],
|
|
71
|
-
offerRefs: [],
|
|
72
|
-
loadedHotelCount: 0
|
|
73
|
-
},
|
|
51
|
+
observation: { kind: 'offers.state', hotelRefs: [], offerRefs: [], loadedHotelCount: 0 },
|
|
74
52
|
resultContract: {
|
|
75
53
|
outcome: 'empty',
|
|
76
54
|
requestedCount: 1,
|
|
77
55
|
actualCount: 0,
|
|
78
56
|
hardCriteriaMet: false,
|
|
79
|
-
factRefs: [
|
|
80
|
-
|
|
81
|
-
],
|
|
82
|
-
gapCodes: [
|
|
83
|
-
'hotel_not_visible:not-visible'
|
|
84
|
-
],
|
|
57
|
+
factRefs: ['hotel:not-visible'],
|
|
58
|
+
gapCodes: ['hotel_not_visible:not-visible'],
|
|
85
59
|
blockers: [],
|
|
86
|
-
relaxationsApplied: []
|
|
87
|
-
}
|
|
60
|
+
relaxationsApplied: [],
|
|
61
|
+
},
|
|
88
62
|
};
|
|
89
63
|
const newNotVisibleReceipt = {
|
|
90
64
|
...oldNotVisibleReceipt,
|
|
91
|
-
resultContract: {
|
|
92
|
-
...oldNotVisibleReceipt.resultContract,
|
|
93
|
-
gapCodes: [
|
|
94
|
-
'hotel_not_visible'
|
|
95
|
-
]
|
|
96
|
-
}
|
|
65
|
+
resultContract: { ...oldNotVisibleReceipt.resultContract, gapCodes: ['hotel_not_visible'] },
|
|
97
66
|
};
|
|
98
67
|
assert.equal(validateBookingSurface(oldNotVisibleReceipt).ok, false, 'legacy dynamic visibility gap code must fail validation');
|
|
99
|
-
assert.deepEqual(validateBookingSurface(newNotVisibleReceipt), {
|
|
100
|
-
|
|
101
|
-
}, 'fixed visibility gap code with hotel fact ref must validate');
|
|
102
|
-
assert.deepEqual(newNotVisibleReceipt.resultContract.factRefs, [
|
|
103
|
-
'hotel:not-visible'
|
|
104
|
-
]);
|
|
68
|
+
assert.deepEqual(validateBookingSurface(newNotVisibleReceipt), { ok: true }, 'fixed visibility gap code with hotel fact ref must validate');
|
|
69
|
+
assert.deepEqual(newNotVisibleReceipt.resultContract.factRefs, ['hotel:not-visible']);
|
|
105
70
|
console.log('BOOKING COPILOT GAP CODE CONTRACT PROOF: dynamic legacy gap codes fail; fixed codes with hotel factRefs pass');
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
//# sourceURL=ts/scripts/booking-copilot-gap-code-contract-proof-tests.ts
|