borgmcp-shared 0.11.0 → 0.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -1
- package/RELEASES.md +14 -0
- package/dist/conformance/adapter.d.ts +3 -0
- package/dist/conformance/adapter.d.ts.map +1 -1
- package/dist/conformance/adapter.js +91 -10
- package/dist/conformance/adapter.js.map +1 -1
- package/dist/conformance/index.d.ts +13 -0
- package/dist/conformance/index.d.ts.map +1 -1
- package/dist/conformance/index.js +83 -14
- package/dist/conformance/index.js.map +1 -1
- package/dist/protocol/contract.d.ts +2 -1
- package/dist/protocol/contract.d.ts.map +1 -1
- package/dist/protocol/contract.js +9 -4
- package/dist/protocol/contract.js.map +1 -1
- package/dist/protocol/coordination.d.ts.map +1 -1
- package/dist/protocol/coordination.js +8 -2
- package/dist/protocol/coordination.js.map +1 -1
- package/dist/protocol/errors.d.ts +1 -0
- package/dist/protocol/errors.d.ts.map +1 -1
- package/dist/protocol/errors.js +1 -0
- package/dist/protocol/errors.js.map +1 -1
- package/dist/protocol/types.d.ts +2 -0
- package/dist/protocol/types.d.ts.map +1 -1
- package/dist/protocol/version.d.ts +1 -1
- package/dist/protocol/version.js +1 -1
- package/docs/release-records.json +89 -0
- package/docs/releases/0.12.0.md +7 -0
- package/docs/releasing.md +102 -20
- package/package.json +1 -1
- package/src/conformance/adapter.ts +110 -9
- package/src/conformance/index.ts +101 -15
- package/src/protocol/contract.ts +11 -5
- package/src/protocol/coordination.ts +8 -2
- package/src/protocol/errors.ts +1 -0
- package/src/protocol/types.ts +2 -0
- package/src/protocol/version.ts +2 -2
package/README.md
CHANGED
|
@@ -104,7 +104,13 @@ Versioned JSON coordination requests and successful responses are carried inside
|
|
|
104
104
|
protocol preflight uses its exact tag-only shape; `204` liveness and
|
|
105
105
|
acknowledgement responses are bodyless. Payload codecs are exported separately
|
|
106
106
|
so adapters can validate the envelope first and then validate the
|
|
107
|
-
operation-specific payload without accepting ambiguous fields.
|
|
107
|
+
operation-specific payload without accepting ambiguous fields. Append-log
|
|
108
|
+
requests require a canonical UUID `post_id`. Identity is scoped by authenticated
|
|
109
|
+
author: an exact retry must preserve the message and fully resolved visibility,
|
|
110
|
+
recipient set, and class routing, then returns the same entry with
|
|
111
|
+
`deduplicated: true`. Reusing an author's `post_id` with a changed tuple returns
|
|
112
|
+
`POST_ID_CONFLICT`; another author may independently use the same UUID. Attach responses include the nullable
|
|
113
|
+
`initial_log_cursor` that anchors subsequent log replay.
|
|
108
114
|
Cube managers reassign a seat with `PATCH /api/cubes/:cubeId/drones/:droneId`
|
|
109
115
|
and evict one with `DELETE` on the same path. Both operations use strict
|
|
110
116
|
versioned request and success envelopes. An evicted seat's former bearer receives
|
package/RELEASES.md
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
# Release History
|
|
2
2
|
|
|
3
|
+
Eight published versions from 0.2.2 through 0.6.2, excluding the isolated 0.4.0
|
|
4
|
+
baseline, predate the canonical release-record convention. Historical incident
|
|
5
|
+
prose below remains their record instead of reconstructed structured entries.
|
|
6
|
+
|
|
3
7
|
`borgmcp-shared@0.4.0` is the published clean-slate v2 baseline and is
|
|
4
8
|
immutable, but its artifact predates the local/self-hosted package cleanup. The
|
|
5
9
|
immutable `v0.4.1` verification artifact exposed a platform-dependent SBOM audit
|
|
@@ -36,3 +40,13 @@ peels to protected-main commit `8e5bd088b8069951a687156c35cf68d44985ddc1`;
|
|
|
36
40
|
successful attempt-1 workflow run `31255563527` published registry integrity
|
|
37
41
|
`sha512-NYZJi6z0g/Txb6ge+5NgRPNRszVEi0eNmICxkoZq5bGkJWm5qEvNSt3ws90Xz8IOKuWcyHC9i6sAK6cbZxwYDw==`.
|
|
38
42
|
Never rerun or move that tag.
|
|
43
|
+
`borgmcp-shared@0.11.0` was published on 2026-08-11 and is immutable:
|
|
44
|
+
annotated tag `v0.11.0` peels to protected-main commit
|
|
45
|
+
`c1df96a858ff7c587d42508d388aa517a0b8545c`. PR #119 added the template
|
|
46
|
+
lifecycle document. PR #120 added local-model routing and ownership,
|
|
47
|
+
two-direction taxonomy agreement, the workflow-discipline mechanism split,
|
|
48
|
+
and minimalism completion. PR #121 added live-cube back-ports and the
|
|
49
|
+
external-surface single-owner directive rule. Successful attempt-1 workflow
|
|
50
|
+
run `31531549256` published registry integrity
|
|
51
|
+
`sha512-I8mixCbSrLKyOAAyqEI/HZJ8cML2rz3r812Up8pr547OdAk9LxZevdCo7ojG42ZwrUmS5u7iKQPg7Vk1XvtX1g==`.
|
|
52
|
+
Never rerun or move that tag.
|
|
@@ -210,6 +210,9 @@ export declare const ADAPTER_CONFORMANCE_FIXTURES: readonly [{
|
|
|
210
210
|
}, {
|
|
211
211
|
readonly id: "security.cross-cube-isolation";
|
|
212
212
|
readonly area: "security";
|
|
213
|
+
}, {
|
|
214
|
+
readonly id: "log.append-idempotency";
|
|
215
|
+
readonly area: "log";
|
|
213
216
|
}, {
|
|
214
217
|
readonly id: "log.read-cursor-tuple";
|
|
215
218
|
readonly area: "cursor";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../../src/conformance/adapter.ts"],"names":[],"mappings":"AAAA,OAAO,EA8BL,KAAK,kBAAkB,EACvB,KAAK,oBAAoB,EACzB,KAAK,YAAY,EAEjB,KAAK,SAAS,EAEd,KAAK,oBAAoB,EAC1B,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../../src/conformance/adapter.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ErrorCode, compareLogCursor, createProtocolEnvelope, decodeAssociateRepositoryCubeResponseEnvelope, decodeCreateCubeResponseEnvelope, decodeDeleteCubeResponseEnvelope, decodeAppendLogResultEnvelope, decodeDecisionResultEnvelope, decodeDecisionsResultEnvelope, decodeEnrollmentExchangeResponseEnvelope, decodeInvitationArtifact, decodeAttachResponseEnvelope, decodeDroneRuntimeMetadataPatch, decodeEvictDroneResultEnvelope, decodeDeleteRoleResultEnvelope, decodeRoleRationaleResultEnvelope, decodeProtocolEnvelope, decodeProtocolErrorEnvelope, decodeProtocolTagPreflight, decodeReadLogResultEnvelope, decodeResolveRepositoryCubeResponseEnvelope, decodeReassignDroneResultEnvelope, decodeUpdateDroneRuntimeMetadataResponseEnvelope, decodeSseFrames, PROTOCOL_LIMIT_CEILINGS, PROTOCOL_HTTP_CONTRACT, PROTOCOL_VERSION, ROLE_IN_USE_DELETE_MESSAGE, utf8ByteLength, } from '../protocol/index.js';
|
|
2
|
-
import { CREATE_CUBE_ASSOCIATION_CONFORMANCE, CREATE_CUBE_RETRY_CONFORMANCE, INVITATION_ARTIFACT_CONFORMANCE, ENROLLMENT_RETRY_CONFORMANCE, } from './index.js';
|
|
2
|
+
import { APPEND_LOG_IDEMPOTENCY_CONFORMANCE, CREATE_CUBE_ASSOCIATION_CONFORMANCE, CREATE_CUBE_RETRY_CONFORMANCE, INVITATION_ARTIFACT_CONFORMANCE, ENROLLMENT_RETRY_CONFORMANCE, } from './index.js';
|
|
3
3
|
export const ADAPTER_CONFORMANCE_FIXTURES = [
|
|
4
4
|
{ id: 'http.unauthenticated-liveness', area: 'http' },
|
|
5
5
|
{ id: 'protocol.credential-free-preflight', area: 'protocol' },
|
|
@@ -9,6 +9,7 @@ export const ADAPTER_CONFORMANCE_FIXTURES = [
|
|
|
9
9
|
{ id: 'security.adapter-boundary-injection', area: 'security' },
|
|
10
10
|
{ id: 'security.oversize-request', area: 'security' },
|
|
11
11
|
{ id: 'security.cross-cube-isolation', area: 'security' },
|
|
12
|
+
{ id: 'log.append-idempotency', area: 'log' },
|
|
12
13
|
{ id: 'log.read-cursor-tuple', area: 'cursor' },
|
|
13
14
|
{ id: 'sse.replay-live-transition', area: 'sse' },
|
|
14
15
|
{ id: 'cursor.explicit-expiry', area: 'cursor' },
|
|
@@ -600,14 +601,20 @@ export async function runAdapterConformance(environment, options = {}) {
|
|
|
600
601
|
});
|
|
601
602
|
await record('security.adapter-boundary-injection', async () => {
|
|
602
603
|
const injectedMessage = "'); DROP TABLE log_entries; --\r\ndata: forged-sse-frame";
|
|
603
|
-
const injectedBody = JSON.stringify(createProtocolEnvelope('inject-b1', {
|
|
604
|
+
const injectedBody = JSON.stringify(createProtocolEnvelope('inject-b1', {
|
|
605
|
+
post_id: '00000000-0000-4000-8000-000000000301',
|
|
606
|
+
message: injectedMessage,
|
|
607
|
+
}));
|
|
604
608
|
invariant(utf8ByteLength(injectedBody) <= PROTOCOL_LIMIT_CEILINGS.max_request_bytes &&
|
|
605
609
|
utf8ByteLength(injectedMessage) <= PROTOCOL_LIMIT_CEILINGS.max_log_message_bytes, 'Injection fixture exceeded the shared request-limit ceiling.');
|
|
606
610
|
const injected = await environment.operations.appendRaw(credentialB, cubeB, injectedBody);
|
|
607
611
|
expectStatus(injected, 201, 'Adapter-boundary injection append');
|
|
608
612
|
const injectedEntry = decodeAppendLogResultEnvelope(injected.body).payload.entry;
|
|
609
613
|
invariant(injectedEntry.message === injectedMessage, 'Adapter altered or interpreted injection-shaped log data.');
|
|
610
|
-
const sentinel = await environment.operations.append(credentialB, cubeB, createProtocolEnvelope('inject-b2', {
|
|
614
|
+
const sentinel = await environment.operations.append(credentialB, cubeB, createProtocolEnvelope('inject-b2', {
|
|
615
|
+
post_id: '00000000-0000-4000-8000-000000000302',
|
|
616
|
+
message: 'post-injection-sentinel',
|
|
617
|
+
}));
|
|
611
618
|
expectStatus(sentinel, 201, 'Post-injection sentinel append');
|
|
612
619
|
const read = await environment.operations.read(credentialB, cubeB, createProtocolEnvelope('inject-read', { cursor: null, limit: 10 }));
|
|
613
620
|
expectStatus(read, 200, 'Post-injection read');
|
|
@@ -636,7 +643,10 @@ export async function runAdapterConformance(environment, options = {}) {
|
|
|
636
643
|
};
|
|
637
644
|
});
|
|
638
645
|
await record('security.oversize-request', async () => {
|
|
639
|
-
const baseBody = JSON.stringify(createProtocolEnvelope('oversize-a1', {
|
|
646
|
+
const baseBody = JSON.stringify(createProtocolEnvelope('oversize-a1', {
|
|
647
|
+
post_id: '00000000-0000-4000-8000-000000000303',
|
|
648
|
+
message: 'must-not-persist',
|
|
649
|
+
}));
|
|
640
650
|
const oversizedBody = baseBody + ' '.repeat(Math.max(0, PROTOCOL_LIMIT_CEILINGS.max_request_bytes - utf8ByteLength(baseBody) + 1));
|
|
641
651
|
invariant(utf8ByteLength(oversizedBody) > PROTOCOL_LIMIT_CEILINGS.max_request_bytes, 'Oversize fixture did not exceed max_request_bytes.');
|
|
642
652
|
const response = await environment.operations.appendRaw(credentialA, cubeA, oversizedBody);
|
|
@@ -647,17 +657,75 @@ export async function runAdapterConformance(environment, options = {}) {
|
|
|
647
657
|
return { status: 413, code: ErrorCode.CONTENT_TOO_LARGE, persisted_entries: 0 };
|
|
648
658
|
});
|
|
649
659
|
await record('security.cross-cube-isolation', async () => {
|
|
650
|
-
const secretAppend = await environment.operations.append(credentialB, cubeB, createProtocolEnvelope('append-b1', {
|
|
660
|
+
const secretAppend = await environment.operations.append(credentialB, cubeB, createProtocolEnvelope('append-b1', {
|
|
661
|
+
post_id: '00000000-0000-4000-8000-000000000304',
|
|
662
|
+
message: 'principal-b-secret',
|
|
663
|
+
}));
|
|
651
664
|
expectStatus(secretAppend, 201, 'Principal B append');
|
|
652
665
|
const denied = await environment.operations.read(credentialA, cubeB, createProtocolEnvelope('read-cross', { cursor: null, limit: 10 }));
|
|
653
666
|
expectError(denied, 404, ErrorCode.NOT_FOUND, 'Cross-cube read');
|
|
654
667
|
return { status: 404, code: ErrorCode.NOT_FOUND };
|
|
655
668
|
});
|
|
669
|
+
await record('log.append-idempotency', async () => {
|
|
670
|
+
const principal = await environment.admin.createPrincipal('append-idempotency');
|
|
671
|
+
const otherPrincipal = await environment.admin.createPrincipal('append-idempotency-other');
|
|
672
|
+
const cube = await environment.admin.createCube('append-idempotency');
|
|
673
|
+
await environment.admin.grantCube(principal, cube);
|
|
674
|
+
await environment.admin.grantCube(otherPrincipal, cube);
|
|
675
|
+
const credential = await environment.admin.issueDroneSession(principal);
|
|
676
|
+
const otherCredential = await environment.admin.issueDroneSession(otherPrincipal);
|
|
677
|
+
const role = await environment.admin.createRole(cube, {
|
|
678
|
+
roleClass: 'worker',
|
|
679
|
+
isHumanSeat: false,
|
|
680
|
+
});
|
|
681
|
+
const firstRecipient = await environment.admin.createDrone(principal, cube, role);
|
|
682
|
+
const secondRecipient = await environment.admin.createDrone(principal, cube, role);
|
|
683
|
+
const postId = '00000000-0000-4000-8000-000000000313';
|
|
684
|
+
const initialPayload = {
|
|
685
|
+
post_id: postId,
|
|
686
|
+
message: 'once',
|
|
687
|
+
visibility: 'direct',
|
|
688
|
+
recipientDroneIds: [firstRecipient.id],
|
|
689
|
+
class: 'review',
|
|
690
|
+
to: ['Coordinator'],
|
|
691
|
+
};
|
|
692
|
+
const first = await environment.operations.append(credential, cube, createProtocolEnvelope('append-idempotency-first', initialPayload));
|
|
693
|
+
expectStatus(first, 201, 'Initial idempotent append');
|
|
694
|
+
const firstResult = decodeAppendLogResultEnvelope(first.body).payload;
|
|
695
|
+
invariant(!firstResult.deduplicated, 'Initial append was reported as deduplicated.');
|
|
696
|
+
for (const [index, vector] of APPEND_LOG_IDEMPOTENCY_CONFORMANCE.entries()) {
|
|
697
|
+
const payload = {
|
|
698
|
+
...initialPayload,
|
|
699
|
+
...(vector.mutation === 'message' ? { message: 'changed' } : {}),
|
|
700
|
+
...(vector.mutation === 'visibility' ? { visibility: 'broadcast' } : {}),
|
|
701
|
+
...(vector.mutation === 'recipient_set' ? { recipientDroneIds: [secondRecipient.id] } : {}),
|
|
702
|
+
...(vector.mutation === 'resolved_class_routing' ? { class: 'security', to: ['Security Auditor'] } : {}),
|
|
703
|
+
};
|
|
704
|
+
const response = await environment.operations.append(vector.actor === 'same' ? credential : otherCredential, cube, createProtocolEnvelope(`append-idempotency-${index}`, payload));
|
|
705
|
+
if (vector.expected === 'POST_ID_CONFLICT') {
|
|
706
|
+
expectError(response, 409, ErrorCode.POST_ID_CONFLICT, vector.name);
|
|
707
|
+
continue;
|
|
708
|
+
}
|
|
709
|
+
expectStatus(response, 201, vector.name);
|
|
710
|
+
const result = decodeAppendLogResultEnvelope(response.body).payload;
|
|
711
|
+
invariant(result.deduplicated === (vector.expected === 'deduplicated'), `${vector.name} returned the wrong deduplicated flag.`);
|
|
712
|
+
invariant(vector.expected === 'deduplicated'
|
|
713
|
+
? result.entry.id === firstResult.entry.id
|
|
714
|
+
: result.entry.id !== firstResult.entry.id, `${vector.name} returned the wrong entry identity.`);
|
|
715
|
+
}
|
|
716
|
+
const read = await environment.operations.read(credential, cube, createProtocolEnvelope('append-idempotency-read', { cursor: null, limit: 10 }));
|
|
717
|
+
expectStatus(read, 200, 'Idempotent append read');
|
|
718
|
+
invariant(decodeReadLogResultEnvelope(read.body).payload.entries.length === 2, 'Append collision controls persisted the wrong number of entries.');
|
|
719
|
+
return { persisted_entries: 2, stable_entry: true, deduplicated: true, conflicts: 4, cross_author_created: true };
|
|
720
|
+
});
|
|
656
721
|
const entries = [];
|
|
657
722
|
let readCursor = null;
|
|
658
723
|
await record('log.read-cursor-tuple', async () => {
|
|
659
724
|
for (const [index, message] of ['alpha', 'beta', 'gamma'].entries()) {
|
|
660
|
-
const response = await environment.operations.append(credentialA, cubeA, createProtocolEnvelope(`append-a${index + 1}`, {
|
|
725
|
+
const response = await environment.operations.append(credentialA, cubeA, createProtocolEnvelope(`append-a${index + 1}`, {
|
|
726
|
+
post_id: `00000000-0000-4000-8000-${String(305 + index).padStart(12, '0')}`,
|
|
727
|
+
message,
|
|
728
|
+
}));
|
|
661
729
|
expectStatus(response, 201, `Append ${message}`);
|
|
662
730
|
const entry = decodeAppendLogResultEnvelope(response.body).payload.entry;
|
|
663
731
|
entries.push({ id: entry.id, created_at: entry.created_at, message: entry.message });
|
|
@@ -679,7 +747,10 @@ export async function runAdapterConformance(environment, options = {}) {
|
|
|
679
747
|
const openPromise = environment.operations.openStream(credentialA, cubeA, readCursor);
|
|
680
748
|
await within(barrier.reached, 'Replay transition boundary', streamDeadlineMs);
|
|
681
749
|
try {
|
|
682
|
-
const appendDelta = environment.operations.append(credentialA, cubeA, createProtocolEnvelope('append-a4', {
|
|
750
|
+
const appendDelta = environment.operations.append(credentialA, cubeA, createProtocolEnvelope('append-a4', {
|
|
751
|
+
post_id: '00000000-0000-4000-8000-000000000308',
|
|
752
|
+
message: 'delta',
|
|
753
|
+
}));
|
|
683
754
|
expectStatus(await appendDelta, 201, 'Transition append');
|
|
684
755
|
}
|
|
685
756
|
finally {
|
|
@@ -700,7 +771,10 @@ export async function runAdapterConformance(environment, options = {}) {
|
|
|
700
771
|
invariant(bookmark.type === 'bookmark' && bookmark.replay_complete, 'Stream omitted its replay-complete bookmark.');
|
|
701
772
|
const noDuplicate = reader.next();
|
|
702
773
|
await provePending(noDuplicate, 'Live stream after delta', pendingProbeMs);
|
|
703
|
-
const epsilonResponse = await environment.operations.append(credentialA, cubeA, createProtocolEnvelope('append-a5', {
|
|
774
|
+
const epsilonResponse = await environment.operations.append(credentialA, cubeA, createProtocolEnvelope('append-a5', {
|
|
775
|
+
post_id: '00000000-0000-4000-8000-000000000309',
|
|
776
|
+
message: 'epsilon',
|
|
777
|
+
}));
|
|
704
778
|
expectStatus(epsilonResponse, 201, 'Live append');
|
|
705
779
|
const epsilon = logEvent(await within(noDuplicate, 'Live epsilon event', streamDeadlineMs), 'Live append');
|
|
706
780
|
invariant(epsilon.entry.message === 'epsilon', 'Live stream duplicated or reordered an event.');
|
|
@@ -970,6 +1044,7 @@ export async function runAdapterConformance(environment, options = {}) {
|
|
|
970
1044
|
invariant(!listedDroneIds(after).includes(evictedDrone.id), 'Evicted drone remained in roster.');
|
|
971
1045
|
expectError(await environment.operations.append(credentialA, cubeA, createProtocolEnvelope('evict-direct-target', {
|
|
972
1046
|
message: 'must-not-fan-out',
|
|
1047
|
+
post_id: '00000000-0000-4000-8000-000000000310',
|
|
973
1048
|
visibility: 'direct',
|
|
974
1049
|
recipientDroneIds: [evictedDrone.id],
|
|
975
1050
|
})), 404, ErrorCode.NOT_FOUND, 'Evicted direct recipient');
|
|
@@ -1075,7 +1150,10 @@ export async function runAdapterConformance(environment, options = {}) {
|
|
|
1075
1150
|
});
|
|
1076
1151
|
const evictedDrone = await environment.admin.createDrone(roleContractPrincipal, roleContractCube, evictedRole);
|
|
1077
1152
|
const evictedSession = await environment.admin.issueManagedDroneSession(evictedDrone);
|
|
1078
|
-
const attributed = await environment.operations.append(evictedSession, roleContractCube, createProtocolEnvelope('role-delete-attribution', {
|
|
1153
|
+
const attributed = await environment.operations.append(evictedSession, roleContractCube, createProtocolEnvelope('role-delete-attribution', {
|
|
1154
|
+
post_id: '00000000-0000-4000-8000-000000000311',
|
|
1155
|
+
message: 'attribution survives',
|
|
1156
|
+
}));
|
|
1079
1157
|
expectStatus(attributed, 201, 'Pre-delete attributed log');
|
|
1080
1158
|
const attributedEntry = decodeAppendLogResultEnvelope(attributed.body).payload.entry;
|
|
1081
1159
|
expectStatus(await environment.operations.evictDrone(roleContractCredential, roleContractCube, evictedDrone, createProtocolEnvelope('role-delete-evict', {})), 200, 'Pre-delete drone eviction');
|
|
@@ -1494,7 +1572,10 @@ export async function runAdapterConformance(environment, options = {}) {
|
|
|
1494
1572
|
await environment.admin.grantCube(writer.principal, cube, 'write');
|
|
1495
1573
|
const drone = await environment.admin.createDrone(creator.principal, cube, role);
|
|
1496
1574
|
const droneCredential = await environment.admin.issueManagedDroneSession(drone);
|
|
1497
|
-
const append = await environment.operations.append(creator.credential, cube, createProtocolEnvelope('delete-log', {
|
|
1575
|
+
const append = await environment.operations.append(creator.credential, cube, createProtocolEnvelope('delete-log', {
|
|
1576
|
+
post_id: '00000000-0000-4000-8000-000000000312',
|
|
1577
|
+
message: 'deleted with cube',
|
|
1578
|
+
}));
|
|
1498
1579
|
expectStatus(append, 201, 'Deletion fixture log');
|
|
1499
1580
|
const entry = decodeAppendLogResultEnvelope(append.body).payload.entry;
|
|
1500
1581
|
expectStatus(await environment.operations.ack(creator.credential, cube, createProtocolEnvelope('delete-claim', { entry_id: entry.id, kind: 'claim' })), 204, 'Deletion fixture claim');
|