@danceiny/gotry 0.0.1-rc.17 → 0.0.1-rc.19
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 +185 -148
- package/README.zh-CN.md +195 -154
- package/bin/gotry-bootstrap.js +246 -26
- package/bin/gotry-inner.js +68 -38
- package/bin/gotry-runtime-resolution.d.ts +1 -1
- package/bin/gotry-runtime-resolution.js +7 -8
- package/cordis.gotry-patch.yml +15 -5
- package/data/stations-12306-verify.json +524 -0
- package/dist/capabilities/agent-reach.js +4 -4
- package/dist/capabilities/channel-health.js +103 -0
- package/dist/capabilities/channel-registry.js +213 -0
- package/dist/capabilities/doctor.js +285 -0
- package/dist/capabilities/effect.js +178 -5
- package/dist/capabilities/flyai.js +13 -0
- package/dist/capabilities/session/adapters/ctrip-hotel.js +207 -0
- package/dist/capabilities/session/adapters/rail-12306.js +285 -0
- package/dist/capabilities/session/extension-bridge.js +14 -1
- package/dist/capabilities/session/extension-channel.js +4 -2
- package/dist/capabilities/session/extension-distribution.js +1 -1
- package/dist/capabilities/session-search.js +311 -0
- package/dist/capabilities/visa-policy.js +126 -0
- package/dist/scripts/agent-planning-turn-deadline-e2e.js +304 -0
- package/dist/scripts/agent-planning-turn-deadline-tests.js +281 -0
- package/dist/scripts/benchmark-environment-bridge-e2e.js +5 -10
- package/dist/scripts/benchmark-environment-bridge-tests.js +148 -142
- package/dist/scripts/booking-copilot-availability-ledger-binding-tests.js +26 -26
- package/dist/scripts/{booking-copilot-availability-policy-v2-tests.js → booking-copilot-availability-policy-tests.js} +115 -115
- package/dist/scripts/booking-copilot-crossrepo-fixture-server.js +41 -1
- package/dist/scripts/booking-copilot-dsh-core-proof-tests.js +75 -120
- package/dist/scripts/booking-copilot-dsh-planner-proof-tests.js +370 -61
- package/dist/scripts/booking-copilot-dsh-plugin-proof-tests.js +2 -2
- package/dist/scripts/booking-copilot-event-sequence-concurrency-proof-tests.js +7 -3
- package/dist/scripts/booking-copilot-gap-code-contract-proof-tests.js +15 -9
- package/dist/scripts/booking-copilot-operation-ledger-concurrency-proof-tests.js +19 -11
- package/dist/scripts/booking-copilot-receipt-ledger-concurrency-proof-tests.js +16 -52
- package/dist/scripts/booking-copilot-runtime-proof-tests.js +3953 -155
- package/dist/scripts/booking-copilot-server-proof-tests.js +58 -23
- package/dist/scripts/booking-copilot-startup-proof-tests.js +10 -119
- package/dist/scripts/booking-surface-contract-proof-tests.js +1154 -326
- package/dist/scripts/bootstrap-tests.js +115 -44
- package/dist/scripts/build-metrics-report.js +339 -0
- package/dist/scripts/channel-probe-tests.js +148 -0
- package/dist/scripts/channel-probe.js +252 -0
- package/dist/scripts/channel-registry-tests.js +262 -0
- package/dist/scripts/doctor-tests.js +121 -0
- package/dist/scripts/effect-tests.js +274 -1
- package/dist/scripts/extension-tests.js +129 -11
- package/dist/scripts/fact-gate-tests.js +91 -2
- package/dist/scripts/flyai-tests.js +17 -1
- package/dist/scripts/hbcli-e2e-tests.js +1 -3
- package/dist/scripts/metrics-report-tests.js +288 -0
- package/dist/scripts/persona-surface-guard-tests.js +19 -0
- package/dist/scripts/session-tests.js +401 -1
- package/dist/scripts/smoke.js +100 -83
- package/dist/scripts/turn-handoff-collect-tests.js +216 -0
- package/dist/scripts/turn-handoff-collect.js +189 -0
- package/dist/scripts/turn-policy-tests.js +56 -0
- package/dist/scripts/typed-contract-canary.js +261 -0
- package/dist/scripts/visa-policy-tests.js +75 -0
- package/dist/scripts/wish-channel-gate-tests.js +111 -0
- package/dist/src/artifact-gate.js +91 -3
- package/dist/src/benchmark-agent-conformance.js +7 -4
- package/dist/src/benchmark-environment-bridge.js +68 -7
- package/dist/src/bookable-facts.js +62 -3
- package/dist/src/booking-surface/{availability-policy-v2.js → availability-policy.js} +89 -89
- package/dist/src/booking-surface/canonical-schema.js +8 -22
- package/dist/src/booking-surface/contracts.js +70 -19
- package/dist/src/booking-surface/dsh-planner.js +310 -177
- package/dist/src/booking-surface/dsh-plugin.js +3 -3
- package/dist/src/booking-surface/index.js +1 -5
- package/dist/src/booking-surface/profile.js +1 -1
- package/dist/src/booking-surface/runtime.js +1682 -247
- package/dist/src/booking-surface/server.js +371 -185
- package/dist/src/booking-surface/startup.js +17 -27
- package/dist/src/booking-surface/validation.js +270 -760
- package/dist/src/index.js +735 -149
- package/dist/src/turn-deadline.js +292 -0
- package/dist/src/turn-policy.js +146 -0
- package/dist/src/wish-pool.js +5 -0
- package/extension/background.js +23 -4
- package/extension/content-main.js +47 -9
- package/extension/manifest.json +27 -9
- package/package.json +6 -26
- package/schemas/booking.surface.schema.json +2593 -0
- package/ts/capabilities/agent-reach.ts +4 -4
- package/ts/capabilities/flyai.ts +21 -3
- package/ts/capabilities/session/action-cache.ts +1 -1
- package/ts/capabilities/session/adapters/ctrip-hotel.ts +238 -0
- package/ts/capabilities/session/adapters/rail-12306.ts +293 -0
- package/ts/capabilities/session/extension-bridge.ts +32 -2
- package/ts/capabilities/session/extension-channel.ts +9 -8
- package/ts/capabilities/session/extension-distribution.ts +3 -1
- package/ts/capabilities/session/health-watch.ts +1 -1
- package/ts/capabilities/session/read-guard.ts +1 -1
- package/ts/capabilities/session/wizard.ts +1 -1
- package/ts/capabilities/session-search.ts +323 -1
- package/ts/package.json +1 -0
- package/ts/scripts/turn-handoff-collect.ts +178 -0
- package/ts/src/artifact-gate.ts +82 -2
- package/ts/src/benchmark-agent-conformance.ts +14 -6
- package/ts/src/benchmark-environment-bridge.ts +29 -10
- package/ts/src/bookable-facts.ts +109 -5
- package/ts/src/booking-saga.ts +1 -1
- package/ts/src/booking-surface/{availability-policy-v2.ts → availability-policy.ts} +124 -125
- package/ts/src/booking-surface/canonical-schema.js +8 -22
- package/ts/src/booking-surface/contracts.ts +278 -239
- package/ts/src/booking-surface/dsh-planner.ts +333 -194
- package/ts/src/booking-surface/dsh-plugin.js +3 -3
- package/ts/src/booking-surface/index.ts +1 -5
- package/ts/src/booking-surface/profile.ts +11 -11
- package/ts/src/booking-surface/runtime.ts +1351 -351
- package/ts/src/booking-surface/server.ts +282 -175
- package/ts/src/booking-surface/startup.ts +36 -48
- package/ts/src/booking-surface/validation.ts +194 -442
- package/ts/src/contracts.ts +1 -1
- package/ts/src/index.ts +489 -171
- package/ts/src/loop.ts +1 -1
- package/ts/src/state-ledger.ts +1 -1
- package/ts/src/turn-deadline.ts +361 -0
- package/ts/src/turn-policy.ts +154 -0
- package/ts/src/wish-pool.ts +17 -4
- package/dist/scripts/agent-planning-budget-e2e.js +0 -227
- package/dist/scripts/agent-planning-budget-tests.js +0 -173
- package/dist/scripts/booking-copilot-v2-runtime-proof-tests.js +0 -3935
- package/dist/scripts/booking-surface-v2-contract-proof-tests.js +0 -1174
- package/dist/src/booking-surface/contracts-v2.js +0 -89
- package/dist/src/booking-surface/runtime-v2.js +0 -1771
- package/dist/src/booking-surface/server-v2.js +0 -334
- package/dist/src/booking-surface/validation-v2.js +0 -319
- package/dist/src/tool-budget.js +0 -136
- package/schemas/booking.surface.v1.schema.json +0 -927
- package/schemas/booking.surface.v2.schema.json +0 -61
- package/ts/src/booking-surface/contracts-v2.ts +0 -118
- package/ts/src/booking-surface/runtime-v2.ts +0 -1466
- package/ts/src/booking-surface/server-v2.ts +0 -247
- package/ts/src/booking-surface/validation-v2.ts +0 -205
- package/ts/src/tool-budget.ts +0 -165
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import assert from 'node:assert/strict';
|
|
2
|
-
import {
|
|
2
|
+
import { validateBookingSurface } from '../src/booking-surface/validation.js';
|
|
3
3
|
const receiptBase = {
|
|
4
|
-
schemaVersion: 'booking.surface
|
|
4
|
+
schemaVersion: 'booking.surface',
|
|
5
5
|
kind: 'action.receipt',
|
|
6
6
|
actionId: 'offers-query-gap-contract',
|
|
7
7
|
contextRef: 'ctx-gap-contract',
|
|
@@ -36,7 +36,9 @@ const oldRatesFailedReceipt = {
|
|
|
36
36
|
...ratesFailedResult,
|
|
37
37
|
gapCodes: [
|
|
38
38
|
'hotel_rates_failed:hotel-1'
|
|
39
|
-
]
|
|
39
|
+
],
|
|
40
|
+
blockers: [],
|
|
41
|
+
relaxationsApplied: []
|
|
40
42
|
}
|
|
41
43
|
};
|
|
42
44
|
const newRatesFailedReceipt = {
|
|
@@ -45,11 +47,13 @@ const newRatesFailedReceipt = {
|
|
|
45
47
|
...ratesFailedResult,
|
|
46
48
|
gapCodes: [
|
|
47
49
|
'hotel_rates_failed'
|
|
48
|
-
]
|
|
50
|
+
],
|
|
51
|
+
blockers: [],
|
|
52
|
+
relaxationsApplied: []
|
|
49
53
|
}
|
|
50
54
|
};
|
|
51
|
-
assert.equal(
|
|
52
|
-
assert.deepEqual(
|
|
55
|
+
assert.equal(validateBookingSurface(oldRatesFailedReceipt).ok, false, 'legacy dynamic supplier gap code must fail validation');
|
|
56
|
+
assert.deepEqual(validateBookingSurface(newRatesFailedReceipt), {
|
|
53
57
|
ok: true
|
|
54
58
|
}, 'fixed supplier gap code with hotel fact ref must validate');
|
|
55
59
|
assert.deepEqual(newRatesFailedReceipt.resultContract.factRefs, [
|
|
@@ -77,7 +81,9 @@ const oldNotVisibleReceipt = {
|
|
|
77
81
|
],
|
|
78
82
|
gapCodes: [
|
|
79
83
|
'hotel_not_visible:not-visible'
|
|
80
|
-
]
|
|
84
|
+
],
|
|
85
|
+
blockers: [],
|
|
86
|
+
relaxationsApplied: []
|
|
81
87
|
}
|
|
82
88
|
};
|
|
83
89
|
const newNotVisibleReceipt = {
|
|
@@ -89,8 +95,8 @@ const newNotVisibleReceipt = {
|
|
|
89
95
|
]
|
|
90
96
|
}
|
|
91
97
|
};
|
|
92
|
-
assert.equal(
|
|
93
|
-
assert.deepEqual(
|
|
98
|
+
assert.equal(validateBookingSurface(oldNotVisibleReceipt).ok, false, 'legacy dynamic visibility gap code must fail validation');
|
|
99
|
+
assert.deepEqual(validateBookingSurface(newNotVisibleReceipt), {
|
|
94
100
|
ok: true
|
|
95
101
|
}, 'fixed visibility gap code with hotel fact ref must validate');
|
|
96
102
|
assert.deepEqual(newNotVisibleReceipt.resultContract.factRefs, [
|
|
@@ -8,7 +8,7 @@ import { ensureLedger } from '../src/state-ledger.js';
|
|
|
8
8
|
import { BookingCopilotTaskRuntime } from '../src/booking-surface/runtime.js';
|
|
9
9
|
const taskId = 'task-operation-atomicity';
|
|
10
10
|
const workspace = {
|
|
11
|
-
schemaVersion: 'booking.surface
|
|
11
|
+
schemaVersion: 'booking.surface',
|
|
12
12
|
contextRef: 'ctx-operation-atomicity',
|
|
13
13
|
surface: 'tenant',
|
|
14
14
|
revision: 0,
|
|
@@ -30,19 +30,19 @@ const workspace = {
|
|
|
30
30
|
}
|
|
31
31
|
};
|
|
32
32
|
const base = {
|
|
33
|
-
schemaVersion: 'booking.surface
|
|
33
|
+
schemaVersion: 'booking.surface',
|
|
34
34
|
kind: 'search.patch',
|
|
35
35
|
actionId: 'action-operation-atomicity',
|
|
36
36
|
contextRef: workspace.contextRef,
|
|
37
37
|
expectedRevision: 0,
|
|
38
|
-
reason: 'raw-reason-marker
|
|
38
|
+
reason: 'raw-reason-marker',
|
|
39
39
|
factRefs: [
|
|
40
40
|
'fact:opaque'
|
|
41
41
|
],
|
|
42
42
|
input: {
|
|
43
43
|
patch: {
|
|
44
44
|
destination: {
|
|
45
|
-
query: '
|
|
45
|
+
query: 'typed-input-marker'
|
|
46
46
|
}
|
|
47
47
|
}
|
|
48
48
|
}
|
|
@@ -207,9 +207,10 @@ async function run(kind, conflictVariant = 'conflict') {
|
|
|
207
207
|
const ledger = ensureLedger(root);
|
|
208
208
|
const runtime = new BookingCopilotTaskRuntime(ledger);
|
|
209
209
|
const turn = {
|
|
210
|
-
schemaVersion: 'booking.surface
|
|
210
|
+
schemaVersion: 'booking.surface',
|
|
211
211
|
kind: 'user.turn',
|
|
212
212
|
taskId,
|
|
213
|
+
turnId: 'operation-anchor-turn',
|
|
213
214
|
workspace,
|
|
214
215
|
request: {
|
|
215
216
|
text: 'opaque'
|
|
@@ -224,7 +225,8 @@ async function run(kind, conflictVariant = 'conflict') {
|
|
|
224
225
|
if (kind === 'same') assert.deepEqual(success[0].event, success[1].event);
|
|
225
226
|
assert.equal(ledger.db.prepare("SELECT COUNT(*) AS n FROM events WHERE kind = 'booking.copilot.action.issued'").get().n, 1);
|
|
226
227
|
const durable = ledger.db.prepare("SELECT payload FROM events WHERE kind = 'booking.copilot.action.issued'").get();
|
|
227
|
-
assert.ok(!/raw-reason-marker
|
|
228
|
+
assert.ok(!/raw-reason-marker|@example|secret/i.test(durable.payload), 'action reason prose is never durable');
|
|
229
|
+
assert.match(durable.payload, /"reasonDigest"/, 'the redacted reason digest is durable');
|
|
228
230
|
if (kind === 'same') {
|
|
229
231
|
const event = success[0].event;
|
|
230
232
|
ledger.close();
|
|
@@ -308,28 +310,33 @@ if (!child) {
|
|
|
308
310
|
const unsafeLedger = ensureLedger(unsafeRoot);
|
|
309
311
|
const unsafeRuntime = new BookingCopilotTaskRuntime(unsafeLedger);
|
|
310
312
|
unsafeRuntime.startTask({
|
|
311
|
-
schemaVersion: 'booking.surface
|
|
313
|
+
schemaVersion: 'booking.surface',
|
|
312
314
|
kind: 'user.turn',
|
|
313
315
|
taskId,
|
|
316
|
+
turnId: 'unsafe-anchor-turn',
|
|
314
317
|
workspace,
|
|
315
318
|
request: {
|
|
316
319
|
text: 'opaque'
|
|
317
320
|
}
|
|
318
321
|
});
|
|
322
|
+
assert.throws(()=>unsafeRuntime.issueOperation(taskId, {
|
|
323
|
+
...base,
|
|
324
|
+
reason: 'raw prose marker@example.invalid'
|
|
325
|
+
}), /invalid_action|unsafe/, 'email prose is rejected before an operation is issued');
|
|
319
326
|
assert.throws(()=>unsafeRuntime.issueOperation(taskId, {
|
|
320
327
|
...base,
|
|
321
328
|
factRefs: [
|
|
322
329
|
'attacker@example.invalid'
|
|
323
330
|
]
|
|
324
|
-
}), /unsafe_fact_ref/);
|
|
331
|
+
}), /invalid_action|unsafe_fact_ref/);
|
|
325
332
|
assert.throws(()=>unsafeRuntime.issueOperation(taskId, {
|
|
326
333
|
...base,
|
|
327
334
|
actionId: 'attacker@example.invalid'
|
|
328
|
-
}), /unsafe_action_id/);
|
|
335
|
+
}), /invalid_action|unsafe_action_id/);
|
|
329
336
|
assert.throws(()=>unsafeRuntime.issueOperation(taskId, {
|
|
330
337
|
...base,
|
|
331
338
|
actionId: 'eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxIn0.signature'
|
|
332
|
-
}), /unsafe_action_id/);
|
|
339
|
+
}), /invalid_action|unsafe_action_id/);
|
|
333
340
|
assert.equal(unsafeLedger.countEvents(), 2);
|
|
334
341
|
unsafeLedger.close();
|
|
335
342
|
rmSync(unsafeRoot, {
|
|
@@ -345,9 +352,10 @@ if (!child) {
|
|
|
345
352
|
const tamperLedger = ensureLedger(tamperRoot);
|
|
346
353
|
const tamperRuntime = new BookingCopilotTaskRuntime(tamperLedger);
|
|
347
354
|
tamperRuntime.startTask({
|
|
348
|
-
schemaVersion: 'booking.surface
|
|
355
|
+
schemaVersion: 'booking.surface',
|
|
349
356
|
kind: 'user.turn',
|
|
350
357
|
taskId,
|
|
358
|
+
turnId: 'tamper-anchor-turn',
|
|
351
359
|
workspace,
|
|
352
360
|
request: {
|
|
353
361
|
text: 'opaque'
|
|
@@ -6,7 +6,7 @@ import { join } from 'node:path';
|
|
|
6
6
|
import { fileURLToPath } from 'node:url';
|
|
7
7
|
import { ensureLedger } from '../src/state-ledger.js';
|
|
8
8
|
import { BookingCopilotTaskRuntime } from '../src/booking-surface/runtime.js';
|
|
9
|
-
import {
|
|
9
|
+
import { validateBookingSurface } from '../src/booking-surface/validation.js';
|
|
10
10
|
const childIndex = process.argv.indexOf('--child');
|
|
11
11
|
const child = childIndex >= 0;
|
|
12
12
|
const root = child ? process.argv[childIndex + 1] : undefined;
|
|
@@ -14,7 +14,7 @@ const actionId = child ? process.argv[childIndex + 2] : undefined;
|
|
|
14
14
|
const variant = child ? process.argv[childIndex + 3] : undefined;
|
|
15
15
|
const release = root ? join(root, 'release') : '';
|
|
16
16
|
const workspace = {
|
|
17
|
-
schemaVersion: 'booking.surface
|
|
17
|
+
schemaVersion: 'booking.surface',
|
|
18
18
|
contextRef: 'ctx-concurrency-opaque',
|
|
19
19
|
surface: 'tenant',
|
|
20
20
|
revision: 0,
|
|
@@ -35,7 +35,7 @@ const workspace = {
|
|
|
35
35
|
}
|
|
36
36
|
};
|
|
37
37
|
const action = {
|
|
38
|
-
schemaVersion: 'booking.surface
|
|
38
|
+
schemaVersion: 'booking.surface',
|
|
39
39
|
kind: 'search.run',
|
|
40
40
|
actionId: 'action-concurrency-opaque',
|
|
41
41
|
contextRef: workspace.contextRef,
|
|
@@ -48,7 +48,7 @@ const action = {
|
|
|
48
48
|
};
|
|
49
49
|
function receipt(which) {
|
|
50
50
|
const value = {
|
|
51
|
-
schemaVersion: 'booking.surface
|
|
51
|
+
schemaVersion: 'booking.surface',
|
|
52
52
|
kind: 'action.receipt',
|
|
53
53
|
actionId: action.actionId,
|
|
54
54
|
contextRef: workspace.contextRef,
|
|
@@ -65,7 +65,9 @@ function receipt(which) {
|
|
|
65
65
|
factRefs: [
|
|
66
66
|
`fact-${which === 'same-a' || which === 'same-b' ? 'same' : which}`
|
|
67
67
|
],
|
|
68
|
-
gapCodes: []
|
|
68
|
+
gapCodes: [],
|
|
69
|
+
blockers: [],
|
|
70
|
+
relaxationsApplied: []
|
|
69
71
|
},
|
|
70
72
|
undoToken: `undo-${which === 'same-a' || which === 'same-b' ? 'same' : which}`
|
|
71
73
|
};
|
|
@@ -84,7 +86,7 @@ function receipt(which) {
|
|
|
84
86
|
}
|
|
85
87
|
function continuation(r, taskId = 'task-concurrency-opaque') {
|
|
86
88
|
return {
|
|
87
|
-
schemaVersion: 'booking.surface
|
|
89
|
+
schemaVersion: 'booking.surface',
|
|
88
90
|
kind: 'action.receipt.continuation',
|
|
89
91
|
taskId,
|
|
90
92
|
workspace: {
|
|
@@ -225,17 +227,18 @@ if (!child) {
|
|
|
225
227
|
const ledger = ensureLedger(stateRoot);
|
|
226
228
|
const r = new BookingCopilotTaskRuntime(ledger);
|
|
227
229
|
const turn = {
|
|
228
|
-
schemaVersion: 'booking.surface
|
|
230
|
+
schemaVersion: 'booking.surface',
|
|
229
231
|
kind: 'user.turn',
|
|
230
232
|
taskId: 'task-concurrency-opaque',
|
|
233
|
+
turnId: 'receipt-anchor-turn',
|
|
231
234
|
workspace,
|
|
232
235
|
request: {
|
|
233
|
-
text: 'unique-pii-marker
|
|
236
|
+
text: 'unique-pii-marker raw-prompt-marker'
|
|
234
237
|
}
|
|
235
238
|
};
|
|
236
239
|
const sensitiveAction = {
|
|
237
240
|
...action,
|
|
238
|
-
reason: 'unique-pii-marker
|
|
241
|
+
reason: 'unique-pii-marker raw-prompt-marker',
|
|
239
242
|
input: {}
|
|
240
243
|
};
|
|
241
244
|
r.startTask(turn);
|
|
@@ -254,12 +257,12 @@ if (!child) {
|
|
|
254
257
|
]
|
|
255
258
|
}
|
|
256
259
|
})), /invalid_receipt_continuation/);
|
|
257
|
-
assert.equal(
|
|
260
|
+
assert.equal(validateBookingSurface({
|
|
258
261
|
...receipt('a'),
|
|
259
262
|
status: 'no_match',
|
|
260
263
|
observation: {
|
|
261
264
|
kind: 'gap',
|
|
262
|
-
code: '
|
|
265
|
+
code: 'no_hotels_matched',
|
|
263
266
|
factRefs: [
|
|
264
267
|
'123'
|
|
265
268
|
]
|
|
@@ -271,7 +274,7 @@ if (!child) {
|
|
|
271
274
|
const after = ledger;
|
|
272
275
|
assert.equal(after.db.prepare("SELECT COUNT(*) AS n FROM events WHERE kind = 'booking.copilot.receipt.observed'").get().n, 1);
|
|
273
276
|
const persisted = after.db.prepare("SELECT payload FROM events WHERE kind LIKE 'booking.copilot.%'").all();
|
|
274
|
-
assert.ok(!persisted.some((row)=>/unique-pii-marker|
|
|
277
|
+
assert.ok(!persisted.some((row)=>/unique-pii-marker|raw-prompt-marker/i.test(row.payload)));
|
|
275
278
|
const winner = differing.find((x)=>x.result === 'success');
|
|
276
279
|
assert.ok(winner?.variant);
|
|
277
280
|
assert.deepEqual(new BookingCopilotTaskRuntime(after).resumeTask(turn.taskId)?.lastReceipt, receipt(winner.variant));
|
|
@@ -393,7 +396,7 @@ if (!child) {
|
|
|
393
396
|
}));
|
|
394
397
|
const reuseEvents = reuseLedger.countEvents();
|
|
395
398
|
const reuseState = reuseRuntime.resumeTask('task-concurrency-opaque');
|
|
396
|
-
assert.throws(()=>reuseRuntime.issueOperation('task-concurrency-opaque', action), /action_already_receipted/);
|
|
399
|
+
assert.throws(()=>reuseRuntime.issueOperation('task-concurrency-opaque', action), /stale_revision|ledger_write_failed:action|action_already_receipted/);
|
|
397
400
|
assert.equal(reuseLedger.countEvents(), reuseEvents);
|
|
398
401
|
assert.deepEqual(reuseRuntime.resumeTask('task-concurrency-opaque'), reuseState);
|
|
399
402
|
reuseLedger.close();
|
|
@@ -401,45 +404,6 @@ if (!child) {
|
|
|
401
404
|
recursive: true,
|
|
402
405
|
force: true
|
|
403
406
|
});
|
|
404
|
-
const tupleRoot = mkdtempSync(join(tmpdir(), 'gotry-receipt-tuple-'));
|
|
405
|
-
const tupleLedger = ensureLedger(tupleRoot);
|
|
406
|
-
const tupleRuntime = new BookingCopilotTaskRuntime(tupleLedger);
|
|
407
|
-
for (const [taskId, actionId] of [
|
|
408
|
-
[
|
|
409
|
-
'task:a',
|
|
410
|
-
'b'
|
|
411
|
-
],
|
|
412
|
-
[
|
|
413
|
-
'task',
|
|
414
|
-
'a:b'
|
|
415
|
-
]
|
|
416
|
-
]){
|
|
417
|
-
tupleRuntime.startTask({
|
|
418
|
-
...turn,
|
|
419
|
-
taskId
|
|
420
|
-
});
|
|
421
|
-
tupleRuntime.issueOperation(taskId, {
|
|
422
|
-
...action,
|
|
423
|
-
actionId
|
|
424
|
-
});
|
|
425
|
-
tupleRuntime.continueWithReceipt(continuation({
|
|
426
|
-
...receipt('same'),
|
|
427
|
-
actionId
|
|
428
|
-
}, taskId));
|
|
429
|
-
}
|
|
430
|
-
assert.equal(tupleLedger.db.prepare("SELECT COUNT(*) AS n FROM events WHERE kind = 'booking.copilot.action.issued'").get().n, 2);
|
|
431
|
-
assert.equal(tupleLedger.db.prepare("SELECT COUNT(DISTINCT idem_key) AS n FROM events WHERE kind = 'booking.copilot.action.issued'").get().n, 2);
|
|
432
|
-
assert.equal(tupleLedger.db.prepare("SELECT COUNT(*) AS n FROM events WHERE kind = 'booking.copilot.receipt.observed'").get().n, 2);
|
|
433
|
-
assert.equal(tupleLedger.db.prepare("SELECT COUNT(DISTINCT idem_key) AS n FROM events WHERE kind = 'booking.copilot.receipt.observed'").get().n, 2);
|
|
434
|
-
for (const taskId of [
|
|
435
|
-
'task:a',
|
|
436
|
-
'task'
|
|
437
|
-
])assert.equal(tupleRuntime.resumeTask(taskId)?.phase, 'planning');
|
|
438
|
-
tupleLedger.close();
|
|
439
|
-
rmSync(tupleRoot, {
|
|
440
|
-
recursive: true,
|
|
441
|
-
force: true
|
|
442
|
-
});
|
|
443
407
|
console.log('BOOKING COPILOT RECEIPT LEDGER CONCURRENCY PROOF: winner/conflict/atomic persistence OK');
|
|
444
408
|
}
|
|
445
409
|
|