borgmcp-shared 1.0.1 → 1.2.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 +37 -8
  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 +546 -281
  7. package/dist/conformance/adapter.js.map +1 -1
  8. package/dist/conformance/index.d.ts +5 -42
  9. package/dist/conformance/index.d.ts.map +1 -1
  10. package/dist/conformance/index.js +16 -52
  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 +2 -2
  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.1.0.md +19 -0
  29. package/docs/releases/1.2.0.md +20 -0
  30. package/docs/releasing.md +13 -23
  31. package/package.json +1 -2
  32. package/src/conformance/adapter.ts +822 -640
  33. package/src/conformance/index.ts +24 -75
  34. package/src/protocol/contract.ts +2 -2
  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 -261
@@ -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,85 @@ 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
+ expectError(await environment.operations.createCube(ownerCredential, createProtocolEnvelope('cube-case-variant-duplicate', {
399
+ ...cubeRequest,
400
+ retry_key: '00000000-0000-4000-8000-000000000214',
401
+ name: 'repository one',
402
+ repository: {
403
+ kind: 'origin',
404
+ value: 'https://github.com/Byte-Ventures/repository-one-case-variant',
405
+ },
406
+ })), 409, ErrorCode.INVALID_INPUT, 'Same-owner case-variant cube name');
407
+ const createdRoleProbes = new Map();
408
+ for (const [kind, roleId, roleClass, isHumanSeat, marker] of [
409
+ ['human-seat', created.human_seat_role_id, 'queen', true, 'H'],
410
+ ['default-worker', created.default_worker_role_id, 'worker', false, 'D'],
411
+ ]) {
412
+ const sessionCredential = marker.repeat(43);
413
+ const attached = await environment.operations.attach(ownerCredential, createProtocolEnvelope(`cube-create-${kind}-probe`, {
414
+ cube_id: created.cube_id,
415
+ role_id: roleId,
416
+ session_credential: sessionCredential,
417
+ }));
418
+ expectStatus(attached, 200, `Created ${kind} role probe`);
419
+ const attachedPayload = decodeAttachResponseEnvelope(attached.body).payload;
420
+ const attachedRole = attachedPayload.role;
421
+ invariant(attachedRole.id === roleId &&
422
+ attachedRole.role_class === roleClass &&
423
+ attachedRole.is_human_seat === isHumanSeat, `Created ${kind} role identity did not match its protocol role.`);
424
+ createdRoleProbes.set(kind, {
425
+ role: attachedRole,
426
+ droneId: attachedPayload.drone.id,
427
+ sessionCredential,
428
+ });
429
+ }
367
430
  const retriedCreateResponse = await environment.operations.createCube(ownerCredential, createProtocolEnvelope('cube-retry', cubeRequest));
368
431
  expectStatus(retriedCreateResponse, 201, 'Exact cube-create retry');
369
432
  const retriedCreate = decodeCreateCubeResponseEnvelope(retriedCreateResponse.body).payload;
370
433
  invariant(retriedCreate.result === 'resolved', 'Exact cube-create retry did not report resolved readback.');
371
434
  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
435
  const displayRetryVector = CREATE_CUBE_RETRY_CONFORMANCE.find((vector) => vector.expected.outcome === 'resolved_response' &&
374
436
  vector.retry.working_repo_name !== vector.initial.working_repo_name);
375
437
  invariant(displayRetryVector !== undefined, 'Missing repository display readback vector.');
376
- const beforeDisplayRetry = await environment.admin.observeAuthorityState();
377
438
  const displayRetryResponse = await environment.operations.createCube(ownerCredential, createProtocolEnvelope('cube-display-retry', {
378
439
  ...displayRetryVector.retry,
379
440
  retry_key: cubeRequest.retry_key,
380
441
  }));
381
442
  expectStatus(displayRetryResponse, 201, 'Changed repository display retry');
382
443
  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
444
  for (const [index, vector] of CREATE_CUBE_RETRY_CONFORMANCE.entries()) {
385
445
  if (vector.expected.outcome !== 'retry_tuple_mismatch')
386
446
  continue;
387
447
  const mismatch = { ...vector.retry, retry_key: cubeRequest.retry_key };
388
- const beforeCreateMismatch = await environment.admin.observeAuthorityState();
389
448
  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}`);
449
+ }
450
+ for (const [kind, roleId] of [
451
+ ['human-seat', created.human_seat_role_id],
452
+ ['default-worker', created.default_worker_role_id],
453
+ ]) {
454
+ const initialProbe = createdRoleProbes.get(kind);
455
+ invariant(initialProbe !== undefined, `Missing initial ${kind} role probe.`);
456
+ const attached = await environment.operations.attach(ownerCredential, createProtocolEnvelope(`cube-create-${kind}-post-refusal-probe`, {
457
+ cube_id: created.cube_id,
458
+ role_id: roleId,
459
+ session_credential: initialProbe.sessionCredential,
460
+ prior_drone_id: initialProbe.droneId,
461
+ }));
462
+ expectStatus(attached, 200, `Post-refusal ${kind} role probe`);
463
+ invariant(same(decodeAttachResponseEnvelope(attached.body).payload.role, initialProbe.role), `Cube-create retry refusal changed the full ${kind} role shape.`);
391
464
  }
392
465
  const sameAssociationVector = CREATE_CUBE_ASSOCIATION_CONFORMANCE.find((vector) => vector.expected.outcome === 'resolved');
393
466
  invariant(sameAssociationVector !== undefined, 'Missing same-repository association vector.');
394
- const beforeAssociationResolve = await environment.admin.observeAuthorityState();
395
467
  const associationResolveResponse = await environment.operations.createCube(ownerCredential, createProtocolEnvelope('cube-association-resolve', {
396
468
  ...sameAssociationVector.request,
397
469
  repository: cubeRequest.repository,
@@ -400,7 +472,6 @@ export async function runAdapterConformance(environment, options = {}) {
400
472
  const associationResolved = decodeCreateCubeResponseEnvelope(associationResolveResponse.body).payload;
401
473
  invariant(associationResolved.result === 'resolved', 'Associated repository did not resolve.');
402
474
  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
475
  await environment.admin.grantCreateCubeCapability(ordinaryPrincipal);
405
476
  const crossClientRequest = {
406
477
  ...cubeRequest,
@@ -410,35 +481,49 @@ export async function runAdapterConformance(environment, options = {}) {
410
481
  value: '00000000-0000-4000-8000-000000000216',
411
482
  },
412
483
  };
413
- const beforeCrossClientCreate = await environment.admin.observeAuthorityState();
414
484
  const crossClientResponse = await environment.operations.createCube(ordinaryCredential, createProtocolEnvelope('cube-cross-client', crossClientRequest));
415
485
  expectStatus(crossClientResponse, 201, 'Cross-client cube create with reused retry key');
416
486
  const crossClientCreated = decodeCreateCubeResponseEnvelope(crossClientResponse.body).payload;
417
487
  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();
488
+ for (const [kind, roleId, originalRoleId, marker] of [
489
+ ['human-seat', crossClientCreated.human_seat_role_id, created.human_seat_role_id, 'V'],
490
+ ['default-worker', crossClientCreated.default_worker_role_id, created.default_worker_role_id, 'W'],
491
+ ]) {
492
+ const originalProbe = createdRoleProbes.get(kind);
493
+ invariant(originalProbe !== undefined, `Missing original ${kind} role probe.`);
494
+ const attached = await environment.operations.attach(ordinaryCredential, createProtocolEnvelope(`cube-cross-client-${kind}-probe`, {
495
+ cube_id: crossClientCreated.cube_id,
496
+ role_id: roleId,
497
+ session_credential: marker.repeat(43),
498
+ }));
499
+ expectStatus(attached, 200, `Cross-client ${kind} role probe`);
500
+ const attachedRole = decodeAttachResponseEnvelope(attached.body).payload.role;
501
+ invariant(same({ ...attachedRole, id: originalRoleId }, originalProbe.role), `Cross-client ${kind} role did not match the full template role shape.`);
502
+ }
421
503
  const crossClientRetry = await environment.operations.createCube(ordinaryCredential, createProtocolEnvelope('cube-cross-client-retry', crossClientRequest));
422
504
  expectStatus(crossClientRetry, 201, 'Exact cross-client cube-create retry');
423
505
  const crossClientResolved = decodeCreateCubeResponseEnvelope(crossClientRetry.body).payload;
424
506
  invariant(crossClientResolved.result === 'resolved', 'Exact cross-client cube-create retry did not report resolved readback.');
425
507
  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
508
  const differentAssociationVector = CREATE_CUBE_ASSOCIATION_CONFORMANCE.find((vector) => vector.expected.outcome === 'created');
428
509
  invariant(differentAssociationVector !== undefined, 'Missing different-repository association vector.');
429
- const beforeSecondCreate = await environment.admin.observeAuthorityState();
430
510
  const secondCreatedResponse = await environment.operations.createCube(ownerCredential, createProtocolEnvelope('cube-create-second', differentAssociationVector.request));
431
511
  expectStatus(secondCreatedResponse, 201, 'Second cube create');
432
512
  const secondCreated = decodeCreateCubeResponseEnvelope(secondCreatedResponse.body).payload;
433
513
  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
514
  await environment.admin.revokePrincipal(ownerPrincipal);
436
- const beforeRevokedCreate = await environment.admin.observeAuthorityState();
437
515
  expectSecretFreeError(await environment.operations.createCube(ownerCredential, createProtocolEnvelope('cube-revoked', {
438
516
  ...cubeRequest,
439
517
  retry_key: '00000000-0000-4000-8000-000000000215',
440
518
  })), 401, ErrorCode.SESSION_REVOKED, 'Revoked owner cube create', ['00000000-0000-4000-8000-000000000215']);
441
- assertStateDelta(beforeRevokedCreate, await environment.admin.observeAuthorityState(), {}, 'Revoked owner cube create');
519
+ return {
520
+ enrollment_status: 201,
521
+ exact_retry_status: 201,
522
+ mismatched_retry: ErrorCode.AUTH_INVALID,
523
+ response_secret_free: true,
524
+ };
525
+ });
526
+ try {
442
527
  await environment.admin.reset();
443
528
  principalA = await environment.admin.createPrincipal('principal-a');
444
529
  principalB = await environment.admin.createPrincipal('principal-b');
@@ -450,42 +535,24 @@ export async function runAdapterConformance(environment, options = {}) {
450
535
  const invitationB = await environment.admin.issueSingleUseInvitation(principalB, 'client');
451
536
  credentialA = 'A'.repeat(43);
452
537
  credentialB = 'E'.repeat(43);
453
- const enrollmentARequest = createProtocolEnvelope('enroll-a1', {
538
+ const enrolledAResponse = await environment.operations.enroll(createProtocolEnvelope('enroll-a1', {
454
539
  invitation: invitationA,
455
540
  retry_key: '00000000-0000-4000-8000-000000000201',
456
541
  client_credential: credentialA,
457
542
  client_name: 'conformance-a',
458
- });
459
- const enrollmentBRequest = createProtocolEnvelope('enroll-b1', {
543
+ }));
544
+ const enrolledBResponse = await environment.operations.enroll(createProtocolEnvelope('enroll-b1', {
460
545
  invitation: invitationB,
461
546
  retry_key: '00000000-0000-4000-8000-000000000202',
462
547
  client_credential: credentialB,
463
548
  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
- });
549
+ }));
550
+ expectStatus(enrolledAResponse, 201, 'Shared principal A enrollment');
551
+ expectStatus(enrolledBResponse, 201, 'Shared principal B enrollment');
552
+ }
553
+ catch (error) {
554
+ prerequisiteFailures.set('shared.enrolled-principals', error instanceof Error ? error.message : String(error));
555
+ }
489
556
  await record('repository.explicit-association', async () => {
490
557
  const repository = {
491
558
  kind: 'origin',
@@ -499,16 +566,24 @@ export async function runAdapterConformance(environment, options = {}) {
499
566
  working_repo_name: 'legacy-repository',
500
567
  repository,
501
568
  };
502
- const beforeNone = await environment.admin.observeAuthorityState();
569
+ const alternateResolveRequest = {
570
+ working_repo_name: 'other-repository',
571
+ repository: {
572
+ kind: 'origin',
573
+ value: 'https://github.com/Byte-Ventures/other-repository',
574
+ },
575
+ };
576
+ const resolve = async (requestId, request) => {
577
+ const response = await environment.operations.resolveRepositoryCube(credentialA, createProtocolEnvelope(requestId, request));
578
+ expectStatus(response, 200, requestId);
579
+ return decodeResolveRepositoryCubeResponseEnvelope(response.body).payload;
580
+ };
503
581
  const noneResponse = await environment.operations.resolveRepositoryCube(credentialA, createProtocolEnvelope('repository-resolve-none', resolveRequest));
504
582
  expectStatus(noneResponse, 200, 'Unassociated repository resolution');
505
583
  invariant(same(decodeResolveRepositoryCubeResponseEnvelope(noneResponse.body).payload, { result: 'none' }), 'Unassociated repository did not return explicit none.');
506
- assertStateDelta(beforeNone, await environment.admin.observeAuthorityState(), {}, 'Repository resolution');
584
+ invariant(same(await resolve('repository-resolve-none-readback', resolveRequest), { result: 'none' }), 'Read-only repository resolution created an association.');
507
585
  const associationRequest = { cube_id: cubeA.id, ...resolveRequest };
508
- const beforeDenied = await environment.admin.observeAuthorityState();
509
586
  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
587
  const associatedResponse = await environment.operations.associateRepositoryCube(credentialA, createProtocolEnvelope('repository-associate', associationRequest));
513
588
  expectStatus(associatedResponse, 200, 'Explicit repository cube association');
514
589
  const associated = decodeAssociateRepositoryCubeResponseEnvelope(associatedResponse.body).payload;
@@ -524,52 +599,42 @@ export async function runAdapterConformance(environment, options = {}) {
524
599
  access: prepared.access,
525
600
  };
526
601
  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
602
  const resolvedResponse = await environment.operations.resolveRepositoryCube(credentialA, createProtocolEnvelope('repository-resolve', {
530
603
  ...resolveRequest,
531
604
  working_repo_name: 'ignored-new-display',
532
605
  }));
533
606
  expectStatus(resolvedResponse, 200, 'Associated repository resolution');
534
607
  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
608
  const retryResponse = await environment.operations.associateRepositoryCube(credentialA, createProtocolEnvelope('repository-associate-retry', associationRequest));
538
609
  expectStatus(retryResponse, 200, 'Exact repository association retry');
539
610
  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
611
  const cubeC = await environment.admin.createCube('cube-c');
542
612
  await environment.admin.grantCube(principalA, cubeC);
543
613
  await environment.admin.prepareRepositoryCube(cubeC, {
544
614
  name: 'Other Legacy Cube',
545
615
  template: 'starter',
546
616
  });
547
- const beforeRepositoryConflict = await environment.admin.observeAuthorityState();
548
617
  expectSecretFreeError(await environment.operations.associateRepositoryCube(credentialA, createProtocolEnvelope('repository-associate-repository-conflict', {
549
618
  ...associationRequest,
550
619
  cube_id: cubeC.id,
551
620
  })), 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();
554
- expectSecretFreeError(await environment.operations.associateRepositoryCube(credentialA, createProtocolEnvelope('repository-associate-cube-conflict', {
621
+ invariant(same(await resolve('repository-resolve-after-repository-conflict', resolveRequest), authoritative), 'Repository conflict changed the authoritative original binding.');
622
+ invariant(same(await resolve('repository-resolve-alternate-after-repository-conflict', alternateResolveRequest), { result: 'none' }), 'Repository conflict created an alternate binding.');
623
+ const alternateAssociationResponse = await environment.operations.associateRepositoryCube(credentialA, createProtocolEnvelope('repository-associate-second-repository', {
555
624
  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
- },
561
- })), 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');
625
+ ...alternateResolveRequest,
626
+ }));
627
+ expectStatus(alternateAssociationResponse, 200, 'Second repository association');
628
+ const alternateAuthoritative = decodeAssociateRepositoryCubeResponseEnvelope(alternateAssociationResponse.body).payload;
629
+ invariant(same(await resolve('repository-resolve-after-second-association', resolveRequest), authoritative), 'Second repository association changed the authoritative original binding.');
630
+ invariant(same(await resolve('repository-resolve-alternate-after-second-association', alternateResolveRequest), alternateAuthoritative), 'Second repository association was not observable.');
563
631
  const preparedB = await environment.admin.prepareRepositoryCube(cubeB, {
564
632
  name: 'Other Client Legacy Cube',
565
633
  template: 'starter',
566
634
  });
567
- const beforeCrossClientResolve = await environment.admin.observeAuthorityState();
568
635
  const crossClientResolve = await environment.operations.resolveRepositoryCube(credentialB, createProtocolEnvelope('repository-resolve-cross-client', resolveRequest));
569
636
  expectStatus(crossClientResolve, 200, 'Cross-client repository resolution');
570
637
  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
638
  const crossClientAssociation = await environment.operations.associateRepositoryCube(credentialB, createProtocolEnvelope('repository-associate-cross-client', {
574
639
  ...associationRequest,
575
640
  cube_id: cubeB.id,
@@ -578,26 +643,26 @@ export async function runAdapterConformance(environment, options = {}) {
578
643
  const crossClientAssociated = decodeAssociateRepositoryCubeResponseEnvelope(crossClientAssociation.body).payload;
579
644
  invariant(crossClientAssociated.cube_id === preparedB.cube_id &&
580
645
  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
646
  await environment.admin.revokeCubeGrant(principalA, cubeA);
583
- const beforeHiddenResolve = await environment.admin.observeAuthorityState();
584
647
  const hiddenResolve = await environment.operations.resolveRepositoryCube(credentialA, createProtocolEnvelope('repository-resolve-inaccessible-binding', resolveRequest));
585
648
  expectStatus(hiddenResolve, 200, 'Inaccessible repository binding resolution');
586
649
  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
650
  expectSecretFreeError(await environment.operations.associateRepositoryCube(credentialA, createProtocolEnvelope('repository-associate-inaccessible-binding', {
590
651
  ...associationRequest,
591
652
  cube_id: cubeC.id,
592
653
  })), 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');
654
+ const hiddenAfterRefusal = await resolve('repository-resolve-after-inaccessible-refusal', resolveRequest);
655
+ const alternateAfterRefusal = await resolve('repository-resolve-alternate-after-inaccessible-refusal', alternateResolveRequest);
594
656
  await environment.admin.grantCube(principalA, cubeA);
657
+ invariant(same(hiddenAfterRefusal, { result: 'none' }), 'Inaccessible-binding refusal changed the hidden authoritative binding.');
658
+ invariant(same(alternateAfterRefusal, { result: 'none' }), 'Inaccessible-binding refusal created an alternate binding.');
659
+ invariant(same(await resolve('repository-resolve-restored-after-inaccessible-refusal', resolveRequest), authoritative), 'Inaccessible-binding refusal did not preserve the original binding.');
595
660
  return {
596
661
  none: true,
597
662
  resolved: true,
598
663
  idempotent: true,
599
664
  repository_conflict: ErrorCode.REPOSITORY_ALREADY_ASSOCIATED,
600
- cube_conflict: ErrorCode.CUBE_ALREADY_ASSOCIATED,
665
+ multiple_repositories_per_cube: true,
601
666
  inaccessible: ErrorCode.ACCESS_DENIED,
602
667
  inaccessible_binding_hidden: true,
603
668
  cross_client_binding_hidden: true,
@@ -890,12 +955,10 @@ export async function runAdapterConformance(environment, options = {}) {
890
955
  });
891
956
  const recipient = await environment.admin.createDrone(principalA, cube, role);
892
957
  const message = 'START NOW exact slice';
893
- const before = await environment.admin.observeAuthorityState();
894
958
  expectError(await environment.operations.append(credentialA, cube, createProtocolEnvelope('mandatory-addressing-omitted', {
895
959
  post_id: '30000000-0000-4000-8000-000000000001',
896
960
  message,
897
961
  })), 400, ErrorCode.INVALID_INPUT, 'Omitted mandatory addressing');
898
- assertStateDelta(before, await environment.admin.observeAuthorityState(), {}, 'Mandatory-addressing refusal');
899
962
  const broadcast = await environment.operations.append(credentialA, cube, createProtocolEnvelope('mandatory-addressing-broadcast', {
900
963
  post_id: '30000000-0000-4000-8000-000000000002',
901
964
  message,
@@ -916,6 +979,10 @@ export async function runAdapterConformance(environment, options = {}) {
916
979
  invariant(directedResult.entry.visibility === 'direct', 'Explicit recipient selectors did not produce direct visibility.');
917
980
  invariant(directedResult.entry.recipient_drone_ids?.includes(recipient.id) === true, 'Explicit recipient selectors did not resolve the named recipient.');
918
981
  invariant(directedResult.entry.recipient_drone_ids?.length === 1, 'Classification changed or fell open the explicit recipient set.');
982
+ const readback = await environment.operations.read(credentialA, cube, createProtocolEnvelope('mandatory-addressing-readback', { cursor: null, limit: 10 }));
983
+ expectStatus(readback, 200, 'Mandatory-addressing persistence readback');
984
+ const persistedIds = decodeReadLogResultEnvelope(readback.body).payload.entries.map((entry) => entry.id);
985
+ invariant(same(persistedIds, [broadcastResult.entry.id, directedResult.entry.id]), 'Rejected mandatory-addressing append was persisted.');
919
986
  return { refused_status: 400, code: ErrorCode.INVALID_INPUT, persisted: false, broadcast: true, union: true, no_fall_open: true };
920
987
  });
921
988
  await record('log.entry-query', async () => {
@@ -936,6 +1003,7 @@ export async function runAdapterConformance(environment, options = {}) {
936
1003
  '22222222-0000-4000-8000-000000000002',
937
1004
  ];
938
1005
  const entries = [];
1006
+ const idSeeds = [];
939
1007
  for (const [index, id] of ids.entries()) {
940
1008
  const response = await environment.operations.append(credentialA, cube, createProtocolEnvelope(`entry-query-append-${index}`, {
941
1009
  post_id: `40000000-0000-4000-8000-00000000000${index}`,
@@ -944,12 +1012,12 @@ export async function runAdapterConformance(environment, options = {}) {
944
1012
  }));
945
1013
  expectStatus(response, 201, `Entry-query fixture append ${index}`);
946
1014
  const entry = decodeAppendLogResultEnvelope(response.body).payload.entry;
947
- await environment.admin.replaceLogEntryId(cube, entry.id, id);
1015
+ idSeeds.push({ current_id: entry.id, query_id: id });
948
1016
  entries.push({ ...entry, id });
949
1017
  }
1018
+ await environment.admin.seedEntryQueryIds(cube, idSeeds);
950
1019
  expectStatus(await environment.operations.ack(acknowledgedCredential, cube, createProtocolEnvelope('entry-query-seed-ack', { entry_id: ids[0], kind: 'ack' })), 204, 'Entry-query acknowledgement seed');
951
1020
  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
1021
  for (const [requestId, selector, expectedId] of [
954
1022
  ['entry-query-full', ids[1], ids[1]],
955
1023
  ['entry-query-prefix', '11111111', ids[0]],
@@ -961,15 +1029,19 @@ export async function runAdapterConformance(environment, options = {}) {
961
1029
  }
962
1030
  expectError(await environment.operations.entryQuery(credentialA, cube, createProtocolEnvelope('entry-query-unknown', { entry_id: 'ffffffff' })), 404, ErrorCode.NOT_FOUND, 'Unknown entry query');
963
1031
  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
1032
  const acknowledgementStatus = decodeAckStatusResultEnvelope((await environment.operations.ackStatus(credentialA, cube, createProtocolEnvelope('entry-query-ack-status', { entry_id: ids[0] }))).body).payload;
966
1033
  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.');
1034
+ const acknowledgedRecipients = acknowledgementStatus.recipients.filter((recipient) => recipient.acknowledged_at !== null);
1035
+ invariant(acknowledgedRecipients.length === 1 &&
1036
+ acknowledgedRecipients[0].drone_id === acknowledgedRecipient.id &&
1037
+ acknowledgementStatus.recipients.find((recipient) => recipient.drone_id === claimingRecipient.id)?.acknowledged_at === null, 'Entry query changed the seeded acknowledgement set.');
1038
+ invariant(claimStatus.claims.length === 1 &&
1039
+ claimStatus.claims[0].drone_id === claimingRecipient.id &&
1040
+ claimStatus.recipients.every((recipient) => recipient.acknowledged_at === null), 'Entry query changed the seeded claim or acknowledgement set.');
969
1041
  const unreadResponse = await environment.operations.read(credentialA, cube, createProtocolEnvelope('entry-query-unread', { cursor: null, limit: 10 }));
970
1042
  expectStatus(unreadResponse, 200, 'Entry-query unread read');
971
1043
  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.');
1044
+ invariant(same(unread.entries, entries), 'Entry query mutated, consumed, or advanced unread activity.');
973
1045
  return {
974
1046
  full_uuid: true,
975
1047
  unique_prefix: true,
@@ -981,9 +1053,8 @@ export async function runAdapterConformance(environment, options = {}) {
981
1053
  mutation: 'none',
982
1054
  };
983
1055
  });
984
- const entries = [];
985
- let readCursor = null;
986
1056
  await record('log.read-cursor-tuple', async () => {
1057
+ const entries = [];
987
1058
  for (const [index, message] of ['alpha', 'beta', 'gamma'].entries()) {
988
1059
  const response = await environment.operations.append(credentialA, cubeA, createProtocolEnvelope(`append-a${index + 1}`, {
989
1060
  post_id: `00000000-0000-4000-8000-${String(305 + index).padStart(12, '0')}`,
@@ -1001,18 +1072,32 @@ export async function runAdapterConformance(environment, options = {}) {
1001
1072
  invariant(page.has_more && page.behind_by === 1, 'Read pagination metadata is incorrect.');
1002
1073
  invariant(page.cursor !== null, 'Read did not return a cursor.');
1003
1074
  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
1075
  return { messages: ['alpha', 'beta'], has_more: true, behind_by: 1, cursor_matches_last_entry: true };
1006
1076
  });
1007
- let liveCursor = null;
1008
1077
  await record('sse.replay-live-transition', async () => {
1009
- invariant(readCursor, 'Cursor fixture did not produce a cursor.');
1078
+ const principal = await environment.admin.createPrincipal('stream-transition');
1079
+ const cube = await environment.admin.createCube('stream-transition');
1080
+ await environment.admin.grantCube(principal, cube);
1081
+ const credential = await environment.admin.issueDroneSession(principal);
1082
+ let readCursor;
1083
+ for (const [index, message] of ['alpha', 'beta', 'gamma'].entries()) {
1084
+ const response = await environment.operations.append(credential, cube, createProtocolEnvelope(`stream-transition-${message}`, {
1085
+ post_id: `00000000-0000-4000-8000-${String(316 + index).padStart(12, '0')}`,
1086
+ to: 'broadcast',
1087
+ message,
1088
+ }));
1089
+ expectStatus(response, 201, `Stream transition append ${message}`);
1090
+ if (message === 'beta') {
1091
+ const entry = decodeAppendLogResultEnvelope(response.body).payload.entry;
1092
+ readCursor = { id: entry.id, created_at: entry.created_at };
1093
+ }
1094
+ }
1010
1095
  const barrier = environment.admin.armReplayTransition();
1011
- const openPromise = environment.operations.openStream(credentialA, cubeA, readCursor);
1096
+ const openPromise = environment.operations.openStream(credential, cube, readCursor);
1012
1097
  await within(barrier.reached, 'Replay transition boundary', streamDeadlineMs);
1013
1098
  try {
1014
- const appendDelta = environment.operations.append(credentialA, cubeA, createProtocolEnvelope('append-a4', {
1015
- post_id: '00000000-0000-4000-8000-000000000308',
1099
+ const appendDelta = environment.operations.append(credential, cube, createProtocolEnvelope('stream-transition-delta', {
1100
+ post_id: '00000000-0000-4000-8000-000000000319',
1016
1101
  to: 'broadcast',
1017
1102
  message: 'delta',
1018
1103
  }));
@@ -1036,8 +1121,8 @@ export async function runAdapterConformance(environment, options = {}) {
1036
1121
  invariant(bookmark.type === 'bookmark' && bookmark.replay_complete, 'Stream omitted its replay-complete bookmark.');
1037
1122
  const noDuplicate = reader.next();
1038
1123
  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',
1124
+ const epsilonResponse = await environment.operations.append(credential, cube, createProtocolEnvelope('stream-transition-epsilon', {
1125
+ post_id: '00000000-0000-4000-8000-000000000320',
1041
1126
  to: 'broadcast',
1042
1127
  message: 'epsilon',
1043
1128
  }));
@@ -1046,7 +1131,6 @@ export async function runAdapterConformance(environment, options = {}) {
1046
1131
  invariant(epsilon.entry.message === 'epsilon', 'Live stream duplicated or reordered an event.');
1047
1132
  invariant(compareLogCursor(delta.cursor, epsilon.cursor) < 0, 'Live stream cursors are not ordered.');
1048
1133
  invariant(new Set([replay.entry.id, delta.entry.id, epsilon.entry.id]).size === 3, 'Stream delivered a duplicate entry.');
1049
- liveCursor = epsilon.cursor;
1050
1134
  return { replay: ['gamma'], transition: 'bookmark', live: ['delta', 'epsilon'], duplicates: 0 };
1051
1135
  }
1052
1136
  finally {
@@ -1054,20 +1138,37 @@ export async function runAdapterConformance(environment, options = {}) {
1054
1138
  }
1055
1139
  });
1056
1140
  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 }));
1141
+ const cube = await environment.admin.createCube('cursor-expiry');
1142
+ await environment.admin.grantCube(principalA, cube);
1143
+ const appended = await environment.operations.append(credentialA, cube, createProtocolEnvelope('cursor-expiry-entry', {
1144
+ post_id: '00000000-0000-4000-8000-000000000321',
1145
+ to: 'broadcast',
1146
+ message: 'expire this cursor',
1147
+ }));
1148
+ expectStatus(appended, 201, 'Cursor expiry fixture append');
1149
+ const entry = decodeAppendLogResultEnvelope(appended.body).payload.entry;
1150
+ const cursor = { id: entry.id, created_at: entry.created_at };
1151
+ await environment.admin.expireCursor(cube, cursor);
1152
+ const response = await environment.operations.read(credentialA, cube, createProtocolEnvelope('read-expired', { cursor, limit: 10 }));
1060
1153
  expectError(response, 410, ErrorCode.CURSOR_EXPIRED, 'Expired cursor read');
1061
- const stream = await environment.operations.openStream(credentialA, cubeA, readCursor);
1154
+ const stream = await environment.operations.openStream(credentialA, cube, cursor);
1062
1155
  expectError(stream, 410, ErrorCode.CURSOR_EXPIRED, 'Expired cursor stream');
1063
1156
  invariant(stream.stream === null, 'Expired cursor stream exposed a body stream.');
1064
1157
  return { read_status: 410, stream_status: 410, code: ErrorCode.CURSOR_EXPIRED };
1065
1158
  });
1066
1159
  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);
1160
+ const cube = await environment.admin.createCube('ack-idempotency');
1161
+ await environment.admin.grantCube(principalA, cube);
1162
+ const appended = await environment.operations.append(credentialA, cube, createProtocolEnvelope('ack-idempotency-entry', {
1163
+ post_id: '00000000-0000-4000-8000-000000000322',
1164
+ to: 'broadcast',
1165
+ message: 'acknowledge this entry',
1166
+ }));
1167
+ expectStatus(appended, 201, 'Acknowledgement fixture append');
1168
+ const entry = decodeAppendLogResultEnvelope(appended.body).payload.entry;
1169
+ const request = createProtocolEnvelope('ack-entry1', { entry_id: entry.id, kind: 'ack' });
1170
+ const first = await environment.operations.ack(credentialA, cube, request);
1171
+ const second = await environment.operations.ack(credentialA, cube, request);
1071
1172
  expectStatus(first, 204, 'First acknowledgement');
1072
1173
  expectStatus(second, 204, 'Repeated acknowledgement');
1073
1174
  invariant((first.body === '' || first.body === undefined) && (second.body === '' || second.body === undefined), 'Acknowledgement responses must be bodyless.');
@@ -1092,7 +1193,6 @@ export async function runAdapterConformance(environment, options = {}) {
1092
1193
  }));
1093
1194
  expectStatus(append, 201, 'Acknowledgement-status fixture append');
1094
1195
  const entry = decodeAppendLogResultEnvelope(append.body).payload.entry;
1095
- const beforeMissing = await environment.admin.observeAuthorityState();
1096
1196
  const missingResponse = await environment.operations.ackStatus(credentialA, cube, createProtocolEnvelope('ack-status-missing', { entry_id: entry.id }));
1097
1197
  expectStatus(missingResponse, 200, 'Missing acknowledgement status');
1098
1198
  const missing = decodeAckStatusResultEnvelope(missingResponse.body).payload;
@@ -1100,10 +1200,8 @@ export async function runAdapterConformance(environment, options = {}) {
1100
1200
  missing.recipients.length === 2 &&
1101
1201
  missing.recipients.every((recipient) => recipient.acknowledged_at === null) &&
1102
1202
  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
1203
  expectStatus(await environment.operations.ack(acknowledgedCredential, cube, createProtocolEnvelope('ack-status-ack', { entry_id: entry.id, kind: 'ack' })), 204, 'Acknowledgement-status acknowledgement');
1105
1204
  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
1205
  const distinctResponse = await environment.operations.ackStatus(credentialA, cube, createProtocolEnvelope('ack-status-distinct', { entry_id: entry.id }));
1108
1206
  expectStatus(distinctResponse, 200, 'Distinct acknowledgement and claim status');
1109
1207
  const distinct = decodeAckStatusResultEnvelope(distinctResponse.body).payload;
@@ -1113,16 +1211,13 @@ export async function runAdapterConformance(environment, options = {}) {
1113
1211
  distinct.claims.length === 1 &&
1114
1212
  distinct.claims[0].drone_id === claimingRecipient.id &&
1115
1213
  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
1214
  expectError(await environment.operations.ackStatus(credentialA, cube, createProtocolEnvelope('ack-status-unknown', {
1123
1215
  entry_id: '00000000-0000-4000-8000-000000000311',
1124
1216
  })), 404, ErrorCode.NOT_FOUND, 'Unknown acknowledgement-status entry');
1125
- assertStateDelta(beforeUnknown, await environment.admin.observeAuthorityState(), {}, 'Unknown acknowledgement status query');
1217
+ const unreadResponse = await environment.operations.read(credentialA, cube, createProtocolEnvelope('ack-status-unread', { cursor: null, limit: 10 }));
1218
+ expectStatus(unreadResponse, 200, 'Post-query unread read');
1219
+ const unread = decodeReadLogResultEnvelope(unreadResponse.body).payload;
1220
+ invariant(same(unread.entries, [entry]), 'Acknowledgement-status query mutated or advanced unread delivery state.');
1126
1221
  return {
1127
1222
  missing_acknowledgement: null,
1128
1223
  acknowledgements: 1,
@@ -1133,15 +1228,26 @@ export async function runAdapterConformance(environment, options = {}) {
1133
1228
  };
1134
1229
  });
1135
1230
  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' }));
1231
+ const principal = await environment.admin.createPrincipal('claim-noncursor');
1232
+ const cube = await environment.admin.createCube('claim-noncursor');
1233
+ await environment.admin.grantCube(principal, cube);
1234
+ const credential = await environment.admin.issueDroneSession(principal);
1235
+ const appended = await environment.operations.append(credential, cube, createProtocolEnvelope('claim-fixture-entry', {
1236
+ post_id: '00000000-0000-4000-8000-000000000314',
1237
+ to: 'broadcast',
1238
+ message: 'claim cursor baseline',
1239
+ }));
1240
+ expectStatus(appended, 201, 'Claim fixture append');
1241
+ const entry = decodeAppendLogResultEnvelope(appended.body).payload.entry;
1242
+ const baselineCursor = { id: entry.id, created_at: entry.created_at };
1243
+ const claim = await environment.operations.ack(credential, cube, createProtocolEnvelope('claim-fixture-claim', { entry_id: entry.id, kind: 'claim' }));
1138
1244
  expectStatus(claim, 204, 'Claim');
1139
- const read = await environment.operations.read(credentialA, cubeA, createProtocolEnvelope('read-claims', { cursor: liveCursor, limit: 10 }));
1245
+ const read = await environment.operations.read(credential, cube, createProtocolEnvelope('claim-fixture-readback', { cursor: baselineCursor, limit: 10 }));
1140
1246
  expectStatus(read, 200, 'Claim-state read');
1141
1247
  const page = decodeReadLogResultEnvelope(read.body).payload;
1142
1248
  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.');
1249
+ invariant(page.cursor !== null && compareLogCursor(page.cursor, baselineCursor) === 0, 'Claim advanced the log cursor.');
1250
+ invariant(page.claims.some((item) => item.log_entry_id === entry.id), 'Claim was not durable in a later read.');
1145
1251
  return { durable_claims: 1, entries: 0, cursor_advanced: false };
1146
1252
  });
1147
1253
  await record('decisions.topic-supersession', async () => {
@@ -1168,6 +1274,7 @@ export async function runAdapterConformance(environment, options = {}) {
1168
1274
  let metadataDroneB;
1169
1275
  let metadataSessionA = '';
1170
1276
  await record('security.drone-management-authorization', async () => {
1277
+ const observationCredential = await environment.admin.issueDroneSession(principalA);
1171
1278
  workerRoleA = await environment.admin.createRole(cubeA, {
1172
1279
  roleClass: 'worker', isHumanSeat: false,
1173
1280
  });
@@ -1193,8 +1300,15 @@ export async function runAdapterConformance(environment, options = {}) {
1193
1300
  deniedCredentials.push({ access: access, credential });
1194
1301
  }
1195
1302
  for (const { access, credential } of deniedCredentials) {
1303
+ const rosterBefore = await environment.operations.listDrones(observationCredential, cubeA);
1304
+ expectStatus(rosterBefore, 200, `${access} principal pre-denial roster`);
1305
+ const workerBefore = listedDrone(rosterBefore, managedWorker.id);
1306
+ invariant(workerBefore, `${access} principal pre-denial roster omitted the managed worker.`);
1196
1307
  expectError(await environment.operations.reassignDrone(credential, cubeA, managedWorker, createProtocolEnvelope(`${access}-reassign-denied`, { role_id: workerRoleA.id })), 403, ErrorCode.ACCESS_DENIED, `${access} principal reassignment`);
1197
1308
  expectError(await environment.operations.evictDrone(credential, cubeA, managedWorker, createProtocolEnvelope(`${access}-evict-denied`, {})), 403, ErrorCode.ACCESS_DENIED, `${access} principal eviction`);
1309
+ const rosterAfter = await environment.operations.listDrones(observationCredential, cubeA);
1310
+ expectStatus(rosterAfter, 200, `${access} principal post-denial roster`);
1311
+ invariant(same(listedDrone(rosterAfter, managedWorker.id), workerBefore), `${access} principal management denial mutated the managed worker.`);
1198
1312
  }
1199
1313
  return { read_status: 403, write_status: 403, manage_required: true };
1200
1314
  });
@@ -1213,12 +1327,8 @@ export async function runAdapterConformance(environment, options = {}) {
1213
1327
  roleClass: 'worker', isHumanSeat: false,
1214
1328
  });
1215
1329
  const evictionTarget = await environment.admin.createDrone(principalA, cubeA, workerRoleA);
1216
- await environment.admin.issueManagedDroneSession(evictionTarget);
1330
+ const evictionTargetCredential = await environment.admin.issueManagedDroneSession(evictionTarget);
1217
1331
  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
1332
  const operations = [
1223
1333
  {
1224
1334
  name: 'cube-update',
@@ -1253,15 +1363,42 @@ export async function runAdapterConformance(environment, options = {}) {
1253
1363
  invoke: (credential, cube) => environment.operations.evictDrone(credential, cube, evictionTarget, createProtocolEnvelope('matrix-drone-evict', {})),
1254
1364
  },
1255
1365
  ];
1366
+ const observableState = async (operationName) => {
1367
+ if (operationName === 'decision-record') {
1368
+ const response = await environment.operations.listDecisions(credentialA, cubeA, createProtocolEnvelope('matrix-observe-decisions', {}));
1369
+ expectStatus(response, 200, 'Matrix decision observation');
1370
+ return decodeDecisionsResultEnvelope(response.body).payload;
1371
+ }
1372
+ if (operationName === 'drone-reassign' || operationName === 'drone-evict') {
1373
+ const response = await environment.operations.listDrones(credentialA, cubeA);
1374
+ expectStatus(response, 200, 'Matrix drone observation');
1375
+ return listedDrone(response, operationName === 'drone-reassign' ? managedWorker.id : evictionTarget.id);
1376
+ }
1377
+ return null;
1378
+ };
1379
+ const assertObservableDenial = async (operationName, before) => {
1380
+ if (operationName === 'role-create') {
1381
+ expectError(await environment.operations.roleRationale(credentialA, cubeA, createProtocolEnvelope('matrix-observe-role', {
1382
+ role: 'Matrix Role',
1383
+ section: 'Workflow rationale',
1384
+ })), 404, ErrorCode.ROLE_NOT_FOUND, 'Denied matrix role observation');
1385
+ }
1386
+ else if (before !== null) {
1387
+ invariant(same(await observableState(operationName), before), `${operationName} changed protocol-visible state after denial.`);
1388
+ }
1389
+ };
1256
1390
  for (const operation of operations) {
1257
1391
  for (const [kind, credential] of [
1258
1392
  ['read', readCredential],
1259
1393
  ['write', writeCredential],
1260
1394
  ['drone-session', droneCredential],
1261
1395
  ]) {
1262
- const before = await snapshot();
1396
+ const before = await observableState(operation.name);
1263
1397
  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.`);
1398
+ await assertObservableDenial(operation.name, before);
1399
+ if (operation.name === 'drone-evict') {
1400
+ expectStatus(await environment.operations.read(evictionTargetCredential, cubeA, createProtocolEnvelope(`matrix-${kind}-eviction-target-probe`, { cursor: null, limit: 1 })), 200, `${kind} denied eviction target probe`);
1401
+ }
1265
1402
  }
1266
1403
  for (const [kind, credential, cube] of [
1267
1404
  ['no-grant', noGrantCredential, cubeA],
@@ -1269,14 +1406,15 @@ export async function runAdapterConformance(environment, options = {}) {
1269
1406
  ['foreign-cube', credentialA, cubeB],
1270
1407
  ['unknown-cube', credentialA, unknownCube],
1271
1408
  ]) {
1272
- const before = await snapshot();
1409
+ const before = await observableState(operation.name);
1273
1410
  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.`);
1411
+ await assertObservableDenial(operation.name, before);
1412
+ if (operation.name === 'drone-evict') {
1413
+ expectStatus(await environment.operations.read(evictionTargetCredential, cubeA, createProtocolEnvelope(`matrix-${kind}-eviction-target-probe`, { cursor: null, limit: 1 })), 200, `${kind} denied eviction target probe`);
1414
+ }
1275
1415
  }
1276
- const beforeSuccess = await environment.admin.inspectCubeManagementState(cubeA);
1277
1416
  const success = await operation.invoke(credentialA, cubeA);
1278
1417
  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
1418
  }
1281
1419
  return {
1282
1420
  operation_count: operations.length,
@@ -1284,7 +1422,8 @@ export async function runAdapterConformance(environment, options = {}) {
1284
1422
  read_write_status: 403,
1285
1423
  drone_session_status: 403,
1286
1424
  hidden_status: 404,
1287
- denied_mutations: 0,
1425
+ observable_non_mutation_operations: 4,
1426
+ write_only_operations: 2,
1288
1427
  role_labels_authoritative: false,
1289
1428
  };
1290
1429
  });
@@ -1327,22 +1466,33 @@ export async function runAdapterConformance(environment, options = {}) {
1327
1466
  roleClass: 'worker', isHumanSeat: false,
1328
1467
  });
1329
1468
  const foreignDrone = await environment.admin.createDrone(principalB, cubeB, foreignRole);
1469
+ const foreignRosterBefore = await environment.operations.listDrones(credentialB, cubeB);
1470
+ const localRosterBefore = await environment.operations.listDrones(credentialA, cubeA);
1471
+ expectStatus(foreignRosterBefore, 200, 'Pre-denial foreign roster');
1472
+ expectStatus(localRosterBefore, 200, 'Pre-denial local roster');
1473
+ const foreignDroneBefore = listedDrone(foreignRosterBefore, foreignDrone.id);
1474
+ const managedWorkerBefore = listedDrone(localRosterBefore, managedWorker.id);
1475
+ invariant(foreignDroneBefore && managedWorkerBefore, 'Pre-denial roster omitted a drone-management target.');
1330
1476
  expectError(await environment.operations.reassignDrone(credentialA, cubeB, foreignDrone, createProtocolEnvelope('cross-cube-reassign', { role_id: foreignRole.id })), 404, ErrorCode.NOT_FOUND, 'Cross-cube reassignment');
1331
1477
  expectError(await environment.operations.evictDrone(credentialA, cubeB, foreignDrone, createProtocolEnvelope('cross-cube-evict', {})), 404, ErrorCode.NOT_FOUND, 'Cross-cube eviction');
1332
1478
  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
1479
  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
1480
  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
1481
  await environment.admin.grantCube(principalA, cubeB, 'read');
1336
- const foreignDroneBefore = await environment.admin.inspectManagedDrone(foreignDrone);
1337
1482
  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
1483
  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.');
1484
+ const foreignRosterAfter = await environment.operations.listDrones(credentialB, cubeB);
1485
+ const localRosterAfter = await environment.operations.listDrones(credentialA, cubeA);
1486
+ expectStatus(foreignRosterAfter, 200, 'Post-denial foreign roster');
1487
+ expectStatus(localRosterAfter, 200, 'Post-denial local roster');
1488
+ invariant(same(listedDrone(foreignRosterAfter, foreignDrone.id), foreignDroneBefore), 'Denied cross-cube management mutated the foreign drone.');
1489
+ invariant(same(listedDrone(localRosterAfter, managedWorker.id), managedWorkerBefore), 'Denied foreign-role management mutated the local drone.');
1341
1490
  return {
1342
1491
  unauthorized_cube_status: 404,
1343
1492
  foreign_drone_status: 404,
1344
1493
  foreign_role_status: 404,
1345
1494
  bound_drone_cross_cube_status: 404,
1495
+ targets_unchanged: true,
1346
1496
  code: ErrorCode.NOT_FOUND,
1347
1497
  };
1348
1498
  });
@@ -1359,11 +1509,6 @@ export async function runAdapterConformance(environment, options = {}) {
1359
1509
  drone_id: evictedDrone.id,
1360
1510
  evicted: true,
1361
1511
  }), '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
1512
  const after = await environment.operations.listDrones(credentialA, cubeA);
1368
1513
  expectStatus(after, 200, 'Post-eviction roster');
1369
1514
  invariant(!listedDroneIds(after).includes(evictedDrone.id), 'Evicted drone remained in roster.');
@@ -1405,44 +1550,78 @@ export async function runAdapterConformance(environment, options = {}) {
1405
1550
  retry_key: '00000000-0000-4000-8000-000000000352',
1406
1551
  client_credential: roleContractReadCredential,
1407
1552
  })), 201, 'Role-contract reader enrollment');
1553
+ const refusalRationale = 'Workflow rationale:\nRefusal role remains.';
1408
1554
  const defaultRole = await environment.admin.createRole(roleContractCube, {
1409
1555
  roleClass: 'worker',
1410
1556
  isHumanSeat: false,
1411
1557
  name: 'Default Worker',
1558
+ detailedDescription: refusalRationale,
1412
1559
  isDefault: true,
1413
1560
  });
1414
1561
  const mandatoryRole = await environment.admin.createRole(roleContractCube, {
1415
1562
  roleClass: 'worker',
1416
1563
  isHumanSeat: false,
1417
1564
  name: 'Mandatory Worker',
1565
+ detailedDescription: refusalRationale,
1418
1566
  isMandatory: true,
1419
1567
  });
1420
1568
  const humanRole = await environment.admin.createRole(roleContractCube, {
1421
1569
  roleClass: 'queen',
1422
1570
  isHumanSeat: true,
1423
1571
  name: 'Human Seat',
1572
+ detailedDescription: refusalRationale,
1424
1573
  });
1425
1574
  const activeRole = await environment.admin.createRole(roleContractCube, {
1426
1575
  roleClass: 'worker',
1427
1576
  isHumanSeat: false,
1428
1577
  name: 'Active Worker',
1578
+ detailedDescription: refusalRationale,
1429
1579
  });
1430
- await environment.admin.createDrone(roleContractPrincipal, roleContractCube, activeRole);
1580
+ const activeDrone = await environment.admin.createDrone(roleContractPrincipal, roleContractCube, activeRole);
1581
+ const activeRosterBefore = await environment.operations.listDrones(roleContractCredential, roleContractCube);
1582
+ expectStatus(activeRosterBefore, 200, 'Pre-refusal active-role roster');
1583
+ const activeDroneBefore = listedDrone(activeRosterBefore, activeDrone.id);
1584
+ invariant(activeDroneBefore, 'Pre-refusal roster omitted the active-role drone.');
1431
1585
  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'],
1586
+ [defaultRole, ErrorCode.DEFAULT_ROLE_REQUIRED, 'default role', 'Default Worker', 'worker', false],
1587
+ [mandatoryRole, ErrorCode.ROLE_REQUIRED, 'mandatory role', 'Mandatory Worker', 'worker', false],
1588
+ [humanRole, ErrorCode.ROLE_REQUIRED, 'human-seat role', 'Human Seat', 'queen', true],
1589
+ [activeRole, ErrorCode.ROLE_IN_USE, 'active-drone role', 'Active Worker', 'worker', false],
1436
1590
  ];
1437
- for (const [index, [role, code, label]] of refusals.entries()) {
1438
- const before = await environment.admin.inspectCubeManagementState(roleContractCube);
1591
+ for (const [index, [role, code, label, roleName, roleClass, isHumanSeat]] of refusals.entries()) {
1439
1592
  const response = await environment.operations.deleteRole(roleContractCredential, roleContractCube, role, createProtocolEnvelope(`delete-refusal-${index}`, {}));
1440
1593
  expectError(response, 409, code, `Delete ${label}`);
1441
- invariant(same(await environment.admin.inspectCubeManagementState(roleContractCube), before), `Delete ${label} mutated cube state after refusal.`);
1442
1594
  if (code === ErrorCode.ROLE_IN_USE) {
1443
1595
  const message = protocolErrorMessage(response) ?? '';
1444
1596
  invariant(message === ROLE_IN_USE_DELETE_MESSAGE, 'ROLE_IN_USE did not direct the caller to reassign or evict the drones first.');
1597
+ const roster = await environment.operations.listDrones(roleContractCredential, roleContractCube);
1598
+ expectStatus(roster, 200, 'Active-role refusal roster readback');
1599
+ invariant(same(listedDrone(roster, activeDrone.id), activeDroneBefore), 'Active-role deletion refusal changed the active drone.');
1445
1600
  }
1601
+ const retained = await environment.operations.roleRationale(roleContractReadCredential, roleContractCube, createProtocolEnvelope(`delete-refusal-${index}-readback`, {
1602
+ role: role.id,
1603
+ section: 'Workflow rationale',
1604
+ }));
1605
+ expectStatus(retained, 200, `Retained ${label} rationale lookup`);
1606
+ const retainedPayload = decodeRoleRationaleResultEnvelope(retained.body).payload;
1607
+ invariant(retainedPayload.role_id === role.id &&
1608
+ retainedPayload.role_name === roleName &&
1609
+ same(retainedPayload.section, {
1610
+ heading: 'Workflow rationale',
1611
+ body: refusalRationale,
1612
+ }), `Retained ${label} rationale lookup returned a different role or section.`);
1613
+ const shapeSession = `${String(index).repeat(42)}S`;
1614
+ const shapeProbe = await environment.operations.attach(roleContractCredential, createProtocolEnvelope(`delete-refusal-${index}-shape-probe`, {
1615
+ cube_id: roleContractCube.id,
1616
+ role_id: role.id,
1617
+ session_credential: shapeSession,
1618
+ }));
1619
+ expectStatus(shapeProbe, 200, `Retained ${label} shape probe`);
1620
+ const shapePayload = decodeAttachResponseEnvelope(shapeProbe.body).payload;
1621
+ invariant(shapePayload.role.id === role.id &&
1622
+ shapePayload.role.role_class === roleClass &&
1623
+ shapePayload.role.is_human_seat === isHumanSeat, `Retained ${label} shape probe returned changed role semantics.`);
1624
+ expectStatus(await environment.operations.evictDrone(roleContractCredential, roleContractCube, { id: shapePayload.drone.id }, createProtocolEnvelope(`delete-refusal-${index}-shape-cleanup`, {})), 200, `Retained ${label} shape cleanup`);
1446
1625
  }
1447
1626
  const unknownRole = { id: '00000000-0000-4000-8000-000000000398' };
1448
1627
  expectError(await environment.operations.deleteRole(roleContractCredential, roleContractCube, unknownRole, createProtocolEnvelope('delete-unknown-role', {})), 404, ErrorCode.NOT_FOUND, 'Delete unknown role');
@@ -1450,10 +1629,32 @@ export async function runAdapterConformance(environment, options = {}) {
1450
1629
  roleClass: 'worker',
1451
1630
  isHumanSeat: false,
1452
1631
  name: 'Disposable Worker',
1632
+ detailedDescription: refusalRationale,
1453
1633
  });
1454
- const beforeReadDenial = await environment.admin.inspectCubeManagementState(roleContractCube);
1455
1634
  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.');
1635
+ const retainedDeletable = await environment.operations.roleRationale(roleContractReadCredential, roleContractCube, createProtocolEnvelope('delete-role-read-denied-readback', {
1636
+ role: deletableRole.id,
1637
+ section: 'Workflow rationale',
1638
+ }));
1639
+ expectStatus(retainedDeletable, 200, 'Read-denied retained role rationale lookup');
1640
+ const retainedDeletablePayload = decodeRoleRationaleResultEnvelope(retainedDeletable.body).payload;
1641
+ invariant(retainedDeletablePayload.role_id === deletableRole.id &&
1642
+ retainedDeletablePayload.role_name === 'Disposable Worker' &&
1643
+ same(retainedDeletablePayload.section, {
1644
+ heading: 'Workflow rationale',
1645
+ body: refusalRationale,
1646
+ }), 'Read-authority deletion denial changed the target role.');
1647
+ const shapeProbe = await environment.operations.attach(roleContractCredential, createProtocolEnvelope('delete-role-read-denied-shape-probe', {
1648
+ cube_id: roleContractCube.id,
1649
+ role_id: deletableRole.id,
1650
+ session_credential: 'S'.repeat(43),
1651
+ }));
1652
+ expectStatus(shapeProbe, 200, 'Read-denied retained role shape probe');
1653
+ const shapePayload = decodeAttachResponseEnvelope(shapeProbe.body).payload;
1654
+ invariant(shapePayload.role.id === deletableRole.id &&
1655
+ shapePayload.role.role_class === 'worker' &&
1656
+ shapePayload.role.is_human_seat === false, 'Read-authority deletion denial changed the target role shape.');
1657
+ 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
1658
  const deleted = await environment.operations.deleteRole(roleContractCredential, roleContractCube, deletableRole, createProtocolEnvelope('delete-empty-role', {}));
1458
1659
  expectStatus(deleted, 200, 'Delete unassigned role');
1459
1660
  invariant(same(decodeDeleteRoleResultEnvelope(deleted.body).payload, {
@@ -1476,7 +1677,6 @@ export async function runAdapterConformance(environment, options = {}) {
1476
1677
  const attributedEntry = decodeAppendLogResultEnvelope(attributed.body).payload.entry;
1477
1678
  expectStatus(await environment.operations.evictDrone(roleContractCredential, roleContractCube, evictedDrone, createProtocolEnvelope('role-delete-evict', {})), 200, 'Pre-delete drone eviction');
1478
1679
  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
1680
  const read = await environment.operations.read(roleContractCredential, roleContractCube, createProtocolEnvelope('read-role-delete-attribution', { cursor: null, limit: 500 }));
1481
1681
  expectStatus(read, 200, 'Post-delete attributed log read');
1482
1682
  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 +1689,7 @@ export async function runAdapterConformance(environment, options = {}) {
1489
1689
  ErrorCode.ROLE_REQUIRED,
1490
1690
  ],
1491
1691
  in_use_message_actionable: true,
1492
- evicted_drone_retargeted: true,
1692
+ refusals_non_mutating: true,
1493
1693
  activity_log_attribution_preserved: true,
1494
1694
  };
1495
1695
  });
@@ -1548,16 +1748,8 @@ export async function runAdapterConformance(environment, options = {}) {
1548
1748
  name: 'Ambiguous Role',
1549
1749
  detailedDescription,
1550
1750
  });
1551
- await environment.admin.createRole(roleContractCube, {
1552
- roleClass: 'worker',
1553
- isHumanSeat: false,
1554
- name: 'AMBIGUOUS ROLE',
1555
- detailedDescription,
1556
- });
1557
- expectError(await environment.operations.roleRationale(roleContractReadCredential, roleContractCube, createProtocolEnvelope('rationale-ambiguous-role', {
1558
- role: 'ambiguous role',
1559
- section: 'Workflow rationale',
1560
- })), 400, ErrorCode.INVALID_INPUT, 'Ambiguous role rationale lookup');
1751
+ expectError(await environment.operations.createRole(roleContractCredential, roleContractCube, createProtocolEnvelope('role-case-variant-duplicate', { name: 'AMBIGUOUS ROLE' })), 409, ErrorCode.INVALID_INPUT, 'Case-variant duplicate role name');
1752
+ expectError(await environment.operations.createRole(roleContractCredential, roleContractCube, createProtocolEnvelope('role-invalid-character', { name: 'Invalid/Role' })), 400, ErrorCode.INVALID_INPUT, 'Invalid role name character');
1561
1753
  expectError(await environment.operations.roleRationale(roleContractReadCredential, roleContractCube, createProtocolEnvelope('rationale-invalid-selector', {
1562
1754
  role: ' Rationale Builder',
1563
1755
  section: 'Workflow rationale',
@@ -1570,7 +1762,8 @@ export async function runAdapterConformance(environment, options = {}) {
1570
1762
  unknown_role_code: ErrorCode.ROLE_NOT_FOUND,
1571
1763
  inaccessible_role_code: ErrorCode.ROLE_NOT_FOUND,
1572
1764
  unknown_section_code: ErrorCode.ROLE_SECTION_NOT_FOUND,
1573
- ambiguous_role_code: ErrorCode.INVALID_INPUT,
1765
+ case_variant_duplicate_status: 409,
1766
+ invalid_name_code: ErrorCode.INVALID_INPUT,
1574
1767
  invalid_selector_code: ErrorCode.INVALID_INPUT,
1575
1768
  };
1576
1769
  });
@@ -1580,12 +1773,19 @@ export async function runAdapterConformance(environment, options = {}) {
1580
1773
  working_repo_name: 'Byte-Ventures/borg-mcp',
1581
1774
  working_repo_origin: 'https://github.com/Byte-Ventures/borg-mcp',
1582
1775
  };
1776
+ try {
1777
+ metadataDroneA = await environment.admin.createDrone(principalA, cubeA, workerRoleA);
1778
+ metadataSessionA = await environment.admin.issueManagedDroneSession(metadataDroneA);
1779
+ }
1780
+ catch (error) {
1781
+ prerequisiteFailures.set('shared.metadata-baseline', error instanceof Error ? error.message : String(error));
1782
+ }
1583
1783
  await record('metadata.attach-report', async () => {
1584
- metadataSessionA = 'M'.repeat(43);
1784
+ const attachSession = 'M'.repeat(43);
1585
1785
  const created = await environment.operations.attach(credentialA, createProtocolEnvelope('metadata-attach-created', {
1586
1786
  cube_id: cubeA.id,
1587
1787
  role_id: workerRoleA.id,
1588
- session_credential: metadataSessionA,
1788
+ session_credential: attachSession,
1589
1789
  runtime_metadata: {
1590
1790
  ...knownMetadata,
1591
1791
  working_repo_origin: 'git@github.com:Byte-Ventures/borg-mcp.git',
@@ -1596,7 +1796,7 @@ export async function runAdapterConformance(environment, options = {}) {
1596
1796
  invariant(createdPayload.result === 'created', 'First metadata attach did not create a seat.');
1597
1797
  invariant(same(createdPayload.drone.runtime_metadata, knownMetadata), 'Attach did not echo canonical metadata.');
1598
1798
  invariant(createdPayload.drone.runtime_metadata_reported, 'Present attach report was not marked reported.');
1599
- metadataDroneA = { id: createdPayload.drone.id };
1799
+ const attachedDrone = { id: createdPayload.drone.id };
1600
1800
  const unavailableSession = 'N'.repeat(43);
1601
1801
  const unavailable = await environment.operations.attach(credentialA, createProtocolEnvelope('metadata-attach-unavailable', {
1602
1802
  cube_id: cubeA.id,
@@ -1629,13 +1829,13 @@ export async function runAdapterConformance(environment, options = {}) {
1629
1829
  const reused = await environment.operations.attach(credentialA, createProtocolEnvelope('metadata-attach-reused', {
1630
1830
  cube_id: cubeA.id,
1631
1831
  role_id: workerRoleA.id,
1632
- prior_drone_id: metadataDroneA.id,
1633
- session_credential: metadataSessionA,
1832
+ prior_drone_id: attachedDrone.id,
1833
+ session_credential: attachSession,
1634
1834
  runtime_metadata: knownMetadata,
1635
1835
  }));
1636
1836
  expectStatus(reused, 200, 'Metadata attach reuse');
1637
1837
  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', {
1838
+ const cleared = await environment.operations.selfMetadataUpdate(attachSession, cubeA, createProtocolEnvelope('metadata-clear-all', {
1639
1839
  agent_kind: null,
1640
1840
  reported_model: null,
1641
1841
  working_repo_name: null,
@@ -1645,7 +1845,7 @@ export async function runAdapterConformance(environment, options = {}) {
1645
1845
  const clearedPayload = decodeUpdateDroneRuntimeMetadataResponseEnvelope(cleared.body).payload;
1646
1846
  invariant(clearedPayload.runtime_metadata_reported, 'Clear-all patch lost reported state.');
1647
1847
  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');
1848
+ expectStatus(await environment.operations.selfMetadataUpdate(attachSession, cubeA, createProtocolEnvelope('metadata-restore-known', knownMetadata)), 200, 'Restore known metadata');
1649
1849
  return {
1650
1850
  created: true,
1651
1851
  reused: true,
@@ -1664,17 +1864,29 @@ export async function runAdapterConformance(environment, options = {}) {
1664
1864
  { request_id: 'metadata-null-repeat', patch: { reported_model: null } },
1665
1865
  { request_id: 'metadata-same-value', patch: { agent_kind: 'opencode' } },
1666
1866
  ];
1867
+ let state;
1667
1868
  for (const update of updates) {
1668
1869
  const response = await environment.operations.selfMetadataUpdate(metadataSessionA, cubeA, createProtocolEnvelope(update.request_id, update.patch));
1669
1870
  expectStatus(response, 200, update.request_id);
1670
- decodeUpdateDroneRuntimeMetadataResponseEnvelope(response.body);
1871
+ state = decodeUpdateDroneRuntimeMetadataResponseEnvelope(response.body).payload;
1671
1872
  }
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.');
1873
+ invariant(state?.runtime_metadata.reported_model === null, 'Explicit null did not clear model metadata.');
1874
+ invariant(state.runtime_metadata.agent_kind === 'opencode', 'Omitted field was not preserved.');
1675
1875
  return { known_replace: true, omitted_unchanged: true, null_clear: true, repeat_safe: true };
1676
1876
  });
1677
1877
  await record('security.metadata-invalid-atomic', async () => {
1878
+ const baselineResponse = await environment.operations.selfMetadataUpdate(metadataSessionA, cubeA, createProtocolEnvelope('metadata-invalid-baseline', {
1879
+ agent_kind: 'opencode',
1880
+ reported_model: null,
1881
+ working_repo_name: 'Byte-Ventures/borg-mcp-shared',
1882
+ working_repo_origin: 'https://github.com/Byte-Ventures/borg-mcp-shared',
1883
+ }));
1884
+ expectStatus(baselineResponse, 200, 'Invalid metadata baseline');
1885
+ decodeUpdateDroneRuntimeMetadataResponseEnvelope(baselineResponse.body);
1886
+ const baselineRoster = await environment.operations.listDrones(credentialA, cubeA);
1887
+ expectStatus(baselineRoster, 200, 'Invalid metadata baseline roster');
1888
+ const baselineDrone = listedDrone(baselineRoster, metadataDroneA.id);
1889
+ invariant(baselineDrone, 'Invalid metadata baseline roster omitted the metadata seat.');
1678
1890
  const invalidPatches = [
1679
1891
  {},
1680
1892
  { agent_kind: 'OpenCode' },
@@ -1692,23 +1904,29 @@ export async function runAdapterConformance(environment, options = {}) {
1692
1904
  { last_seen: '2026-07-14T10:00:00.000Z' },
1693
1905
  ];
1694
1906
  for (const [index, patch] of invalidPatches.entries()) {
1695
- const before = await environment.admin.inspectDroneRuntimeState(metadataDroneA);
1696
1907
  const response = await environment.operations.selfMetadataUpdate(metadataSessionA, cubeA, createProtocolEnvelope(`metadata-invalid-${index}`, patch));
1697
1908
  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.`);
1909
+ const readbackResponse = await environment.operations.listDrones(credentialA, cubeA);
1910
+ expectStatus(readbackResponse, 200, `Invalid metadata readback ${index}`);
1911
+ invariant(same(listedDrone(readbackResponse, metadataDroneA.id), baselineDrone), `Invalid metadata patch ${index} partially mutated state.`);
1699
1912
  }
1700
1913
  return { cases: invalidPatches.length, atomic: true, prior_safe_state_retained: true };
1701
1914
  });
1702
1915
  await record('security.metadata-own-seat', async () => {
1703
1916
  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);
1917
+ const rosterBefore = await environment.operations.listDrones(credentialA, cubeA);
1918
+ expectStatus(rosterBefore, 200, 'Pre-update metadata roster');
1919
+ const peerBefore = listedDrone(rosterBefore, peer.id);
1920
+ const managedBefore = listedDrone(rosterBefore, managedWorker.id);
1921
+ const ownBefore = listedDrone(rosterBefore, metadataDroneA.id);
1922
+ invariant(peerBefore && managedBefore && ownBefore, 'Pre-update metadata roster omitted a fixture drone.');
1707
1923
  const response = await environment.operations.selfMetadataUpdate(metadataSessionA, cubeA, createProtocolEnvelope('metadata-own-seat', { agent_kind: 'claude' }));
1708
1924
  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.');
1925
+ const rosterAfter = await environment.operations.listDrones(credentialA, cubeA);
1926
+ expectStatus(rosterAfter, 200, 'Post-update metadata roster');
1927
+ invariant(same(listedDrone(rosterAfter, peer.id), peerBefore), 'Own-seat update mutated a peer seat.');
1928
+ invariant(same(listedDrone(rosterAfter, managedWorker.id), managedBefore), 'Own-seat update mutated another existing seat.');
1929
+ invariant(listedDrone(rosterAfter, metadataDroneA.id)?.role_id === ownBefore.role_id, 'Metadata update changed the current seat role.');
1712
1930
  expectError(await environment.operations.selfMetadataUpdate(credentialA, cubeA, createProtocolEnvelope('metadata-manager-denied', { agent_kind: 'codex' })), 403, ErrorCode.ACCESS_DENIED, 'Manager metadata update');
1713
1931
  expectError(await environment.operations.selfMetadataUpdate('Z'.repeat(43), cubeA, createProtocolEnvelope('metadata-invalid-session', { agent_kind: null })), 401, ErrorCode.AUTH_INVALID, 'Unknown metadata session');
1714
1932
  const rejectedStates = [];
@@ -1721,9 +1939,20 @@ export async function runAdapterConformance(environment, options = {}) {
1721
1939
  expectStatus(await environment.operations.evictDrone(credentialA, cubeA, evicted, createProtocolEnvelope('metadata-evict-seat', {})), 200, 'Metadata seat eviction');
1722
1940
  rejectedStates.push(['evicted', evicted, evictedSession, 410, ErrorCode.DRONE_EVICTED]);
1723
1941
  for (const [label, drone, session, status, code] of rejectedStates) {
1724
- const before = await environment.admin.inspectDroneRuntimeState(drone);
1942
+ const rosterBefore = label === 'revoked'
1943
+ ? await environment.operations.listDrones(credentialA, cubeA)
1944
+ : null;
1945
+ if (rosterBefore)
1946
+ expectStatus(rosterBefore, 200, 'Pre-denial revoked metadata roster');
1947
+ const droneBefore = rosterBefore ? listedDrone(rosterBefore, drone.id) : null;
1948
+ if (rosterBefore)
1949
+ invariant(droneBefore, 'Pre-denial roster omitted the revoked metadata seat.');
1725
1950
  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.`);
1951
+ if (droneBefore) {
1952
+ const rosterAfter = await environment.operations.listDrones(credentialA, cubeA);
1953
+ expectStatus(rosterAfter, 200, 'Post-denial revoked metadata roster');
1954
+ invariant(same(listedDrone(rosterAfter, drone.id), droneBefore), 'Revoked metadata denial mutated the protocol-visible seat.');
1955
+ }
1727
1956
  }
1728
1957
  return {
1729
1958
  own_seat_only: true,
@@ -1750,19 +1979,27 @@ export async function runAdapterConformance(environment, options = {}) {
1750
1979
  }));
1751
1980
  expectStatus(attachedB, 200, 'Cube B metadata attach');
1752
1981
  metadataDroneB = { id: decodeAttachResponseEnvelope(attachedB.body).payload.drone.id };
1753
- const beforeB = await environment.admin.inspectDroneRuntimeState(metadataDroneB);
1982
+ const rosterBefore = await environment.operations.listDrones(credentialB, cubeB);
1983
+ expectStatus(rosterBefore, 200, 'Pre-probe cube B roster');
1984
+ const beforeB = listedDrone(rosterBefore, metadataDroneB.id);
1985
+ invariant(beforeB, 'Pre-probe cube B roster omitted its metadata seat.');
1754
1986
  const foreign = await environment.operations.selfMetadataUpdate(metadataSessionA, cubeB, createProtocolEnvelope('metadata-cross-cube', { reported_model: 'foreign/probe' }));
1755
1987
  expectError(foreign, 404, ErrorCode.NOT_FOUND, 'Cross-cube metadata update');
1756
1988
  const unknown = await environment.operations.selfMetadataUpdate(metadataSessionA, { id: '90000000-0000-4000-8000-000000000001' }, createProtocolEnvelope('metadata-unknown-cube', { reported_model: 'foreign/probe' }));
1757
1989
  expectError(unknown, 404, ErrorCode.NOT_FOUND, 'Unknown-cube metadata update');
1758
1990
  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.');
1991
+ const rosterAfter = await environment.operations.listDrones(credentialB, cubeB);
1992
+ expectStatus(rosterAfter, 200, 'Post-probe cube B roster');
1993
+ invariant(same(listedDrone(rosterAfter, metadataDroneB.id), beforeB), 'Cross-cube metadata update mutated the foreign seat.');
1760
1994
  const listedA = await environment.operations.listDrones(credentialA, cubeA);
1761
1995
  invariant(!listedDroneIds(listedA).includes(metadataDroneB.id), 'Cube A roster disclosed cube B metadata seat.');
1762
1996
  return { update_status: 404, foreign_unknown_indistinguishable: true, foreign_unchanged: true, roster_isolated: true };
1763
1997
  });
1764
1998
  await record('security.metadata-noninterference', async () => {
1765
- const before = await environment.admin.inspectDroneRuntimeState(metadataDroneA);
1999
+ const rosterBefore = await environment.operations.listDrones(credentialA, cubeA);
2000
+ expectStatus(rosterBefore, 200, 'Pre-update noninterference roster');
2001
+ const before = listedDrone(rosterBefore, metadataDroneA.id);
2002
+ invariant(before, 'Pre-update noninterference roster omitted the metadata seat.');
1766
2003
  for (const [requestId, patch] of [
1767
2004
  ['metadata-noninterference-known', { reported_model: 'openai/gpt-5.6-sol' }],
1768
2005
  ['metadata-noninterference-repeat', { reported_model: 'openai/gpt-5.6-sol' }],
@@ -1778,28 +2015,28 @@ export async function runAdapterConformance(environment, options = {}) {
1778
2015
  session_credential: metadataSessionA,
1779
2016
  }));
1780
2017
  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
- };
2018
+ const rosterAfter = await environment.operations.listDrones(credentialA, cubeA);
2019
+ expectStatus(rosterAfter, 200, 'Post-update noninterference roster');
2020
+ const after = listedDrone(rosterAfter, metadataDroneA.id);
2021
+ invariant(after, 'Post-update noninterference roster omitted the metadata seat.');
2022
+ invariant(same(withoutRuntimeMetadata(before), withoutRuntimeMetadata(after)), 'Metadata update changed non-metadata roster state.');
2023
+ return { non_metadata_roster_state_unchanged: true };
1792
2024
  });
1793
2025
  await record('security.metadata-secret-non-echo', async () => {
1794
2026
  const marker = 'SECRET-METADATA-MARKER';
1795
- const before = await environment.admin.inspectDroneRuntimeState(metadataDroneA);
2027
+ const rosterBefore = await environment.operations.listDrones(credentialA, cubeA);
2028
+ expectStatus(rosterBefore, 200, 'Pre-secret metadata roster');
2029
+ const before = listedDrone(rosterBefore, metadataDroneA.id);
2030
+ invariant(before, 'Pre-secret metadata roster omitted the metadata seat.');
1796
2031
  const response = await environment.operations.selfMetadataUpdate(metadataSessionA, cubeA, createProtocolEnvelope('metadata-secret', {
1797
2032
  working_repo_name: 'owner/repo',
1798
2033
  working_repo_origin: `https://user:${marker}@github.com/owner/repo?token=${marker}`,
1799
2034
  }));
1800
2035
  expectError(response, 400, ErrorCode.INVALID_INPUT, 'Secret-bearing metadata update');
1801
2036
  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.');
2037
+ const rosterAfter = await environment.operations.listDrones(credentialA, cubeA);
2038
+ expectStatus(rosterAfter, 200, 'Post-secret metadata roster');
2039
+ invariant(same(listedDrone(rosterAfter, metadataDroneA.id), before), 'Secret-bearing metadata input was persisted.');
1803
2040
  const hostileKeys = [
1804
2041
  'SECRET-METADATA-KEY-MARKER',
1805
2042
  `control\u001b[2J`,
@@ -1825,8 +2062,19 @@ export async function runAdapterConformance(environment, options = {}) {
1825
2062
  };
1826
2063
  });
1827
2064
  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);
2065
+ const principal = await environment.admin.createPrincipal('stream-revocation');
2066
+ const cube = await environment.admin.createCube('stream-revocation');
2067
+ await environment.admin.grantCube(principal, cube);
2068
+ const credential = await environment.admin.issueDroneSession(principal);
2069
+ const appended = await environment.operations.append(credential, cube, createProtocolEnvelope('stream-revocation-entry', {
2070
+ post_id: '00000000-0000-4000-8000-000000000315',
2071
+ to: 'broadcast',
2072
+ message: 'revocation cursor baseline',
2073
+ }));
2074
+ expectStatus(appended, 201, 'Revocation fixture append');
2075
+ const entry = decodeAppendLogResultEnvelope(appended.body).payload.entry;
2076
+ const cursor = { id: entry.id, created_at: entry.created_at };
2077
+ const opened = await environment.operations.openStream(credential, cube, cursor);
1830
2078
  expectStatus(opened, 200, 'Revocation stream open');
1831
2079
  invariant(opened.stream, 'Successful revocation stream omitted its AsyncIterable.');
1832
2080
  const reader = new SseEventReader(opened.stream);
@@ -1835,7 +2083,7 @@ export async function runAdapterConformance(environment, options = {}) {
1835
2083
  invariant(bookmark.type === 'bookmark' && bookmark.replay_complete, 'Fresh live stream did not complete replay.');
1836
2084
  const pending = reader.next();
1837
2085
  await provePending(pending, 'Idle live stream', pendingProbeMs);
1838
- await environment.admin.revokePrincipal(principalA);
2086
+ await environment.admin.revokePrincipal(principal);
1839
2087
  let terminated = false;
1840
2088
  try {
1841
2089
  await within(pending, 'Revoked stream termination', streamDeadlineMs);
@@ -1850,7 +2098,7 @@ export async function runAdapterConformance(environment, options = {}) {
1850
2098
  finally {
1851
2099
  await reader.close();
1852
2100
  }
1853
- const rejected = await environment.operations.read(credentialA, cubeA, createProtocolEnvelope('read-revoked', { cursor: liveCursor, limit: 10 }));
2101
+ const rejected = await environment.operations.read(credential, cube, createProtocolEnvelope('read-revoked', { cursor, limit: 10 }));
1854
2102
  expectError(rejected, 401, ErrorCode.SESSION_REVOKED, 'Post-revocation request');
1855
2103
  return { stream_terminated: true, subsequent_status: 401, subsequent_code: ErrorCode.SESSION_REVOKED };
1856
2104
  });
@@ -1873,13 +2121,14 @@ export async function runAdapterConformance(environment, options = {}) {
1873
2121
  const writer = await enrollParent('delete-writer', 'W', '704');
1874
2122
  const outsider = await enrollParent('delete-outsider', 'O', '705');
1875
2123
  await environment.admin.grantCreateCubeCapability(creator.principal);
1876
- const createResponse = await environment.operations.createCube(creator.credential, createProtocolEnvelope('delete-cube-create', {
2124
+ const deleteCubeRequest = {
1877
2125
  retry_key: '00000000-0000-4000-8000-000000000706',
1878
2126
  name: 'Disposable Cube',
1879
2127
  working_repo_name: 'disposable-cube',
1880
2128
  repository: { kind: 'local', value: '00000000-0000-4000-8000-000000000707' },
1881
- template: 'default',
1882
- }));
2129
+ template: 'software-dev',
2130
+ };
2131
+ const createResponse = await environment.operations.createCube(creator.credential, createProtocolEnvelope('delete-cube-create', deleteCubeRequest));
1883
2132
  expectStatus(createResponse, 201, 'Disposable cube creation');
1884
2133
  const created = decodeCreateCubeResponseEnvelope(createResponse.body).payload;
1885
2134
  const cube = { id: created.cube_id };
@@ -1889,6 +2138,14 @@ export async function runAdapterConformance(environment, options = {}) {
1889
2138
  await environment.admin.grantCube(writer.principal, cube, 'write');
1890
2139
  const drone = await environment.admin.createDrone(creator.principal, cube, role);
1891
2140
  const droneCredential = await environment.admin.issueManagedDroneSession(drone);
2141
+ const roleProbeSession = 'T'.repeat(43);
2142
+ const initialRoleProbe = await environment.operations.attach(manager.credential, createProtocolEnvelope('delete-role-shape-baseline', {
2143
+ cube_id: cube.id,
2144
+ role_id: role.id,
2145
+ session_credential: roleProbeSession,
2146
+ }));
2147
+ expectStatus(initialRoleProbe, 200, 'Deletion default-role shape baseline');
2148
+ const roleProbeDrone = decodeAttachResponseEnvelope(initialRoleProbe.body).payload.drone;
1892
2149
  const append = await environment.operations.append(creator.credential, cube, createProtocolEnvelope('delete-log', {
1893
2150
  post_id: '00000000-0000-4000-8000-000000000312',
1894
2151
  to: 'broadcast',
@@ -1898,16 +2155,45 @@ export async function runAdapterConformance(environment, options = {}) {
1898
2155
  const entry = decodeAppendLogResultEnvelope(append.body).payload.entry;
1899
2156
  expectStatus(await environment.operations.ack(creator.credential, cube, createProtocolEnvelope('delete-claim', { entry_id: entry.id, kind: 'claim' })), 204, 'Deletion fixture claim');
1900
2157
  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);
2158
+ const readDenialState = async (label) => {
2159
+ const decisions = await environment.operations.listDecisions(manager.credential, cube, createProtocolEnvelope(`delete-${label}-decision-readback`, {}));
2160
+ expectStatus(decisions, 200, `${label} deletion decision readback`);
2161
+ const active = decodeDecisionsResultEnvelope(decisions.body).payload.decisions;
2162
+ const log = await environment.operations.read(manager.credential, cube, createProtocolEnvelope(`delete-${label}-log-readback`, { cursor: null, limit: 500 }));
2163
+ expectStatus(log, 200, `${label} deletion log readback`);
2164
+ const logPayload = decodeReadLogResultEnvelope(log.body).payload;
2165
+ const roster = await environment.operations.listDrones(manager.credential, cube);
2166
+ expectStatus(roster, 200, `${label} deletion roster readback`);
2167
+ const roleReadback = await environment.operations.attach(manager.credential, createProtocolEnvelope(`delete-${label}-role-readback`, {
2168
+ cube_id: cube.id,
2169
+ role_id: role.id,
2170
+ prior_drone_id: roleProbeDrone.id,
2171
+ session_credential: roleProbeSession,
2172
+ }));
2173
+ expectStatus(roleReadback, 200, `${label} deletion role readback`);
2174
+ const rolePayload = decodeAttachResponseEnvelope(roleReadback.body).payload.role;
2175
+ return {
2176
+ decisions: active,
2177
+ entries: logPayload.entries,
2178
+ claims: logPayload.claims,
2179
+ drone: listedDrone(roster, drone.id),
2180
+ role: rolePayload,
2181
+ };
2182
+ };
2183
+ const denialBaseline = await readDenialState('baseline');
2184
+ const assertDenialState = async (label) => {
2185
+ invariant(same(await readDenialState(label), denialBaseline), `${label} cube deletion denial mutated protocol-visible cube state.`);
2186
+ };
1902
2187
  for (const [kind, credential] of [
1903
2188
  ['read', reader.credential],
1904
2189
  ['write', writer.credential],
1905
2190
  ['drone-session', droneCredential],
1906
2191
  ]) {
1907
2192
  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.`);
2193
+ await assertDenialState(kind);
1909
2194
  }
1910
2195
  expectError(await environment.operations.deleteCube(outsider.credential, cube, createProtocolEnvelope('delete-outsider-denied', {})), 404, ErrorCode.NOT_FOUND, 'Never-authorized cube deletion');
2196
+ await assertDenialState('outsider');
1911
2197
  const parentStream = await environment.operations.openStream(manager.credential, cube, null);
1912
2198
  const droneStream = await environment.operations.openStream(droneCredential, cube, null);
1913
2199
  expectStatus(parentStream, 200, 'Deletion parent stream');
@@ -1949,19 +2235,6 @@ export async function runAdapterConformance(environment, options = {}) {
1949
2235
  invariant(closed, 'Deleted cube stream yielded after its terminal error.');
1950
2236
  await streamReader.close();
1951
2237
  }
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
2238
  for (const [kind, credential] of [
1966
2239
  ['creator', creator.credential],
1967
2240
  ['manager', manager.credential],
@@ -1974,30 +2247,22 @@ export async function runAdapterConformance(environment, options = {}) {
1974
2247
  }
1975
2248
  expectError(await environment.operations.deleteCube(outsider.credential, cube, createProtocolEnvelope('delete-outsider-hidden-repeat', {})), 404, ErrorCode.NOT_FOUND, 'Never-authorized post-delete DELETE');
1976
2249
  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');
2250
+ const recreatedResponse = await environment.operations.createCube(creator.credential, createProtocolEnvelope('delete-cube-recreate', deleteCubeRequest));
2251
+ expectStatus(recreatedResponse, 201, 'Post-delete cube recreation');
2252
+ const recreated = decodeCreateCubeResponseEnvelope(recreatedResponse.body).payload;
2253
+ invariant(recreated.result === 'created' && recreated.cube_id !== cube.id, 'Post-delete recreation resolved retained cube-owned creation state.');
1990
2254
  return {
1991
2255
  deletion_status: 200,
1992
- cascade_complete: true,
1993
2256
  terminal_stream_error: ErrorCode.CUBE_DELETED,
1994
2257
  terminal_http_status: 410,
1995
- terminal_state_durable_after_restart: true,
1996
2258
  unknown_hidden_status: 404,
1997
2259
  non_member_manager: true,
2260
+ recreation_created_new_cube: true,
1998
2261
  };
1999
2262
  });
2000
- const normalizedTranscript = results.map(({ id, observations }) => ({ id, observations }));
2263
+ const normalizedTranscript = results
2264
+ .filter((result) => !result.skipped)
2265
+ .map(({ id, observations }) => ({ id, observations }));
2001
2266
  return { ok: results.every((result) => result.ok), results, normalizedTranscript };
2002
2267
  }
2003
2268
  //# sourceMappingURL=adapter.js.map