@quolu/lattice 0.52.3 → 0.52.4
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/package.json +1 -1
- package/src/artifact-contracts-v2.mjs +325 -325
- package/src/artifact-contracts.mjs +895 -895
- package/src/boundary-compiler.mjs +712 -712
- package/src/boundary-observation-compiler-v2.mjs +344 -344
- package/src/bounded-seam.mjs +230 -230
- package/src/bridge-address.mjs +107 -107
- package/src/bridge-cli.mjs +297 -297
- package/src/bridge-config.mjs +346 -346
- package/src/bridge-daemon.mjs +378 -378
- package/src/bridge-hub-protocol.mjs +198 -0
- package/src/bridge-launch-agent.mjs +323 -323
- package/src/bridge-registrar.mjs +102 -102
- package/src/bridge-server.mjs +376 -376
- package/src/cli-help.mjs +308 -308
- package/src/cli-stdio.mjs +40 -40
- package/src/control-compiler.mjs +532 -532
- package/src/dag-chain.mjs +261 -261
- package/src/factory-diagnostics.mjs +188 -188
- package/src/git-process.mjs +72 -0
- package/src/hash-chain.mjs +76 -76
- package/src/hooks-cli.mjs +1057 -1057
- package/src/isolation-runner.mjs +409 -409
- package/src/node-version-guard.mjs +44 -44
- package/src/project-cli.mjs +3 -3
- package/src/project-identity.mjs +130 -130
- package/src/rc1-black-box-oracle.mjs +906 -906
- package/src/rc1-comparison.mjs +154 -154
- package/src/rc1-evidence-bundle.mjs +456 -456
- package/src/rc1-v4-campaign.mjs +708 -708
- package/src/rc1-v4-transform.mjs +467 -467
- package/src/rc1-v5-artifact-set.mjs +855 -855
- package/src/rc1-v5-behavior-evidence.mjs +594 -594
- package/src/rc1-v5-campaign.mjs +797 -797
- package/src/rc1-v5-transform.mjs +421 -421
- package/src/rc1-v6-artifact-set.mjs +807 -807
- package/src/rc1-v6-behavior-evidence.mjs +273 -273
- package/src/rc1-v6-campaign.mjs +623 -623
- package/src/rc1-v6-causal-binding.mjs +473 -473
- package/src/rc1-v6-measurement.mjs +313 -313
- package/src/rc2-artifact-set.mjs +1584 -1584
- package/src/rc2-campaign.mjs +1506 -1506
- package/src/rc2-delivery-policy-front-end.mjs +1079 -1079
- package/src/rc2-delivery-policy-oracle.mjs +134 -134
- package/src/rc2-delivery-policy-transform.mjs +1127 -1127
- package/src/rc2-rc1-transfer-front-end.mjs +511 -511
- package/src/rc3-actual-dogfood.mjs +652 -652
- package/src/rc3-dogfood-scaffold.mjs +315 -315
- package/src/rc3-scripted-campaign.mjs +1383 -1383
- package/src/rc4-stage1-dogfood.mjs +673 -673
- package/src/runtime-adapter-registry.mjs +524 -524
- package/src/runtime-cli.mjs +4588 -4588
- package/src/runtime-contracts.mjs +824 -824
- package/src/runtime-control-store.mjs +604 -604
- package/src/runtime-controller-protocol.mjs +587 -587
- package/src/runtime-decision-verifier.mjs +701 -701
- package/src/runtime-diff-observer.mjs +361 -361
- package/src/runtime-direct-os-observer.mjs +301 -301
- package/src/runtime-driver-state.mjs +166 -166
- package/src/runtime-engine.mjs +779 -779
- package/src/runtime-errors.mjs +356 -356
- package/src/runtime-event-store.mjs +189 -189
- package/src/runtime-front-end.mjs +925 -925
- package/src/runtime-gate-store.mjs +481 -481
- package/src/runtime-hold-recompile.mjs +916 -916
- package/src/runtime-io-sentinel.mjs +391 -391
- package/src/runtime-lifecycle-lock.mjs +294 -294
- package/src/runtime-managed-supervisor.mjs +1490 -1490
- package/src/runtime-multi-epoch-store.mjs +838 -838
- package/src/runtime-projection.mjs +269 -269
- package/src/runtime-pull-intake.mjs +1192 -1192
- package/src/runtime-scripted-adapter-controller.mjs +1160 -1160
- package/src/runtime-scripted-executor.mjs +163 -163
- package/src/runtime-scripted-worktree.mjs +104 -104
- package/src/runtime-seam-resolve.mjs +428 -428
- package/src/runtime-seam-treatment.mjs +173 -173
- package/src/runtime-socket-owner.mjs +125 -125
- package/src/runtime-work-order-contracts.mjs +91 -91
- package/src/runtime-work-order-controller.mjs +1171 -1171
- package/src/runtime-worktree-executor.mjs +199 -199
- package/src/schedulability-compiler-v2.mjs +303 -303
- package/src/schedulability-verifier-v2.mjs +317 -317
- package/src/seam-apply.mjs +549 -549
- package/src/seam-commit-shared.mjs +22 -22
- package/src/seam-commit-transform.mjs +81 -81
- package/src/seam-commit.mjs +18 -18
- package/src/seam-cost.mjs +322 -322
- package/src/seam-derivation.mjs +188 -188
- package/src/seam-gate.mjs +146 -146
- package/src/seam-proposal-contracts.mjs +446 -446
- package/src/seam-proposal-queries.mjs +521 -521
- package/src/seam-proposal.mjs +2011 -2011
- package/src/seam-ref.mjs +33 -33
- package/src/seam-rewrite.mjs +286 -286
- package/src/seam-transform.mjs +554 -554
- package/src/seam-verification.mjs +260 -260
- package/src/sensor-adapter.mjs +432 -432
- package/src/sensor-cli.mjs +139 -139
- package/src/sensor-diff.mjs +661 -661
- package/src/sensor-node-runtime.mjs +53 -53
- package/src/sensor-runtime.mjs +52 -52
- package/src/timestamp-contract.mjs +8 -8
- package/src/todo-audit-pending.mjs +91 -91
- package/src/todo-chain.mjs +178 -178
- package/src/todo-cli.mjs +8 -8
- package/src/todo-contracts.mjs +728 -728
- package/src/todo-dashboard-registry.mjs +573 -573
- package/src/todo-dispatch-shape.mjs +190 -190
- package/src/todo-gantt-html-independence.mjs +239 -239
- package/src/todo-gantt-html-shared.mjs +226 -226
- package/src/todo-gantt-html-style.mjs +131 -131
- package/src/todo-gantt-html.mjs +248 -248
- package/src/todo-gantt-layout.mjs +974 -974
- package/src/todo-gantt-live.mjs +361 -361
- package/src/todo-gantt-nested.mjs +263 -263
- package/src/todo-gantt-presentation.mjs +217 -217
- package/src/todo-gantt-scope.mjs +123 -123
- package/src/todo-gantt-svg.mjs +353 -353
- package/src/todo-independence-contracts.mjs +595 -595
- package/src/todo-independence-guidance.mjs +322 -322
- package/src/todo-independence.mjs +640 -640
- package/src/todo-markdown-renderer.mjs +260 -260
- package/src/todo-migration.mjs +448 -448
- package/src/todo-narrative-anchor.mjs +130 -130
- package/src/todo-note-store.mjs +629 -629
- package/src/todo-parallel-candidates.mjs +114 -114
- package/src/todo-revision.mjs +995 -995
- package/src/todo-split.mjs +472 -472
- package/src/todo-status.mjs +690 -690
- package/src/todo-store-git-transaction.mjs +418 -418
- package/src/todo-store.mjs +42 -21
- package/src/treatment-compiler.mjs +728 -728
- package/src/treatment-runner.mjs +656 -656
- package/src/witness-scaffold.mjs +180 -180
|
@@ -1,134 +1,134 @@
|
|
|
1
|
-
import { execFile } from 'node:child_process';
|
|
2
|
-
import { createHash } from 'node:crypto';
|
|
3
|
-
import { realpath } from 'node:fs/promises';
|
|
4
|
-
import path from 'node:path';
|
|
5
|
-
import { promisify } from 'node:util';
|
|
6
|
-
|
|
7
|
-
const execFileAsync = promisify(execFile);
|
|
8
|
-
const ENTRYPOINT = 'research/fixtures/delivery-policy-registry/src/delivery-policy-registry.mjs';
|
|
9
|
-
|
|
10
|
-
const CASES = Object.freeze([
|
|
11
|
-
['email-routine', { channel: 'email', urgency: 'routine' }, { channel: 'email', transport: 'smtp', retry_limit: 3, delay_seconds: 60 }],
|
|
12
|
-
['email-urgent', { channel: 'email', urgency: 'urgent' }, { channel: 'email', transport: 'smtp', retry_limit: 5, delay_seconds: 0 }],
|
|
13
|
-
['sms-routine', { channel: 'sms', urgency: 'routine' }, { channel: 'sms', transport: 'sms', retry_limit: 2, delay_seconds: 30 }],
|
|
14
|
-
['sms-urgent', { channel: 'sms', urgency: 'urgent' }, { channel: 'sms', transport: 'sms', retry_limit: 4, delay_seconds: 0 }],
|
|
15
|
-
['push-routine', { channel: 'push', urgency: 'routine' }, { channel: 'push', transport: 'push', retry_limit: 1, delay_seconds: 10 }],
|
|
16
|
-
['push-urgent', { channel: 'push', urgency: 'urgent' }, { channel: 'push', transport: 'push', retry_limit: 3, delay_seconds: 0 }],
|
|
17
|
-
]);
|
|
18
|
-
|
|
19
|
-
const CHILD_PROGRAM = String.raw`
|
|
20
|
-
import { createHash } from 'node:crypto';
|
|
21
|
-
import { pathToFileURL } from 'node:url';
|
|
22
|
-
const [entrypoint, serializedCases] = process.argv.slice(1);
|
|
23
|
-
const cases = JSON.parse(serializedCases);
|
|
24
|
-
const targetModule = await import(pathToFileURL(entrypoint).href);
|
|
25
|
-
if (typeof targetModule.resolveDeliveryPolicy !== 'function') {
|
|
26
|
-
throw new TypeError('resolveDeliveryPolicy export is not a function');
|
|
27
|
-
}
|
|
28
|
-
const case_results = cases.map(({ id, input }) => ({
|
|
29
|
-
id,
|
|
30
|
-
output_digest: createHash('sha256')
|
|
31
|
-
.update(JSON.stringify(targetModule.resolveDeliveryPolicy(input)))
|
|
32
|
-
.digest('hex'),
|
|
33
|
-
}));
|
|
34
|
-
process.stdout.write(JSON.stringify({ case_results }) + '\n');
|
|
35
|
-
`;
|
|
36
|
-
|
|
37
|
-
function sha256(value) {
|
|
38
|
-
return createHash('sha256').update(value).digest('hex');
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
function inside(root, target) {
|
|
42
|
-
const relative = path.relative(root, target);
|
|
43
|
-
return relative !== ''
|
|
44
|
-
&& relative !== '..'
|
|
45
|
-
&& !relative.startsWith(`..${path.sep}`)
|
|
46
|
-
&& !path.isAbsolute(relative);
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
function exactRecord(value, keys) {
|
|
50
|
-
if (value === null || typeof value !== 'object' || Array.isArray(value)
|
|
51
|
-
|| Object.getPrototypeOf(value) !== Object.prototype) return false;
|
|
52
|
-
const actual = Object.keys(value).sort();
|
|
53
|
-
const expected = [...keys].sort();
|
|
54
|
-
return actual.length === expected.length
|
|
55
|
-
&& actual.every((key, index) => key === expected[index]);
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
function expectedDigest(value) {
|
|
59
|
-
return sha256(JSON.stringify(value));
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
/** runtime oracleとartifact verifierが共有する唯一のexpected receiptを返す。 */
|
|
63
|
-
export function expectedRc2DeliveryPolicyOracleReceipt() {
|
|
64
|
-
return {
|
|
65
|
-
schema: 'lattice.rc2.delivery_policy_oracle_receipt.v1',
|
|
66
|
-
outcome: 'passed',
|
|
67
|
-
case_results: CASES.map(([id, _input, expected]) => ({
|
|
68
|
-
id,
|
|
69
|
-
outcome: 'passed',
|
|
70
|
-
output_digest: expectedDigest(expected),
|
|
71
|
-
})),
|
|
72
|
-
};
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
async function resolveEntrypoint(repoRoot) {
|
|
76
|
-
if (typeof repoRoot !== 'string' || repoRoot.length === 0) {
|
|
77
|
-
throw new TypeError('repoRoot must be a non-empty path');
|
|
78
|
-
}
|
|
79
|
-
const root = await realpath(repoRoot);
|
|
80
|
-
const entrypoint = await realpath(path.resolve(root, ENTRYPOINT));
|
|
81
|
-
if (!inside(root, entrypoint)) throw new TypeError('delivery policy entrypoint is outside repoRoot');
|
|
82
|
-
return entrypoint;
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
function parseChildReceipt(stdout) {
|
|
86
|
-
let value;
|
|
87
|
-
try {
|
|
88
|
-
value = JSON.parse(stdout);
|
|
89
|
-
} catch {
|
|
90
|
-
throw new TypeError('delivery policy oracle child returned invalid JSON');
|
|
91
|
-
}
|
|
92
|
-
if (!exactRecord(value, ['case_results'])
|
|
93
|
-
|| !Array.isArray(value.case_results)
|
|
94
|
-
|| value.case_results.length !== CASES.length) {
|
|
95
|
-
throw new TypeError('delivery policy oracle child receipt shape is invalid');
|
|
96
|
-
}
|
|
97
|
-
return value.case_results;
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
/** 指定worktreeのfixtureをfresh Node processでblack-box照合する。 */
|
|
101
|
-
export async function runRc2DeliveryPolicyOracle({ repoRoot } = {}) {
|
|
102
|
-
const entrypoint = await resolveEntrypoint(repoRoot);
|
|
103
|
-
const childCases = CASES.map(([id, input]) => ({ id, input }));
|
|
104
|
-
const expectedReceipt = expectedRc2DeliveryPolicyOracleReceipt();
|
|
105
|
-
let stdout;
|
|
106
|
-
let stderr;
|
|
107
|
-
try {
|
|
108
|
-
({ stdout, stderr } = await execFileAsync(process.execPath, [
|
|
109
|
-
'--input-type=module',
|
|
110
|
-
'--eval',
|
|
111
|
-
CHILD_PROGRAM,
|
|
112
|
-
entrypoint,
|
|
113
|
-
JSON.stringify(childCases),
|
|
114
|
-
], { encoding: 'utf8', maxBuffer: 64 * 1024 }));
|
|
115
|
-
} catch (error) {
|
|
116
|
-
throw new Error(`delivery policy oracle child failed: ${error.message}`, { cause: error });
|
|
117
|
-
}
|
|
118
|
-
if (stderr.length !== 0) throw new Error('delivery policy oracle child wrote stderr');
|
|
119
|
-
|
|
120
|
-
const childResults = parseChildReceipt(stdout);
|
|
121
|
-
childResults.forEach((result, index) => {
|
|
122
|
-
const expected = expectedReceipt.case_results[index];
|
|
123
|
-
if (!exactRecord(result, ['id', 'output_digest'])
|
|
124
|
-
|| result.id !== expected.id
|
|
125
|
-
|| typeof result.output_digest !== 'string'
|
|
126
|
-
|| !/^[0-9a-f]{64}$/.test(result.output_digest)) {
|
|
127
|
-
throw new TypeError('delivery policy oracle child case receipt is invalid');
|
|
128
|
-
}
|
|
129
|
-
if (result.output_digest !== expected.output_digest) {
|
|
130
|
-
throw new Error(`delivery policy behavior mismatch: ${expected.id}`);
|
|
131
|
-
}
|
|
132
|
-
});
|
|
133
|
-
return expectedReceipt;
|
|
134
|
-
}
|
|
1
|
+
import { execFile } from 'node:child_process';
|
|
2
|
+
import { createHash } from 'node:crypto';
|
|
3
|
+
import { realpath } from 'node:fs/promises';
|
|
4
|
+
import path from 'node:path';
|
|
5
|
+
import { promisify } from 'node:util';
|
|
6
|
+
|
|
7
|
+
const execFileAsync = promisify(execFile);
|
|
8
|
+
const ENTRYPOINT = 'research/fixtures/delivery-policy-registry/src/delivery-policy-registry.mjs';
|
|
9
|
+
|
|
10
|
+
const CASES = Object.freeze([
|
|
11
|
+
['email-routine', { channel: 'email', urgency: 'routine' }, { channel: 'email', transport: 'smtp', retry_limit: 3, delay_seconds: 60 }],
|
|
12
|
+
['email-urgent', { channel: 'email', urgency: 'urgent' }, { channel: 'email', transport: 'smtp', retry_limit: 5, delay_seconds: 0 }],
|
|
13
|
+
['sms-routine', { channel: 'sms', urgency: 'routine' }, { channel: 'sms', transport: 'sms', retry_limit: 2, delay_seconds: 30 }],
|
|
14
|
+
['sms-urgent', { channel: 'sms', urgency: 'urgent' }, { channel: 'sms', transport: 'sms', retry_limit: 4, delay_seconds: 0 }],
|
|
15
|
+
['push-routine', { channel: 'push', urgency: 'routine' }, { channel: 'push', transport: 'push', retry_limit: 1, delay_seconds: 10 }],
|
|
16
|
+
['push-urgent', { channel: 'push', urgency: 'urgent' }, { channel: 'push', transport: 'push', retry_limit: 3, delay_seconds: 0 }],
|
|
17
|
+
]);
|
|
18
|
+
|
|
19
|
+
const CHILD_PROGRAM = String.raw`
|
|
20
|
+
import { createHash } from 'node:crypto';
|
|
21
|
+
import { pathToFileURL } from 'node:url';
|
|
22
|
+
const [entrypoint, serializedCases] = process.argv.slice(1);
|
|
23
|
+
const cases = JSON.parse(serializedCases);
|
|
24
|
+
const targetModule = await import(pathToFileURL(entrypoint).href);
|
|
25
|
+
if (typeof targetModule.resolveDeliveryPolicy !== 'function') {
|
|
26
|
+
throw new TypeError('resolveDeliveryPolicy export is not a function');
|
|
27
|
+
}
|
|
28
|
+
const case_results = cases.map(({ id, input }) => ({
|
|
29
|
+
id,
|
|
30
|
+
output_digest: createHash('sha256')
|
|
31
|
+
.update(JSON.stringify(targetModule.resolveDeliveryPolicy(input)))
|
|
32
|
+
.digest('hex'),
|
|
33
|
+
}));
|
|
34
|
+
process.stdout.write(JSON.stringify({ case_results }) + '\n');
|
|
35
|
+
`;
|
|
36
|
+
|
|
37
|
+
function sha256(value) {
|
|
38
|
+
return createHash('sha256').update(value).digest('hex');
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function inside(root, target) {
|
|
42
|
+
const relative = path.relative(root, target);
|
|
43
|
+
return relative !== ''
|
|
44
|
+
&& relative !== '..'
|
|
45
|
+
&& !relative.startsWith(`..${path.sep}`)
|
|
46
|
+
&& !path.isAbsolute(relative);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function exactRecord(value, keys) {
|
|
50
|
+
if (value === null || typeof value !== 'object' || Array.isArray(value)
|
|
51
|
+
|| Object.getPrototypeOf(value) !== Object.prototype) return false;
|
|
52
|
+
const actual = Object.keys(value).sort();
|
|
53
|
+
const expected = [...keys].sort();
|
|
54
|
+
return actual.length === expected.length
|
|
55
|
+
&& actual.every((key, index) => key === expected[index]);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function expectedDigest(value) {
|
|
59
|
+
return sha256(JSON.stringify(value));
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/** runtime oracleとartifact verifierが共有する唯一のexpected receiptを返す。 */
|
|
63
|
+
export function expectedRc2DeliveryPolicyOracleReceipt() {
|
|
64
|
+
return {
|
|
65
|
+
schema: 'lattice.rc2.delivery_policy_oracle_receipt.v1',
|
|
66
|
+
outcome: 'passed',
|
|
67
|
+
case_results: CASES.map(([id, _input, expected]) => ({
|
|
68
|
+
id,
|
|
69
|
+
outcome: 'passed',
|
|
70
|
+
output_digest: expectedDigest(expected),
|
|
71
|
+
})),
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
async function resolveEntrypoint(repoRoot) {
|
|
76
|
+
if (typeof repoRoot !== 'string' || repoRoot.length === 0) {
|
|
77
|
+
throw new TypeError('repoRoot must be a non-empty path');
|
|
78
|
+
}
|
|
79
|
+
const root = await realpath(repoRoot);
|
|
80
|
+
const entrypoint = await realpath(path.resolve(root, ENTRYPOINT));
|
|
81
|
+
if (!inside(root, entrypoint)) throw new TypeError('delivery policy entrypoint is outside repoRoot');
|
|
82
|
+
return entrypoint;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
function parseChildReceipt(stdout) {
|
|
86
|
+
let value;
|
|
87
|
+
try {
|
|
88
|
+
value = JSON.parse(stdout);
|
|
89
|
+
} catch {
|
|
90
|
+
throw new TypeError('delivery policy oracle child returned invalid JSON');
|
|
91
|
+
}
|
|
92
|
+
if (!exactRecord(value, ['case_results'])
|
|
93
|
+
|| !Array.isArray(value.case_results)
|
|
94
|
+
|| value.case_results.length !== CASES.length) {
|
|
95
|
+
throw new TypeError('delivery policy oracle child receipt shape is invalid');
|
|
96
|
+
}
|
|
97
|
+
return value.case_results;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/** 指定worktreeのfixtureをfresh Node processでblack-box照合する。 */
|
|
101
|
+
export async function runRc2DeliveryPolicyOracle({ repoRoot } = {}) {
|
|
102
|
+
const entrypoint = await resolveEntrypoint(repoRoot);
|
|
103
|
+
const childCases = CASES.map(([id, input]) => ({ id, input }));
|
|
104
|
+
const expectedReceipt = expectedRc2DeliveryPolicyOracleReceipt();
|
|
105
|
+
let stdout;
|
|
106
|
+
let stderr;
|
|
107
|
+
try {
|
|
108
|
+
({ stdout, stderr } = await execFileAsync(process.execPath, [
|
|
109
|
+
'--input-type=module',
|
|
110
|
+
'--eval',
|
|
111
|
+
CHILD_PROGRAM,
|
|
112
|
+
entrypoint,
|
|
113
|
+
JSON.stringify(childCases),
|
|
114
|
+
], { encoding: 'utf8', maxBuffer: 64 * 1024 }));
|
|
115
|
+
} catch (error) {
|
|
116
|
+
throw new Error(`delivery policy oracle child failed: ${error.message}`, { cause: error });
|
|
117
|
+
}
|
|
118
|
+
if (stderr.length !== 0) throw new Error('delivery policy oracle child wrote stderr');
|
|
119
|
+
|
|
120
|
+
const childResults = parseChildReceipt(stdout);
|
|
121
|
+
childResults.forEach((result, index) => {
|
|
122
|
+
const expected = expectedReceipt.case_results[index];
|
|
123
|
+
if (!exactRecord(result, ['id', 'output_digest'])
|
|
124
|
+
|| result.id !== expected.id
|
|
125
|
+
|| typeof result.output_digest !== 'string'
|
|
126
|
+
|| !/^[0-9a-f]{64}$/.test(result.output_digest)) {
|
|
127
|
+
throw new TypeError('delivery policy oracle child case receipt is invalid');
|
|
128
|
+
}
|
|
129
|
+
if (result.output_digest !== expected.output_digest) {
|
|
130
|
+
throw new Error(`delivery policy behavior mismatch: ${expected.id}`);
|
|
131
|
+
}
|
|
132
|
+
});
|
|
133
|
+
return expectedReceipt;
|
|
134
|
+
}
|