mcp-usage-control 1.0.0
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/LICENSE +201 -0
- package/README.md +141 -0
- package/dist/index.d.ts +533 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +2131 -0
- package/dist/index.js.map +1 -0
- package/dist/observability.d.ts +154 -0
- package/dist/observability.d.ts.map +1 -0
- package/dist/observability.js +171 -0
- package/dist/observability.js.map +1 -0
- package/dist/operational.d.ts +87 -0
- package/dist/operational.d.ts.map +1 -0
- package/dist/operational.js +193 -0
- package/dist/operational.js.map +1 -0
- package/dist/progressive-store-conformance.d.ts +4 -0
- package/dist/progressive-store-conformance.d.ts.map +1 -0
- package/dist/progressive-store-conformance.js +333 -0
- package/dist/progressive-store-conformance.js.map +1 -0
- package/dist/reconciliation-conformance.d.ts +36 -0
- package/dist/reconciliation-conformance.d.ts.map +1 -0
- package/dist/reconciliation-conformance.js +211 -0
- package/dist/reconciliation-conformance.js.map +1 -0
- package/dist/settlement-outcomes.d.ts +24 -0
- package/dist/settlement-outcomes.d.ts.map +1 -0
- package/dist/settlement-outcomes.js +68 -0
- package/dist/settlement-outcomes.js.map +1 -0
- package/dist/store-conformance.d.ts +50 -0
- package/dist/store-conformance.d.ts.map +1 -0
- package/dist/store-conformance.js +378 -0
- package/dist/store-conformance.js.map +1 -0
- package/dist/thresholds.d.ts +26 -0
- package/dist/thresholds.d.ts.map +1 -0
- package/dist/thresholds.js +56 -0
- package/dist/thresholds.js.map +1 -0
- package/dist/vector-store-conformance.d.ts +4 -0
- package/dist/vector-store-conformance.d.ts.map +1 -0
- package/dist/vector-store-conformance.js +297 -0
- package/dist/vector-store-conformance.js.map +1 -0
- package/dist/weighted-credits.d.ts +41 -0
- package/dist/weighted-credits.d.ts.map +1 -0
- package/dist/weighted-credits.js +143 -0
- package/dist/weighted-credits.js.map +1 -0
- package/dist/windowed-budget-keys.d.ts +36 -0
- package/dist/windowed-budget-keys.d.ts.map +1 -0
- package/dist/windowed-budget-keys.js +178 -0
- package/dist/windowed-budget-keys.js.map +1 -0
- package/package.json +113 -0
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
export class OperationReconciliationConformanceError extends Error {
|
|
2
|
+
report;
|
|
3
|
+
constructor(report) {
|
|
4
|
+
const failed = report.cases.filter(result => !result.passed);
|
|
5
|
+
super(`Operation reconciliation conformance failed: ${failed
|
|
6
|
+
.map(result => `${result.name}: ${result.error ?? 'unknown failure'}`)
|
|
7
|
+
.join('; ')}`);
|
|
8
|
+
this.report = report;
|
|
9
|
+
this.name = 'OperationReconciliationConformanceError';
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
/** Portable scalar-only read-only reconciliation contract for optional Store implementations. */
|
|
13
|
+
export async function runOperationReconciliationStoreConformance(harness) {
|
|
14
|
+
const ttlMs = harness.leaseTtlMs ?? 40;
|
|
15
|
+
assertPositiveInteger(ttlMs, 'leaseTtlMs');
|
|
16
|
+
const cases = [];
|
|
17
|
+
await runCase(harness, cases, 'absent-active-liable-settled', async (store) => {
|
|
18
|
+
const input = reconciliationInput('lifecycle');
|
|
19
|
+
const absent = await store.reconcileOperation(input);
|
|
20
|
+
assert(absent.status === 'absent', 'new logical operation must be absent');
|
|
21
|
+
const reserved = await store.reserve({ ...input, ttlMs: 5_000 });
|
|
22
|
+
assertAccepted(reserved, 'lifecycle reserve');
|
|
23
|
+
const pending = await store.reconcileOperation(input);
|
|
24
|
+
assert(pending.status === 'active' && pending.state === 'pending', 'pending state not reconciled');
|
|
25
|
+
if (pending.status === 'active') {
|
|
26
|
+
assert(pending.reservation.id === reserved.reservation.id, 'reservation identity changed');
|
|
27
|
+
}
|
|
28
|
+
await store.markLiable({ reservationId: reserved.reservation.id });
|
|
29
|
+
const liable = await store.reconcileOperation(input);
|
|
30
|
+
assert(liable.status === 'active' && liable.state === 'liable', 'liable state not reconciled');
|
|
31
|
+
await store.settle({
|
|
32
|
+
reservationId: reserved.reservation.id,
|
|
33
|
+
actualUnits: 1,
|
|
34
|
+
outcome: 'conformance_completed',
|
|
35
|
+
});
|
|
36
|
+
const settled = await store.reconcileOperation(input);
|
|
37
|
+
assert(settled.status === 'settled' && settled.reservedUnits === 1 && settled.actualUnits === 1, 'settled state not reconciled');
|
|
38
|
+
});
|
|
39
|
+
await runCase(harness, cases, 'expired-read-only', async (store) => {
|
|
40
|
+
const input = reconciliationInput('expired');
|
|
41
|
+
const reserved = await store.reserve({ ...input, ttlMs });
|
|
42
|
+
assertAccepted(reserved, 'expiring reserve');
|
|
43
|
+
await harness.waitForLeaseExpiry(ttlMs, 'expired-read-only');
|
|
44
|
+
const first = await store.reconcileOperation(input);
|
|
45
|
+
const second = await store.reconcileOperation(input);
|
|
46
|
+
assert(first.status === 'expired' && first.state === 'pending', 'expired pending state not reported');
|
|
47
|
+
assert(second.status === 'expired' && second.state === 'pending', 'reconciliation mutated expired state');
|
|
48
|
+
});
|
|
49
|
+
await runCase(harness, cases, 'mismatched-quote-fails-closed', async (store) => {
|
|
50
|
+
const input = reconciliationInput('mismatch');
|
|
51
|
+
const reserved = await store.reserve({ ...input, ttlMs: 5_000 });
|
|
52
|
+
assertAccepted(reserved, 'mismatch seed reserve');
|
|
53
|
+
await assertRejects(() => store.reconcileOperation({ ...input, units: 2 }), 'mismatched reserved units must fail closed');
|
|
54
|
+
await assertRejects(() => store.reconcileOperation({
|
|
55
|
+
...input,
|
|
56
|
+
budgets: [{ key: 'contract:reconcile:other', limit: 10 }],
|
|
57
|
+
}), 'mismatched budgets must fail closed');
|
|
58
|
+
});
|
|
59
|
+
return { passed: cases.every(result => result.passed), cases };
|
|
60
|
+
}
|
|
61
|
+
/** Portable read-only initial-vector-reserve reconciliation contract. */
|
|
62
|
+
export async function runVectorOperationReconciliationStoreConformance(harness) {
|
|
63
|
+
const ttlMs = harness.leaseTtlMs ?? 40;
|
|
64
|
+
assertPositiveInteger(ttlMs, 'leaseTtlMs');
|
|
65
|
+
const cases = [];
|
|
66
|
+
await runVectorCase(harness, cases, 'vector-absent-active-liable-settled', async (store) => {
|
|
67
|
+
const input = vectorReconciliationInput('lifecycle');
|
|
68
|
+
assert((await store.reconcileVectorOperation(input)).status === 'absent', 'new vector operation must be absent');
|
|
69
|
+
const reserved = await store.reserveVector({ ...input, ttlMs: 5_000 });
|
|
70
|
+
assertVectorAccepted(reserved, 'vector lifecycle reserve');
|
|
71
|
+
const pending = await store.reconcileVectorOperation(input);
|
|
72
|
+
assert(pending.status === 'active' && pending.state === 'pending', 'vector pending state not reconciled');
|
|
73
|
+
await store.markLiable({ reservationId: reserved.reservation.id });
|
|
74
|
+
const liable = await store.reconcileVectorOperation(input);
|
|
75
|
+
assert(liable.status === 'active' && liable.state === 'liable', 'vector liable state not reconciled');
|
|
76
|
+
await store.settleVector({
|
|
77
|
+
reservationId: reserved.reservation.id,
|
|
78
|
+
actualByDimension: input.dimensions.map(dimension => ({ key: dimension.key, actualUnits: dimension.units })),
|
|
79
|
+
outcome: 'conformance_completed',
|
|
80
|
+
});
|
|
81
|
+
const settled = await store.reconcileVectorOperation(input);
|
|
82
|
+
assert(settled.status === 'settled', 'vector settled state not reconciled');
|
|
83
|
+
if (settled.status === 'settled') {
|
|
84
|
+
assert(settled.reservedByDimension.length === input.dimensions.length, 'settled vector reserved topology changed');
|
|
85
|
+
assert(settled.actualByDimension.length === input.dimensions.length, 'settled vector actual topology changed');
|
|
86
|
+
}
|
|
87
|
+
});
|
|
88
|
+
await runVectorCase(harness, cases, 'vector-expired-read-only', async (store) => {
|
|
89
|
+
const input = vectorReconciliationInput('expired');
|
|
90
|
+
const reserved = await store.reserveVector({ ...input, ttlMs });
|
|
91
|
+
assertVectorAccepted(reserved, 'expiring vector reserve');
|
|
92
|
+
await harness.waitForLeaseExpiry(ttlMs, 'vector-expired-read-only');
|
|
93
|
+
const first = await store.reconcileVectorOperation(input);
|
|
94
|
+
const second = await store.reconcileVectorOperation(input);
|
|
95
|
+
assert(first.status === 'expired' && first.state === 'pending', 'expired vector pending state not reported');
|
|
96
|
+
assert(second.status === 'expired' && second.state === 'pending', 'vector reconciliation mutated expired state');
|
|
97
|
+
});
|
|
98
|
+
await runVectorCase(harness, cases, 'vector-topology-mismatch-fails-closed', async (store) => {
|
|
99
|
+
const input = vectorReconciliationInput('mismatch');
|
|
100
|
+
const reserved = await store.reserveVector({ ...input, ttlMs: 5_000 });
|
|
101
|
+
assertVectorAccepted(reserved, 'vector mismatch seed reserve');
|
|
102
|
+
await assertRejects(() => store.reconcileVectorOperation({
|
|
103
|
+
...input,
|
|
104
|
+
dimensions: [{ ...input.dimensions[0], units: input.dimensions[0].units + 1 }, input.dimensions[1]],
|
|
105
|
+
}), 'mismatched vector units must fail closed');
|
|
106
|
+
await assertRejects(() => store.reconcileVectorOperation({
|
|
107
|
+
...input,
|
|
108
|
+
dimensions: [{ ...input.dimensions[0], budgets: [{ key: 'contract:vector:other', limit: 10 }] }, input.dimensions[1]],
|
|
109
|
+
}), 'mismatched vector budgets must fail closed');
|
|
110
|
+
});
|
|
111
|
+
return { passed: cases.every(result => result.passed), cases };
|
|
112
|
+
}
|
|
113
|
+
export async function assertVectorOperationReconciliationStoreConformance(harness) {
|
|
114
|
+
const report = await runVectorOperationReconciliationStoreConformance(harness);
|
|
115
|
+
if (!report.passed)
|
|
116
|
+
throw new OperationReconciliationConformanceError(report);
|
|
117
|
+
}
|
|
118
|
+
export async function assertOperationReconciliationStoreConformance(harness) {
|
|
119
|
+
const report = await runOperationReconciliationStoreConformance(harness);
|
|
120
|
+
if (!report.passed)
|
|
121
|
+
throw new OperationReconciliationConformanceError(report);
|
|
122
|
+
}
|
|
123
|
+
async function runCase(harness, results, name, body) {
|
|
124
|
+
try {
|
|
125
|
+
const store = await harness.createStore(name);
|
|
126
|
+
await body(store);
|
|
127
|
+
results.push({ name, passed: true });
|
|
128
|
+
}
|
|
129
|
+
catch (error) {
|
|
130
|
+
results.push({ name, passed: false, error: errorMessage(error) });
|
|
131
|
+
}
|
|
132
|
+
finally {
|
|
133
|
+
try {
|
|
134
|
+
await harness.cleanup?.(name);
|
|
135
|
+
}
|
|
136
|
+
catch (error) {
|
|
137
|
+
results.push({ name: `${name}:cleanup`, passed: false, error: errorMessage(error) });
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
async function runVectorCase(harness, results, name, body) {
|
|
142
|
+
try {
|
|
143
|
+
const store = await harness.createStore(name);
|
|
144
|
+
await body(store);
|
|
145
|
+
results.push({ name, passed: true });
|
|
146
|
+
}
|
|
147
|
+
catch (error) {
|
|
148
|
+
results.push({ name, passed: false, error: errorMessage(error) });
|
|
149
|
+
}
|
|
150
|
+
finally {
|
|
151
|
+
try {
|
|
152
|
+
await harness.cleanup?.(name);
|
|
153
|
+
}
|
|
154
|
+
catch (error) {
|
|
155
|
+
results.push({ name: `${name}:cleanup`, passed: false, error: errorMessage(error) });
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
function vectorReconciliationInput(operationId) {
|
|
160
|
+
const dimensions = [
|
|
161
|
+
{ key: 'requests', units: 1, budgets: [{ key: `contract:vector:${operationId}:requests`, limit: 10 }] },
|
|
162
|
+
{ key: 'tokens', units: 3, budgets: [{ key: `contract:vector:${operationId}:tokens`, limit: 100 }] },
|
|
163
|
+
];
|
|
164
|
+
return { request: request(`vector-${operationId}`), dimensions };
|
|
165
|
+
}
|
|
166
|
+
function assertVectorAccepted(result, context) {
|
|
167
|
+
assert(result.accepted, `${context}: expected accepted reservation`);
|
|
168
|
+
}
|
|
169
|
+
function reconciliationInput(operationId) {
|
|
170
|
+
return {
|
|
171
|
+
request: request(operationId),
|
|
172
|
+
units: 1,
|
|
173
|
+
budgets: [{ key: `contract:reconcile:${operationId}`, limit: 10 }],
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
function request(operationId) {
|
|
177
|
+
return {
|
|
178
|
+
operationId,
|
|
179
|
+
principal: { id: 'user-1', tenantId: 'tenant-1' },
|
|
180
|
+
tool: 'contract-tool',
|
|
181
|
+
args: { conformance: true },
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
function assertAccepted(result, context) {
|
|
185
|
+
assert(result.accepted, `${context}: expected accepted reservation`);
|
|
186
|
+
}
|
|
187
|
+
async function assertRejects(action, message) {
|
|
188
|
+
let rejected = false;
|
|
189
|
+
try {
|
|
190
|
+
await action();
|
|
191
|
+
}
|
|
192
|
+
catch {
|
|
193
|
+
rejected = true;
|
|
194
|
+
}
|
|
195
|
+
assert(rejected, message);
|
|
196
|
+
}
|
|
197
|
+
function assert(condition, message) {
|
|
198
|
+
if (!condition)
|
|
199
|
+
throw new Error(message);
|
|
200
|
+
}
|
|
201
|
+
function assertPositiveInteger(value, name) {
|
|
202
|
+
if (!Number.isSafeInteger(value) || value <= 0) {
|
|
203
|
+
throw new RangeError(`${name} must be a positive safe integer`);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
function errorMessage(error) {
|
|
207
|
+
if (error instanceof Error)
|
|
208
|
+
return `${error.name}: ${error.message}`;
|
|
209
|
+
return String(error);
|
|
210
|
+
}
|
|
211
|
+
//# sourceMappingURL=reconciliation-conformance.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reconciliation-conformance.js","sourceRoot":"","sources":["../src/reconciliation-conformance.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export declare const CANONICAL_SETTLEMENT_OUTCOMES: readonly ["authorization_denied", "invalid_arguments", "pre_dispatch_rejected", "pre_dispatch_no_effect", "cancelled_before_dispatch", "completed", "proven_no_effect", "dispatched_conservative", "cancelled_after_dispatch"];
|
|
2
|
+
export type CanonicalSettlementOutcome = (typeof CANONICAL_SETTLEMENT_OUTCOMES)[number];
|
|
3
|
+
export type SettlementOutcomeAliases = Readonly<Record<string, CanonicalSettlementOutcome>>;
|
|
4
|
+
export interface SettlementOutcomeDiagnosticSink {
|
|
5
|
+
onInvalidSettlementOutcome(): void | Promise<void>;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Compatibility aliases used by the built-in MCP adapter and older integrations.
|
|
9
|
+
* New integrations should emit the canonical vocabulary directly.
|
|
10
|
+
*/
|
|
11
|
+
export declare const DEFAULT_SETTLEMENT_OUTCOME_ALIASES: SettlementOutcomeAliases;
|
|
12
|
+
/** Bounded diagnostic for integration vocabulary drift; raw input is deliberately not retained. */
|
|
13
|
+
export declare class InvalidSettlementOutcomeError extends TypeError {
|
|
14
|
+
readonly code: "invalid_settlement_outcome";
|
|
15
|
+
constructor();
|
|
16
|
+
}
|
|
17
|
+
export declare function isCanonicalSettlementOutcome(value: unknown): value is CanonicalSettlementOutcome;
|
|
18
|
+
/**
|
|
19
|
+
* Normalize a bounded consumer/domain outcome before it crosses the usage boundary.
|
|
20
|
+
* Invalid vocabulary fails before Store settlement and is distinguishable from backend failure.
|
|
21
|
+
* Diagnostic delivery is best-effort and can never replace the bounded normalization error.
|
|
22
|
+
*/
|
|
23
|
+
export declare function normalizeSettlementOutcome(value: unknown, aliases?: SettlementOutcomeAliases, diagnostics?: SettlementOutcomeDiagnosticSink): CanonicalSettlementOutcome;
|
|
24
|
+
//# sourceMappingURL=settlement-outcomes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"settlement-outcomes.d.ts","sourceRoot":"","sources":["../src/settlement-outcomes.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,6BAA6B,gOAUhC,CAAC;AAEX,MAAM,MAAM,0BAA0B,GAAG,CAAC,OAAO,6BAA6B,CAAC,CAAC,MAAM,CAAC,CAAC;AAExF,MAAM,MAAM,wBAAwB,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,0BAA0B,CAAC,CAAC,CAAC;AAE5F,MAAM,WAAW,+BAA+B;IAC9C,0BAA0B,IAAI,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACpD;AAED;;;GAGG;AACH,eAAO,MAAM,kCAAkC,EAAE,wBAQ/C,CAAC;AAEH,mGAAmG;AACnG,qBAAa,6BAA8B,SAAQ,SAAS;IAC1D,QAAQ,CAAC,IAAI,EAAG,4BAA4B,CAAU;;CAMvD;AAED,wBAAgB,4BAA4B,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,0BAA0B,CAKhG;AAED;;;;GAIG;AACH,wBAAgB,0BAA0B,CACxC,KAAK,EAAE,OAAO,EACd,OAAO,GAAE,wBAA6D,EACtE,WAAW,CAAC,EAAE,+BAA+B,GAC5C,0BAA0B,CAU5B"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
export const CANONICAL_SETTLEMENT_OUTCOMES = [
|
|
2
|
+
'authorization_denied',
|
|
3
|
+
'invalid_arguments',
|
|
4
|
+
'pre_dispatch_rejected',
|
|
5
|
+
'pre_dispatch_no_effect',
|
|
6
|
+
'cancelled_before_dispatch',
|
|
7
|
+
'completed',
|
|
8
|
+
'proven_no_effect',
|
|
9
|
+
'dispatched_conservative',
|
|
10
|
+
'cancelled_after_dispatch',
|
|
11
|
+
];
|
|
12
|
+
/**
|
|
13
|
+
* Compatibility aliases used by the built-in MCP adapter and older integrations.
|
|
14
|
+
* New integrations should emit the canonical vocabulary directly.
|
|
15
|
+
*/
|
|
16
|
+
export const DEFAULT_SETTLEMENT_OUTCOME_ALIASES = Object.freeze({
|
|
17
|
+
success: 'completed',
|
|
18
|
+
tool_error: 'completed',
|
|
19
|
+
error: 'dispatched_conservative',
|
|
20
|
+
unsupported_input_required: 'dispatched_conservative',
|
|
21
|
+
input_required_round_limit: 'dispatched_conservative',
|
|
22
|
+
invalid_input_required_state: 'dispatched_conservative',
|
|
23
|
+
input_required_suspend_failed: 'dispatched_conservative',
|
|
24
|
+
});
|
|
25
|
+
/** Bounded diagnostic for integration vocabulary drift; raw input is deliberately not retained. */
|
|
26
|
+
export class InvalidSettlementOutcomeError extends TypeError {
|
|
27
|
+
code = 'invalid_settlement_outcome';
|
|
28
|
+
constructor() {
|
|
29
|
+
super('Settlement outcome is not part of the canonical usage vocabulary');
|
|
30
|
+
this.name = 'InvalidSettlementOutcomeError';
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
export function isCanonicalSettlementOutcome(value) {
|
|
34
|
+
return (typeof value === 'string' &&
|
|
35
|
+
CANONICAL_SETTLEMENT_OUTCOMES.includes(value));
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Normalize a bounded consumer/domain outcome before it crosses the usage boundary.
|
|
39
|
+
* Invalid vocabulary fails before Store settlement and is distinguishable from backend failure.
|
|
40
|
+
* Diagnostic delivery is best-effort and can never replace the bounded normalization error.
|
|
41
|
+
*/
|
|
42
|
+
export function normalizeSettlementOutcome(value, aliases = DEFAULT_SETTLEMENT_OUTCOME_ALIASES, diagnostics) {
|
|
43
|
+
if (isCanonicalSettlementOutcome(value))
|
|
44
|
+
return value;
|
|
45
|
+
if (typeof value !== 'string' || value.length === 0 || value.length > 128) {
|
|
46
|
+
return rejectInvalidSettlementOutcome(diagnostics);
|
|
47
|
+
}
|
|
48
|
+
const normalized = aliases[value];
|
|
49
|
+
if (normalized === undefined || !isCanonicalSettlementOutcome(normalized)) {
|
|
50
|
+
return rejectInvalidSettlementOutcome(diagnostics);
|
|
51
|
+
}
|
|
52
|
+
return normalized;
|
|
53
|
+
}
|
|
54
|
+
function rejectInvalidSettlementOutcome(diagnostics) {
|
|
55
|
+
if (diagnostics !== undefined) {
|
|
56
|
+
try {
|
|
57
|
+
const result = diagnostics.onInvalidSettlementOutcome();
|
|
58
|
+
if (result && typeof result.catch === 'function') {
|
|
59
|
+
void result.catch(() => undefined);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
catch {
|
|
63
|
+
// Diagnostics are not part of settlement normalization or enforcement.
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
throw new InvalidSettlementOutcomeError();
|
|
67
|
+
}
|
|
68
|
+
//# sourceMappingURL=settlement-outcomes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"settlement-outcomes.js","sourceRoot":"","sources":["../src/settlement-outcomes.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,6BAA6B,GAAG;IAC3C,sBAAsB;IACtB,mBAAmB;IACnB,uBAAuB;IACvB,wBAAwB;IACxB,2BAA2B;IAC3B,WAAW;IACX,kBAAkB;IAClB,yBAAyB;IACzB,0BAA0B;CAClB,CAAC;AAUX;;;GAGG;AACH,MAAM,CAAC,MAAM,kCAAkC,GAA6B,MAAM,CAAC,MAAM,CAAC;IACxF,OAAO,EAAE,WAAW;IACpB,UAAU,EAAE,WAAW;IACvB,KAAK,EAAE,yBAAyB;IAChC,0BAA0B,EAAE,yBAAyB;IACrD,0BAA0B,EAAE,yBAAyB;IACrD,4BAA4B,EAAE,yBAAyB;IACvD,6BAA6B,EAAE,yBAAyB;CACzD,CAAC,CAAC;AAEH,mGAAmG;AACnG,MAAM,OAAO,6BAA8B,SAAQ,SAAS;IACjD,IAAI,GAAG,4BAAqC,CAAC;IAEtD;QACE,KAAK,CAAC,kEAAkE,CAAC,CAAC;QAC1E,IAAI,CAAC,IAAI,GAAG,+BAA+B,CAAC;IAC9C,CAAC;CACF;AAED,MAAM,UAAU,4BAA4B,CAAC,KAAc;IACzD,OAAO,CACL,OAAO,KAAK,KAAK,QAAQ;QACxB,6BAAmD,CAAC,QAAQ,CAAC,KAAK,CAAC,CACrE,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,0BAA0B,CACxC,KAAc,EACd,UAAoC,kCAAkC,EACtE,WAA6C;IAE7C,IAAI,4BAA4B,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IACtD,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,IAAI,KAAK,CAAC,MAAM,GAAG,GAAG,EAAE,CAAC;QAC1E,OAAO,8BAA8B,CAAC,WAAW,CAAC,CAAC;IACrD,CAAC;IACD,MAAM,UAAU,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC;IAClC,IAAI,UAAU,KAAK,SAAS,IAAI,CAAC,4BAA4B,CAAC,UAAU,CAAC,EAAE,CAAC;QAC1E,OAAO,8BAA8B,CAAC,WAAW,CAAC,CAAC;IACrD,CAAC;IACD,OAAO,UAAU,CAAC;AACpB,CAAC;AAED,SAAS,8BAA8B,CACrC,WAAwD;IAExD,IAAI,WAAW,KAAK,SAAS,EAAE,CAAC;QAC9B,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,WAAW,CAAC,0BAA0B,EAAE,CAAC;YACxD,IAAI,MAAM,IAAI,OAAQ,MAAwB,CAAC,KAAK,KAAK,UAAU,EAAE,CAAC;gBACpE,KAAM,MAAwB,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;YACxD,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,uEAAuE;QACzE,CAAC;IACH,CAAC;IACD,MAAM,IAAI,6BAA6B,EAAE,CAAC;AAC5C,CAAC"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
export * from './reconciliation-conformance.js';
|
|
2
|
+
export * from './progressive-store-conformance.js';
|
|
3
|
+
export * from './vector-store-conformance.js';
|
|
4
|
+
import type { UsageStore } from './index.js';
|
|
5
|
+
type MaybePromise<T> = T | Promise<T>;
|
|
6
|
+
export interface UsageStoreConformanceHarness {
|
|
7
|
+
/**
|
|
8
|
+
* Return an isolated store transaction domain for one conformance scenario.
|
|
9
|
+
* The scenario name is stable and may be used to derive a Redis prefix,
|
|
10
|
+
* Durable Object name, Firestore collection prefix, database schema, etc.
|
|
11
|
+
*/
|
|
12
|
+
createStore(scenario: string): MaybePromise<UsageStore>;
|
|
13
|
+
/**
|
|
14
|
+
* Wait until a lease with the supplied TTL is authoritatively expired for the
|
|
15
|
+
* tested store. Real stores may sleep; emulator/fake-clock harnesses may advance
|
|
16
|
+
* their store clock instead. Include any configured expiry grace here.
|
|
17
|
+
*/
|
|
18
|
+
waitForLeaseExpiry(ttlMs: number, scenario: string): MaybePromise<void>;
|
|
19
|
+
/** Optional cleanup for the isolated scenario domain. */
|
|
20
|
+
cleanup?(scenario: string): MaybePromise<void>;
|
|
21
|
+
/** Lease TTL used by expiry cases. Defaults to 40 ms. */
|
|
22
|
+
leaseTtlMs?: number;
|
|
23
|
+
/** Parallel contenders used by the admission race case. Defaults to 16. */
|
|
24
|
+
concurrency?: number;
|
|
25
|
+
}
|
|
26
|
+
export interface UsageStoreConformanceCaseResult {
|
|
27
|
+
name: string;
|
|
28
|
+
passed: boolean;
|
|
29
|
+
error?: string;
|
|
30
|
+
}
|
|
31
|
+
export interface UsageStoreConformanceReport {
|
|
32
|
+
passed: boolean;
|
|
33
|
+
cases: UsageStoreConformanceCaseResult[];
|
|
34
|
+
}
|
|
35
|
+
export declare class UsageStoreConformanceError extends Error {
|
|
36
|
+
readonly report: UsageStoreConformanceReport;
|
|
37
|
+
constructor(report: UsageStoreConformanceReport);
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Run the portable, provider-neutral behavioral contract for a UsageStore.
|
|
41
|
+
*
|
|
42
|
+
* Passing this suite means that the public store semantics are compatible. It
|
|
43
|
+
* does not by itself prove persistence/HA, store-time authority, network ACK
|
|
44
|
+
* ambiguity behavior, or platform-specific fault tolerance. Those production
|
|
45
|
+
* safety requirements need adapter-specific evidence in addition to this suite.
|
|
46
|
+
*/
|
|
47
|
+
export declare function runUsageStoreConformance(harness: UsageStoreConformanceHarness): Promise<UsageStoreConformanceReport>;
|
|
48
|
+
/** Run the suite and throw a single detailed error if any case fails. */
|
|
49
|
+
export declare function assertUsageStoreConformance(harness: UsageStoreConformanceHarness): Promise<UsageStoreConformanceReport>;
|
|
50
|
+
//# sourceMappingURL=store-conformance.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"store-conformance.d.ts","sourceRoot":"","sources":["../src/store-conformance.ts"],"names":[],"mappings":"AAAA,cAAc,iCAAiC,CAAC;AAChD,cAAc,oCAAoC,CAAC;AACnD,cAAc,+BAA+B,CAAC;AAC9C,OAAO,KAAK,EAA4C,UAAU,EAAE,MAAM,YAAY,CAAC;AAEvF,KAAK,YAAY,CAAC,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;AAEtC,MAAM,WAAW,4BAA4B;IAC3C;;;;OAIG;IACH,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,YAAY,CAAC,UAAU,CAAC,CAAC;IAExD;;;;OAIG;IACH,kBAAkB,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC;IAExE,yDAAyD;IACzD,OAAO,CAAC,CAAC,QAAQ,EAAE,MAAM,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC;IAE/C,yDAAyD;IACzD,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB,2EAA2E;IAC3E,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,+BAA+B;IAC9C,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,OAAO,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,2BAA2B;IAC1C,MAAM,EAAE,OAAO,CAAC;IAChB,KAAK,EAAE,+BAA+B,EAAE,CAAC;CAC1C;AAED,qBAAa,0BAA2B,SAAQ,KAAK;aACvB,MAAM,EAAE,2BAA2B;gBAAnC,MAAM,EAAE,2BAA2B;CAShE;AAED;;;;;;;GAOG;AACH,wBAAsB,wBAAwB,CAC5C,OAAO,EAAE,4BAA4B,GACpC,OAAO,CAAC,2BAA2B,CAAC,CA6WtC;AAED,yEAAyE;AACzE,wBAAsB,2BAA2B,CAC/C,OAAO,EAAE,4BAA4B,GACpC,OAAO,CAAC,2BAA2B,CAAC,CAItC"}
|