borgmcp-shared 0.2.2 → 0.4.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 +52 -35
- package/dist/conformance/adapter.d.ts +34 -6
- package/dist/conformance/adapter.d.ts.map +1 -1
- package/dist/conformance/adapter.js +215 -54
- package/dist/conformance/adapter.js.map +1 -1
- package/dist/conformance/index.d.ts +49 -0
- package/dist/conformance/index.d.ts.map +1 -1
- package/dist/conformance/index.js +111 -0
- package/dist/conformance/index.js.map +1 -1
- package/dist/protocol/contract.d.ts +81 -28
- package/dist/protocol/contract.d.ts.map +1 -1
- package/dist/protocol/contract.js +213 -128
- package/dist/protocol/contract.js.map +1 -1
- package/dist/protocol/errors.d.ts +2 -4
- package/dist/protocol/errors.d.ts.map +1 -1
- package/dist/protocol/errors.js +1 -1
- package/dist/protocol/errors.js.map +1 -1
- package/dist/protocol/version.d.ts +2 -10
- package/dist/protocol/version.d.ts.map +1 -1
- package/dist/protocol/version.js +1 -13
- package/dist/protocol/version.js.map +1 -1
- package/docs/compatibility.md +44 -25
- package/docs/enrollment.md +167 -0
- package/docs/releasing.md +77 -6
- package/package.json +2 -1
- package/src/conformance/adapter.ts +386 -63
- package/src/conformance/index.ts +139 -0
- package/src/protocol/contract.ts +373 -180
- package/src/protocol/errors.ts +7 -3
- package/src/protocol/version.ts +3 -30
package/src/conformance/index.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { BroadcastHwm } from '../log-stream-hwm.js';
|
|
2
|
+
import type { EnrollmentExchangeRequest } from '../protocol/contract.js';
|
|
2
3
|
|
|
3
4
|
export * from './adapter.js';
|
|
4
5
|
|
|
@@ -66,3 +67,141 @@ export const ROLE_SECTION_ROUND_TRIP_CONFORMANCE: readonly string[] = [
|
|
|
66
67
|
'Preamble.\n\nWorkflow:\n- step one\n\nProject conventions:\n- TDD.\n',
|
|
67
68
|
'**Markdown heading:**\nMust remain part of the preamble.\n',
|
|
68
69
|
];
|
|
70
|
+
|
|
71
|
+
export interface EnrollmentRetryConformanceVector {
|
|
72
|
+
name: string;
|
|
73
|
+
initial: EnrollmentExchangeRequest;
|
|
74
|
+
retry: EnrollmentExchangeRequest;
|
|
75
|
+
expected:
|
|
76
|
+
| {
|
|
77
|
+
outcome: 'stable_non_secret_identity';
|
|
78
|
+
status: 201;
|
|
79
|
+
forbidden_response_fields: readonly [
|
|
80
|
+
'credential',
|
|
81
|
+
'client_credential',
|
|
82
|
+
'invitation',
|
|
83
|
+
'retry_key',
|
|
84
|
+
];
|
|
85
|
+
}
|
|
86
|
+
| {
|
|
87
|
+
outcome: 'uniform_auth_invalid';
|
|
88
|
+
status: 401;
|
|
89
|
+
error: 'AUTH_INVALID';
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
const ENROLLMENT_INVITATION = 'I'.repeat(43);
|
|
94
|
+
const ENROLLMENT_CREDENTIAL = 'A'.repeat(43);
|
|
95
|
+
const ENROLLMENT_RETRY_KEY = '00000000-0000-4000-8000-000000000101';
|
|
96
|
+
|
|
97
|
+
/** Stateful vectors: adapters must compare the complete canonical retry tuple. */
|
|
98
|
+
export const ENROLLMENT_RETRY_CONFORMANCE: readonly EnrollmentRetryConformanceVector[] = [
|
|
99
|
+
{
|
|
100
|
+
name: 'exact credential-proven retry returns stable non-secret identities',
|
|
101
|
+
initial: {
|
|
102
|
+
invitation: ENROLLMENT_INVITATION,
|
|
103
|
+
retry_key: ENROLLMENT_RETRY_KEY,
|
|
104
|
+
client_credential: ENROLLMENT_CREDENTIAL,
|
|
105
|
+
client_name: 'operator-laptop',
|
|
106
|
+
},
|
|
107
|
+
retry: {
|
|
108
|
+
invitation: ENROLLMENT_INVITATION,
|
|
109
|
+
retry_key: ENROLLMENT_RETRY_KEY,
|
|
110
|
+
client_credential: ENROLLMENT_CREDENTIAL,
|
|
111
|
+
client_name: 'operator-laptop',
|
|
112
|
+
},
|
|
113
|
+
expected: {
|
|
114
|
+
outcome: 'stable_non_secret_identity',
|
|
115
|
+
status: 201,
|
|
116
|
+
forbidden_response_fields: [
|
|
117
|
+
'credential',
|
|
118
|
+
'client_credential',
|
|
119
|
+
'invitation',
|
|
120
|
+
'retry_key',
|
|
121
|
+
],
|
|
122
|
+
},
|
|
123
|
+
},
|
|
124
|
+
{
|
|
125
|
+
name: 'retry-key mismatch is uniformly invalid',
|
|
126
|
+
initial: {
|
|
127
|
+
invitation: ENROLLMENT_INVITATION,
|
|
128
|
+
retry_key: ENROLLMENT_RETRY_KEY,
|
|
129
|
+
client_credential: ENROLLMENT_CREDENTIAL,
|
|
130
|
+
},
|
|
131
|
+
retry: {
|
|
132
|
+
invitation: ENROLLMENT_INVITATION,
|
|
133
|
+
retry_key: '00000000-0000-4000-8000-000000000102',
|
|
134
|
+
client_credential: ENROLLMENT_CREDENTIAL,
|
|
135
|
+
},
|
|
136
|
+
expected: { outcome: 'uniform_auth_invalid', status: 401, error: 'AUTH_INVALID' },
|
|
137
|
+
},
|
|
138
|
+
{
|
|
139
|
+
name: 'credential mismatch is uniformly invalid',
|
|
140
|
+
initial: {
|
|
141
|
+
invitation: ENROLLMENT_INVITATION,
|
|
142
|
+
retry_key: ENROLLMENT_RETRY_KEY,
|
|
143
|
+
client_credential: ENROLLMENT_CREDENTIAL,
|
|
144
|
+
},
|
|
145
|
+
retry: {
|
|
146
|
+
invitation: ENROLLMENT_INVITATION,
|
|
147
|
+
retry_key: ENROLLMENT_RETRY_KEY,
|
|
148
|
+
client_credential: 'E'.repeat(43),
|
|
149
|
+
},
|
|
150
|
+
expected: { outcome: 'uniform_auth_invalid', status: 401, error: 'AUTH_INVALID' },
|
|
151
|
+
},
|
|
152
|
+
{
|
|
153
|
+
name: 'client-name mismatch is uniformly invalid',
|
|
154
|
+
initial: {
|
|
155
|
+
invitation: ENROLLMENT_INVITATION,
|
|
156
|
+
retry_key: ENROLLMENT_RETRY_KEY,
|
|
157
|
+
client_credential: ENROLLMENT_CREDENTIAL,
|
|
158
|
+
client_name: 'operator-laptop',
|
|
159
|
+
},
|
|
160
|
+
retry: {
|
|
161
|
+
invitation: ENROLLMENT_INVITATION,
|
|
162
|
+
retry_key: ENROLLMENT_RETRY_KEY,
|
|
163
|
+
client_credential: ENROLLMENT_CREDENTIAL,
|
|
164
|
+
client_name: 'different-client',
|
|
165
|
+
},
|
|
166
|
+
expected: { outcome: 'uniform_auth_invalid', status: 401, error: 'AUTH_INVALID' },
|
|
167
|
+
},
|
|
168
|
+
];
|
|
169
|
+
|
|
170
|
+
export const ENROLLMENT_AUTHORITY_CONFORMANCE = [
|
|
171
|
+
{
|
|
172
|
+
name: 'ordinary enrollment creates no authority or cube state',
|
|
173
|
+
response: {
|
|
174
|
+
purpose: 'client',
|
|
175
|
+
client_id: '00000000-0000-4000-8000-000000000111',
|
|
176
|
+
server_capabilities: [],
|
|
177
|
+
},
|
|
178
|
+
expected_state_delta: { cubes: 0, roles: 0, grants: 0, server_capabilities: 0 },
|
|
179
|
+
},
|
|
180
|
+
{
|
|
181
|
+
name: 'owner enrollment grants create-cube authority without cube state',
|
|
182
|
+
response: {
|
|
183
|
+
purpose: 'owner',
|
|
184
|
+
client_id: '00000000-0000-4000-8000-000000000111',
|
|
185
|
+
server_capabilities: ['create_cube'],
|
|
186
|
+
},
|
|
187
|
+
expected_state_delta: { cubes: 0, roles: 0, grants: 0, server_capabilities: 1 },
|
|
188
|
+
},
|
|
189
|
+
] as const;
|
|
190
|
+
|
|
191
|
+
export const ENROLLMENT_REDACTION_CONFORMANCE: readonly ConformanceVector<string, string>[] = [
|
|
192
|
+
{
|
|
193
|
+
name: 'redacts invitation and client credential from diagnostics',
|
|
194
|
+
input: `invitation=${ENROLLMENT_INVITATION} client_credential=${ENROLLMENT_CREDENTIAL}`,
|
|
195
|
+
expected: 'invitation=<REDACTED> client_credential=<REDACTED>',
|
|
196
|
+
},
|
|
197
|
+
{
|
|
198
|
+
name: 'redacts a contextual enrollment retry key',
|
|
199
|
+
input: `retry_key=${ENROLLMENT_RETRY_KEY}`,
|
|
200
|
+
expected: 'retry_key=<REDACTED>',
|
|
201
|
+
},
|
|
202
|
+
{
|
|
203
|
+
name: 'preserves unrelated public UUIDs',
|
|
204
|
+
input: `cube_id=${ENROLLMENT_RETRY_KEY}`,
|
|
205
|
+
expected: `cube_id=${ENROLLMENT_RETRY_KEY}`,
|
|
206
|
+
},
|
|
207
|
+
];
|