borgmcp-shared 0.5.1 → 0.6.2
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 +30 -8
- package/dist/conformance/adapter.d.ts +54 -1
- package/dist/conformance/adapter.d.ts.map +1 -1
- package/dist/conformance/adapter.js +265 -1
- package/dist/conformance/adapter.js.map +1 -1
- package/dist/conformance/index.d.ts +9 -0
- package/dist/conformance/index.d.ts.map +1 -1
- package/dist/conformance/index.js +57 -1
- package/dist/conformance/index.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/protocol/contract.d.ts +30 -2
- package/dist/protocol/contract.d.ts.map +1 -1
- package/dist/protocol/contract.js +62 -4
- package/dist/protocol/contract.js.map +1 -1
- package/dist/protocol/types.d.ts +16 -5
- package/dist/protocol/types.d.ts.map +1 -1
- package/dist/runtime-metadata.d.ts +28 -0
- package/dist/runtime-metadata.d.ts.map +1 -0
- package/dist/runtime-metadata.js +251 -0
- package/dist/runtime-metadata.js.map +1 -0
- package/dist/templates.d.ts.map +1 -1
- package/dist/templates.js +5 -3
- package/dist/templates.js.map +1 -1
- package/docs/compatibility.md +28 -0
- package/docs/enrollment.md +13 -4
- package/docs/releasing.md +16 -5
- package/package.json +5 -1
- package/src/conformance/adapter.ts +457 -0
- package/src/conformance/index.ts +66 -1
- package/src/index.ts +1 -0
- package/src/protocol/contract.ts +110 -5
- package/src/protocol/types.ts +18 -5
- package/src/runtime-metadata.ts +304 -0
- package/src/templates.ts +5 -3
package/dist/templates.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"templates.js","sourceRoot":"","sources":["../src/templates.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"templates.js","sourceRoot":"","sources":["../src/templates.ts"],"names":[],"mappings":"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"}
|
package/docs/compatibility.md
CHANGED
|
@@ -61,3 +61,31 @@ Model/provider selection is intentionally absent from the coordination contract.
|
|
|
61
61
|
Agent CLIs own model configuration; Borg servers may expose the separate
|
|
62
62
|
advisory `reported_model` field for session observability, but clients must not
|
|
63
63
|
use it for routing, launch configuration, or authorization.
|
|
64
|
+
|
|
65
|
+
## Advisory Runtime Metadata
|
|
66
|
+
|
|
67
|
+
Protocol v3 defines one optional complete runtime-metadata report during attach
|
|
68
|
+
and one authenticated own-seat patch at
|
|
69
|
+
`PATCH /api/cubes/:cubeId/drones/self/metadata`. A complete report contains
|
|
70
|
+
`agent_kind`, `reported_model`, `working_repo_name`, and
|
|
71
|
+
`working_repo_origin`; each value may be explicitly `null`. In a patch, an
|
|
72
|
+
omitted field is unchanged, `null` clears the field, and a value replaces it.
|
|
73
|
+
Repository name and origin are one atomic pair.
|
|
74
|
+
|
|
75
|
+
Every identity response also carries required `runtime_metadata_reported`.
|
|
76
|
+
`false` means no complete report has been received, while `true` means the
|
|
77
|
+
client reported metadata even when every value is explicitly `null`. A valid
|
|
78
|
+
self-update patch sets the state to reported; clearing all four fields therefore
|
|
79
|
+
remains distinguishable from an omitted attach report.
|
|
80
|
+
|
|
81
|
+
The shared pure canonicalizer accepts public HTTPS and literal-`git` SSH/SCP
|
|
82
|
+
repository identities and returns a credential-free HTTPS identity. It performs
|
|
83
|
+
no DNS lookup or network request. It rejects local paths, IP and private hosts,
|
|
84
|
+
userinfo, non-default ports, queries, fragments, percent encoding, malformed
|
|
85
|
+
Unicode, terminal controls, and inconsistent repository pairs. Consumers use
|
|
86
|
+
the exported conformance corpus rather than maintaining independent parsers.
|
|
87
|
+
|
|
88
|
+
Runtime metadata is descriptive only. It cannot alter roles, grants,
|
|
89
|
+
authorization, wake or liveness state, timestamps, logs, routing, or model
|
|
90
|
+
execution. Mixed shared/server/client artifacts fail closed; there is no legacy
|
|
91
|
+
decoder, hosted fallback, or metadata-derived authority.
|
package/docs/enrollment.md
CHANGED
|
@@ -9,10 +9,19 @@ This contract replaced the server-generated bearer response used by the
|
|
|
9
9
|
published `borgmcp-shared@0.3.0` v1 baseline and shipped in the immutable
|
|
10
10
|
`0.4.0` clean-slate v2 release. The immutable `v0.4.1` verification artifact
|
|
11
11
|
failed its cross-platform SBOM audit and must never be published or rerun.
|
|
12
|
-
`borgmcp-shared@0.4.2`, `borgmcp-shared@0.4.3`,
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
12
|
+
`borgmcp-shared@0.4.2`, `borgmcp-shared@0.4.3`, `borgmcp-shared@0.5.0`,
|
|
13
|
+
and `borgmcp-shared@0.5.1` are published and immutable. The accepted `0.5.1`
|
|
14
|
+
incident is bound to tag object `045268aa8873da330819860012ecaddb4bc2883c`, protected-main commit
|
|
15
|
+
`1981d7373e77f6edb4567872c1544bdbe2b1ef20`, attempt-1 run `29984423571`, and registry integrity
|
|
16
|
+
`sha512-XUJq+FjY/cbarU9V1dIWnhNYcqyURTiGb6KyIzg99gy5hk/fEs5ee/8X/qvp7pw1Rshqt2J6I3TVbwJdlde2tA==`.
|
|
17
|
+
`borgmcp-shared@0.6.0` was never published: annotated tag object
|
|
18
|
+
`90a1cf686a0ce32a7aef836b0b82a930191b9030` peels to protected-main commit
|
|
19
|
+
`fd69b08586481a60c88099dede8e4e066f73f2f2`; attempt-1 workflow run
|
|
20
|
+
`30054936226` failed in tests before build, packaging, authentication, or registry
|
|
21
|
+
mutation and must never be rerun or moved. `borgmcp-shared@0.6.1` is published
|
|
22
|
+
and immutable. This source now identifies the unpublished `0.6.2` Coordinator
|
|
23
|
+
activation-cadence release. The version bump grants no tag or publication
|
|
24
|
+
authority: creating `v0.6.2` and publishing the reviewed artifact remain separate,
|
|
16
25
|
independently gated steps.
|
|
17
26
|
There is no compatibility path that returns a bearer from the server.
|
|
18
27
|
|
package/docs/releasing.md
CHANGED
|
@@ -122,10 +122,21 @@ These records remain evidence, not reusable release inputs:
|
|
|
122
122
|
postpublish check reconstructed the wrong workflow identity and is the reason
|
|
123
123
|
that machinery was removed.
|
|
124
124
|
|
|
125
|
-
`borgmcp-shared@0.4.3
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
postpublish registry
|
|
125
|
+
`borgmcp-shared@0.4.3`, `borgmcp-shared@0.5.0`, and `borgmcp-shared@0.5.1`
|
|
126
|
+
are published and immutable. The annotated `v0.5.1` tag object `045268aa8873da330819860012ecaddb4bc2883c`
|
|
127
|
+
peels to protected-main commit `1981d7373e77f6edb4567872c1544bdbe2b1ef20`. Attempt-1 workflow run
|
|
128
|
+
`29984423571` published registry integrity `sha512-XUJq+FjY/cbarU9V1dIWnhNYcqyURTiGb6KyIzg99gy5hk/fEs5ee/8X/qvp7pw1Rshqt2J6I3TVbwJdlde2tA==`; its
|
|
129
|
+
postpublish signature check raced registry propagation and the immutable run ended
|
|
130
|
+
failed. Independent pinned npm verification confirmed the registry signature and
|
|
131
|
+
SLSA provenance, and the incident was explicitly accepted. Never rerun or move
|
|
132
|
+
that tag. `borgmcp-shared@0.6.0` was never published. Its annotated tag object
|
|
133
|
+
`90a1cf686a0ce32a7aef836b0b82a930191b9030` peels to protected-main commit
|
|
134
|
+
`fd69b08586481a60c88099dede8e4e066f73f2f2`; attempt-1 workflow run
|
|
135
|
+
`30054936226` failed in tests before build, packaging, authentication, or registry
|
|
136
|
+
mutation. Never rerun or move that tag. `borgmcp-shared@0.6.1` is published and
|
|
137
|
+
immutable. This source identifies the unpublished `0.6.2` Coordinator
|
|
138
|
+
activation-cadence release. Its release requires reviewed source and explicit publication authorization
|
|
139
|
+
through one protected publish run, followed by postpublish registry integrity,
|
|
140
|
+
signature, and attestation verification. Consumers
|
|
130
141
|
must update the reviewed shared artifact before adopting the matching server and
|
|
131
142
|
client releases; protocol v2 and v3 peers fail closed at credential-free preflight.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "borgmcp-shared",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.2",
|
|
4
4
|
"description": "Shared protocol, domain, templates, and conformance contracts for Borg MCP implementations.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -26,6 +26,10 @@
|
|
|
26
26
|
"types": "./dist/drone-address.d.ts",
|
|
27
27
|
"import": "./dist/drone-address.js"
|
|
28
28
|
},
|
|
29
|
+
"./runtime-metadata": {
|
|
30
|
+
"types": "./dist/runtime-metadata.d.ts",
|
|
31
|
+
"import": "./dist/runtime-metadata.js"
|
|
32
|
+
},
|
|
29
33
|
"./protocol": {
|
|
30
34
|
"types": "./dist/protocol/index.d.ts",
|
|
31
35
|
"import": "./dist/protocol/index.js"
|
|
@@ -7,12 +7,15 @@ import {
|
|
|
7
7
|
decodeDecisionResultEnvelope,
|
|
8
8
|
decodeDecisionsResultEnvelope,
|
|
9
9
|
decodeEnrollmentExchangeResponseEnvelope,
|
|
10
|
+
decodeAttachResponseEnvelope,
|
|
11
|
+
decodeDroneRuntimeMetadataPatch,
|
|
10
12
|
decodeEvictDroneResultEnvelope,
|
|
11
13
|
decodeProtocolEnvelope,
|
|
12
14
|
decodeProtocolErrorEnvelope,
|
|
13
15
|
decodeProtocolTagPreflight,
|
|
14
16
|
decodeReadLogResultEnvelope,
|
|
15
17
|
decodeReassignDroneResultEnvelope,
|
|
18
|
+
decodeUpdateDroneRuntimeMetadataResponseEnvelope,
|
|
16
19
|
decodeSseFrames,
|
|
17
20
|
PROTOCOL_LIMIT_CEILINGS,
|
|
18
21
|
PROTOCOL_HTTP_CONTRACT,
|
|
@@ -21,6 +24,7 @@ import {
|
|
|
21
24
|
type CreateCubeResponse,
|
|
22
25
|
type LogCursor,
|
|
23
26
|
type StreamEvent,
|
|
27
|
+
type DroneRuntimeMetadata,
|
|
24
28
|
} from '../protocol/index.js';
|
|
25
29
|
import { ENROLLMENT_RETRY_CONFORMANCE } from './index.js';
|
|
26
30
|
|
|
@@ -45,6 +49,36 @@ export interface ConformanceDrone {
|
|
|
45
49
|
readonly id: string;
|
|
46
50
|
}
|
|
47
51
|
|
|
52
|
+
export interface ConformanceDroneRuntimeState {
|
|
53
|
+
readonly metadata: DroneRuntimeMetadata;
|
|
54
|
+
readonly metadata_reported: boolean;
|
|
55
|
+
readonly metadata_revision: number;
|
|
56
|
+
readonly cube_id: string;
|
|
57
|
+
readonly role_id: string;
|
|
58
|
+
readonly session_state: 'active' | 'revoked' | 'expired';
|
|
59
|
+
readonly evicted: boolean;
|
|
60
|
+
readonly last_seen: string;
|
|
61
|
+
readonly heartbeat_count: number;
|
|
62
|
+
readonly wake_count: number;
|
|
63
|
+
readonly log_count: number;
|
|
64
|
+
readonly model_turn_count: number;
|
|
65
|
+
readonly grant_access: ConformanceCubeAccess | null;
|
|
66
|
+
readonly server_capabilities: readonly string[];
|
|
67
|
+
readonly principal_revoked: boolean;
|
|
68
|
+
readonly session_bound: boolean;
|
|
69
|
+
readonly last_log_post: string | null;
|
|
70
|
+
readonly last_regen_at: string | null;
|
|
71
|
+
readonly last_read_log_at: string | null;
|
|
72
|
+
readonly last_event_received_at: string | null;
|
|
73
|
+
readonly wake_path: 'live';
|
|
74
|
+
readonly wake_alert: null;
|
|
75
|
+
readonly monitor_armed: boolean;
|
|
76
|
+
readonly sse_connected: boolean;
|
|
77
|
+
readonly claim_count: number;
|
|
78
|
+
readonly decision_count: number;
|
|
79
|
+
readonly routing_eligible: boolean;
|
|
80
|
+
}
|
|
81
|
+
|
|
48
82
|
export type ConformanceCubeAccess = 'read' | 'write' | 'manage';
|
|
49
83
|
|
|
50
84
|
export interface ConformanceCubeManagementState {
|
|
@@ -133,6 +167,7 @@ export interface ConformanceAdmin {
|
|
|
133
167
|
readonly evicted: boolean;
|
|
134
168
|
readonly session_revoked: boolean;
|
|
135
169
|
}>;
|
|
170
|
+
inspectDroneRuntimeState(drone: ConformanceDrone): Promise<ConformanceDroneRuntimeState>;
|
|
136
171
|
/** Observes every cube field mutated by a represented manage-scoped operation. */
|
|
137
172
|
inspectCubeManagementState(cube: ConformanceCube): Promise<ConformanceCubeManagementState>;
|
|
138
173
|
grantCreateCubeCapability(principal: ConformancePrincipal): Promise<void>;
|
|
@@ -158,6 +193,12 @@ export interface ConformanceOperations {
|
|
|
158
193
|
protocol(credential: string | null): Promise<ConformanceHttpResponse>;
|
|
159
194
|
enroll(request: unknown): Promise<ConformanceHttpResponse>;
|
|
160
195
|
createCube(credential: string | null, request: unknown): Promise<ConformanceHttpResponse>;
|
|
196
|
+
attach(credential: string, request: unknown): Promise<ConformanceHttpResponse>;
|
|
197
|
+
selfMetadataUpdate(
|
|
198
|
+
credential: string,
|
|
199
|
+
cube: ConformanceCube,
|
|
200
|
+
request: unknown,
|
|
201
|
+
): Promise<ConformanceHttpResponse>;
|
|
161
202
|
append(
|
|
162
203
|
credential: string,
|
|
163
204
|
cube: ConformanceCube,
|
|
@@ -251,6 +292,13 @@ export const ADAPTER_CONFORMANCE_FIXTURES = [
|
|
|
251
292
|
{ id: 'security.cross-cube-drone-management', area: 'security' },
|
|
252
293
|
{ id: 'drones.evict-terminal-signal', area: 'drones' },
|
|
253
294
|
{ id: 'security.drone-session-rejection-causes', area: 'security' },
|
|
295
|
+
{ id: 'metadata.attach-report', area: 'metadata' },
|
|
296
|
+
{ id: 'metadata.self-heal-patch', area: 'metadata' },
|
|
297
|
+
{ id: 'security.metadata-invalid-atomic', area: 'security' },
|
|
298
|
+
{ id: 'security.metadata-own-seat', area: 'security' },
|
|
299
|
+
{ id: 'security.metadata-cross-cube-isolation', area: 'security' },
|
|
300
|
+
{ id: 'security.metadata-noninterference', area: 'security' },
|
|
301
|
+
{ id: 'security.metadata-secret-non-echo', area: 'security' },
|
|
254
302
|
{ id: 'security.active-stream-revocation', area: 'security' },
|
|
255
303
|
] as const;
|
|
256
304
|
|
|
@@ -1086,6 +1134,9 @@ export async function runAdapterConformance(
|
|
|
1086
1134
|
let readCredential = '';
|
|
1087
1135
|
let writeCredential = '';
|
|
1088
1136
|
let workerSession = '';
|
|
1137
|
+
let metadataDroneA!: ConformanceDrone;
|
|
1138
|
+
let metadataDroneB!: ConformanceDrone;
|
|
1139
|
+
let metadataSessionA = '';
|
|
1089
1140
|
await record('security.drone-management-authorization', async () => {
|
|
1090
1141
|
workerRoleA = await environment.admin.createRole(cubeA, {
|
|
1091
1142
|
roleClass: 'worker', isHumanSeat: false,
|
|
@@ -1566,6 +1617,412 @@ export async function runAdapterConformance(
|
|
|
1566
1617
|
};
|
|
1567
1618
|
});
|
|
1568
1619
|
|
|
1620
|
+
const knownMetadata = {
|
|
1621
|
+
agent_kind: 'opencode' as const,
|
|
1622
|
+
reported_model: 'openai/gpt-5.6-sol',
|
|
1623
|
+
working_repo_name: 'Byte-Ventures/borg-mcp',
|
|
1624
|
+
working_repo_origin: 'https://github.com/Byte-Ventures/borg-mcp',
|
|
1625
|
+
};
|
|
1626
|
+
await record('metadata.attach-report', async () => {
|
|
1627
|
+
metadataSessionA = 'M'.repeat(43);
|
|
1628
|
+
const created = await environment.operations.attach(
|
|
1629
|
+
credentialA,
|
|
1630
|
+
createProtocolEnvelope('metadata-attach-created', {
|
|
1631
|
+
cube_id: cubeA.id,
|
|
1632
|
+
role_id: workerRoleA.id,
|
|
1633
|
+
session_credential: metadataSessionA,
|
|
1634
|
+
runtime_metadata: {
|
|
1635
|
+
...knownMetadata,
|
|
1636
|
+
working_repo_origin: 'git@github.com:Byte-Ventures/borg-mcp.git',
|
|
1637
|
+
},
|
|
1638
|
+
}),
|
|
1639
|
+
);
|
|
1640
|
+
expectStatus(created, 200, 'Metadata attach create');
|
|
1641
|
+
const createdPayload = decodeAttachResponseEnvelope(created.body).payload;
|
|
1642
|
+
invariant(createdPayload.result === 'created', 'First metadata attach did not create a seat.');
|
|
1643
|
+
invariant(same(createdPayload.drone.runtime_metadata, knownMetadata), 'Attach did not echo canonical metadata.');
|
|
1644
|
+
invariant(createdPayload.drone.runtime_metadata_reported, 'Present attach report was not marked reported.');
|
|
1645
|
+
metadataDroneA = { id: createdPayload.drone.id };
|
|
1646
|
+
|
|
1647
|
+
const unavailableSession = 'N'.repeat(43);
|
|
1648
|
+
const unavailable = await environment.operations.attach(
|
|
1649
|
+
credentialA,
|
|
1650
|
+
createProtocolEnvelope('metadata-attach-unavailable', {
|
|
1651
|
+
cube_id: cubeA.id,
|
|
1652
|
+
role_id: workerRoleA.id,
|
|
1653
|
+
session_credential: unavailableSession,
|
|
1654
|
+
}),
|
|
1655
|
+
);
|
|
1656
|
+
expectStatus(unavailable, 200, 'Unavailable metadata attach');
|
|
1657
|
+
const unavailableDrone = decodeAttachResponseEnvelope(unavailable.body).payload.drone;
|
|
1658
|
+
invariant(
|
|
1659
|
+
same(unavailableDrone.runtime_metadata, {
|
|
1660
|
+
agent_kind: null,
|
|
1661
|
+
reported_model: null,
|
|
1662
|
+
working_repo_name: null,
|
|
1663
|
+
working_repo_origin: null,
|
|
1664
|
+
}),
|
|
1665
|
+
'Omitted attach report synthesized metadata.',
|
|
1666
|
+
);
|
|
1667
|
+
invariant(!unavailableDrone.runtime_metadata_reported, 'Omitted attach report was marked reported.');
|
|
1668
|
+
|
|
1669
|
+
const explicitUnknown = await environment.operations.attach(
|
|
1670
|
+
credentialA,
|
|
1671
|
+
createProtocolEnvelope('metadata-attach-explicit-unknown', {
|
|
1672
|
+
cube_id: cubeA.id,
|
|
1673
|
+
role_id: workerRoleA.id,
|
|
1674
|
+
session_credential: 'U'.repeat(43),
|
|
1675
|
+
runtime_metadata: {
|
|
1676
|
+
agent_kind: null,
|
|
1677
|
+
reported_model: null,
|
|
1678
|
+
working_repo_name: null,
|
|
1679
|
+
working_repo_origin: null,
|
|
1680
|
+
},
|
|
1681
|
+
}),
|
|
1682
|
+
);
|
|
1683
|
+
expectStatus(explicitUnknown, 200, 'Explicit unknown metadata attach');
|
|
1684
|
+
const explicitUnknownDrone = decodeAttachResponseEnvelope(explicitUnknown.body).payload.drone;
|
|
1685
|
+
invariant(explicitUnknownDrone.runtime_metadata_reported, 'All-null attach report was not marked reported.');
|
|
1686
|
+
|
|
1687
|
+
const reused = await environment.operations.attach(
|
|
1688
|
+
credentialA,
|
|
1689
|
+
createProtocolEnvelope('metadata-attach-reused', {
|
|
1690
|
+
cube_id: cubeA.id,
|
|
1691
|
+
role_id: workerRoleA.id,
|
|
1692
|
+
prior_drone_id: metadataDroneA.id,
|
|
1693
|
+
session_credential: metadataSessionA,
|
|
1694
|
+
runtime_metadata: knownMetadata,
|
|
1695
|
+
}),
|
|
1696
|
+
);
|
|
1697
|
+
expectStatus(reused, 200, 'Metadata attach reuse');
|
|
1698
|
+
invariant(decodeAttachResponseEnvelope(reused.body).payload.result === 'reused', 'Prior seat was not reused.');
|
|
1699
|
+
const cleared = await environment.operations.selfMetadataUpdate(
|
|
1700
|
+
metadataSessionA,
|
|
1701
|
+
cubeA,
|
|
1702
|
+
createProtocolEnvelope('metadata-clear-all', {
|
|
1703
|
+
agent_kind: null,
|
|
1704
|
+
reported_model: null,
|
|
1705
|
+
working_repo_name: null,
|
|
1706
|
+
working_repo_origin: null,
|
|
1707
|
+
}),
|
|
1708
|
+
);
|
|
1709
|
+
expectStatus(cleared, 200, 'Clear-all metadata patch');
|
|
1710
|
+
const clearedPayload = decodeUpdateDroneRuntimeMetadataResponseEnvelope(cleared.body).payload;
|
|
1711
|
+
invariant(clearedPayload.runtime_metadata_reported, 'Clear-all patch lost reported state.');
|
|
1712
|
+
invariant(
|
|
1713
|
+
same(clearedPayload.runtime_metadata, explicitUnknownDrone.runtime_metadata),
|
|
1714
|
+
'Clear-all patch did not produce explicit unknown metadata.',
|
|
1715
|
+
);
|
|
1716
|
+
expectStatus(
|
|
1717
|
+
await environment.operations.selfMetadataUpdate(
|
|
1718
|
+
metadataSessionA,
|
|
1719
|
+
cubeA,
|
|
1720
|
+
createProtocolEnvelope('metadata-restore-known', knownMetadata),
|
|
1721
|
+
),
|
|
1722
|
+
200,
|
|
1723
|
+
'Restore known metadata',
|
|
1724
|
+
);
|
|
1725
|
+
return {
|
|
1726
|
+
created: true,
|
|
1727
|
+
reused: true,
|
|
1728
|
+
report_states: [
|
|
1729
|
+
unavailableDrone.runtime_metadata_reported,
|
|
1730
|
+
explicitUnknownDrone.runtime_metadata_reported,
|
|
1731
|
+
clearedPayload.runtime_metadata_reported,
|
|
1732
|
+
],
|
|
1733
|
+
canonical_response: true,
|
|
1734
|
+
};
|
|
1735
|
+
});
|
|
1736
|
+
|
|
1737
|
+
await record('metadata.self-heal-patch', async () => {
|
|
1738
|
+
const updates = [
|
|
1739
|
+
{ request_id: 'metadata-known-new', patch: { reported_model: 'openai/gpt-5.6-terra' } },
|
|
1740
|
+
{ request_id: 'metadata-null-clear', patch: { reported_model: null } },
|
|
1741
|
+
{ request_id: 'metadata-null-repeat', patch: { reported_model: null } },
|
|
1742
|
+
{ request_id: 'metadata-same-value', patch: { agent_kind: 'opencode' as const } },
|
|
1743
|
+
];
|
|
1744
|
+
for (const update of updates) {
|
|
1745
|
+
const response = await environment.operations.selfMetadataUpdate(
|
|
1746
|
+
metadataSessionA,
|
|
1747
|
+
cubeA,
|
|
1748
|
+
createProtocolEnvelope(update.request_id, update.patch),
|
|
1749
|
+
);
|
|
1750
|
+
expectStatus(response, 200, update.request_id);
|
|
1751
|
+
decodeUpdateDroneRuntimeMetadataResponseEnvelope(response.body);
|
|
1752
|
+
}
|
|
1753
|
+
const state = await environment.admin.inspectDroneRuntimeState(metadataDroneA);
|
|
1754
|
+
invariant(state.metadata.reported_model === null, 'Explicit null did not clear model metadata.');
|
|
1755
|
+
invariant(state.metadata.agent_kind === 'opencode', 'Omitted field was not preserved.');
|
|
1756
|
+
return { known_replace: true, omitted_unchanged: true, null_clear: true, repeat_safe: true };
|
|
1757
|
+
});
|
|
1758
|
+
|
|
1759
|
+
await record('security.metadata-invalid-atomic', async () => {
|
|
1760
|
+
const invalidPatches: unknown[] = [
|
|
1761
|
+
{},
|
|
1762
|
+
{ agent_kind: 'OpenCode' },
|
|
1763
|
+
{ reported_model: '' },
|
|
1764
|
+
{ reported_model: 'a'.repeat(161) },
|
|
1765
|
+
{ reported_model: 'safe\u001b[2J' },
|
|
1766
|
+
{ reported_model: 'safe\u061cnext' },
|
|
1767
|
+
{ working_repo_name: 'owner/repo' },
|
|
1768
|
+
{ working_repo_name: 'owner/repo', working_repo_origin: 'https://user:secret@github.com/owner/repo' },
|
|
1769
|
+
{
|
|
1770
|
+
working_repo_name: 'owner/repo',
|
|
1771
|
+
working_repo_origin: ['file:/', '', 'Users', 'secret', 'repo'].join('/'),
|
|
1772
|
+
},
|
|
1773
|
+
{ role_id: workerRoleA.id },
|
|
1774
|
+
{ last_seen: '2026-07-14T10:00:00.000Z' },
|
|
1775
|
+
];
|
|
1776
|
+
for (const [index, patch] of invalidPatches.entries()) {
|
|
1777
|
+
const before = await environment.admin.inspectDroneRuntimeState(metadataDroneA);
|
|
1778
|
+
const response = await environment.operations.selfMetadataUpdate(
|
|
1779
|
+
metadataSessionA,
|
|
1780
|
+
cubeA,
|
|
1781
|
+
createProtocolEnvelope(`metadata-invalid-${index}`, patch),
|
|
1782
|
+
);
|
|
1783
|
+
expectError(response, 400, ErrorCode.INVALID_INPUT, `Invalid metadata patch ${index}`);
|
|
1784
|
+
invariant(
|
|
1785
|
+
same(await environment.admin.inspectDroneRuntimeState(metadataDroneA), before),
|
|
1786
|
+
`Invalid metadata patch ${index} partially mutated state.`,
|
|
1787
|
+
);
|
|
1788
|
+
}
|
|
1789
|
+
return { cases: invalidPatches.length, atomic: true, prior_safe_state_retained: true };
|
|
1790
|
+
});
|
|
1791
|
+
|
|
1792
|
+
await record('security.metadata-own-seat', async () => {
|
|
1793
|
+
const peer = await environment.admin.createDrone(principalA, cubeA, workerRoleA);
|
|
1794
|
+
const peerBefore = await environment.admin.inspectDroneRuntimeState(peer);
|
|
1795
|
+
const managedBefore = await environment.admin.inspectDroneRuntimeState(managedWorker);
|
|
1796
|
+
const ownBefore = await environment.admin.inspectDroneRuntimeState(metadataDroneA);
|
|
1797
|
+
const response = await environment.operations.selfMetadataUpdate(
|
|
1798
|
+
metadataSessionA,
|
|
1799
|
+
cubeA,
|
|
1800
|
+
createProtocolEnvelope('metadata-own-seat', { agent_kind: 'claude' }),
|
|
1801
|
+
);
|
|
1802
|
+
expectStatus(response, 200, 'Own-seat metadata update');
|
|
1803
|
+
invariant(
|
|
1804
|
+
same(await environment.admin.inspectDroneRuntimeState(peer), peerBefore),
|
|
1805
|
+
'Own-seat update mutated a peer seat.',
|
|
1806
|
+
);
|
|
1807
|
+
invariant(
|
|
1808
|
+
same(await environment.admin.inspectDroneRuntimeState(managedWorker), managedBefore),
|
|
1809
|
+
'Own-seat update mutated another existing seat.',
|
|
1810
|
+
);
|
|
1811
|
+
invariant(
|
|
1812
|
+
(await environment.admin.inspectDroneRuntimeState(metadataDroneA)).role_id === ownBefore.role_id,
|
|
1813
|
+
'Metadata update changed the current seat role.',
|
|
1814
|
+
);
|
|
1815
|
+
expectError(
|
|
1816
|
+
await environment.operations.selfMetadataUpdate(
|
|
1817
|
+
credentialA,
|
|
1818
|
+
cubeA,
|
|
1819
|
+
createProtocolEnvelope('metadata-manager-denied', { agent_kind: 'codex' }),
|
|
1820
|
+
),
|
|
1821
|
+
403,
|
|
1822
|
+
ErrorCode.ACCESS_DENIED,
|
|
1823
|
+
'Manager metadata update',
|
|
1824
|
+
);
|
|
1825
|
+
expectError(
|
|
1826
|
+
await environment.operations.selfMetadataUpdate(
|
|
1827
|
+
'Z'.repeat(43),
|
|
1828
|
+
cubeA,
|
|
1829
|
+
createProtocolEnvelope('metadata-invalid-session', { agent_kind: null }),
|
|
1830
|
+
),
|
|
1831
|
+
401,
|
|
1832
|
+
ErrorCode.AUTH_INVALID,
|
|
1833
|
+
'Unknown metadata session',
|
|
1834
|
+
);
|
|
1835
|
+
const rejectedStates: Array<[string, ConformanceDrone, string, number, ErrorCode]> = [];
|
|
1836
|
+
const revoked = await environment.admin.createDrone(principalA, cubeA, workerRoleA);
|
|
1837
|
+
const revokedSession = await environment.admin.issueManagedDroneSession(revoked);
|
|
1838
|
+
await environment.admin.revokeManagedDroneSession(revoked);
|
|
1839
|
+
rejectedStates.push(['revoked', revoked, revokedSession, 401, ErrorCode.SESSION_REVOKED]);
|
|
1840
|
+
const expired = await environment.admin.createDrone(principalA, cubeA, workerRoleA);
|
|
1841
|
+
const expiredSession = await environment.admin.issueManagedDroneSession(expired);
|
|
1842
|
+
await environment.admin.expireManagedDroneSession(expired);
|
|
1843
|
+
rejectedStates.push(['expired', expired, expiredSession, 401, ErrorCode.AUTH_EXPIRED]);
|
|
1844
|
+
const evicted = await environment.admin.createDrone(principalA, cubeA, workerRoleA);
|
|
1845
|
+
const evictedSession = await environment.admin.issueManagedDroneSession(evicted);
|
|
1846
|
+
expectStatus(
|
|
1847
|
+
await environment.operations.evictDrone(
|
|
1848
|
+
credentialA,
|
|
1849
|
+
cubeA,
|
|
1850
|
+
evicted,
|
|
1851
|
+
createProtocolEnvelope('metadata-evict-seat', {}),
|
|
1852
|
+
),
|
|
1853
|
+
200,
|
|
1854
|
+
'Metadata seat eviction',
|
|
1855
|
+
);
|
|
1856
|
+
rejectedStates.push(['evicted', evicted, evictedSession, 410, ErrorCode.DRONE_EVICTED]);
|
|
1857
|
+
for (const [label, drone, session, status, code] of rejectedStates) {
|
|
1858
|
+
const before = await environment.admin.inspectDroneRuntimeState(drone);
|
|
1859
|
+
expectError(
|
|
1860
|
+
await environment.operations.selfMetadataUpdate(
|
|
1861
|
+
session,
|
|
1862
|
+
cubeA,
|
|
1863
|
+
createProtocolEnvelope(`metadata-${label}-denied`, { agent_kind: null }),
|
|
1864
|
+
),
|
|
1865
|
+
status,
|
|
1866
|
+
code,
|
|
1867
|
+
`${label} metadata session`,
|
|
1868
|
+
);
|
|
1869
|
+
invariant(
|
|
1870
|
+
same(await environment.admin.inspectDroneRuntimeState(drone), before),
|
|
1871
|
+
`${label} metadata denial mutated state.`,
|
|
1872
|
+
);
|
|
1873
|
+
}
|
|
1874
|
+
return {
|
|
1875
|
+
own_seat_only: true,
|
|
1876
|
+
manager_denied: true,
|
|
1877
|
+
unknown_session_denied: true,
|
|
1878
|
+
revoked_expired_evicted_denied: true,
|
|
1879
|
+
};
|
|
1880
|
+
});
|
|
1881
|
+
|
|
1882
|
+
await record('security.metadata-cross-cube-isolation', async () => {
|
|
1883
|
+
const sessionB = 'P'.repeat(43);
|
|
1884
|
+
const metadataRoleB = await environment.admin.createRole(cubeB, {
|
|
1885
|
+
roleClass: 'worker', isHumanSeat: false,
|
|
1886
|
+
});
|
|
1887
|
+
const attachedB = await environment.operations.attach(
|
|
1888
|
+
credentialB,
|
|
1889
|
+
createProtocolEnvelope('metadata-attach-b', {
|
|
1890
|
+
cube_id: cubeB.id,
|
|
1891
|
+
role_id: metadataRoleB.id,
|
|
1892
|
+
session_credential: sessionB,
|
|
1893
|
+
runtime_metadata: {
|
|
1894
|
+
agent_kind: 'codex',
|
|
1895
|
+
reported_model: null,
|
|
1896
|
+
working_repo_name: 'Byte-Ventures/borg-mcp-server',
|
|
1897
|
+
working_repo_origin: 'https://github.com/Byte-Ventures/borg-mcp-server',
|
|
1898
|
+
},
|
|
1899
|
+
}),
|
|
1900
|
+
);
|
|
1901
|
+
expectStatus(attachedB, 200, 'Cube B metadata attach');
|
|
1902
|
+
metadataDroneB = { id: decodeAttachResponseEnvelope(attachedB.body).payload.drone.id };
|
|
1903
|
+
const beforeB = await environment.admin.inspectDroneRuntimeState(metadataDroneB);
|
|
1904
|
+
const foreign = await environment.operations.selfMetadataUpdate(
|
|
1905
|
+
metadataSessionA,
|
|
1906
|
+
cubeB,
|
|
1907
|
+
createProtocolEnvelope('metadata-cross-cube', { reported_model: 'foreign/probe' }),
|
|
1908
|
+
);
|
|
1909
|
+
expectError(foreign, 404, ErrorCode.NOT_FOUND, 'Cross-cube metadata update');
|
|
1910
|
+
const unknown = await environment.operations.selfMetadataUpdate(
|
|
1911
|
+
metadataSessionA,
|
|
1912
|
+
{ id: '90000000-0000-4000-8000-000000000001' },
|
|
1913
|
+
createProtocolEnvelope('metadata-unknown-cube', { reported_model: 'foreign/probe' }),
|
|
1914
|
+
);
|
|
1915
|
+
expectError(unknown, 404, ErrorCode.NOT_FOUND, 'Unknown-cube metadata update');
|
|
1916
|
+
invariant(same(foreign.body, unknown.body), 'Foreign and unknown metadata probes were distinguishable.');
|
|
1917
|
+
invariant(
|
|
1918
|
+
same(await environment.admin.inspectDroneRuntimeState(metadataDroneB), beforeB),
|
|
1919
|
+
'Cross-cube metadata update mutated the foreign seat.',
|
|
1920
|
+
);
|
|
1921
|
+
const listedA = await environment.operations.listDrones(credentialA, cubeA);
|
|
1922
|
+
invariant(!listedDroneIds(listedA).includes(metadataDroneB.id), 'Cube A roster disclosed cube B metadata seat.');
|
|
1923
|
+
return { update_status: 404, foreign_unknown_indistinguishable: true, foreign_unchanged: true, roster_isolated: true };
|
|
1924
|
+
});
|
|
1925
|
+
|
|
1926
|
+
await record('security.metadata-noninterference', async () => {
|
|
1927
|
+
const before = await environment.admin.inspectDroneRuntimeState(metadataDroneA);
|
|
1928
|
+
for (const [requestId, patch] of [
|
|
1929
|
+
['metadata-noninterference-known', { reported_model: 'openai/gpt-5.6-sol' }],
|
|
1930
|
+
['metadata-noninterference-repeat', { reported_model: 'openai/gpt-5.6-sol' }],
|
|
1931
|
+
['metadata-noninterference-null', { reported_model: null }],
|
|
1932
|
+
] as const) {
|
|
1933
|
+
expectStatus(
|
|
1934
|
+
await environment.operations.selfMetadataUpdate(
|
|
1935
|
+
metadataSessionA,
|
|
1936
|
+
cubeA,
|
|
1937
|
+
createProtocolEnvelope(requestId, patch),
|
|
1938
|
+
),
|
|
1939
|
+
200,
|
|
1940
|
+
requestId,
|
|
1941
|
+
);
|
|
1942
|
+
}
|
|
1943
|
+
expectError(
|
|
1944
|
+
await environment.operations.selfMetadataUpdate(
|
|
1945
|
+
metadataSessionA,
|
|
1946
|
+
cubeA,
|
|
1947
|
+
createProtocolEnvelope('metadata-noninterference-reject', { authority: 'manage' }),
|
|
1948
|
+
),
|
|
1949
|
+
400,
|
|
1950
|
+
ErrorCode.INVALID_INPUT,
|
|
1951
|
+
'Rejected metadata non-interference update',
|
|
1952
|
+
);
|
|
1953
|
+
const reattached = await environment.operations.attach(
|
|
1954
|
+
credentialA,
|
|
1955
|
+
createProtocolEnvelope('metadata-noninterference-reattach', {
|
|
1956
|
+
cube_id: cubeA.id,
|
|
1957
|
+
role_id: workerRoleA.id,
|
|
1958
|
+
prior_drone_id: metadataDroneA.id,
|
|
1959
|
+
session_credential: metadataSessionA,
|
|
1960
|
+
}),
|
|
1961
|
+
);
|
|
1962
|
+
expectStatus(reattached, 200, 'Metadata non-interference reattach');
|
|
1963
|
+
const after = await environment.admin.inspectDroneRuntimeState(metadataDroneA);
|
|
1964
|
+
const { metadata: _beforeMetadata, metadata_revision: _beforeRevision, ...beforeInvariant } = before;
|
|
1965
|
+
const { metadata: _afterMetadata, metadata_revision: _afterRevision, ...afterInvariant } = after;
|
|
1966
|
+
invariant(same(beforeInvariant, afterInvariant), 'Metadata update changed authority/liveness/log state.');
|
|
1967
|
+
return {
|
|
1968
|
+
authority_unchanged: true,
|
|
1969
|
+
role_unchanged: true,
|
|
1970
|
+
liveness_unchanged: true,
|
|
1971
|
+
logs_unchanged: true,
|
|
1972
|
+
model_turns_unchanged: true,
|
|
1973
|
+
};
|
|
1974
|
+
});
|
|
1975
|
+
|
|
1976
|
+
await record('security.metadata-secret-non-echo', async () => {
|
|
1977
|
+
const marker = 'SECRET-METADATA-MARKER';
|
|
1978
|
+
const before = await environment.admin.inspectDroneRuntimeState(metadataDroneA);
|
|
1979
|
+
const response = await environment.operations.selfMetadataUpdate(
|
|
1980
|
+
metadataSessionA,
|
|
1981
|
+
cubeA,
|
|
1982
|
+
createProtocolEnvelope('metadata-secret', {
|
|
1983
|
+
working_repo_name: 'owner/repo',
|
|
1984
|
+
working_repo_origin: `https://user:${marker}@github.com/owner/repo?token=${marker}`,
|
|
1985
|
+
}),
|
|
1986
|
+
);
|
|
1987
|
+
expectError(response, 400, ErrorCode.INVALID_INPUT, 'Secret-bearing metadata update');
|
|
1988
|
+
invariant(!JSON.stringify(response.body).includes(marker), 'Metadata error echoed hostile secret input.');
|
|
1989
|
+
invariant(
|
|
1990
|
+
same(await environment.admin.inspectDroneRuntimeState(metadataDroneA), before),
|
|
1991
|
+
'Secret-bearing metadata input was persisted.',
|
|
1992
|
+
);
|
|
1993
|
+
const hostileKeys = [
|
|
1994
|
+
'SECRET-METADATA-KEY-MARKER',
|
|
1995
|
+
`control\u001b[2J`,
|
|
1996
|
+
`bidi\u061cmarker`,
|
|
1997
|
+
`token_${'a'.repeat(48)}`,
|
|
1998
|
+
];
|
|
1999
|
+
for (const [index, key] of hostileKeys.entries()) {
|
|
2000
|
+
const rejected = await environment.operations.selfMetadataUpdate(
|
|
2001
|
+
metadataSessionA,
|
|
2002
|
+
cubeA,
|
|
2003
|
+
createProtocolEnvelope(`metadata-secret-key-${index}`, { [key]: 'x' }),
|
|
2004
|
+
);
|
|
2005
|
+
expectError(rejected, 400, ErrorCode.INVALID_INPUT, `Hostile metadata key ${index}`);
|
|
2006
|
+
invariant(!JSON.stringify(rejected.body).includes(key), `Metadata error echoed hostile key ${index}.`);
|
|
2007
|
+
}
|
|
2008
|
+
const logs = await environment.operations.read(
|
|
2009
|
+
credentialA,
|
|
2010
|
+
cubeA,
|
|
2011
|
+
createProtocolEnvelope('metadata-secret-log-read', { cursor: null, limit: 500 }),
|
|
2012
|
+
);
|
|
2013
|
+
expectStatus(logs, 200, 'Metadata secret log read');
|
|
2014
|
+
for (const hostile of [marker, ...hostileKeys]) {
|
|
2015
|
+
invariant(!JSON.stringify(logs.body).includes(hostile), 'Metadata input leaked into activity logs.');
|
|
2016
|
+
}
|
|
2017
|
+
return {
|
|
2018
|
+
rejected_pre_persistence: true,
|
|
2019
|
+
response_secret_free: true,
|
|
2020
|
+
state_secret_free: true,
|
|
2021
|
+
log_secret_free: true,
|
|
2022
|
+
unknown_key_secret_free: true,
|
|
2023
|
+
};
|
|
2024
|
+
});
|
|
2025
|
+
|
|
1569
2026
|
await record('security.active-stream-revocation', async () => {
|
|
1570
2027
|
invariant(liveCursor, 'Stream fixture did not produce a live cursor.');
|
|
1571
2028
|
const opened = await environment.operations.openStream(credentialA, cubeA, liveCursor);
|