stitchkit 0.66.0 → 0.66.1
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.
|
@@ -1,6 +1,39 @@
|
|
|
1
1
|
import type { AgentRuntimeStore } from '../agent-runtime/store';
|
|
2
|
+
/**
|
|
3
|
+
* What the scenario is about to touch, handed over before the first mutation.
|
|
4
|
+
*
|
|
5
|
+
* The kit used to pick its conversation identities *after* `createStore()`
|
|
6
|
+
* returned, which locked out exactly the adapters it exists to certify: a
|
|
7
|
+
* durable store whose runtime rows hang off an application-owned conversation
|
|
8
|
+
* row cannot serve the first admission, because nobody ever told it which
|
|
9
|
+
* parent to provision. Running the kit against the memory reference store
|
|
10
|
+
* instead proves the reducer — which is not the thing under test.
|
|
11
|
+
*/
|
|
12
|
+
export interface AgentStoreConformanceContext {
|
|
13
|
+
/**
|
|
14
|
+
* Every conversation the scenario mutates, in the order it first touches
|
|
15
|
+
* them. Provision one parent per id before returning the store, and remove
|
|
16
|
+
* them again in `cleanup`.
|
|
17
|
+
*/
|
|
18
|
+
readonly conversationIds: readonly string[];
|
|
19
|
+
}
|
|
2
20
|
export interface AgentStoreConformanceConfig {
|
|
3
|
-
|
|
21
|
+
/**
|
|
22
|
+
* Build the store under test. The context arrives first so an adapter can
|
|
23
|
+
* provision fixture state; a factory that needs none may ignore it, and an
|
|
24
|
+
* existing zero-argument factory stays valid unchanged.
|
|
25
|
+
*/
|
|
26
|
+
createStore(context: AgentStoreConformanceContext): AgentRuntimeStore | Promise<AgentRuntimeStore>;
|
|
27
|
+
/**
|
|
28
|
+
* Remove whatever `createStore` provisioned.
|
|
29
|
+
*
|
|
30
|
+
* Runs exactly once, after the scenario, whether it passed or failed — a kit
|
|
31
|
+
* that only cleans up on success leaks a row for every red run, which is the
|
|
32
|
+
* shape that makes a failing suite un-rerunnable. A failure here never
|
|
33
|
+
* replaces the scenario's own: the answer to "does this adapter conform" is
|
|
34
|
+
* not overwritten by the answer to "did the teardown work".
|
|
35
|
+
*/
|
|
36
|
+
cleanup?(context: AgentStoreConformanceContext): void | Promise<void>;
|
|
4
37
|
}
|
|
5
38
|
/** Black-box contract shared by memory and third-party durable agent stores. */
|
|
6
39
|
export declare function runAgentStoreConformance(config: AgentStoreConformanceConfig): Promise<void>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent-store-conformance.d.ts","sourceRoot":"","sources":["../../src/testing/agent-store-conformance.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAEhE,MAAM,WAAW,2BAA2B;IAC1C,WAAW,
|
|
1
|
+
{"version":3,"file":"agent-store-conformance.d.ts","sourceRoot":"","sources":["../../src/testing/agent-store-conformance.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAEhE;;;;;;;;;GASG;AACH,MAAM,WAAW,4BAA4B;IAC3C;;;;OAIG;IACH,QAAQ,CAAC,eAAe,EAAE,SAAS,MAAM,EAAE,CAAC;CAC7C;AAED,MAAM,WAAW,2BAA2B;IAC1C;;;;OAIG;IACH,WAAW,CACT,OAAO,EAAE,4BAA4B,GACpC,iBAAiB,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC;IAClD;;;;;;;;OAQG;IACH,OAAO,CAAC,CAAC,OAAO,EAAE,4BAA4B,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACvE;AAwCD,gFAAgF;AAChF,wBAAsB,wBAAwB,CAC5C,MAAM,EAAE,2BAA2B,GAClC,OAAO,CAAC,IAAI,CAAC,CA2Bf"}
|
package/dist/testing.d.ts
CHANGED
|
@@ -32,7 +32,7 @@ export declare function createHandlerTestClients<T extends Record<string, Contra
|
|
|
32
32
|
[P in keyof T]: ScopedHttpClient<T[P]['endpoints'], ScopedKeys<K>>;
|
|
33
33
|
};
|
|
34
34
|
export { type AgentRaceBarrier, type AgentRaceDriver, type AgentRaceTrace, type AgentRaceTraceEntry, createAgentRaceBarrier, createAgentRaceDriver, createAgentRaceTrace, } from './agent-runtime/testing';
|
|
35
|
-
export { type AgentStoreConformanceConfig, runAgentStoreConformance, } from './testing/agent-store-conformance';
|
|
35
|
+
export { type AgentStoreConformanceConfig, type AgentStoreConformanceContext, runAgentStoreConformance, } from './testing/agent-store-conformance';
|
|
36
36
|
export { type ManagedResourceConformanceConfig, type ManagedResourceConformanceControls, ManagedResourceConformanceError, type ManagedResourceConformanceFactoryInput, type ManagedResourceConformanceFixture, type ManagedResourceConformancePhase, ManagedResourceConformancePhaseSchema, type ManagedResourceConformanceScenario, type ManagedResourceConformanceScenarioId, ManagedResourceConformanceScenarioIdSchema, ManagedResourceConformanceScenarioSchema, type ManagedResourceConformanceTraceEntry, ManagedResourceConformanceTraceEntrySchema, type ManagedResourceConformanceTraceOutcome, ManagedResourceConformanceTraceOutcomeSchema, runManagedResourceConformance, } from './testing/managed-resource-conformance';
|
|
37
37
|
export { assertSurfaceDiscovery, type ConformanceTransport, type CreateRealtimeProbeDriverConfig, createRealtimeProbeDriver, type DefineRealtimeProbeConfig, defineRealtimeProbe, type RealtimeDisconnectObservation, RealtimeDisconnectObservationSchema, type RealtimeProbeAdapter, type RealtimeProbeFixture, type RealtimeProbeScenario, type RealtimeRejectionObservation, RealtimeRejectionObservationSchema, type RunSurfaceProbesConfig, runSurfaceProbes, type SurfaceDiscoveryObservation, type SurfaceProbe, type SurfaceProbeDriver, type SurfaceRealtimeDiscoveryObservation, type SurfaceToolDiscoveryObservation, type TransportObservation, TransportObservationSchema, } from './testing/surface-conformance';
|
|
38
38
|
export { assertSurfaceManifestSnapshot, buildSurfaceManifest, type IncompatibleSchemaPolicy, type McpSchemaValidationConfig, type SurfaceAgentProjection, type SurfaceManifest, type SurfaceManifestConfig, type SurfaceManifestExtension, SurfaceManifestExtensionSchema, type SurfaceManifestOperation, SurfaceManifestOperationSchema, type SurfaceManifestRealtimeEvent, SurfaceManifestRealtimeEventSchema, SurfaceManifestSchema, type SurfaceManifestTool, SurfaceManifestToolSchema, type SurfaceManifestToolSurface, SurfaceManifestToolSurfaceSchema, type SurfaceMcpPreparation, SurfaceRealtimeSchemaPairSchema, type SurfaceRuntimeToolDefinition, SurfaceSchemaDigestsSchema, type SurfaceToolDefinition, type SurfaceToolExtension, serializeSurfaceValue, } from './testing/surface-manifest';
|
package/dist/testing.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"testing.d.ts","sourceRoot":"","sources":["../src/testing.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"testing.d.ts","sourceRoot":"","sources":["../src/testing.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EACL,KAAK,YAAY,EAEjB,KAAK,oBAAoB,EAGzB,KAAK,UAAU,EAChB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAC7E,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAEnD,MAAM,MAAM,yBAAyB,GAAG,IAAI,CAAC,YAAY,EAAE,SAAS,GAAG,OAAO,CAAC,CAAC;AAEhF,MAAM,WAAW,0BAA0B,CAAC,OAAO;IACjD,OAAO,EAAE,YAAY,CAAC,OAAO,CAAC,CAAC;IAC/B,2DAA2D;IAC3D,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,qFAAqF;IACrF,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,6EAA6E;IAC7E,MAAM,CAAC,EAAE,yBAAyB,CAAC;IACnC,2DAA2D;IAC3D,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,uBAAuB,CACtC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,EACrC,OAAO,GAAG,OAAO,EACjB,CAAC,SAAS,MAAM,GAAG,KAAK,CACxB,SAAQ,0BAA0B,CAAC,OAAO,CAAC;IAC3C,QAAQ,EAAE,WAAW,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;IACjC,cAAc,CAAC,EAAE,oBAAoB,CAAC,CAAC,CAAC,CAAC;CAC1C;AAED,MAAM,WAAW,wBAAwB,CACvC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,CAAC,CAAC,EAC1E,OAAO,GAAG,OAAO,EACjB,CAAC,SAAS,MAAM,GAAG,KAAK,CACxB,SAAQ,0BAA0B,CAAC,OAAO,CAAC;IAC3C,SAAS,EAAE,CAAC,CAAC;IACb,cAAc,CAAC,EAAE,oBAAoB,CAAC,CAAC,CAAC,CAAC;CAC1C;AA+BD,gGAAgG;AAChG,wBAAgB,uBAAuB,CACrC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,EACrC,OAAO,GAAG,OAAO,EACjB,KAAK,CAAC,CAAC,SAAS,MAAM,GAAG,KAAK,EAC9B,MAAM,EAAE,uBAAuB,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,GAAG,gBAAgB,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC,CAEpF;AAED,2FAA2F;AAC3F,wBAAgB,wBAAwB,CACtC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,CAAC,CAAC,EAC1E,OAAO,GAAG,OAAO,EACjB,KAAK,CAAC,CAAC,SAAS,MAAM,GAAG,KAAK,EAE9B,MAAM,EAAE,wBAAwB,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,GAC9C;KAAG,CAAC,IAAI,MAAM,CAAC,GAAG,gBAAgB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC;CAAE,CAMxE;AAED,OAAO,EACL,KAAK,gBAAgB,EACrB,KAAK,eAAe,EACpB,KAAK,cAAc,EACnB,KAAK,mBAAmB,EACxB,sBAAsB,EACtB,qBAAqB,EACrB,oBAAoB,GACrB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EACL,KAAK,2BAA2B,EAChC,KAAK,4BAA4B,EACjC,wBAAwB,GACzB,MAAM,mCAAmC,CAAC;AAC3C,OAAO,EACL,KAAK,gCAAgC,EACrC,KAAK,kCAAkC,EACvC,+BAA+B,EAC/B,KAAK,sCAAsC,EAC3C,KAAK,iCAAiC,EACtC,KAAK,+BAA+B,EACpC,qCAAqC,EACrC,KAAK,kCAAkC,EACvC,KAAK,oCAAoC,EACzC,0CAA0C,EAC1C,wCAAwC,EACxC,KAAK,oCAAoC,EACzC,0CAA0C,EAC1C,KAAK,sCAAsC,EAC3C,4CAA4C,EAC5C,6BAA6B,GAC9B,MAAM,wCAAwC,CAAC;AAChD,OAAO,EACL,sBAAsB,EACtB,KAAK,oBAAoB,EACzB,KAAK,+BAA+B,EACpC,yBAAyB,EACzB,KAAK,yBAAyB,EAC9B,mBAAmB,EACnB,KAAK,6BAA6B,EAClC,mCAAmC,EACnC,KAAK,oBAAoB,EACzB,KAAK,oBAAoB,EACzB,KAAK,qBAAqB,EAC1B,KAAK,4BAA4B,EACjC,kCAAkC,EAClC,KAAK,sBAAsB,EAC3B,gBAAgB,EAChB,KAAK,2BAA2B,EAChC,KAAK,YAAY,EACjB,KAAK,kBAAkB,EACvB,KAAK,mCAAmC,EACxC,KAAK,+BAA+B,EACpC,KAAK,oBAAoB,EACzB,0BAA0B,GAC3B,MAAM,+BAA+B,CAAC;AACvC,OAAO,EACL,6BAA6B,EAC7B,oBAAoB,EACpB,KAAK,wBAAwB,EAC7B,KAAK,yBAAyB,EAC9B,KAAK,sBAAsB,EAC3B,KAAK,eAAe,EACpB,KAAK,qBAAqB,EAC1B,KAAK,wBAAwB,EAC7B,8BAA8B,EAC9B,KAAK,wBAAwB,EAC7B,8BAA8B,EAC9B,KAAK,4BAA4B,EACjC,kCAAkC,EAClC,qBAAqB,EACrB,KAAK,mBAAmB,EACxB,yBAAyB,EACzB,KAAK,0BAA0B,EAC/B,gCAAgC,EAChC,KAAK,qBAAqB,EAC1B,+BAA+B,EAC/B,KAAK,4BAA4B,EACjC,0BAA0B,EAC1B,KAAK,qBAAqB,EAC1B,KAAK,oBAAoB,EACzB,qBAAqB,GACtB,MAAM,4BAA4B,CAAC"}
|
package/dist/testing.js
CHANGED
|
@@ -141,8 +141,33 @@ function requireOutcome(actual, expected) {
|
|
|
141
141
|
}
|
|
142
142
|
}
|
|
143
143
|
async function runAgentStoreConformance(config) {
|
|
144
|
-
const
|
|
145
|
-
const
|
|
144
|
+
const run = `conformance-${crypto.randomUUID()}`;
|
|
145
|
+
const context = {
|
|
146
|
+
conversationIds: [run, `${run}-recovery`, `${run}-absorb`]
|
|
147
|
+
};
|
|
148
|
+
const store = await config.createStore(context);
|
|
149
|
+
let failure;
|
|
150
|
+
try {
|
|
151
|
+
await conformanceScenario(store, context.conversationIds);
|
|
152
|
+
} catch (error) {
|
|
153
|
+
failure = error;
|
|
154
|
+
}
|
|
155
|
+
try {
|
|
156
|
+
await config.cleanup?.(context);
|
|
157
|
+
} catch (cleanupError) {
|
|
158
|
+
if (failure === undefined)
|
|
159
|
+
throw cleanupError;
|
|
160
|
+
throw new AggregateError([failure, cleanupError], `${failure instanceof Error ? failure.message : String(failure)} (cleanup also failed: ${cleanupError instanceof Error ? cleanupError.message : String(cleanupError)})`);
|
|
161
|
+
}
|
|
162
|
+
if (failure !== undefined)
|
|
163
|
+
throw failure;
|
|
164
|
+
}
|
|
165
|
+
async function conformanceScenario(store, conversationIds) {
|
|
166
|
+
const [conversationId, recoveryConversationId, absorbConversationId] = conversationIds;
|
|
167
|
+
if (!conversationId || !recoveryConversationId || !absorbConversationId) {
|
|
168
|
+
throw new Error("Agent store conformance requires three conversation identities");
|
|
169
|
+
}
|
|
170
|
+
const absentConversationId = `${conversationId}-absent`;
|
|
146
171
|
const firstInput = userMessage(conversationId, "input-1");
|
|
147
172
|
const firstRun = queuedRun(conversationId, firstInput.id, "run-1");
|
|
148
173
|
const accepted = await store.acceptInputAndAssignRun({
|
|
@@ -373,7 +398,7 @@ async function runAgentStoreConformance(config) {
|
|
|
373
398
|
if (await store.loadRun({ conversationId, runId: "no-such-run" })) {
|
|
374
399
|
throw new Error("loadRun must return undefined for an unknown run");
|
|
375
400
|
}
|
|
376
|
-
if (await store.loadRun({ conversationId:
|
|
401
|
+
if (await store.loadRun({ conversationId: absentConversationId, runId: running.id })) {
|
|
377
402
|
throw new Error("loadRun must not cross conversation boundaries");
|
|
378
403
|
}
|
|
379
404
|
const activeRuns = await store.listActiveRuns(conversationId);
|
|
@@ -393,7 +418,7 @@ async function runAgentStoreConformance(config) {
|
|
|
393
418
|
throw new Error("listActiveRuns must order by createdAt and then by id");
|
|
394
419
|
}
|
|
395
420
|
}
|
|
396
|
-
if ((await store.listActiveRuns(
|
|
421
|
+
if ((await store.listActiveRuns(absentConversationId)).length !== 0) {
|
|
397
422
|
throw new Error("listActiveRuns must be empty for an unknown conversation");
|
|
398
423
|
}
|
|
399
424
|
const recoverable = await store.scanRecoverable({ limit: 10 });
|
|
@@ -488,7 +513,6 @@ async function runAgentStoreConformance(config) {
|
|
|
488
513
|
if (duplicateTerminal.run.terminalReason !== "success" || JSON.stringify(duplicateTerminal.assistant) !== JSON.stringify(terminalAssistant)) {
|
|
489
514
|
throw new Error("Compaction discarded the canonical duplicate terminal result");
|
|
490
515
|
}
|
|
491
|
-
const recoveryConversationId = `${conversationId}-recovery`;
|
|
492
516
|
const recoveryInput = userMessage(recoveryConversationId, "recovery-input");
|
|
493
517
|
const recoveryRun = queuedRun(recoveryConversationId, recoveryInput.id, "recovery-run");
|
|
494
518
|
const recoveryAccepted = await store.acceptInputAndAssignRun({
|
|
@@ -522,10 +546,9 @@ async function runAgentStoreConformance(config) {
|
|
|
522
546
|
if (terminalRun?.state !== "abandoned" || terminalMessage?.status !== "failed") {
|
|
523
547
|
throw new Error("Abandon recovery did not atomically terminalize its assistant record");
|
|
524
548
|
}
|
|
525
|
-
await assertAbsorptionIsAtomic(store);
|
|
549
|
+
await assertAbsorptionIsAtomic(store, absorbConversationId);
|
|
526
550
|
}
|
|
527
|
-
async function assertAbsorptionIsAtomic(store) {
|
|
528
|
-
const conversationId = `conformance-absorb-${crypto.randomUUID()}`;
|
|
551
|
+
async function assertAbsorptionIsAtomic(store, conversationId) {
|
|
529
552
|
const leadInput = userMessage(conversationId, "absorb-input-1");
|
|
530
553
|
const leadRun = queuedRun(conversationId, leadInput.id, "absorb-run-1");
|
|
531
554
|
const lead = await store.acceptInputAndAssignRun({
|
package/llms-full.txt
CHANGED
|
@@ -4171,8 +4171,14 @@ outbox.
|
|
|
4171
4171
|
`stitchkit/testing` exports `createAgentRaceBarrier`, `createAgentRaceDriver` and
|
|
4172
4172
|
`createAgentRaceTrace`. Barriers have bounded teardown, traces assert exact partial order, and the
|
|
4173
4173
|
helpers are exercised from packed Bun and Node consumers. `runAgentStoreConformance` runs duplicate,
|
|
4174
|
-
coalescing, collision, stale checkpoint, replay safety, terminal race,
|
|
4175
|
-
invariants against any fresh durable adapter.
|
|
4174
|
+
coalescing, collision, stale checkpoint, replay safety, terminal race, absorption, bounded reads,
|
|
4175
|
+
compaction and recovery invariants against any fresh durable adapter.
|
|
4176
|
+
|
|
4177
|
+
It picks its conversation identities itself and passes them to `createStore(context)` **before the
|
|
4178
|
+
first mutation**, so an adapter whose runtime rows reference an application-owned conversation row
|
|
4179
|
+
can provision those parents; the optional `cleanup(context)` removes them again, and runs once
|
|
4180
|
+
whether the scenario passed or failed. A factory that owns no fixture state ignores the argument and
|
|
4181
|
+
keeps working unchanged.
|
|
4176
4182
|
|
|
4177
4183
|
|
|
4178
4184
|
==============================================================================
|
|
@@ -7856,9 +7862,28 @@ Prisma adapter, an in-memory one, anything — run the conformance kit against i
|
|
|
7856
7862
|
```ts
|
|
7857
7863
|
import { runAgentStoreConformance } from 'stitchkit/testing'
|
|
7858
7864
|
|
|
7859
|
-
await runAgentStoreConformance({
|
|
7865
|
+
await runAgentStoreConformance({ createStore: () => yourStore })
|
|
7860
7866
|
```
|
|
7861
7867
|
|
|
7868
|
+
The kit picks the conversation identities itself and hands them over **before**
|
|
7869
|
+
the first mutation, so a store whose runtime rows hang off an application-owned
|
|
7870
|
+
conversation row can provision the parents — and take them away again:
|
|
7871
|
+
|
|
7872
|
+
```ts
|
|
7873
|
+
await runAgentStoreConformance({
|
|
7874
|
+
createStore: (context) => {
|
|
7875
|
+
for (const conversationId of context.conversationIds) createConversationRow(conversationId)
|
|
7876
|
+
return yourStore
|
|
7877
|
+
},
|
|
7878
|
+
cleanup: (context) => {
|
|
7879
|
+
for (const conversationId of context.conversationIds) deleteConversationRow(conversationId)
|
|
7880
|
+
},
|
|
7881
|
+
})
|
|
7882
|
+
```
|
|
7883
|
+
|
|
7884
|
+
`cleanup` runs exactly once, after the scenario, whether it passed or failed —
|
|
7885
|
+
and a failure in it never replaces the scenario's own.
|
|
7886
|
+
|
|
7862
7887
|
Green before and red after tells you the contract grew and where, in one run,
|
|
7863
7888
|
instead of one failure at a time in production. Green both times means the
|
|
7864
7889
|
upgrade owes you nothing on that surface — which is the usual answer if you
|
|
@@ -11126,7 +11151,8 @@ handler pipeline without opening a TCP port.
|
|
|
11126
11151
|
| `createHandlerTestClient` | function | one contract client backed by an in-process `FetchHandler` |
|
|
11127
11152
|
| `createHandlerTestClients` | function | exact contract-registry batch form |
|
|
11128
11153
|
| `runAgentStoreConformance` | function | reusable black-box duplicate/coalescing/stale/recovery contract for durable agent-store adapters |
|
|
11129
|
-
| `AgentStoreConformanceConfig` | _type_ |
|
|
11154
|
+
| `AgentStoreConformanceConfig` | _type_ | `{ createStore(context), cleanup?(context) }` — the factory the contract runs against, plus a teardown that runs once whether the scenario passed or failed |
|
|
11155
|
+
| `AgentStoreConformanceContext` | _type_ | `{ conversationIds }` — every conversation the scenario will mutate, handed over **before** the first mutation so an adapter can provision application-owned parent rows; a zero-argument factory stays valid |
|
|
11130
11156
|
| `runManagedResourceConformance` | function | run the canonical deterministic lifecycle matrix against a fresh consumer-owned `ManagedResource` fixture; resolves `void` or throws `ManagedResourceConformanceError` with a stable scenario ID and normalized trace |
|
|
11131
11157
|
| `ManagedResourceConformanceScenarioIdSchema` / `ManagedResourceConformanceScenarioId` | schema / _type_ | stable clean, rollback, readiness/completion, activation, shutdown-race and forced-cleanup scenario vocabulary |
|
|
11132
11158
|
| `ManagedResourceConformanceScenarioSchema` / `ManagedResourceConformanceScenario` | schema / _type_ | discriminated scenario record including whether the controlled resource is required |
|
package/package.json
CHANGED