borgmcp-shared 1.0.0 → 1.1.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.
Files changed (38) hide show
  1. package/CONTRIBUTING.md +4 -1
  2. package/README.md +28 -5
  3. package/RELEASES.md +2 -3
  4. package/dist/conformance/adapter.d.ts +6 -101
  5. package/dist/conformance/adapter.d.ts.map +1 -1
  6. package/dist/conformance/adapter.js +528 -267
  7. package/dist/conformance/adapter.js.map +1 -1
  8. package/dist/conformance/index.d.ts +2 -39
  9. package/dist/conformance/index.d.ts.map +1 -1
  10. package/dist/conformance/index.js +13 -42
  11. package/dist/conformance/index.js.map +1 -1
  12. package/dist/protocol/contract.d.ts +2 -2
  13. package/dist/protocol/contract.d.ts.map +1 -1
  14. package/dist/protocol/contract.js +3 -3
  15. package/dist/protocol/contract.js.map +1 -1
  16. package/dist/protocol/errors.d.ts +0 -14
  17. package/dist/protocol/errors.d.ts.map +1 -1
  18. package/dist/protocol/errors.js +0 -8
  19. package/dist/protocol/errors.js.map +1 -1
  20. package/dist/protocol/version.d.ts +1 -1
  21. package/dist/protocol/version.js +1 -1
  22. package/dist/templates.d.ts +0 -1
  23. package/dist/templates.d.ts.map +1 -1
  24. package/dist/templates.js +1 -2
  25. package/dist/templates.js.map +1 -1
  26. package/docs/compatibility.md +11 -0
  27. package/docs/enrollment.md +6 -9
  28. package/docs/releases/1.0.1.md +5 -0
  29. package/docs/releases/1.1.0.md +19 -0
  30. package/docs/releasing.md +13 -23
  31. package/package.json +1 -2
  32. package/src/conformance/adapter.ts +779 -614
  33. package/src/conformance/index.ts +19 -62
  34. package/src/protocol/contract.ts +3 -3
  35. package/src/protocol/errors.ts +0 -17
  36. package/src/protocol/version.ts +2 -2
  37. package/src/templates.ts +1 -3
  38. package/docs/release-records.json +0 -247
@@ -1,4 +1,4 @@
1
- import { ErrorCode, compareLogCursor, createProtocolEnvelope, decodeAssociateRepositoryCubeResponseEnvelope, decodeCreateCubeResponseEnvelope, decodeDeleteCubeResponseEnvelope, decodeAppendLogResultEnvelope, decodeAckStatusResultEnvelope, decodeEntryQueryResultEnvelope, decodeDecisionResultEnvelope, decodeDecisionsResultEnvelope, decodeEnrollmentExchangeResponseEnvelope, decodeInvitationArtifact, decodeAttachResponseEnvelope, decodeDroneRuntimeMetadataPatch, decodeEvictDroneResultEnvelope, decodeDeleteRoleResultEnvelope, decodeRoleRationaleResultEnvelope, decodeProtocolEnvelope, decodeProtocolErrorEnvelope, decodeProtocolTagPreflight, decodeReadLogResultEnvelope, decodeResolveRepositoryCubeResponseEnvelope, decodeReassignDroneResultEnvelope, decodeUpdateDroneRuntimeMetadataResponseEnvelope, decodeGetDocumentResultEnvelope, decodeListDocumentsResultEnvelope, decodePutDocumentResultEnvelope, decodeRemoveDocumentResultEnvelope, decodeSseFrames, PROTOCOL_LIMIT_CEILINGS, PROTOCOL_HTTP_CONTRACT, PROTOCOL_VERSION, ROLE_IN_USE_DELETE_MESSAGE, utf8ByteLength, } from '../protocol/index.js';
1
+ import { ErrorCode, compareLogCursor, createProtocolEnvelope, decodeAssociateRepositoryCubeResponseEnvelope, decodeCreateCubeResponseEnvelope, decodeDeleteCubeResponseEnvelope, decodeAppendLogResultEnvelope, decodeAckStatusResultEnvelope, decodeEntryQueryResultEnvelope, decodeDecisionResultEnvelope, decodeDecisionsResultEnvelope, decodeEnrollmentExchangeResponseEnvelope, decodeInvitationArtifact, decodeAttachResponseEnvelope, decodeEvictDroneResultEnvelope, decodeDeleteRoleResultEnvelope, decodeRoleRationaleResultEnvelope, decodeProtocolEnvelope, decodeProtocolErrorEnvelope, decodeProtocolTagPreflight, decodeReadLogResultEnvelope, decodeResolveRepositoryCubeResponseEnvelope, decodeReassignDroneResultEnvelope, decodeUpdateDroneRuntimeMetadataResponseEnvelope, decodeGetDocumentResultEnvelope, decodeListDocumentsResultEnvelope, decodePutDocumentResultEnvelope, decodeRemoveDocumentResultEnvelope, decodeSseFrames, PROTOCOL_LIMIT_CEILINGS, PROTOCOL_HTTP_CONTRACT, PROTOCOL_VERSION, ROLE_IN_USE_DELETE_MESSAGE, utf8ByteLength, } from '../protocol/index.js';
2
2
  import { APPEND_LOG_IDEMPOTENCY_CONFORMANCE, CREATE_CUBE_ASSOCIATION_CONFORMANCE, CREATE_CUBE_RETRY_CONFORMANCE, INVITATION_ARTIFACT_CONFORMANCE, ENROLLMENT_RETRY_CONFORMANCE, DOCUMENT_CONFORMANCE, } from './index.js';
3
3
  export const ADAPTER_CONFORMANCE_FIXTURES = [
4
4
  { id: 'http.unauthenticated-liveness', area: 'http' },
@@ -37,6 +37,33 @@ export const ADAPTER_CONFORMANCE_FIXTURES = [
37
37
  { id: 'security.active-stream-revocation', area: 'security' },
38
38
  { id: 'cubes.delete-terminal-cascade', area: 'cubes' },
39
39
  ];
40
+ const FIXTURE_PREREQUISITES = {
41
+ 'repository.explicit-association': ['shared.enrolled-principals'],
42
+ 'documents.lifecycle': ['shared.enrolled-principals'],
43
+ 'security.adapter-boundary-injection': ['shared.enrolled-principals'],
44
+ 'security.oversize-request': ['shared.enrolled-principals'],
45
+ 'security.cross-cube-isolation': ['shared.enrolled-principals'],
46
+ 'log.mandatory-addressing': ['shared.enrolled-principals'],
47
+ 'log.entry-query': ['shared.enrolled-principals'],
48
+ 'log.read-cursor-tuple': ['shared.enrolled-principals'],
49
+ 'sse.replay-live-transition': ['shared.enrolled-principals'],
50
+ 'cursor.explicit-expiry': ['shared.enrolled-principals'],
51
+ 'acks.idempotent': ['shared.enrolled-principals'],
52
+ 'acks.status-query': ['shared.enrolled-principals'],
53
+ 'claims.durable-noncursor': ['shared.enrolled-principals'],
54
+ 'decisions.topic-supersession': ['shared.enrolled-principals'],
55
+ 'security.manage-access-matrix': ['shared.enrolled-principals'],
56
+ 'drones.reassign-invariants': ['shared.enrolled-principals'],
57
+ 'security.cross-cube-drone-management': ['shared.enrolled-principals'],
58
+ 'drones.evict-terminal-signal': ['shared.enrolled-principals'],
59
+ 'metadata.attach-report': ['shared.enrolled-principals'],
60
+ 'metadata.self-heal-patch': ['shared.enrolled-principals', 'shared.metadata-baseline'],
61
+ 'security.metadata-invalid-atomic': ['shared.enrolled-principals', 'shared.metadata-baseline'],
62
+ 'security.metadata-own-seat': ['shared.enrolled-principals', 'shared.metadata-baseline'],
63
+ 'security.metadata-cross-cube-isolation': ['shared.enrolled-principals', 'shared.metadata-baseline'],
64
+ 'security.metadata-noninterference': ['shared.enrolled-principals', 'shared.metadata-baseline'],
65
+ 'security.metadata-secret-non-echo': ['shared.enrolled-principals', 'shared.metadata-baseline'],
66
+ };
40
67
  const DEFAULT_STREAM_DEADLINE_MS = 5_000;
41
68
  const DEFAULT_PENDING_PROBE_MS = 25;
42
69
  function invariant(condition, message) {
@@ -160,10 +187,19 @@ function listedDroneIds(response) {
160
187
  });
161
188
  }).payload;
162
189
  }
163
- function assertStateDelta(before, after, expected, description) {
164
- for (const key of Object.keys(before)) {
165
- invariant(after[key] - before[key] === (expected[key] ?? 0), `${description} changed ${key} by ${after[key] - before[key]}; expected ${expected[key] ?? 0}.`);
166
- }
190
+ function listedDrone(response, droneId) {
191
+ return decodeProtocolEnvelope(response.body, (payload) => {
192
+ invariant(typeof payload === 'object' && payload !== null, 'Roster payload is not an object.');
193
+ const drones = payload.drones;
194
+ invariant(Array.isArray(drones), 'Roster payload omitted drones.');
195
+ const drone = drones.find((candidate) => typeof candidate === 'object' && candidate !== null &&
196
+ candidate.id === droneId);
197
+ return drone ? { ...drone } : null;
198
+ }).payload;
199
+ }
200
+ function withoutRuntimeMetadata(drone) {
201
+ const { agent_kind: _agentKind, reported_model: _reportedModel, working_repo_name: _workingRepoName, working_repo_origin: _workingRepoOrigin, runtime_metadata_reported: _runtimeMetadataReported, ...rest } = drone;
202
+ return rest;
167
203
  }
168
204
  function assertEnrollmentErrorIsSecretFree(response, requests, description) {
169
205
  const diagnostic = JSON.stringify(response.body);
@@ -189,16 +225,30 @@ export async function runAdapterConformance(environment, options = {}) {
189
225
  invariant(streamDeadlineMs > 0, 'streamDeadlineMs must be positive.');
190
226
  invariant(pendingProbeMs > 0, 'pendingProbeMs must be positive.');
191
227
  const results = [];
192
- const record = async (id, execute) => {
228
+ const prerequisiteFailures = new Map();
229
+ const record = async (id, execute, prerequisites = []) => {
230
+ const required = [...(FIXTURE_PREREQUISITES[id] ?? []), ...prerequisites];
231
+ const failedPrerequisite = required.find((name) => prerequisiteFailures.has(name));
232
+ if (failedPrerequisite) {
233
+ results.push({
234
+ id,
235
+ ok: false,
236
+ skipped: true,
237
+ observations: {},
238
+ error: `Skipped because prerequisite ${failedPrerequisite} failed: ${prerequisiteFailures.get(failedPrerequisite)}`,
239
+ });
240
+ return;
241
+ }
193
242
  try {
194
243
  results.push({ id, ok: true, observations: await execute() });
195
244
  }
196
245
  catch (error) {
246
+ const message = error instanceof Error ? error.message : String(error);
197
247
  results.push({
198
248
  id,
199
249
  ok: false,
200
250
  observations: {},
201
- error: error instanceof Error ? error.message : String(error),
251
+ error: message,
202
252
  });
203
253
  }
204
254
  };
@@ -216,13 +266,11 @@ export async function runAdapterConformance(environment, options = {}) {
216
266
  return { status: 204, bodyless: true };
217
267
  });
218
268
  await record('protocol.credential-free-preflight', async () => {
219
- const before = await environment.admin.observeAuthorityState();
220
269
  const response = await environment.operations.protocol(null);
221
270
  expectStatus(response, 200, 'Credential-free protocol-tag preflight');
222
271
  const preflight = decodeProtocolTagPreflight(response.body);
223
272
  invariant(Object.keys(preflight).length === 1 && preflight.protocol_version === PROTOCOL_VERSION, 'Protocol-tag preflight exposed more than the exact tag.');
224
- assertStateDelta(before, await environment.admin.observeAuthorityState(), {}, 'Protocol-tag preflight');
225
- return { authenticated: false, mutation_free: true, protocol_version: preflight.protocol_version };
273
+ return { authenticated: false, protocol_version: preflight.protocol_version };
226
274
  });
227
275
  await record('enrollment.invitation-artifact', async () => {
228
276
  const errors = [];
@@ -260,19 +308,11 @@ export async function runAdapterConformance(environment, options = {}) {
260
308
  const invitation = await environment.admin.issueSingleUseInvitation(principal, purpose);
261
309
  const initialPayload = { ...vector.initial, invitation };
262
310
  const retryPayload = { ...vector.retry, invitation };
263
- const beforeInitial = await environment.admin.observeAuthorityState();
264
311
  const initialResponse = await environment.operations.enroll(createProtocolEnvelope(`retry-${index}-initial`, initialPayload));
265
312
  expectStatus(initialResponse, 201, `${vector.name} initial request`);
266
313
  const initial = decodeEnrollmentExchangeResponseEnvelope(initialResponse.body).payload;
267
314
  invariant(initial.purpose === purpose, `${purpose} ${vector.name} returned the wrong purpose.`);
268
315
  invariant(same(initial.server_capabilities, purpose === 'owner' ? ['create_cube'] : []), `${purpose} ${vector.name} returned incorrect server authority.`);
269
- const afterInitial = await environment.admin.observeAuthorityState();
270
- assertStateDelta(beforeInitial, afterInitial, {
271
- enrolled_clients: 1,
272
- enrollment_claims: 1,
273
- server_capabilities: purpose === 'owner' ? 1 : 0,
274
- }, `${purpose} ${vector.name} initial request`);
275
- const beforeRetry = await environment.admin.observeAuthorityState();
276
316
  const retryResponse = await environment.operations.enroll(createProtocolEnvelope(`retry-${index}-retry`, retryPayload));
277
317
  if (vector.expected.outcome === 'stable_non_secret_identity') {
278
318
  expectStatus(retryResponse, 201, `${purpose} ${vector.name}`);
@@ -286,12 +326,25 @@ export async function runAdapterConformance(environment, options = {}) {
286
326
  expectError(retryResponse, vector.expected.status, ErrorCode.AUTH_INVALID, `${purpose} ${vector.name}`);
287
327
  assertEnrollmentErrorIsSecretFree(retryResponse, [initialPayload, retryPayload], `${purpose} ${vector.name}`);
288
328
  }
289
- assertStateDelta(beforeRetry, await environment.admin.observeAuthorityState(), {}, `${purpose} ${vector.name} retry`);
290
- invariant(same(await environment.admin.inspectEnrollmentPrincipal(principal, initial.client_id), {
291
- response_client_matches: true,
292
- active_credential_bindings: 1,
293
- bound_credential_matches_enrollment: true,
294
- }), `${purpose} ${vector.name} changed enrollment binding ownership.`);
329
+ const credentialProbeCube = await environment.admin.createCube(`${purpose}-credential-probe-${index}`);
330
+ await environment.admin.grantCube(principal, credentialProbeCube, 'read');
331
+ expectStatus(await environment.operations.read(initialPayload.client_credential, credentialProbeCube, createProtocolEnvelope(`retry-${index}-credential-probe`, { cursor: null, limit: 1 })), 200, `${purpose} ${vector.name} original credential probe`);
332
+ const capabilityProbe = await environment.operations.createCube(initialPayload.client_credential, createProtocolEnvelope(`retry-${index}-${purpose}-capability-probe`, {
333
+ retry_key: `10000000-0000-4000-8000-${String(index + (purpose === 'owner' ? 700 : 600)).padStart(12, '0')}`,
334
+ name: `${purpose} capability probe ${index}`,
335
+ working_repo_name: `${purpose}-capability-probe-${index}`,
336
+ repository: {
337
+ kind: 'local',
338
+ value: `20000000-0000-4000-8000-${String(index + (purpose === 'owner' ? 700 : 600)).padStart(12, '0')}`,
339
+ },
340
+ template: 'software-dev',
341
+ }));
342
+ if (purpose === 'owner') {
343
+ expectStatus(capabilityProbe, 201, `${purpose} ${vector.name} capability probe`);
344
+ }
345
+ else {
346
+ expectError(capabilityProbe, 403, ErrorCode.ACCESS_DENIED, `${purpose} ${vector.name} capability probe`);
347
+ }
295
348
  }
296
349
  catch (error) {
297
350
  retryVectorErrors.push(`${purpose} ${vector.name}: ${error instanceof Error ? error.message : String(error)}`);
@@ -306,7 +359,6 @@ export async function runAdapterConformance(environment, options = {}) {
306
359
  const ordinaryInvitation = await environment.admin.issueSingleUseInvitation(ordinaryPrincipal, 'client');
307
360
  const ownerCredential = `${'Q'.repeat(42)}U`;
308
361
  const ordinaryCredential = `${'Y'.repeat(42)}U`;
309
- const beforeAuthorityEnrollment = await environment.admin.observeAuthorityState();
310
362
  const ownerResponse = await environment.operations.enroll(createProtocolEnvelope('owner-enroll', {
311
363
  invitation: ownerInvitation,
312
364
  retry_key: '00000000-0000-4000-8000-000000000211',
@@ -325,7 +377,6 @@ export async function runAdapterConformance(environment, options = {}) {
325
377
  const ordinary = decodeEnrollmentExchangeResponseEnvelope(ordinaryResponse.body).payload;
326
378
  invariant(owner.purpose === 'owner' && same(owner.server_capabilities, ['create_cube']), 'Owner enrollment lacked exact create-cube authority.');
327
379
  invariant(ordinary.purpose === 'client' && ordinary.server_capabilities.length === 0, 'Ordinary enrollment gained authority.');
328
- assertStateDelta(beforeAuthorityEnrollment, await environment.admin.observeAuthorityState(), { enrolled_clients: 2, enrollment_claims: 2, server_capabilities: 1 }, 'Owner and ordinary enrollment');
329
380
  const cubeRequest = {
330
381
  retry_key: '00000000-0000-4000-8000-000000000213',
331
382
  name: 'Repository One',
@@ -334,64 +385,76 @@ export async function runAdapterConformance(environment, options = {}) {
334
385
  kind: 'origin',
335
386
  value: 'https://github.com/Byte-Ventures/repository-one',
336
387
  },
337
- template: 'default',
388
+ template: 'software-dev',
338
389
  };
339
390
  const droneCredential = await environment.admin.issueDroneSession(ownerPrincipal);
340
- const beforeDeniedCreate = await environment.admin.observeAuthorityState();
341
391
  expectSecretFreeError(await environment.operations.createCube(null, createProtocolEnvelope('cube-missing-auth', cubeRequest)), 401, ErrorCode.AUTH_MISSING, 'Missing-auth cube create', [cubeRequest.retry_key]);
342
392
  expectSecretFreeError(await environment.operations.createCube('invalid-credential', createProtocolEnvelope('cube-invalid-auth', cubeRequest)), 401, ErrorCode.AUTH_INVALID, 'Invalid-auth cube create', [cubeRequest.retry_key]);
343
393
  expectSecretFreeError(await environment.operations.createCube(ordinaryCredential, createProtocolEnvelope('cube-denied', cubeRequest)), 403, ErrorCode.ACCESS_DENIED, 'Ordinary cube create', [cubeRequest.retry_key]);
344
394
  expectSecretFreeError(await environment.operations.createCube(droneCredential, createProtocolEnvelope('cube-drone-denied', cubeRequest)), 403, ErrorCode.ACCESS_DENIED, 'Drone-session cube create', [cubeRequest.retry_key]);
345
- assertStateDelta(beforeDeniedCreate, await environment.admin.observeAuthorityState(), {}, 'Denied ordinary cube create');
346
- const beforeCreate = await environment.admin.observeAuthorityState();
347
395
  const createdResponse = await environment.operations.createCube(ownerCredential, createProtocolEnvelope('cube-create', cubeRequest));
348
396
  expectStatus(createdResponse, 201, 'Owner cube create');
349
397
  const created = decodeCreateCubeResponseEnvelope(createdResponse.body).payload;
350
- assertStateDelta(beforeCreate, await environment.admin.observeAuthorityState(), { cubes: 1, roles: 2, grants: 1, cube_create_bindings: 1, repository_associations: 1 }, 'Owner cube create');
351
- invariant(same(await environment.admin.inspectCreatedCube(ownerPrincipal, created), {
352
- cube_exists: true,
353
- creator_has_grant: true,
354
- creator_access: 'manage',
355
- grant_count: 1,
356
- role_count: 2,
357
- name: cubeRequest.name,
358
- working_repo_name: cubeRequest.working_repo_name,
359
- repository: cubeRequest.repository,
360
- template: cubeRequest.template,
361
- human_seat_role_id: created.human_seat_role_id,
362
- default_worker_role_id: created.default_worker_role_id,
363
- human_seat_role_matches: true,
364
- default_worker_role_matches: true,
365
- }), 'Created cube identities or creator grant did not match persisted authority state.');
366
- const beforeCreateRetry = await environment.admin.observeAuthorityState();
398
+ const createdRoleProbes = new Map();
399
+ for (const [kind, roleId, roleClass, isHumanSeat, marker] of [
400
+ ['human-seat', created.human_seat_role_id, 'queen', true, 'H'],
401
+ ['default-worker', created.default_worker_role_id, 'worker', false, 'D'],
402
+ ]) {
403
+ const sessionCredential = marker.repeat(43);
404
+ const attached = await environment.operations.attach(ownerCredential, createProtocolEnvelope(`cube-create-${kind}-probe`, {
405
+ cube_id: created.cube_id,
406
+ role_id: roleId,
407
+ session_credential: sessionCredential,
408
+ }));
409
+ expectStatus(attached, 200, `Created ${kind} role probe`);
410
+ const attachedPayload = decodeAttachResponseEnvelope(attached.body).payload;
411
+ const attachedRole = attachedPayload.role;
412
+ invariant(attachedRole.id === roleId &&
413
+ attachedRole.role_class === roleClass &&
414
+ attachedRole.is_human_seat === isHumanSeat, `Created ${kind} role identity did not match its protocol role.`);
415
+ createdRoleProbes.set(kind, {
416
+ role: attachedRole,
417
+ droneId: attachedPayload.drone.id,
418
+ sessionCredential,
419
+ });
420
+ }
367
421
  const retriedCreateResponse = await environment.operations.createCube(ownerCredential, createProtocolEnvelope('cube-retry', cubeRequest));
368
422
  expectStatus(retriedCreateResponse, 201, 'Exact cube-create retry');
369
423
  const retriedCreate = decodeCreateCubeResponseEnvelope(retriedCreateResponse.body).payload;
370
424
  invariant(retriedCreate.result === 'resolved', 'Exact cube-create retry did not report resolved readback.');
371
425
  invariant(same({ ...retriedCreate, result: 'created' }, created), 'Exact cube-create retry returned different authoritative fields.');
372
- assertStateDelta(beforeCreateRetry, await environment.admin.observeAuthorityState(), {}, 'Exact cube-create retry');
373
426
  const displayRetryVector = CREATE_CUBE_RETRY_CONFORMANCE.find((vector) => vector.expected.outcome === 'resolved_response' &&
374
427
  vector.retry.working_repo_name !== vector.initial.working_repo_name);
375
428
  invariant(displayRetryVector !== undefined, 'Missing repository display readback vector.');
376
- const beforeDisplayRetry = await environment.admin.observeAuthorityState();
377
429
  const displayRetryResponse = await environment.operations.createCube(ownerCredential, createProtocolEnvelope('cube-display-retry', {
378
430
  ...displayRetryVector.retry,
379
431
  retry_key: cubeRequest.retry_key,
380
432
  }));
381
433
  expectStatus(displayRetryResponse, 201, 'Changed repository display retry');
382
434
  invariant(same(decodeCreateCubeResponseEnvelope(displayRetryResponse.body).payload, retriedCreate), 'Changed repository display retry did not return stored authoritative display.');
383
- assertStateDelta(beforeDisplayRetry, await environment.admin.observeAuthorityState(), {}, 'Changed repository display retry');
384
435
  for (const [index, vector] of CREATE_CUBE_RETRY_CONFORMANCE.entries()) {
385
436
  if (vector.expected.outcome !== 'retry_tuple_mismatch')
386
437
  continue;
387
438
  const mismatch = { ...vector.retry, retry_key: cubeRequest.retry_key };
388
- const beforeCreateMismatch = await environment.admin.observeAuthorityState();
389
439
  expectSecretFreeError(await environment.operations.createCube(ownerCredential, createProtocolEnvelope(`cube-mismatch-${index}`, mismatch)), 409, ErrorCode.INVALID_INPUT, `Cube-create ${vector.name}`, [cubeRequest.retry_key]);
390
- assertStateDelta(beforeCreateMismatch, await environment.admin.observeAuthorityState(), {}, `Cube-create ${vector.name}`);
440
+ }
441
+ for (const [kind, roleId] of [
442
+ ['human-seat', created.human_seat_role_id],
443
+ ['default-worker', created.default_worker_role_id],
444
+ ]) {
445
+ const initialProbe = createdRoleProbes.get(kind);
446
+ invariant(initialProbe !== undefined, `Missing initial ${kind} role probe.`);
447
+ const attached = await environment.operations.attach(ownerCredential, createProtocolEnvelope(`cube-create-${kind}-post-refusal-probe`, {
448
+ cube_id: created.cube_id,
449
+ role_id: roleId,
450
+ session_credential: initialProbe.sessionCredential,
451
+ prior_drone_id: initialProbe.droneId,
452
+ }));
453
+ expectStatus(attached, 200, `Post-refusal ${kind} role probe`);
454
+ invariant(same(decodeAttachResponseEnvelope(attached.body).payload.role, initialProbe.role), `Cube-create retry refusal changed the full ${kind} role shape.`);
391
455
  }
392
456
  const sameAssociationVector = CREATE_CUBE_ASSOCIATION_CONFORMANCE.find((vector) => vector.expected.outcome === 'resolved');
393
457
  invariant(sameAssociationVector !== undefined, 'Missing same-repository association vector.');
394
- const beforeAssociationResolve = await environment.admin.observeAuthorityState();
395
458
  const associationResolveResponse = await environment.operations.createCube(ownerCredential, createProtocolEnvelope('cube-association-resolve', {
396
459
  ...sameAssociationVector.request,
397
460
  repository: cubeRequest.repository,
@@ -400,7 +463,6 @@ export async function runAdapterConformance(environment, options = {}) {
400
463
  const associationResolved = decodeCreateCubeResponseEnvelope(associationResolveResponse.body).payload;
401
464
  invariant(associationResolved.result === 'resolved', 'Associated repository did not resolve.');
402
465
  invariant(same({ ...associationResolved, result: 'created' }, created), 'Associated repository did not return stored authoritative fields.');
403
- assertStateDelta(beforeAssociationResolve, await environment.admin.observeAuthorityState(), sameAssociationVector.expected.authority_state_delta, 'Fresh retry for associated repository');
404
466
  await environment.admin.grantCreateCubeCapability(ordinaryPrincipal);
405
467
  const crossClientRequest = {
406
468
  ...cubeRequest,
@@ -410,35 +472,49 @@ export async function runAdapterConformance(environment, options = {}) {
410
472
  value: '00000000-0000-4000-8000-000000000216',
411
473
  },
412
474
  };
413
- const beforeCrossClientCreate = await environment.admin.observeAuthorityState();
414
475
  const crossClientResponse = await environment.operations.createCube(ordinaryCredential, createProtocolEnvelope('cube-cross-client', crossClientRequest));
415
476
  expectStatus(crossClientResponse, 201, 'Cross-client cube create with reused retry key');
416
477
  const crossClientCreated = decodeCreateCubeResponseEnvelope(crossClientResponse.body).payload;
417
478
  invariant(crossClientCreated.cube_id !== created.cube_id, 'Cross-client retry key reused another client\'s cube.');
418
- assertStateDelta(beforeCrossClientCreate, await environment.admin.observeAuthorityState(), { cubes: 1, roles: 2, grants: 1, cube_create_bindings: 1, repository_associations: 1 }, 'Cross-client cube create');
419
- invariant((await environment.admin.inspectCreatedCube(ordinaryPrincipal, crossClientCreated)).creator_has_grant, 'Cross-client cube creation did not grant its authenticated creator.');
420
- const beforeCrossClientRetry = await environment.admin.observeAuthorityState();
479
+ for (const [kind, roleId, originalRoleId, marker] of [
480
+ ['human-seat', crossClientCreated.human_seat_role_id, created.human_seat_role_id, 'V'],
481
+ ['default-worker', crossClientCreated.default_worker_role_id, created.default_worker_role_id, 'W'],
482
+ ]) {
483
+ const originalProbe = createdRoleProbes.get(kind);
484
+ invariant(originalProbe !== undefined, `Missing original ${kind} role probe.`);
485
+ const attached = await environment.operations.attach(ordinaryCredential, createProtocolEnvelope(`cube-cross-client-${kind}-probe`, {
486
+ cube_id: crossClientCreated.cube_id,
487
+ role_id: roleId,
488
+ session_credential: marker.repeat(43),
489
+ }));
490
+ expectStatus(attached, 200, `Cross-client ${kind} role probe`);
491
+ const attachedRole = decodeAttachResponseEnvelope(attached.body).payload.role;
492
+ invariant(same({ ...attachedRole, id: originalRoleId }, originalProbe.role), `Cross-client ${kind} role did not match the full template role shape.`);
493
+ }
421
494
  const crossClientRetry = await environment.operations.createCube(ordinaryCredential, createProtocolEnvelope('cube-cross-client-retry', crossClientRequest));
422
495
  expectStatus(crossClientRetry, 201, 'Exact cross-client cube-create retry');
423
496
  const crossClientResolved = decodeCreateCubeResponseEnvelope(crossClientRetry.body).payload;
424
497
  invariant(crossClientResolved.result === 'resolved', 'Exact cross-client cube-create retry did not report resolved readback.');
425
498
  invariant(same({ ...crossClientResolved, result: 'created' }, crossClientCreated), 'Exact cross-client cube-create retry returned different authoritative fields.');
426
- assertStateDelta(beforeCrossClientRetry, await environment.admin.observeAuthorityState(), {}, 'Exact cross-client cube-create retry');
427
499
  const differentAssociationVector = CREATE_CUBE_ASSOCIATION_CONFORMANCE.find((vector) => vector.expected.outcome === 'created');
428
500
  invariant(differentAssociationVector !== undefined, 'Missing different-repository association vector.');
429
- const beforeSecondCreate = await environment.admin.observeAuthorityState();
430
501
  const secondCreatedResponse = await environment.operations.createCube(ownerCredential, createProtocolEnvelope('cube-create-second', differentAssociationVector.request));
431
502
  expectStatus(secondCreatedResponse, 201, 'Second cube create');
432
503
  const secondCreated = decodeCreateCubeResponseEnvelope(secondCreatedResponse.body).payload;
433
504
  invariant(secondCreated.cube_id !== created.cube_id, 'Fresh cube-create retry key reused an existing cube.');
434
- assertStateDelta(beforeSecondCreate, await environment.admin.observeAuthorityState(), differentAssociationVector.expected.authority_state_delta, 'Second cube create');
435
505
  await environment.admin.revokePrincipal(ownerPrincipal);
436
- const beforeRevokedCreate = await environment.admin.observeAuthorityState();
437
506
  expectSecretFreeError(await environment.operations.createCube(ownerCredential, createProtocolEnvelope('cube-revoked', {
438
507
  ...cubeRequest,
439
508
  retry_key: '00000000-0000-4000-8000-000000000215',
440
509
  })), 401, ErrorCode.SESSION_REVOKED, 'Revoked owner cube create', ['00000000-0000-4000-8000-000000000215']);
441
- assertStateDelta(beforeRevokedCreate, await environment.admin.observeAuthorityState(), {}, 'Revoked owner cube create');
510
+ return {
511
+ enrollment_status: 201,
512
+ exact_retry_status: 201,
513
+ mismatched_retry: ErrorCode.AUTH_INVALID,
514
+ response_secret_free: true,
515
+ };
516
+ });
517
+ try {
442
518
  await environment.admin.reset();
443
519
  principalA = await environment.admin.createPrincipal('principal-a');
444
520
  principalB = await environment.admin.createPrincipal('principal-b');
@@ -450,42 +526,24 @@ export async function runAdapterConformance(environment, options = {}) {
450
526
  const invitationB = await environment.admin.issueSingleUseInvitation(principalB, 'client');
451
527
  credentialA = 'A'.repeat(43);
452
528
  credentialB = 'E'.repeat(43);
453
- const enrollmentARequest = createProtocolEnvelope('enroll-a1', {
529
+ const enrolledAResponse = await environment.operations.enroll(createProtocolEnvelope('enroll-a1', {
454
530
  invitation: invitationA,
455
531
  retry_key: '00000000-0000-4000-8000-000000000201',
456
532
  client_credential: credentialA,
457
533
  client_name: 'conformance-a',
458
- });
459
- const enrollmentBRequest = createProtocolEnvelope('enroll-b1', {
534
+ }));
535
+ const enrolledBResponse = await environment.operations.enroll(createProtocolEnvelope('enroll-b1', {
460
536
  invitation: invitationB,
461
537
  retry_key: '00000000-0000-4000-8000-000000000202',
462
538
  client_credential: credentialB,
463
539
  client_name: 'conformance-b',
464
- });
465
- const enrolledAResponse = await environment.operations.enroll(enrollmentARequest);
466
- const enrolledBResponse = await environment.operations.enroll(enrollmentBRequest);
467
- expectStatus(enrolledAResponse, 201, 'Principal A enrollment');
468
- expectStatus(enrolledBResponse, 201, 'Principal B enrollment');
469
- const enrolledA = decodeEnrollmentExchangeResponseEnvelope(enrolledAResponse.body).payload;
470
- const enrolledB = decodeEnrollmentExchangeResponseEnvelope(enrolledBResponse.body).payload;
471
- invariant(enrolledA.purpose === 'client' && enrolledB.purpose === 'client', 'Ordinary enrollment returned owner authority.');
472
- invariant(enrolledA.server_capabilities.length === 0 && enrolledB.server_capabilities.length === 0, 'Ordinary enrollment returned a server capability.');
473
- invariant(!('credential' in enrolledA) && !('credential' in enrolledB), 'Enrollment response returned a bearer.');
474
- const retriedAResponse = await environment.operations.enroll(enrollmentARequest);
475
- expectStatus(retriedAResponse, 201, 'Exact enrollment retry');
476
- invariant(JSON.stringify(decodeEnrollmentExchangeResponseEnvelope(retriedAResponse.body).payload) ===
477
- JSON.stringify(enrolledA), 'Exact enrollment retry returned different identities.');
478
- expectError(await environment.operations.enroll(createProtocolEnvelope('enroll-a-mismatch', {
479
- ...enrollmentARequest.payload,
480
- retry_key: '00000000-0000-4000-8000-000000000203',
481
- })), 401, ErrorCode.AUTH_INVALID, 'Enrollment retry mismatch');
482
- return {
483
- enrollment_status: 201,
484
- exact_retry_status: 201,
485
- mismatched_retry: ErrorCode.AUTH_INVALID,
486
- response_secret_free: true,
487
- };
488
- });
540
+ }));
541
+ expectStatus(enrolledAResponse, 201, 'Shared principal A enrollment');
542
+ expectStatus(enrolledBResponse, 201, 'Shared principal B enrollment');
543
+ }
544
+ catch (error) {
545
+ prerequisiteFailures.set('shared.enrolled-principals', error instanceof Error ? error.message : String(error));
546
+ }
489
547
  await record('repository.explicit-association', async () => {
490
548
  const repository = {
491
549
  kind: 'origin',
@@ -499,16 +557,24 @@ export async function runAdapterConformance(environment, options = {}) {
499
557
  working_repo_name: 'legacy-repository',
500
558
  repository,
501
559
  };
502
- const beforeNone = await environment.admin.observeAuthorityState();
560
+ const alternateResolveRequest = {
561
+ working_repo_name: 'other-repository',
562
+ repository: {
563
+ kind: 'origin',
564
+ value: 'https://github.com/Byte-Ventures/other-repository',
565
+ },
566
+ };
567
+ const resolve = async (requestId, request) => {
568
+ const response = await environment.operations.resolveRepositoryCube(credentialA, createProtocolEnvelope(requestId, request));
569
+ expectStatus(response, 200, requestId);
570
+ return decodeResolveRepositoryCubeResponseEnvelope(response.body).payload;
571
+ };
503
572
  const noneResponse = await environment.operations.resolveRepositoryCube(credentialA, createProtocolEnvelope('repository-resolve-none', resolveRequest));
504
573
  expectStatus(noneResponse, 200, 'Unassociated repository resolution');
505
574
  invariant(same(decodeResolveRepositoryCubeResponseEnvelope(noneResponse.body).payload, { result: 'none' }), 'Unassociated repository did not return explicit none.');
506
- assertStateDelta(beforeNone, await environment.admin.observeAuthorityState(), {}, 'Repository resolution');
575
+ invariant(same(await resolve('repository-resolve-none-readback', resolveRequest), { result: 'none' }), 'Read-only repository resolution created an association.');
507
576
  const associationRequest = { cube_id: cubeA.id, ...resolveRequest };
508
- const beforeDenied = await environment.admin.observeAuthorityState();
509
577
  expectSecretFreeError(await environment.operations.associateRepositoryCube(credentialB, createProtocolEnvelope('repository-associate-denied', associationRequest)), 403, ErrorCode.ACCESS_DENIED, 'Inaccessible repository cube association', [associationRequest.cube_id, repository.value]);
510
- assertStateDelta(beforeDenied, await environment.admin.observeAuthorityState(), {}, 'Denied repository association');
511
- const beforeAssociation = await environment.admin.observeAuthorityState();
512
578
  const associatedResponse = await environment.operations.associateRepositoryCube(credentialA, createProtocolEnvelope('repository-associate', associationRequest));
513
579
  expectStatus(associatedResponse, 200, 'Explicit repository cube association');
514
580
  const associated = decodeAssociateRepositoryCubeResponseEnvelope(associatedResponse.body).payload;
@@ -524,52 +590,40 @@ export async function runAdapterConformance(environment, options = {}) {
524
590
  access: prepared.access,
525
591
  };
526
592
  invariant(same(associated, authoritative), 'Repository association did not return authoritative stored fields.');
527
- assertStateDelta(beforeAssociation, await environment.admin.observeAuthorityState(), { repository_associations: 1 }, 'Explicit repository association');
528
- const beforeResolve = await environment.admin.observeAuthorityState();
529
593
  const resolvedResponse = await environment.operations.resolveRepositoryCube(credentialA, createProtocolEnvelope('repository-resolve', {
530
594
  ...resolveRequest,
531
595
  working_repo_name: 'ignored-new-display',
532
596
  }));
533
597
  expectStatus(resolvedResponse, 200, 'Associated repository resolution');
534
598
  invariant(same(decodeResolveRepositoryCubeResponseEnvelope(resolvedResponse.body).payload, authoritative), 'Associated repository did not return stored authoritative display.');
535
- assertStateDelta(beforeResolve, await environment.admin.observeAuthorityState(), {}, 'Associated repository resolution');
536
- const beforeRetry = await environment.admin.observeAuthorityState();
537
599
  const retryResponse = await environment.operations.associateRepositoryCube(credentialA, createProtocolEnvelope('repository-associate-retry', associationRequest));
538
600
  expectStatus(retryResponse, 200, 'Exact repository association retry');
539
601
  invariant(same(decodeAssociateRepositoryCubeResponseEnvelope(retryResponse.body).payload, authoritative), 'Exact repository association retry changed authoritative fields.');
540
- assertStateDelta(beforeRetry, await environment.admin.observeAuthorityState(), {}, 'Repository association retry');
541
602
  const cubeC = await environment.admin.createCube('cube-c');
542
603
  await environment.admin.grantCube(principalA, cubeC);
543
604
  await environment.admin.prepareRepositoryCube(cubeC, {
544
605
  name: 'Other Legacy Cube',
545
606
  template: 'starter',
546
607
  });
547
- const beforeRepositoryConflict = await environment.admin.observeAuthorityState();
548
608
  expectSecretFreeError(await environment.operations.associateRepositoryCube(credentialA, createProtocolEnvelope('repository-associate-repository-conflict', {
549
609
  ...associationRequest,
550
610
  cube_id: cubeC.id,
551
611
  })), 409, ErrorCode.REPOSITORY_ALREADY_ASSOCIATED, 'Repository-to-other-cube conflict', [cubeA.id, cubeC.id, repository.value]);
552
- assertStateDelta(beforeRepositoryConflict, await environment.admin.observeAuthorityState(), {}, 'Repository-to-other-cube conflict');
553
- const beforeCubeConflict = await environment.admin.observeAuthorityState();
612
+ invariant(same(await resolve('repository-resolve-after-repository-conflict', resolveRequest), authoritative), 'Repository conflict changed the authoritative original binding.');
613
+ invariant(same(await resolve('repository-resolve-alternate-after-repository-conflict', alternateResolveRequest), { result: 'none' }), 'Repository conflict created an alternate binding.');
554
614
  expectSecretFreeError(await environment.operations.associateRepositoryCube(credentialA, createProtocolEnvelope('repository-associate-cube-conflict', {
555
615
  cube_id: cubeA.id,
556
- working_repo_name: 'other-repository',
557
- repository: {
558
- kind: 'origin',
559
- value: 'https://github.com/Byte-Ventures/other-repository',
560
- },
616
+ ...alternateResolveRequest,
561
617
  })), 409, ErrorCode.CUBE_ALREADY_ASSOCIATED, 'Cube-to-other-repository conflict', [cubeA.id, repository.value, 'https://github.com/Byte-Ventures/other-repository']);
562
- assertStateDelta(beforeCubeConflict, await environment.admin.observeAuthorityState(), {}, 'Cube-to-other-repository conflict');
618
+ invariant(same(await resolve('repository-resolve-after-cube-conflict', resolveRequest), authoritative), 'Cube conflict changed the authoritative original binding.');
619
+ invariant(same(await resolve('repository-resolve-alternate-after-cube-conflict', alternateResolveRequest), { result: 'none' }), 'Cube conflict created the refused alternate binding.');
563
620
  const preparedB = await environment.admin.prepareRepositoryCube(cubeB, {
564
621
  name: 'Other Client Legacy Cube',
565
622
  template: 'starter',
566
623
  });
567
- const beforeCrossClientResolve = await environment.admin.observeAuthorityState();
568
624
  const crossClientResolve = await environment.operations.resolveRepositoryCube(credentialB, createProtocolEnvelope('repository-resolve-cross-client', resolveRequest));
569
625
  expectStatus(crossClientResolve, 200, 'Cross-client repository resolution');
570
626
  invariant(same(decodeResolveRepositoryCubeResponseEnvelope(crossClientResolve.body).payload, { result: 'none' }), 'Another client repository binding was exposed by resolution.');
571
- assertStateDelta(beforeCrossClientResolve, await environment.admin.observeAuthorityState(), {}, 'Cross-client repository resolution');
572
- const beforeCrossClientAssociation = await environment.admin.observeAuthorityState();
573
627
  const crossClientAssociation = await environment.operations.associateRepositoryCube(credentialB, createProtocolEnvelope('repository-associate-cross-client', {
574
628
  ...associationRequest,
575
629
  cube_id: cubeB.id,
@@ -578,20 +632,20 @@ export async function runAdapterConformance(environment, options = {}) {
578
632
  const crossClientAssociated = decodeAssociateRepositoryCubeResponseEnvelope(crossClientAssociation.body).payload;
579
633
  invariant(crossClientAssociated.cube_id === preparedB.cube_id &&
580
634
  crossClientAssociated.repository.value === repository.value, 'Another client binding changed cross-client association identity.');
581
- assertStateDelta(beforeCrossClientAssociation, await environment.admin.observeAuthorityState(), { repository_associations: 1 }, 'Cross-client repository association');
582
635
  await environment.admin.revokeCubeGrant(principalA, cubeA);
583
- const beforeHiddenResolve = await environment.admin.observeAuthorityState();
584
636
  const hiddenResolve = await environment.operations.resolveRepositoryCube(credentialA, createProtocolEnvelope('repository-resolve-inaccessible-binding', resolveRequest));
585
637
  expectStatus(hiddenResolve, 200, 'Inaccessible repository binding resolution');
586
638
  invariant(same(decodeResolveRepositoryCubeResponseEnvelope(hiddenResolve.body).payload, { result: 'none' }), 'Inaccessible repository binding was exposed by read-only resolution.');
587
- assertStateDelta(beforeHiddenResolve, await environment.admin.observeAuthorityState(), {}, 'Inaccessible repository binding resolution');
588
- const beforeHiddenAssociation = await environment.admin.observeAuthorityState();
589
639
  expectSecretFreeError(await environment.operations.associateRepositoryCube(credentialA, createProtocolEnvelope('repository-associate-inaccessible-binding', {
590
640
  ...associationRequest,
591
641
  cube_id: cubeC.id,
592
642
  })), 403, ErrorCode.ACCESS_DENIED, 'Inaccessible existing repository binding', [cubeA.id, cubeC.id, repository.value]);
593
- assertStateDelta(beforeHiddenAssociation, await environment.admin.observeAuthorityState(), {}, 'Inaccessible existing repository binding');
643
+ const hiddenAfterRefusal = await resolve('repository-resolve-after-inaccessible-refusal', resolveRequest);
644
+ const alternateAfterRefusal = await resolve('repository-resolve-alternate-after-inaccessible-refusal', alternateResolveRequest);
594
645
  await environment.admin.grantCube(principalA, cubeA);
646
+ invariant(same(hiddenAfterRefusal, { result: 'none' }), 'Inaccessible-binding refusal changed the hidden authoritative binding.');
647
+ invariant(same(alternateAfterRefusal, { result: 'none' }), 'Inaccessible-binding refusal created an alternate binding.');
648
+ invariant(same(await resolve('repository-resolve-restored-after-inaccessible-refusal', resolveRequest), authoritative), 'Inaccessible-binding refusal did not preserve the original binding.');
595
649
  return {
596
650
  none: true,
597
651
  resolved: true,
@@ -890,12 +944,10 @@ export async function runAdapterConformance(environment, options = {}) {
890
944
  });
891
945
  const recipient = await environment.admin.createDrone(principalA, cube, role);
892
946
  const message = 'START NOW exact slice';
893
- const before = await environment.admin.observeAuthorityState();
894
947
  expectError(await environment.operations.append(credentialA, cube, createProtocolEnvelope('mandatory-addressing-omitted', {
895
948
  post_id: '30000000-0000-4000-8000-000000000001',
896
949
  message,
897
950
  })), 400, ErrorCode.INVALID_INPUT, 'Omitted mandatory addressing');
898
- assertStateDelta(before, await environment.admin.observeAuthorityState(), {}, 'Mandatory-addressing refusal');
899
951
  const broadcast = await environment.operations.append(credentialA, cube, createProtocolEnvelope('mandatory-addressing-broadcast', {
900
952
  post_id: '30000000-0000-4000-8000-000000000002',
901
953
  message,
@@ -916,6 +968,10 @@ export async function runAdapterConformance(environment, options = {}) {
916
968
  invariant(directedResult.entry.visibility === 'direct', 'Explicit recipient selectors did not produce direct visibility.');
917
969
  invariant(directedResult.entry.recipient_drone_ids?.includes(recipient.id) === true, 'Explicit recipient selectors did not resolve the named recipient.');
918
970
  invariant(directedResult.entry.recipient_drone_ids?.length === 1, 'Classification changed or fell open the explicit recipient set.');
971
+ const readback = await environment.operations.read(credentialA, cube, createProtocolEnvelope('mandatory-addressing-readback', { cursor: null, limit: 10 }));
972
+ expectStatus(readback, 200, 'Mandatory-addressing persistence readback');
973
+ const persistedIds = decodeReadLogResultEnvelope(readback.body).payload.entries.map((entry) => entry.id);
974
+ invariant(same(persistedIds, [broadcastResult.entry.id, directedResult.entry.id]), 'Rejected mandatory-addressing append was persisted.');
919
975
  return { refused_status: 400, code: ErrorCode.INVALID_INPUT, persisted: false, broadcast: true, union: true, no_fall_open: true };
920
976
  });
921
977
  await record('log.entry-query', async () => {
@@ -936,6 +992,7 @@ export async function runAdapterConformance(environment, options = {}) {
936
992
  '22222222-0000-4000-8000-000000000002',
937
993
  ];
938
994
  const entries = [];
995
+ const idSeeds = [];
939
996
  for (const [index, id] of ids.entries()) {
940
997
  const response = await environment.operations.append(credentialA, cube, createProtocolEnvelope(`entry-query-append-${index}`, {
941
998
  post_id: `40000000-0000-4000-8000-00000000000${index}`,
@@ -944,12 +1001,12 @@ export async function runAdapterConformance(environment, options = {}) {
944
1001
  }));
945
1002
  expectStatus(response, 201, `Entry-query fixture append ${index}`);
946
1003
  const entry = decodeAppendLogResultEnvelope(response.body).payload.entry;
947
- await environment.admin.replaceLogEntryId(cube, entry.id, id);
1004
+ idSeeds.push({ current_id: entry.id, query_id: id });
948
1005
  entries.push({ ...entry, id });
949
1006
  }
1007
+ await environment.admin.seedEntryQueryIds(cube, idSeeds);
950
1008
  expectStatus(await environment.operations.ack(acknowledgedCredential, cube, createProtocolEnvelope('entry-query-seed-ack', { entry_id: ids[0], kind: 'ack' })), 204, 'Entry-query acknowledgement seed');
951
1009
  expectStatus(await environment.operations.ack(claimingCredential, cube, createProtocolEnvelope('entry-query-seed-claim', { entry_id: ids[1], kind: 'claim' })), 204, 'Entry-query claim seed');
952
- const before = await environment.admin.observeAuthorityState();
953
1010
  for (const [requestId, selector, expectedId] of [
954
1011
  ['entry-query-full', ids[1], ids[1]],
955
1012
  ['entry-query-prefix', '11111111', ids[0]],
@@ -961,15 +1018,19 @@ export async function runAdapterConformance(environment, options = {}) {
961
1018
  }
962
1019
  expectError(await environment.operations.entryQuery(credentialA, cube, createProtocolEnvelope('entry-query-unknown', { entry_id: 'ffffffff' })), 404, ErrorCode.NOT_FOUND, 'Unknown entry query');
963
1020
  expectError(await environment.operations.entryQuery(credentialA, cube, createProtocolEnvelope('entry-query-ambiguous', { entry_id: '22222222' })), 409, ErrorCode.LOG_ENTRY_PREFIX_AMBIGUOUS, 'Ambiguous entry query');
964
- assertStateDelta(before, await environment.admin.observeAuthorityState(), {}, 'Entry query');
965
1021
  const acknowledgementStatus = decodeAckStatusResultEnvelope((await environment.operations.ackStatus(credentialA, cube, createProtocolEnvelope('entry-query-ack-status', { entry_id: ids[0] }))).body).payload;
966
1022
  const claimStatus = decodeAckStatusResultEnvelope((await environment.operations.ackStatus(credentialA, cube, createProtocolEnvelope('entry-query-claim-status', { entry_id: ids[1] }))).body).payload;
967
- invariant(acknowledgementStatus.recipients.some((recipient) => recipient.drone_id === acknowledgedRecipient.id && recipient.acknowledged_at !== null), 'Entry query removed the seeded acknowledgement.');
968
- invariant(claimStatus.claims.some((claim) => claim.drone_id === claimingRecipient.id), 'Entry query removed the seeded claim.');
1023
+ const acknowledgedRecipients = acknowledgementStatus.recipients.filter((recipient) => recipient.acknowledged_at !== null);
1024
+ invariant(acknowledgedRecipients.length === 1 &&
1025
+ acknowledgedRecipients[0].drone_id === acknowledgedRecipient.id &&
1026
+ acknowledgementStatus.recipients.find((recipient) => recipient.drone_id === claimingRecipient.id)?.acknowledged_at === null, 'Entry query changed the seeded acknowledgement set.');
1027
+ invariant(claimStatus.claims.length === 1 &&
1028
+ claimStatus.claims[0].drone_id === claimingRecipient.id &&
1029
+ claimStatus.recipients.every((recipient) => recipient.acknowledged_at === null), 'Entry query changed the seeded claim or acknowledgement set.');
969
1030
  const unreadResponse = await environment.operations.read(credentialA, cube, createProtocolEnvelope('entry-query-unread', { cursor: null, limit: 10 }));
970
1031
  expectStatus(unreadResponse, 200, 'Entry-query unread read');
971
1032
  const unread = decodeReadLogResultEnvelope(unreadResponse.body).payload;
972
- invariant(unread.entries.length === entries.length && entries.every((entry) => unread.entries.some((item) => item.id === entry.id)), 'Entry query consumed or advanced unread activity.');
1033
+ invariant(same(unread.entries, entries), 'Entry query mutated, consumed, or advanced unread activity.');
973
1034
  return {
974
1035
  full_uuid: true,
975
1036
  unique_prefix: true,
@@ -981,9 +1042,8 @@ export async function runAdapterConformance(environment, options = {}) {
981
1042
  mutation: 'none',
982
1043
  };
983
1044
  });
984
- const entries = [];
985
- let readCursor = null;
986
1045
  await record('log.read-cursor-tuple', async () => {
1046
+ const entries = [];
987
1047
  for (const [index, message] of ['alpha', 'beta', 'gamma'].entries()) {
988
1048
  const response = await environment.operations.append(credentialA, cubeA, createProtocolEnvelope(`append-a${index + 1}`, {
989
1049
  post_id: `00000000-0000-4000-8000-${String(305 + index).padStart(12, '0')}`,
@@ -1001,18 +1061,32 @@ export async function runAdapterConformance(environment, options = {}) {
1001
1061
  invariant(page.has_more && page.behind_by === 1, 'Read pagination metadata is incorrect.');
1002
1062
  invariant(page.cursor !== null, 'Read did not return a cursor.');
1003
1063
  invariant(page.cursor.id === entries[1].id && page.cursor.created_at === entries[1].created_at, 'Read cursor does not equal the final delivered entry tuple.');
1004
- readCursor = page.cursor;
1005
1064
  return { messages: ['alpha', 'beta'], has_more: true, behind_by: 1, cursor_matches_last_entry: true };
1006
1065
  });
1007
- let liveCursor = null;
1008
1066
  await record('sse.replay-live-transition', async () => {
1009
- invariant(readCursor, 'Cursor fixture did not produce a cursor.');
1067
+ const principal = await environment.admin.createPrincipal('stream-transition');
1068
+ const cube = await environment.admin.createCube('stream-transition');
1069
+ await environment.admin.grantCube(principal, cube);
1070
+ const credential = await environment.admin.issueDroneSession(principal);
1071
+ let readCursor;
1072
+ for (const [index, message] of ['alpha', 'beta', 'gamma'].entries()) {
1073
+ const response = await environment.operations.append(credential, cube, createProtocolEnvelope(`stream-transition-${message}`, {
1074
+ post_id: `00000000-0000-4000-8000-${String(316 + index).padStart(12, '0')}`,
1075
+ to: 'broadcast',
1076
+ message,
1077
+ }));
1078
+ expectStatus(response, 201, `Stream transition append ${message}`);
1079
+ if (message === 'beta') {
1080
+ const entry = decodeAppendLogResultEnvelope(response.body).payload.entry;
1081
+ readCursor = { id: entry.id, created_at: entry.created_at };
1082
+ }
1083
+ }
1010
1084
  const barrier = environment.admin.armReplayTransition();
1011
- const openPromise = environment.operations.openStream(credentialA, cubeA, readCursor);
1085
+ const openPromise = environment.operations.openStream(credential, cube, readCursor);
1012
1086
  await within(barrier.reached, 'Replay transition boundary', streamDeadlineMs);
1013
1087
  try {
1014
- const appendDelta = environment.operations.append(credentialA, cubeA, createProtocolEnvelope('append-a4', {
1015
- post_id: '00000000-0000-4000-8000-000000000308',
1088
+ const appendDelta = environment.operations.append(credential, cube, createProtocolEnvelope('stream-transition-delta', {
1089
+ post_id: '00000000-0000-4000-8000-000000000319',
1016
1090
  to: 'broadcast',
1017
1091
  message: 'delta',
1018
1092
  }));
@@ -1036,8 +1110,8 @@ export async function runAdapterConformance(environment, options = {}) {
1036
1110
  invariant(bookmark.type === 'bookmark' && bookmark.replay_complete, 'Stream omitted its replay-complete bookmark.');
1037
1111
  const noDuplicate = reader.next();
1038
1112
  await provePending(noDuplicate, 'Live stream after delta', pendingProbeMs);
1039
- const epsilonResponse = await environment.operations.append(credentialA, cubeA, createProtocolEnvelope('append-a5', {
1040
- post_id: '00000000-0000-4000-8000-000000000309',
1113
+ const epsilonResponse = await environment.operations.append(credential, cube, createProtocolEnvelope('stream-transition-epsilon', {
1114
+ post_id: '00000000-0000-4000-8000-000000000320',
1041
1115
  to: 'broadcast',
1042
1116
  message: 'epsilon',
1043
1117
  }));
@@ -1046,7 +1120,6 @@ export async function runAdapterConformance(environment, options = {}) {
1046
1120
  invariant(epsilon.entry.message === 'epsilon', 'Live stream duplicated or reordered an event.');
1047
1121
  invariant(compareLogCursor(delta.cursor, epsilon.cursor) < 0, 'Live stream cursors are not ordered.');
1048
1122
  invariant(new Set([replay.entry.id, delta.entry.id, epsilon.entry.id]).size === 3, 'Stream delivered a duplicate entry.');
1049
- liveCursor = epsilon.cursor;
1050
1123
  return { replay: ['gamma'], transition: 'bookmark', live: ['delta', 'epsilon'], duplicates: 0 };
1051
1124
  }
1052
1125
  finally {
@@ -1054,20 +1127,37 @@ export async function runAdapterConformance(environment, options = {}) {
1054
1127
  }
1055
1128
  });
1056
1129
  await record('cursor.explicit-expiry', async () => {
1057
- invariant(readCursor, 'Cursor fixture did not produce a cursor.');
1058
- await environment.admin.expireCursor(cubeA, readCursor);
1059
- const response = await environment.operations.read(credentialA, cubeA, createProtocolEnvelope('read-expired', { cursor: readCursor, limit: 10 }));
1130
+ const cube = await environment.admin.createCube('cursor-expiry');
1131
+ await environment.admin.grantCube(principalA, cube);
1132
+ const appended = await environment.operations.append(credentialA, cube, createProtocolEnvelope('cursor-expiry-entry', {
1133
+ post_id: '00000000-0000-4000-8000-000000000321',
1134
+ to: 'broadcast',
1135
+ message: 'expire this cursor',
1136
+ }));
1137
+ expectStatus(appended, 201, 'Cursor expiry fixture append');
1138
+ const entry = decodeAppendLogResultEnvelope(appended.body).payload.entry;
1139
+ const cursor = { id: entry.id, created_at: entry.created_at };
1140
+ await environment.admin.expireCursor(cube, cursor);
1141
+ const response = await environment.operations.read(credentialA, cube, createProtocolEnvelope('read-expired', { cursor, limit: 10 }));
1060
1142
  expectError(response, 410, ErrorCode.CURSOR_EXPIRED, 'Expired cursor read');
1061
- const stream = await environment.operations.openStream(credentialA, cubeA, readCursor);
1143
+ const stream = await environment.operations.openStream(credentialA, cube, cursor);
1062
1144
  expectError(stream, 410, ErrorCode.CURSOR_EXPIRED, 'Expired cursor stream');
1063
1145
  invariant(stream.stream === null, 'Expired cursor stream exposed a body stream.');
1064
1146
  return { read_status: 410, stream_status: 410, code: ErrorCode.CURSOR_EXPIRED };
1065
1147
  });
1066
1148
  await record('acks.idempotent', async () => {
1067
- invariant(entries[0], 'Append fixture did not produce an entry.');
1068
- const request = createProtocolEnvelope('ack-entry1', { entry_id: entries[0].id, kind: 'ack' });
1069
- const first = await environment.operations.ack(credentialA, cubeA, request);
1070
- const second = await environment.operations.ack(credentialA, cubeA, request);
1149
+ const cube = await environment.admin.createCube('ack-idempotency');
1150
+ await environment.admin.grantCube(principalA, cube);
1151
+ const appended = await environment.operations.append(credentialA, cube, createProtocolEnvelope('ack-idempotency-entry', {
1152
+ post_id: '00000000-0000-4000-8000-000000000322',
1153
+ to: 'broadcast',
1154
+ message: 'acknowledge this entry',
1155
+ }));
1156
+ expectStatus(appended, 201, 'Acknowledgement fixture append');
1157
+ const entry = decodeAppendLogResultEnvelope(appended.body).payload.entry;
1158
+ const request = createProtocolEnvelope('ack-entry1', { entry_id: entry.id, kind: 'ack' });
1159
+ const first = await environment.operations.ack(credentialA, cube, request);
1160
+ const second = await environment.operations.ack(credentialA, cube, request);
1071
1161
  expectStatus(first, 204, 'First acknowledgement');
1072
1162
  expectStatus(second, 204, 'Repeated acknowledgement');
1073
1163
  invariant((first.body === '' || first.body === undefined) && (second.body === '' || second.body === undefined), 'Acknowledgement responses must be bodyless.');
@@ -1092,7 +1182,6 @@ export async function runAdapterConformance(environment, options = {}) {
1092
1182
  }));
1093
1183
  expectStatus(append, 201, 'Acknowledgement-status fixture append');
1094
1184
  const entry = decodeAppendLogResultEnvelope(append.body).payload.entry;
1095
- const beforeMissing = await environment.admin.observeAuthorityState();
1096
1185
  const missingResponse = await environment.operations.ackStatus(credentialA, cube, createProtocolEnvelope('ack-status-missing', { entry_id: entry.id }));
1097
1186
  expectStatus(missingResponse, 200, 'Missing acknowledgement status');
1098
1187
  const missing = decodeAckStatusResultEnvelope(missingResponse.body).payload;
@@ -1100,10 +1189,8 @@ export async function runAdapterConformance(environment, options = {}) {
1100
1189
  missing.recipients.length === 2 &&
1101
1190
  missing.recipients.every((recipient) => recipient.acknowledged_at === null) &&
1102
1191
  missing.claims.length === 0, 'Missing acknowledgement was not represented as nullable per-recipient state.');
1103
- assertStateDelta(beforeMissing, await environment.admin.observeAuthorityState(), {}, 'Missing acknowledgement status query');
1104
1192
  expectStatus(await environment.operations.ack(acknowledgedCredential, cube, createProtocolEnvelope('ack-status-ack', { entry_id: entry.id, kind: 'ack' })), 204, 'Acknowledgement-status acknowledgement');
1105
1193
  expectStatus(await environment.operations.ack(claimingCredential, cube, createProtocolEnvelope('ack-status-claim', { entry_id: entry.id, kind: 'claim' })), 204, 'Acknowledgement-status claim');
1106
- const beforeDistinct = await environment.admin.observeAuthorityState();
1107
1194
  const distinctResponse = await environment.operations.ackStatus(credentialA, cube, createProtocolEnvelope('ack-status-distinct', { entry_id: entry.id }));
1108
1195
  expectStatus(distinctResponse, 200, 'Distinct acknowledgement and claim status');
1109
1196
  const distinct = decodeAckStatusResultEnvelope(distinctResponse.body).payload;
@@ -1113,16 +1200,13 @@ export async function runAdapterConformance(environment, options = {}) {
1113
1200
  distinct.claims.length === 1 &&
1114
1201
  distinct.claims[0].drone_id === claimingRecipient.id &&
1115
1202
  distinct.recipients.find((recipient) => recipient.drone_id === claimingRecipient.id)?.acknowledged_at === null, 'Acknowledgement status conflated acknowledgement and claim records.');
1116
- assertStateDelta(beforeDistinct, await environment.admin.observeAuthorityState(), {}, 'Distinct acknowledgement and claim status query');
1117
- const unreadResponse = await environment.operations.read(credentialA, cube, createProtocolEnvelope('ack-status-unread', { cursor: null, limit: 10 }));
1118
- expectStatus(unreadResponse, 200, 'Post-query unread read');
1119
- const unread = decodeReadLogResultEnvelope(unreadResponse.body).payload;
1120
- invariant(unread.entries.length === 1 && unread.entries[0].id === entry.id, 'Acknowledgement-status query advanced unread delivery state.');
1121
- const beforeUnknown = await environment.admin.observeAuthorityState();
1122
1203
  expectError(await environment.operations.ackStatus(credentialA, cube, createProtocolEnvelope('ack-status-unknown', {
1123
1204
  entry_id: '00000000-0000-4000-8000-000000000311',
1124
1205
  })), 404, ErrorCode.NOT_FOUND, 'Unknown acknowledgement-status entry');
1125
- assertStateDelta(beforeUnknown, await environment.admin.observeAuthorityState(), {}, 'Unknown acknowledgement status query');
1206
+ const unreadResponse = await environment.operations.read(credentialA, cube, createProtocolEnvelope('ack-status-unread', { cursor: null, limit: 10 }));
1207
+ expectStatus(unreadResponse, 200, 'Post-query unread read');
1208
+ const unread = decodeReadLogResultEnvelope(unreadResponse.body).payload;
1209
+ invariant(same(unread.entries, [entry]), 'Acknowledgement-status query mutated or advanced unread delivery state.');
1126
1210
  return {
1127
1211
  missing_acknowledgement: null,
1128
1212
  acknowledgements: 1,
@@ -1133,15 +1217,26 @@ export async function runAdapterConformance(environment, options = {}) {
1133
1217
  };
1134
1218
  });
1135
1219
  await record('claims.durable-noncursor', async () => {
1136
- invariant(entries[1] && liveCursor, 'Log fixtures did not produce claim state.');
1137
- const claim = await environment.operations.ack(credentialA, cubeA, createProtocolEnvelope('claim-entry2', { entry_id: entries[1].id, kind: 'claim' }));
1220
+ const principal = await environment.admin.createPrincipal('claim-noncursor');
1221
+ const cube = await environment.admin.createCube('claim-noncursor');
1222
+ await environment.admin.grantCube(principal, cube);
1223
+ const credential = await environment.admin.issueDroneSession(principal);
1224
+ const appended = await environment.operations.append(credential, cube, createProtocolEnvelope('claim-fixture-entry', {
1225
+ post_id: '00000000-0000-4000-8000-000000000314',
1226
+ to: 'broadcast',
1227
+ message: 'claim cursor baseline',
1228
+ }));
1229
+ expectStatus(appended, 201, 'Claim fixture append');
1230
+ const entry = decodeAppendLogResultEnvelope(appended.body).payload.entry;
1231
+ const baselineCursor = { id: entry.id, created_at: entry.created_at };
1232
+ const claim = await environment.operations.ack(credential, cube, createProtocolEnvelope('claim-fixture-claim', { entry_id: entry.id, kind: 'claim' }));
1138
1233
  expectStatus(claim, 204, 'Claim');
1139
- const read = await environment.operations.read(credentialA, cubeA, createProtocolEnvelope('read-claims', { cursor: liveCursor, limit: 10 }));
1234
+ const read = await environment.operations.read(credential, cube, createProtocolEnvelope('claim-fixture-readback', { cursor: baselineCursor, limit: 10 }));
1140
1235
  expectStatus(read, 200, 'Claim-state read');
1141
1236
  const page = decodeReadLogResultEnvelope(read.body).payload;
1142
1237
  invariant(page.entries.length === 0, 'Claim unexpectedly created a log entry.');
1143
- invariant(page.cursor !== null && compareLogCursor(page.cursor, liveCursor) === 0, 'Claim advanced the log cursor.');
1144
- invariant(page.claims.some((item) => item.log_entry_id === entries[1].id), 'Claim was not durable in a later read.');
1238
+ invariant(page.cursor !== null && compareLogCursor(page.cursor, baselineCursor) === 0, 'Claim advanced the log cursor.');
1239
+ invariant(page.claims.some((item) => item.log_entry_id === entry.id), 'Claim was not durable in a later read.');
1145
1240
  return { durable_claims: 1, entries: 0, cursor_advanced: false };
1146
1241
  });
1147
1242
  await record('decisions.topic-supersession', async () => {
@@ -1168,6 +1263,7 @@ export async function runAdapterConformance(environment, options = {}) {
1168
1263
  let metadataDroneB;
1169
1264
  let metadataSessionA = '';
1170
1265
  await record('security.drone-management-authorization', async () => {
1266
+ const observationCredential = await environment.admin.issueDroneSession(principalA);
1171
1267
  workerRoleA = await environment.admin.createRole(cubeA, {
1172
1268
  roleClass: 'worker', isHumanSeat: false,
1173
1269
  });
@@ -1193,8 +1289,15 @@ export async function runAdapterConformance(environment, options = {}) {
1193
1289
  deniedCredentials.push({ access: access, credential });
1194
1290
  }
1195
1291
  for (const { access, credential } of deniedCredentials) {
1292
+ const rosterBefore = await environment.operations.listDrones(observationCredential, cubeA);
1293
+ expectStatus(rosterBefore, 200, `${access} principal pre-denial roster`);
1294
+ const workerBefore = listedDrone(rosterBefore, managedWorker.id);
1295
+ invariant(workerBefore, `${access} principal pre-denial roster omitted the managed worker.`);
1196
1296
  expectError(await environment.operations.reassignDrone(credential, cubeA, managedWorker, createProtocolEnvelope(`${access}-reassign-denied`, { role_id: workerRoleA.id })), 403, ErrorCode.ACCESS_DENIED, `${access} principal reassignment`);
1197
1297
  expectError(await environment.operations.evictDrone(credential, cubeA, managedWorker, createProtocolEnvelope(`${access}-evict-denied`, {})), 403, ErrorCode.ACCESS_DENIED, `${access} principal eviction`);
1298
+ const rosterAfter = await environment.operations.listDrones(observationCredential, cubeA);
1299
+ expectStatus(rosterAfter, 200, `${access} principal post-denial roster`);
1300
+ invariant(same(listedDrone(rosterAfter, managedWorker.id), workerBefore), `${access} principal management denial mutated the managed worker.`);
1198
1301
  }
1199
1302
  return { read_status: 403, write_status: 403, manage_required: true };
1200
1303
  });
@@ -1213,12 +1316,8 @@ export async function runAdapterConformance(environment, options = {}) {
1213
1316
  roleClass: 'worker', isHumanSeat: false,
1214
1317
  });
1215
1318
  const evictionTarget = await environment.admin.createDrone(principalA, cubeA, workerRoleA);
1216
- await environment.admin.issueManagedDroneSession(evictionTarget);
1319
+ const evictionTargetCredential = await environment.admin.issueManagedDroneSession(evictionTarget);
1217
1320
  const unknownCube = { id: '00000000-0000-4000-8000-000000000399' };
1218
- const snapshot = async () => ({
1219
- cubeA: await environment.admin.inspectCubeManagementState(cubeA),
1220
- cubeB: await environment.admin.inspectCubeManagementState(cubeB),
1221
- });
1222
1321
  const operations = [
1223
1322
  {
1224
1323
  name: 'cube-update',
@@ -1253,15 +1352,42 @@ export async function runAdapterConformance(environment, options = {}) {
1253
1352
  invoke: (credential, cube) => environment.operations.evictDrone(credential, cube, evictionTarget, createProtocolEnvelope('matrix-drone-evict', {})),
1254
1353
  },
1255
1354
  ];
1355
+ const observableState = async (operationName) => {
1356
+ if (operationName === 'decision-record') {
1357
+ const response = await environment.operations.listDecisions(credentialA, cubeA, createProtocolEnvelope('matrix-observe-decisions', {}));
1358
+ expectStatus(response, 200, 'Matrix decision observation');
1359
+ return decodeDecisionsResultEnvelope(response.body).payload;
1360
+ }
1361
+ if (operationName === 'drone-reassign' || operationName === 'drone-evict') {
1362
+ const response = await environment.operations.listDrones(credentialA, cubeA);
1363
+ expectStatus(response, 200, 'Matrix drone observation');
1364
+ return listedDrone(response, operationName === 'drone-reassign' ? managedWorker.id : evictionTarget.id);
1365
+ }
1366
+ return null;
1367
+ };
1368
+ const assertObservableDenial = async (operationName, before) => {
1369
+ if (operationName === 'role-create') {
1370
+ expectError(await environment.operations.roleRationale(credentialA, cubeA, createProtocolEnvelope('matrix-observe-role', {
1371
+ role: 'Matrix Role',
1372
+ section: 'Workflow rationale',
1373
+ })), 404, ErrorCode.ROLE_NOT_FOUND, 'Denied matrix role observation');
1374
+ }
1375
+ else if (before !== null) {
1376
+ invariant(same(await observableState(operationName), before), `${operationName} changed protocol-visible state after denial.`);
1377
+ }
1378
+ };
1256
1379
  for (const operation of operations) {
1257
1380
  for (const [kind, credential] of [
1258
1381
  ['read', readCredential],
1259
1382
  ['write', writeCredential],
1260
1383
  ['drone-session', droneCredential],
1261
1384
  ]) {
1262
- const before = await snapshot();
1385
+ const before = await observableState(operation.name);
1263
1386
  expectError(await operation.invoke(credential, cubeA), 403, ErrorCode.ACCESS_DENIED, `${operation.name} by ${kind} principal`);
1264
- invariant(same(await snapshot(), before), `${operation.name} mutated state after ${kind} denial.`);
1387
+ await assertObservableDenial(operation.name, before);
1388
+ if (operation.name === 'drone-evict') {
1389
+ expectStatus(await environment.operations.read(evictionTargetCredential, cubeA, createProtocolEnvelope(`matrix-${kind}-eviction-target-probe`, { cursor: null, limit: 1 })), 200, `${kind} denied eviction target probe`);
1390
+ }
1265
1391
  }
1266
1392
  for (const [kind, credential, cube] of [
1267
1393
  ['no-grant', noGrantCredential, cubeA],
@@ -1269,14 +1395,15 @@ export async function runAdapterConformance(environment, options = {}) {
1269
1395
  ['foreign-cube', credentialA, cubeB],
1270
1396
  ['unknown-cube', credentialA, unknownCube],
1271
1397
  ]) {
1272
- const before = await snapshot();
1398
+ const before = await observableState(operation.name);
1273
1399
  expectError(await operation.invoke(credential, cube), 404, ErrorCode.NOT_FOUND, `${operation.name} against ${kind}`);
1274
- invariant(same(await snapshot(), before), `${operation.name} mutated state after ${kind} denial.`);
1400
+ await assertObservableDenial(operation.name, before);
1401
+ if (operation.name === 'drone-evict') {
1402
+ expectStatus(await environment.operations.read(evictionTargetCredential, cubeA, createProtocolEnvelope(`matrix-${kind}-eviction-target-probe`, { cursor: null, limit: 1 })), 200, `${kind} denied eviction target probe`);
1403
+ }
1275
1404
  }
1276
- const beforeSuccess = await environment.admin.inspectCubeManagementState(cubeA);
1277
1405
  const success = await operation.invoke(credentialA, cubeA);
1278
1406
  expectStatus(success, operation.successStatus, `${operation.name} by managing principal`);
1279
- invariant(!same(await environment.admin.inspectCubeManagementState(cubeA), beforeSuccess), `${operation.name} managing success did not mutate its declared state.`);
1280
1407
  }
1281
1408
  return {
1282
1409
  operation_count: operations.length,
@@ -1284,7 +1411,8 @@ export async function runAdapterConformance(environment, options = {}) {
1284
1411
  read_write_status: 403,
1285
1412
  drone_session_status: 403,
1286
1413
  hidden_status: 404,
1287
- denied_mutations: 0,
1414
+ observable_non_mutation_operations: 4,
1415
+ write_only_operations: 2,
1288
1416
  role_labels_authoritative: false,
1289
1417
  };
1290
1418
  });
@@ -1327,22 +1455,33 @@ export async function runAdapterConformance(environment, options = {}) {
1327
1455
  roleClass: 'worker', isHumanSeat: false,
1328
1456
  });
1329
1457
  const foreignDrone = await environment.admin.createDrone(principalB, cubeB, foreignRole);
1458
+ const foreignRosterBefore = await environment.operations.listDrones(credentialB, cubeB);
1459
+ const localRosterBefore = await environment.operations.listDrones(credentialA, cubeA);
1460
+ expectStatus(foreignRosterBefore, 200, 'Pre-denial foreign roster');
1461
+ expectStatus(localRosterBefore, 200, 'Pre-denial local roster');
1462
+ const foreignDroneBefore = listedDrone(foreignRosterBefore, foreignDrone.id);
1463
+ const managedWorkerBefore = listedDrone(localRosterBefore, managedWorker.id);
1464
+ invariant(foreignDroneBefore && managedWorkerBefore, 'Pre-denial roster omitted a drone-management target.');
1330
1465
  expectError(await environment.operations.reassignDrone(credentialA, cubeB, foreignDrone, createProtocolEnvelope('cross-cube-reassign', { role_id: foreignRole.id })), 404, ErrorCode.NOT_FOUND, 'Cross-cube reassignment');
1331
1466
  expectError(await environment.operations.evictDrone(credentialA, cubeB, foreignDrone, createProtocolEnvelope('cross-cube-evict', {})), 404, ErrorCode.NOT_FOUND, 'Cross-cube eviction');
1332
1467
  expectError(await environment.operations.reassignDrone(credentialA, cubeA, foreignDrone, createProtocolEnvelope('foreign-drone-local-route', { role_id: workerRoleA.id })), 404, ErrorCode.NOT_FOUND, 'Foreign drone reassignment through authorized cube route');
1333
1468
  expectError(await environment.operations.evictDrone(credentialA, cubeA, foreignDrone, createProtocolEnvelope('foreign-drone-local-evict', {})), 404, ErrorCode.NOT_FOUND, 'Foreign drone eviction through authorized cube route');
1334
1469
  expectError(await environment.operations.reassignDrone(credentialA, cubeA, managedWorker, createProtocolEnvelope('foreign-role-local-drone', { role_id: foreignRole.id })), 404, ErrorCode.NOT_FOUND, 'Foreign role reassignment through authorized cube route');
1335
1470
  await environment.admin.grantCube(principalA, cubeB, 'read');
1336
- const foreignDroneBefore = await environment.admin.inspectManagedDrone(foreignDrone);
1337
1471
  expectError(await environment.operations.reassignDrone(workerSession, cubeB, foreignDrone, createProtocolEnvelope('bound-drone-cross-cube-reassign', { role_id: foreignRole.id })), 404, ErrorCode.NOT_FOUND, 'Bound drone cross-cube reassignment');
1338
- invariant(same(await environment.admin.inspectManagedDrone(foreignDrone), foreignDroneBefore), 'Bound drone cross-cube reassignment mutated the foreign target.');
1339
1472
  expectError(await environment.operations.evictDrone(workerSession, cubeB, foreignDrone, createProtocolEnvelope('bound-drone-cross-cube-evict', {})), 404, ErrorCode.NOT_FOUND, 'Bound drone cross-cube eviction');
1340
- invariant(same(await environment.admin.inspectManagedDrone(foreignDrone), foreignDroneBefore), 'Bound drone cross-cube eviction mutated the foreign target.');
1473
+ const foreignRosterAfter = await environment.operations.listDrones(credentialB, cubeB);
1474
+ const localRosterAfter = await environment.operations.listDrones(credentialA, cubeA);
1475
+ expectStatus(foreignRosterAfter, 200, 'Post-denial foreign roster');
1476
+ expectStatus(localRosterAfter, 200, 'Post-denial local roster');
1477
+ invariant(same(listedDrone(foreignRosterAfter, foreignDrone.id), foreignDroneBefore), 'Denied cross-cube management mutated the foreign drone.');
1478
+ invariant(same(listedDrone(localRosterAfter, managedWorker.id), managedWorkerBefore), 'Denied foreign-role management mutated the local drone.');
1341
1479
  return {
1342
1480
  unauthorized_cube_status: 404,
1343
1481
  foreign_drone_status: 404,
1344
1482
  foreign_role_status: 404,
1345
1483
  bound_drone_cross_cube_status: 404,
1484
+ targets_unchanged: true,
1346
1485
  code: ErrorCode.NOT_FOUND,
1347
1486
  };
1348
1487
  });
@@ -1359,11 +1498,6 @@ export async function runAdapterConformance(environment, options = {}) {
1359
1498
  drone_id: evictedDrone.id,
1360
1499
  evicted: true,
1361
1500
  }), 'Eviction response did not identify the terminal seat.');
1362
- invariant(same(await environment.admin.inspectManagedDrone(evictedDrone), {
1363
- role_id: workerRoleA.id,
1364
- evicted: true,
1365
- session_revoked: true,
1366
- }), 'Eviction did not atomically mark the drone evicted and revoke its session.');
1367
1501
  const after = await environment.operations.listDrones(credentialA, cubeA);
1368
1502
  expectStatus(after, 200, 'Post-eviction roster');
1369
1503
  invariant(!listedDroneIds(after).includes(evictedDrone.id), 'Evicted drone remained in roster.');
@@ -1405,44 +1539,78 @@ export async function runAdapterConformance(environment, options = {}) {
1405
1539
  retry_key: '00000000-0000-4000-8000-000000000352',
1406
1540
  client_credential: roleContractReadCredential,
1407
1541
  })), 201, 'Role-contract reader enrollment');
1542
+ const refusalRationale = 'Workflow rationale:\nRefusal role remains.';
1408
1543
  const defaultRole = await environment.admin.createRole(roleContractCube, {
1409
1544
  roleClass: 'worker',
1410
1545
  isHumanSeat: false,
1411
1546
  name: 'Default Worker',
1547
+ detailedDescription: refusalRationale,
1412
1548
  isDefault: true,
1413
1549
  });
1414
1550
  const mandatoryRole = await environment.admin.createRole(roleContractCube, {
1415
1551
  roleClass: 'worker',
1416
1552
  isHumanSeat: false,
1417
1553
  name: 'Mandatory Worker',
1554
+ detailedDescription: refusalRationale,
1418
1555
  isMandatory: true,
1419
1556
  });
1420
1557
  const humanRole = await environment.admin.createRole(roleContractCube, {
1421
1558
  roleClass: 'queen',
1422
1559
  isHumanSeat: true,
1423
1560
  name: 'Human Seat',
1561
+ detailedDescription: refusalRationale,
1424
1562
  });
1425
1563
  const activeRole = await environment.admin.createRole(roleContractCube, {
1426
1564
  roleClass: 'worker',
1427
1565
  isHumanSeat: false,
1428
1566
  name: 'Active Worker',
1567
+ detailedDescription: refusalRationale,
1429
1568
  });
1430
- await environment.admin.createDrone(roleContractPrincipal, roleContractCube, activeRole);
1569
+ const activeDrone = await environment.admin.createDrone(roleContractPrincipal, roleContractCube, activeRole);
1570
+ const activeRosterBefore = await environment.operations.listDrones(roleContractCredential, roleContractCube);
1571
+ expectStatus(activeRosterBefore, 200, 'Pre-refusal active-role roster');
1572
+ const activeDroneBefore = listedDrone(activeRosterBefore, activeDrone.id);
1573
+ invariant(activeDroneBefore, 'Pre-refusal roster omitted the active-role drone.');
1431
1574
  const refusals = [
1432
- [defaultRole, ErrorCode.DEFAULT_ROLE_REQUIRED, 'default role'],
1433
- [mandatoryRole, ErrorCode.ROLE_REQUIRED, 'mandatory role'],
1434
- [humanRole, ErrorCode.ROLE_REQUIRED, 'human-seat role'],
1435
- [activeRole, ErrorCode.ROLE_IN_USE, 'active-drone role'],
1575
+ [defaultRole, ErrorCode.DEFAULT_ROLE_REQUIRED, 'default role', 'Default Worker', 'worker', false],
1576
+ [mandatoryRole, ErrorCode.ROLE_REQUIRED, 'mandatory role', 'Mandatory Worker', 'worker', false],
1577
+ [humanRole, ErrorCode.ROLE_REQUIRED, 'human-seat role', 'Human Seat', 'queen', true],
1578
+ [activeRole, ErrorCode.ROLE_IN_USE, 'active-drone role', 'Active Worker', 'worker', false],
1436
1579
  ];
1437
- for (const [index, [role, code, label]] of refusals.entries()) {
1438
- const before = await environment.admin.inspectCubeManagementState(roleContractCube);
1580
+ for (const [index, [role, code, label, roleName, roleClass, isHumanSeat]] of refusals.entries()) {
1439
1581
  const response = await environment.operations.deleteRole(roleContractCredential, roleContractCube, role, createProtocolEnvelope(`delete-refusal-${index}`, {}));
1440
1582
  expectError(response, 409, code, `Delete ${label}`);
1441
- invariant(same(await environment.admin.inspectCubeManagementState(roleContractCube), before), `Delete ${label} mutated cube state after refusal.`);
1442
1583
  if (code === ErrorCode.ROLE_IN_USE) {
1443
1584
  const message = protocolErrorMessage(response) ?? '';
1444
1585
  invariant(message === ROLE_IN_USE_DELETE_MESSAGE, 'ROLE_IN_USE did not direct the caller to reassign or evict the drones first.');
1586
+ const roster = await environment.operations.listDrones(roleContractCredential, roleContractCube);
1587
+ expectStatus(roster, 200, 'Active-role refusal roster readback');
1588
+ invariant(same(listedDrone(roster, activeDrone.id), activeDroneBefore), 'Active-role deletion refusal changed the active drone.');
1445
1589
  }
1590
+ const retained = await environment.operations.roleRationale(roleContractReadCredential, roleContractCube, createProtocolEnvelope(`delete-refusal-${index}-readback`, {
1591
+ role: role.id,
1592
+ section: 'Workflow rationale',
1593
+ }));
1594
+ expectStatus(retained, 200, `Retained ${label} rationale lookup`);
1595
+ const retainedPayload = decodeRoleRationaleResultEnvelope(retained.body).payload;
1596
+ invariant(retainedPayload.role_id === role.id &&
1597
+ retainedPayload.role_name === roleName &&
1598
+ same(retainedPayload.section, {
1599
+ heading: 'Workflow rationale',
1600
+ body: refusalRationale,
1601
+ }), `Retained ${label} rationale lookup returned a different role or section.`);
1602
+ const shapeSession = `${String(index).repeat(42)}S`;
1603
+ const shapeProbe = await environment.operations.attach(roleContractCredential, createProtocolEnvelope(`delete-refusal-${index}-shape-probe`, {
1604
+ cube_id: roleContractCube.id,
1605
+ role_id: role.id,
1606
+ session_credential: shapeSession,
1607
+ }));
1608
+ expectStatus(shapeProbe, 200, `Retained ${label} shape probe`);
1609
+ const shapePayload = decodeAttachResponseEnvelope(shapeProbe.body).payload;
1610
+ invariant(shapePayload.role.id === role.id &&
1611
+ shapePayload.role.role_class === roleClass &&
1612
+ shapePayload.role.is_human_seat === isHumanSeat, `Retained ${label} shape probe returned changed role semantics.`);
1613
+ expectStatus(await environment.operations.evictDrone(roleContractCredential, roleContractCube, { id: shapePayload.drone.id }, createProtocolEnvelope(`delete-refusal-${index}-shape-cleanup`, {})), 200, `Retained ${label} shape cleanup`);
1446
1614
  }
1447
1615
  const unknownRole = { id: '00000000-0000-4000-8000-000000000398' };
1448
1616
  expectError(await environment.operations.deleteRole(roleContractCredential, roleContractCube, unknownRole, createProtocolEnvelope('delete-unknown-role', {})), 404, ErrorCode.NOT_FOUND, 'Delete unknown role');
@@ -1450,10 +1618,32 @@ export async function runAdapterConformance(environment, options = {}) {
1450
1618
  roleClass: 'worker',
1451
1619
  isHumanSeat: false,
1452
1620
  name: 'Disposable Worker',
1621
+ detailedDescription: refusalRationale,
1453
1622
  });
1454
- const beforeReadDenial = await environment.admin.inspectCubeManagementState(roleContractCube);
1455
1623
  expectError(await environment.operations.deleteRole(roleContractReadCredential, roleContractCube, deletableRole, createProtocolEnvelope('delete-role-read-denied', {})), 403, ErrorCode.ACCESS_DENIED, 'Delete role with read authority');
1456
- invariant(same(await environment.admin.inspectCubeManagementState(roleContractCube), beforeReadDenial), 'Read-authority role deletion mutated cube state.');
1624
+ const retainedDeletable = await environment.operations.roleRationale(roleContractReadCredential, roleContractCube, createProtocolEnvelope('delete-role-read-denied-readback', {
1625
+ role: deletableRole.id,
1626
+ section: 'Workflow rationale',
1627
+ }));
1628
+ expectStatus(retainedDeletable, 200, 'Read-denied retained role rationale lookup');
1629
+ const retainedDeletablePayload = decodeRoleRationaleResultEnvelope(retainedDeletable.body).payload;
1630
+ invariant(retainedDeletablePayload.role_id === deletableRole.id &&
1631
+ retainedDeletablePayload.role_name === 'Disposable Worker' &&
1632
+ same(retainedDeletablePayload.section, {
1633
+ heading: 'Workflow rationale',
1634
+ body: refusalRationale,
1635
+ }), 'Read-authority deletion denial changed the target role.');
1636
+ const shapeProbe = await environment.operations.attach(roleContractCredential, createProtocolEnvelope('delete-role-read-denied-shape-probe', {
1637
+ cube_id: roleContractCube.id,
1638
+ role_id: deletableRole.id,
1639
+ session_credential: 'S'.repeat(43),
1640
+ }));
1641
+ expectStatus(shapeProbe, 200, 'Read-denied retained role shape probe');
1642
+ const shapePayload = decodeAttachResponseEnvelope(shapeProbe.body).payload;
1643
+ invariant(shapePayload.role.id === deletableRole.id &&
1644
+ shapePayload.role.role_class === 'worker' &&
1645
+ shapePayload.role.is_human_seat === false, 'Read-authority deletion denial changed the target role shape.');
1646
+ expectStatus(await environment.operations.evictDrone(roleContractCredential, roleContractCube, { id: shapePayload.drone.id }, createProtocolEnvelope('delete-role-read-denied-shape-cleanup', {})), 200, 'Read-denied retained role shape cleanup');
1457
1647
  const deleted = await environment.operations.deleteRole(roleContractCredential, roleContractCube, deletableRole, createProtocolEnvelope('delete-empty-role', {}));
1458
1648
  expectStatus(deleted, 200, 'Delete unassigned role');
1459
1649
  invariant(same(decodeDeleteRoleResultEnvelope(deleted.body).payload, {
@@ -1476,7 +1666,6 @@ export async function runAdapterConformance(environment, options = {}) {
1476
1666
  const attributedEntry = decodeAppendLogResultEnvelope(attributed.body).payload.entry;
1477
1667
  expectStatus(await environment.operations.evictDrone(roleContractCredential, roleContractCube, evictedDrone, createProtocolEnvelope('role-delete-evict', {})), 200, 'Pre-delete drone eviction');
1478
1668
  expectStatus(await environment.operations.deleteRole(roleContractCredential, roleContractCube, evictedRole, createProtocolEnvelope('delete-evicted-role', {})), 200, 'Delete role held only by an evicted drone');
1479
- invariant((await environment.admin.inspectManagedDrone(evictedDrone)).role_id === defaultRole.id, 'Role deletion did not retarget the evicted drone to the surviving default role.');
1480
1669
  const read = await environment.operations.read(roleContractCredential, roleContractCube, createProtocolEnvelope('read-role-delete-attribution', { cursor: null, limit: 500 }));
1481
1670
  expectStatus(read, 200, 'Post-delete attributed log read');
1482
1671
  invariant(decodeReadLogResultEnvelope(read.body).payload.entries.some((entry) => entry.id === attributedEntry.id && entry.drone_id === evictedDrone.id), 'Deleting the evicted drone role lost the drone attribution of an existing log entry.');
@@ -1489,7 +1678,7 @@ export async function runAdapterConformance(environment, options = {}) {
1489
1678
  ErrorCode.ROLE_REQUIRED,
1490
1679
  ],
1491
1680
  in_use_message_actionable: true,
1492
- evicted_drone_retargeted: true,
1681
+ refusals_non_mutating: true,
1493
1682
  activity_log_attribution_preserved: true,
1494
1683
  };
1495
1684
  });
@@ -1580,12 +1769,19 @@ export async function runAdapterConformance(environment, options = {}) {
1580
1769
  working_repo_name: 'Byte-Ventures/borg-mcp',
1581
1770
  working_repo_origin: 'https://github.com/Byte-Ventures/borg-mcp',
1582
1771
  };
1772
+ try {
1773
+ metadataDroneA = await environment.admin.createDrone(principalA, cubeA, workerRoleA);
1774
+ metadataSessionA = await environment.admin.issueManagedDroneSession(metadataDroneA);
1775
+ }
1776
+ catch (error) {
1777
+ prerequisiteFailures.set('shared.metadata-baseline', error instanceof Error ? error.message : String(error));
1778
+ }
1583
1779
  await record('metadata.attach-report', async () => {
1584
- metadataSessionA = 'M'.repeat(43);
1780
+ const attachSession = 'M'.repeat(43);
1585
1781
  const created = await environment.operations.attach(credentialA, createProtocolEnvelope('metadata-attach-created', {
1586
1782
  cube_id: cubeA.id,
1587
1783
  role_id: workerRoleA.id,
1588
- session_credential: metadataSessionA,
1784
+ session_credential: attachSession,
1589
1785
  runtime_metadata: {
1590
1786
  ...knownMetadata,
1591
1787
  working_repo_origin: 'git@github.com:Byte-Ventures/borg-mcp.git',
@@ -1596,7 +1792,7 @@ export async function runAdapterConformance(environment, options = {}) {
1596
1792
  invariant(createdPayload.result === 'created', 'First metadata attach did not create a seat.');
1597
1793
  invariant(same(createdPayload.drone.runtime_metadata, knownMetadata), 'Attach did not echo canonical metadata.');
1598
1794
  invariant(createdPayload.drone.runtime_metadata_reported, 'Present attach report was not marked reported.');
1599
- metadataDroneA = { id: createdPayload.drone.id };
1795
+ const attachedDrone = { id: createdPayload.drone.id };
1600
1796
  const unavailableSession = 'N'.repeat(43);
1601
1797
  const unavailable = await environment.operations.attach(credentialA, createProtocolEnvelope('metadata-attach-unavailable', {
1602
1798
  cube_id: cubeA.id,
@@ -1629,13 +1825,13 @@ export async function runAdapterConformance(environment, options = {}) {
1629
1825
  const reused = await environment.operations.attach(credentialA, createProtocolEnvelope('metadata-attach-reused', {
1630
1826
  cube_id: cubeA.id,
1631
1827
  role_id: workerRoleA.id,
1632
- prior_drone_id: metadataDroneA.id,
1633
- session_credential: metadataSessionA,
1828
+ prior_drone_id: attachedDrone.id,
1829
+ session_credential: attachSession,
1634
1830
  runtime_metadata: knownMetadata,
1635
1831
  }));
1636
1832
  expectStatus(reused, 200, 'Metadata attach reuse');
1637
1833
  invariant(decodeAttachResponseEnvelope(reused.body).payload.result === 'reused', 'Prior seat was not reused.');
1638
- const cleared = await environment.operations.selfMetadataUpdate(metadataSessionA, cubeA, createProtocolEnvelope('metadata-clear-all', {
1834
+ const cleared = await environment.operations.selfMetadataUpdate(attachSession, cubeA, createProtocolEnvelope('metadata-clear-all', {
1639
1835
  agent_kind: null,
1640
1836
  reported_model: null,
1641
1837
  working_repo_name: null,
@@ -1645,7 +1841,7 @@ export async function runAdapterConformance(environment, options = {}) {
1645
1841
  const clearedPayload = decodeUpdateDroneRuntimeMetadataResponseEnvelope(cleared.body).payload;
1646
1842
  invariant(clearedPayload.runtime_metadata_reported, 'Clear-all patch lost reported state.');
1647
1843
  invariant(same(clearedPayload.runtime_metadata, explicitUnknownDrone.runtime_metadata), 'Clear-all patch did not produce explicit unknown metadata.');
1648
- expectStatus(await environment.operations.selfMetadataUpdate(metadataSessionA, cubeA, createProtocolEnvelope('metadata-restore-known', knownMetadata)), 200, 'Restore known metadata');
1844
+ expectStatus(await environment.operations.selfMetadataUpdate(attachSession, cubeA, createProtocolEnvelope('metadata-restore-known', knownMetadata)), 200, 'Restore known metadata');
1649
1845
  return {
1650
1846
  created: true,
1651
1847
  reused: true,
@@ -1664,17 +1860,29 @@ export async function runAdapterConformance(environment, options = {}) {
1664
1860
  { request_id: 'metadata-null-repeat', patch: { reported_model: null } },
1665
1861
  { request_id: 'metadata-same-value', patch: { agent_kind: 'opencode' } },
1666
1862
  ];
1863
+ let state;
1667
1864
  for (const update of updates) {
1668
1865
  const response = await environment.operations.selfMetadataUpdate(metadataSessionA, cubeA, createProtocolEnvelope(update.request_id, update.patch));
1669
1866
  expectStatus(response, 200, update.request_id);
1670
- decodeUpdateDroneRuntimeMetadataResponseEnvelope(response.body);
1867
+ state = decodeUpdateDroneRuntimeMetadataResponseEnvelope(response.body).payload;
1671
1868
  }
1672
- const state = await environment.admin.inspectDroneRuntimeState(metadataDroneA);
1673
- invariant(state.metadata.reported_model === null, 'Explicit null did not clear model metadata.');
1674
- invariant(state.metadata.agent_kind === 'opencode', 'Omitted field was not preserved.');
1869
+ invariant(state?.runtime_metadata.reported_model === null, 'Explicit null did not clear model metadata.');
1870
+ invariant(state.runtime_metadata.agent_kind === 'opencode', 'Omitted field was not preserved.');
1675
1871
  return { known_replace: true, omitted_unchanged: true, null_clear: true, repeat_safe: true };
1676
1872
  });
1677
1873
  await record('security.metadata-invalid-atomic', async () => {
1874
+ const baselineResponse = await environment.operations.selfMetadataUpdate(metadataSessionA, cubeA, createProtocolEnvelope('metadata-invalid-baseline', {
1875
+ agent_kind: 'opencode',
1876
+ reported_model: null,
1877
+ working_repo_name: 'Byte-Ventures/borg-mcp-shared',
1878
+ working_repo_origin: 'https://github.com/Byte-Ventures/borg-mcp-shared',
1879
+ }));
1880
+ expectStatus(baselineResponse, 200, 'Invalid metadata baseline');
1881
+ decodeUpdateDroneRuntimeMetadataResponseEnvelope(baselineResponse.body);
1882
+ const baselineRoster = await environment.operations.listDrones(credentialA, cubeA);
1883
+ expectStatus(baselineRoster, 200, 'Invalid metadata baseline roster');
1884
+ const baselineDrone = listedDrone(baselineRoster, metadataDroneA.id);
1885
+ invariant(baselineDrone, 'Invalid metadata baseline roster omitted the metadata seat.');
1678
1886
  const invalidPatches = [
1679
1887
  {},
1680
1888
  { agent_kind: 'OpenCode' },
@@ -1692,23 +1900,29 @@ export async function runAdapterConformance(environment, options = {}) {
1692
1900
  { last_seen: '2026-07-14T10:00:00.000Z' },
1693
1901
  ];
1694
1902
  for (const [index, patch] of invalidPatches.entries()) {
1695
- const before = await environment.admin.inspectDroneRuntimeState(metadataDroneA);
1696
1903
  const response = await environment.operations.selfMetadataUpdate(metadataSessionA, cubeA, createProtocolEnvelope(`metadata-invalid-${index}`, patch));
1697
1904
  expectError(response, 400, ErrorCode.INVALID_INPUT, `Invalid metadata patch ${index}`);
1698
- invariant(same(await environment.admin.inspectDroneRuntimeState(metadataDroneA), before), `Invalid metadata patch ${index} partially mutated state.`);
1905
+ const readbackResponse = await environment.operations.listDrones(credentialA, cubeA);
1906
+ expectStatus(readbackResponse, 200, `Invalid metadata readback ${index}`);
1907
+ invariant(same(listedDrone(readbackResponse, metadataDroneA.id), baselineDrone), `Invalid metadata patch ${index} partially mutated state.`);
1699
1908
  }
1700
1909
  return { cases: invalidPatches.length, atomic: true, prior_safe_state_retained: true };
1701
1910
  });
1702
1911
  await record('security.metadata-own-seat', async () => {
1703
1912
  const peer = await environment.admin.createDrone(principalA, cubeA, workerRoleA);
1704
- const peerBefore = await environment.admin.inspectDroneRuntimeState(peer);
1705
- const managedBefore = await environment.admin.inspectDroneRuntimeState(managedWorker);
1706
- const ownBefore = await environment.admin.inspectDroneRuntimeState(metadataDroneA);
1913
+ const rosterBefore = await environment.operations.listDrones(credentialA, cubeA);
1914
+ expectStatus(rosterBefore, 200, 'Pre-update metadata roster');
1915
+ const peerBefore = listedDrone(rosterBefore, peer.id);
1916
+ const managedBefore = listedDrone(rosterBefore, managedWorker.id);
1917
+ const ownBefore = listedDrone(rosterBefore, metadataDroneA.id);
1918
+ invariant(peerBefore && managedBefore && ownBefore, 'Pre-update metadata roster omitted a fixture drone.');
1707
1919
  const response = await environment.operations.selfMetadataUpdate(metadataSessionA, cubeA, createProtocolEnvelope('metadata-own-seat', { agent_kind: 'claude' }));
1708
1920
  expectStatus(response, 200, 'Own-seat metadata update');
1709
- invariant(same(await environment.admin.inspectDroneRuntimeState(peer), peerBefore), 'Own-seat update mutated a peer seat.');
1710
- invariant(same(await environment.admin.inspectDroneRuntimeState(managedWorker), managedBefore), 'Own-seat update mutated another existing seat.');
1711
- invariant((await environment.admin.inspectDroneRuntimeState(metadataDroneA)).role_id === ownBefore.role_id, 'Metadata update changed the current seat role.');
1921
+ const rosterAfter = await environment.operations.listDrones(credentialA, cubeA);
1922
+ expectStatus(rosterAfter, 200, 'Post-update metadata roster');
1923
+ invariant(same(listedDrone(rosterAfter, peer.id), peerBefore), 'Own-seat update mutated a peer seat.');
1924
+ invariant(same(listedDrone(rosterAfter, managedWorker.id), managedBefore), 'Own-seat update mutated another existing seat.');
1925
+ invariant(listedDrone(rosterAfter, metadataDroneA.id)?.role_id === ownBefore.role_id, 'Metadata update changed the current seat role.');
1712
1926
  expectError(await environment.operations.selfMetadataUpdate(credentialA, cubeA, createProtocolEnvelope('metadata-manager-denied', { agent_kind: 'codex' })), 403, ErrorCode.ACCESS_DENIED, 'Manager metadata update');
1713
1927
  expectError(await environment.operations.selfMetadataUpdate('Z'.repeat(43), cubeA, createProtocolEnvelope('metadata-invalid-session', { agent_kind: null })), 401, ErrorCode.AUTH_INVALID, 'Unknown metadata session');
1714
1928
  const rejectedStates = [];
@@ -1721,9 +1935,20 @@ export async function runAdapterConformance(environment, options = {}) {
1721
1935
  expectStatus(await environment.operations.evictDrone(credentialA, cubeA, evicted, createProtocolEnvelope('metadata-evict-seat', {})), 200, 'Metadata seat eviction');
1722
1936
  rejectedStates.push(['evicted', evicted, evictedSession, 410, ErrorCode.DRONE_EVICTED]);
1723
1937
  for (const [label, drone, session, status, code] of rejectedStates) {
1724
- const before = await environment.admin.inspectDroneRuntimeState(drone);
1938
+ const rosterBefore = label === 'revoked'
1939
+ ? await environment.operations.listDrones(credentialA, cubeA)
1940
+ : null;
1941
+ if (rosterBefore)
1942
+ expectStatus(rosterBefore, 200, 'Pre-denial revoked metadata roster');
1943
+ const droneBefore = rosterBefore ? listedDrone(rosterBefore, drone.id) : null;
1944
+ if (rosterBefore)
1945
+ invariant(droneBefore, 'Pre-denial roster omitted the revoked metadata seat.');
1725
1946
  expectError(await environment.operations.selfMetadataUpdate(session, cubeA, createProtocolEnvelope(`metadata-${label}-denied`, { agent_kind: null })), status, code, `${label} metadata session`);
1726
- invariant(same(await environment.admin.inspectDroneRuntimeState(drone), before), `${label} metadata denial mutated state.`);
1947
+ if (droneBefore) {
1948
+ const rosterAfter = await environment.operations.listDrones(credentialA, cubeA);
1949
+ expectStatus(rosterAfter, 200, 'Post-denial revoked metadata roster');
1950
+ invariant(same(listedDrone(rosterAfter, drone.id), droneBefore), 'Revoked metadata denial mutated the protocol-visible seat.');
1951
+ }
1727
1952
  }
1728
1953
  return {
1729
1954
  own_seat_only: true,
@@ -1750,19 +1975,27 @@ export async function runAdapterConformance(environment, options = {}) {
1750
1975
  }));
1751
1976
  expectStatus(attachedB, 200, 'Cube B metadata attach');
1752
1977
  metadataDroneB = { id: decodeAttachResponseEnvelope(attachedB.body).payload.drone.id };
1753
- const beforeB = await environment.admin.inspectDroneRuntimeState(metadataDroneB);
1978
+ const rosterBefore = await environment.operations.listDrones(credentialB, cubeB);
1979
+ expectStatus(rosterBefore, 200, 'Pre-probe cube B roster');
1980
+ const beforeB = listedDrone(rosterBefore, metadataDroneB.id);
1981
+ invariant(beforeB, 'Pre-probe cube B roster omitted its metadata seat.');
1754
1982
  const foreign = await environment.operations.selfMetadataUpdate(metadataSessionA, cubeB, createProtocolEnvelope('metadata-cross-cube', { reported_model: 'foreign/probe' }));
1755
1983
  expectError(foreign, 404, ErrorCode.NOT_FOUND, 'Cross-cube metadata update');
1756
1984
  const unknown = await environment.operations.selfMetadataUpdate(metadataSessionA, { id: '90000000-0000-4000-8000-000000000001' }, createProtocolEnvelope('metadata-unknown-cube', { reported_model: 'foreign/probe' }));
1757
1985
  expectError(unknown, 404, ErrorCode.NOT_FOUND, 'Unknown-cube metadata update');
1758
1986
  invariant(same(foreign.body, unknown.body), 'Foreign and unknown metadata probes were distinguishable.');
1759
- invariant(same(await environment.admin.inspectDroneRuntimeState(metadataDroneB), beforeB), 'Cross-cube metadata update mutated the foreign seat.');
1987
+ const rosterAfter = await environment.operations.listDrones(credentialB, cubeB);
1988
+ expectStatus(rosterAfter, 200, 'Post-probe cube B roster');
1989
+ invariant(same(listedDrone(rosterAfter, metadataDroneB.id), beforeB), 'Cross-cube metadata update mutated the foreign seat.');
1760
1990
  const listedA = await environment.operations.listDrones(credentialA, cubeA);
1761
1991
  invariant(!listedDroneIds(listedA).includes(metadataDroneB.id), 'Cube A roster disclosed cube B metadata seat.');
1762
1992
  return { update_status: 404, foreign_unknown_indistinguishable: true, foreign_unchanged: true, roster_isolated: true };
1763
1993
  });
1764
1994
  await record('security.metadata-noninterference', async () => {
1765
- const before = await environment.admin.inspectDroneRuntimeState(metadataDroneA);
1995
+ const rosterBefore = await environment.operations.listDrones(credentialA, cubeA);
1996
+ expectStatus(rosterBefore, 200, 'Pre-update noninterference roster');
1997
+ const before = listedDrone(rosterBefore, metadataDroneA.id);
1998
+ invariant(before, 'Pre-update noninterference roster omitted the metadata seat.');
1766
1999
  for (const [requestId, patch] of [
1767
2000
  ['metadata-noninterference-known', { reported_model: 'openai/gpt-5.6-sol' }],
1768
2001
  ['metadata-noninterference-repeat', { reported_model: 'openai/gpt-5.6-sol' }],
@@ -1778,28 +2011,28 @@ export async function runAdapterConformance(environment, options = {}) {
1778
2011
  session_credential: metadataSessionA,
1779
2012
  }));
1780
2013
  expectStatus(reattached, 200, 'Metadata non-interference reattach');
1781
- const after = await environment.admin.inspectDroneRuntimeState(metadataDroneA);
1782
- const { metadata: _beforeMetadata, metadata_revision: _beforeRevision, ...beforeInvariant } = before;
1783
- const { metadata: _afterMetadata, metadata_revision: _afterRevision, ...afterInvariant } = after;
1784
- invariant(same(beforeInvariant, afterInvariant), 'Metadata update changed authority/liveness/log state.');
1785
- return {
1786
- authority_unchanged: true,
1787
- role_unchanged: true,
1788
- liveness_unchanged: true,
1789
- logs_unchanged: true,
1790
- model_turns_unchanged: true,
1791
- };
2014
+ const rosterAfter = await environment.operations.listDrones(credentialA, cubeA);
2015
+ expectStatus(rosterAfter, 200, 'Post-update noninterference roster');
2016
+ const after = listedDrone(rosterAfter, metadataDroneA.id);
2017
+ invariant(after, 'Post-update noninterference roster omitted the metadata seat.');
2018
+ invariant(same(withoutRuntimeMetadata(before), withoutRuntimeMetadata(after)), 'Metadata update changed non-metadata roster state.');
2019
+ return { non_metadata_roster_state_unchanged: true };
1792
2020
  });
1793
2021
  await record('security.metadata-secret-non-echo', async () => {
1794
2022
  const marker = 'SECRET-METADATA-MARKER';
1795
- const before = await environment.admin.inspectDroneRuntimeState(metadataDroneA);
2023
+ const rosterBefore = await environment.operations.listDrones(credentialA, cubeA);
2024
+ expectStatus(rosterBefore, 200, 'Pre-secret metadata roster');
2025
+ const before = listedDrone(rosterBefore, metadataDroneA.id);
2026
+ invariant(before, 'Pre-secret metadata roster omitted the metadata seat.');
1796
2027
  const response = await environment.operations.selfMetadataUpdate(metadataSessionA, cubeA, createProtocolEnvelope('metadata-secret', {
1797
2028
  working_repo_name: 'owner/repo',
1798
2029
  working_repo_origin: `https://user:${marker}@github.com/owner/repo?token=${marker}`,
1799
2030
  }));
1800
2031
  expectError(response, 400, ErrorCode.INVALID_INPUT, 'Secret-bearing metadata update');
1801
2032
  invariant(!JSON.stringify(response.body).includes(marker), 'Metadata error echoed hostile secret input.');
1802
- invariant(same(await environment.admin.inspectDroneRuntimeState(metadataDroneA), before), 'Secret-bearing metadata input was persisted.');
2033
+ const rosterAfter = await environment.operations.listDrones(credentialA, cubeA);
2034
+ expectStatus(rosterAfter, 200, 'Post-secret metadata roster');
2035
+ invariant(same(listedDrone(rosterAfter, metadataDroneA.id), before), 'Secret-bearing metadata input was persisted.');
1803
2036
  const hostileKeys = [
1804
2037
  'SECRET-METADATA-KEY-MARKER',
1805
2038
  `control\u001b[2J`,
@@ -1825,8 +2058,19 @@ export async function runAdapterConformance(environment, options = {}) {
1825
2058
  };
1826
2059
  });
1827
2060
  await record('security.active-stream-revocation', async () => {
1828
- invariant(liveCursor, 'Stream fixture did not produce a live cursor.');
1829
- const opened = await environment.operations.openStream(credentialA, cubeA, liveCursor);
2061
+ const principal = await environment.admin.createPrincipal('stream-revocation');
2062
+ const cube = await environment.admin.createCube('stream-revocation');
2063
+ await environment.admin.grantCube(principal, cube);
2064
+ const credential = await environment.admin.issueDroneSession(principal);
2065
+ const appended = await environment.operations.append(credential, cube, createProtocolEnvelope('stream-revocation-entry', {
2066
+ post_id: '00000000-0000-4000-8000-000000000315',
2067
+ to: 'broadcast',
2068
+ message: 'revocation cursor baseline',
2069
+ }));
2070
+ expectStatus(appended, 201, 'Revocation fixture append');
2071
+ const entry = decodeAppendLogResultEnvelope(appended.body).payload.entry;
2072
+ const cursor = { id: entry.id, created_at: entry.created_at };
2073
+ const opened = await environment.operations.openStream(credential, cube, cursor);
1830
2074
  expectStatus(opened, 200, 'Revocation stream open');
1831
2075
  invariant(opened.stream, 'Successful revocation stream omitted its AsyncIterable.');
1832
2076
  const reader = new SseEventReader(opened.stream);
@@ -1835,7 +2079,7 @@ export async function runAdapterConformance(environment, options = {}) {
1835
2079
  invariant(bookmark.type === 'bookmark' && bookmark.replay_complete, 'Fresh live stream did not complete replay.');
1836
2080
  const pending = reader.next();
1837
2081
  await provePending(pending, 'Idle live stream', pendingProbeMs);
1838
- await environment.admin.revokePrincipal(principalA);
2082
+ await environment.admin.revokePrincipal(principal);
1839
2083
  let terminated = false;
1840
2084
  try {
1841
2085
  await within(pending, 'Revoked stream termination', streamDeadlineMs);
@@ -1850,7 +2094,7 @@ export async function runAdapterConformance(environment, options = {}) {
1850
2094
  finally {
1851
2095
  await reader.close();
1852
2096
  }
1853
- const rejected = await environment.operations.read(credentialA, cubeA, createProtocolEnvelope('read-revoked', { cursor: liveCursor, limit: 10 }));
2097
+ const rejected = await environment.operations.read(credential, cube, createProtocolEnvelope('read-revoked', { cursor, limit: 10 }));
1854
2098
  expectError(rejected, 401, ErrorCode.SESSION_REVOKED, 'Post-revocation request');
1855
2099
  return { stream_terminated: true, subsequent_status: 401, subsequent_code: ErrorCode.SESSION_REVOKED };
1856
2100
  });
@@ -1873,13 +2117,14 @@ export async function runAdapterConformance(environment, options = {}) {
1873
2117
  const writer = await enrollParent('delete-writer', 'W', '704');
1874
2118
  const outsider = await enrollParent('delete-outsider', 'O', '705');
1875
2119
  await environment.admin.grantCreateCubeCapability(creator.principal);
1876
- const createResponse = await environment.operations.createCube(creator.credential, createProtocolEnvelope('delete-cube-create', {
2120
+ const deleteCubeRequest = {
1877
2121
  retry_key: '00000000-0000-4000-8000-000000000706',
1878
2122
  name: 'Disposable Cube',
1879
2123
  working_repo_name: 'disposable-cube',
1880
2124
  repository: { kind: 'local', value: '00000000-0000-4000-8000-000000000707' },
1881
- template: 'default',
1882
- }));
2125
+ template: 'software-dev',
2126
+ };
2127
+ const createResponse = await environment.operations.createCube(creator.credential, createProtocolEnvelope('delete-cube-create', deleteCubeRequest));
1883
2128
  expectStatus(createResponse, 201, 'Disposable cube creation');
1884
2129
  const created = decodeCreateCubeResponseEnvelope(createResponse.body).payload;
1885
2130
  const cube = { id: created.cube_id };
@@ -1889,6 +2134,14 @@ export async function runAdapterConformance(environment, options = {}) {
1889
2134
  await environment.admin.grantCube(writer.principal, cube, 'write');
1890
2135
  const drone = await environment.admin.createDrone(creator.principal, cube, role);
1891
2136
  const droneCredential = await environment.admin.issueManagedDroneSession(drone);
2137
+ const roleProbeSession = 'T'.repeat(43);
2138
+ const initialRoleProbe = await environment.operations.attach(manager.credential, createProtocolEnvelope('delete-role-shape-baseline', {
2139
+ cube_id: cube.id,
2140
+ role_id: role.id,
2141
+ session_credential: roleProbeSession,
2142
+ }));
2143
+ expectStatus(initialRoleProbe, 200, 'Deletion default-role shape baseline');
2144
+ const roleProbeDrone = decodeAttachResponseEnvelope(initialRoleProbe.body).payload.drone;
1892
2145
  const append = await environment.operations.append(creator.credential, cube, createProtocolEnvelope('delete-log', {
1893
2146
  post_id: '00000000-0000-4000-8000-000000000312',
1894
2147
  to: 'broadcast',
@@ -1898,16 +2151,45 @@ export async function runAdapterConformance(environment, options = {}) {
1898
2151
  const entry = decodeAppendLogResultEnvelope(append.body).payload.entry;
1899
2152
  expectStatus(await environment.operations.ack(creator.credential, cube, createProtocolEnvelope('delete-claim', { entry_id: entry.id, kind: 'claim' })), 204, 'Deletion fixture claim');
1900
2153
  expectStatus(await environment.operations.recordDecision(manager.credential, cube, createProtocolEnvelope('delete-decision', { topic: 'cleanup', decision: 'delete' })), 201, 'Deletion fixture decision');
1901
- const beforeDenied = await environment.admin.inspectCubeManagementState(cube);
2154
+ const readDenialState = async (label) => {
2155
+ const decisions = await environment.operations.listDecisions(manager.credential, cube, createProtocolEnvelope(`delete-${label}-decision-readback`, {}));
2156
+ expectStatus(decisions, 200, `${label} deletion decision readback`);
2157
+ const active = decodeDecisionsResultEnvelope(decisions.body).payload.decisions;
2158
+ const log = await environment.operations.read(manager.credential, cube, createProtocolEnvelope(`delete-${label}-log-readback`, { cursor: null, limit: 500 }));
2159
+ expectStatus(log, 200, `${label} deletion log readback`);
2160
+ const logPayload = decodeReadLogResultEnvelope(log.body).payload;
2161
+ const roster = await environment.operations.listDrones(manager.credential, cube);
2162
+ expectStatus(roster, 200, `${label} deletion roster readback`);
2163
+ const roleReadback = await environment.operations.attach(manager.credential, createProtocolEnvelope(`delete-${label}-role-readback`, {
2164
+ cube_id: cube.id,
2165
+ role_id: role.id,
2166
+ prior_drone_id: roleProbeDrone.id,
2167
+ session_credential: roleProbeSession,
2168
+ }));
2169
+ expectStatus(roleReadback, 200, `${label} deletion role readback`);
2170
+ const rolePayload = decodeAttachResponseEnvelope(roleReadback.body).payload.role;
2171
+ return {
2172
+ decisions: active,
2173
+ entries: logPayload.entries,
2174
+ claims: logPayload.claims,
2175
+ drone: listedDrone(roster, drone.id),
2176
+ role: rolePayload,
2177
+ };
2178
+ };
2179
+ const denialBaseline = await readDenialState('baseline');
2180
+ const assertDenialState = async (label) => {
2181
+ invariant(same(await readDenialState(label), denialBaseline), `${label} cube deletion denial mutated protocol-visible cube state.`);
2182
+ };
1902
2183
  for (const [kind, credential] of [
1903
2184
  ['read', reader.credential],
1904
2185
  ['write', writer.credential],
1905
2186
  ['drone-session', droneCredential],
1906
2187
  ]) {
1907
2188
  expectError(await environment.operations.deleteCube(credential, cube, createProtocolEnvelope(`delete-${kind}-denied`, {})), 403, ErrorCode.ACCESS_DENIED, `${kind} cube deletion`);
1908
- invariant(same(await environment.admin.inspectCubeManagementState(cube), beforeDenied), `${kind} cube deletion denial mutated the cube.`);
2189
+ await assertDenialState(kind);
1909
2190
  }
1910
2191
  expectError(await environment.operations.deleteCube(outsider.credential, cube, createProtocolEnvelope('delete-outsider-denied', {})), 404, ErrorCode.NOT_FOUND, 'Never-authorized cube deletion');
2192
+ await assertDenialState('outsider');
1911
2193
  const parentStream = await environment.operations.openStream(manager.credential, cube, null);
1912
2194
  const droneStream = await environment.operations.openStream(droneCredential, cube, null);
1913
2195
  expectStatus(parentStream, 200, 'Deletion parent stream');
@@ -1949,19 +2231,6 @@ export async function runAdapterConformance(environment, options = {}) {
1949
2231
  invariant(closed, 'Deleted cube stream yielded after its terminal error.');
1950
2232
  await streamReader.close();
1951
2233
  }
1952
- invariant(same(await environment.admin.inspectDeletedCube(cube), {
1953
- cube_exists: false,
1954
- role_count: 0,
1955
- drone_count: 0,
1956
- log_count: 0,
1957
- claim_count: 0,
1958
- decision_count: 0,
1959
- grant_count: 0,
1960
- cube_create_binding_count: 0,
1961
- repository_association_count: 0,
1962
- active_stream_count: 0,
1963
- terminal_credential_count: 5,
1964
- }), 'Cube deletion did not atomically remove cube-owned state and preserve only terminal credentials.');
1965
2234
  for (const [kind, credential] of [
1966
2235
  ['creator', creator.credential],
1967
2236
  ['manager', manager.credential],
@@ -1974,30 +2243,22 @@ export async function runAdapterConformance(environment, options = {}) {
1974
2243
  }
1975
2244
  expectError(await environment.operations.deleteCube(outsider.credential, cube, createProtocolEnvelope('delete-outsider-hidden-repeat', {})), 404, ErrorCode.NOT_FOUND, 'Never-authorized post-delete DELETE');
1976
2245
  expectError(await environment.operations.read(outsider.credential, cube, createProtocolEnvelope('delete-outsider-hidden', { cursor: null, limit: 1 })), 404, ErrorCode.NOT_FOUND, 'Never-authorized post-delete request');
1977
- await environment.admin.restartAuthority();
1978
- for (const [kind, credential] of [
1979
- ['creator', creator.credential],
1980
- ['manager', manager.credential],
1981
- ['reader', reader.credential],
1982
- ['writer', writer.credential],
1983
- ['drone', droneCredential],
1984
- ]) {
1985
- expectError(await environment.operations.read(credential, cube, createProtocolEnvelope(`delete-${kind}-after-restart`, { cursor: null, limit: 1 })), PROTOCOL_HTTP_CONTRACT.cube_deleted_status, ErrorCode.CUBE_DELETED, `${kind} post-restart deleted-cube request`);
1986
- expectError(await environment.operations.deleteCube(credential, cube, createProtocolEnvelope(`delete-${kind}-repeat-after-restart`, {})), PROTOCOL_HTTP_CONTRACT.cube_deleted_status, ErrorCode.CUBE_DELETED, `${kind} post-restart DELETE`);
1987
- }
1988
- expectError(await environment.operations.deleteCube(outsider.credential, cube, createProtocolEnvelope('delete-outsider-hidden-repeat-after-restart', {})), 404, ErrorCode.NOT_FOUND, 'Never-authorized post-restart DELETE');
1989
- expectError(await environment.operations.read(outsider.credential, cube, createProtocolEnvelope('delete-outsider-hidden-after-restart', { cursor: null, limit: 1 })), 404, ErrorCode.NOT_FOUND, 'Never-authorized post-restart request');
2246
+ const recreatedResponse = await environment.operations.createCube(creator.credential, createProtocolEnvelope('delete-cube-recreate', deleteCubeRequest));
2247
+ expectStatus(recreatedResponse, 201, 'Post-delete cube recreation');
2248
+ const recreated = decodeCreateCubeResponseEnvelope(recreatedResponse.body).payload;
2249
+ invariant(recreated.result === 'created' && recreated.cube_id !== cube.id, 'Post-delete recreation resolved retained cube-owned creation state.');
1990
2250
  return {
1991
2251
  deletion_status: 200,
1992
- cascade_complete: true,
1993
2252
  terminal_stream_error: ErrorCode.CUBE_DELETED,
1994
2253
  terminal_http_status: 410,
1995
- terminal_state_durable_after_restart: true,
1996
2254
  unknown_hidden_status: 404,
1997
2255
  non_member_manager: true,
2256
+ recreation_created_new_cube: true,
1998
2257
  };
1999
2258
  });
2000
- const normalizedTranscript = results.map(({ id, observations }) => ({ id, observations }));
2259
+ const normalizedTranscript = results
2260
+ .filter((result) => !result.skipped)
2261
+ .map(({ id, observations }) => ({ id, observations }));
2001
2262
  return { ok: results.every((result) => result.ok), results, normalizedTranscript };
2002
2263
  }
2003
2264
  //# sourceMappingURL=adapter.js.map