@cotal-ai/core 0.54.0 → 0.56.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/dist/auth-provider.d.ts +24 -1
- package/dist/auth-provider.d.ts.map +1 -1
- package/dist/auth-provider.js.map +1 -1
- package/dist/connector.d.ts +7 -1
- package/dist/connector.d.ts.map +1 -1
- package/dist/connector.js.map +1 -1
- package/dist/endpoint-invoke.js +1 -1
- package/dist/endpoint-invoke.js.map +1 -1
- package/dist/endpoint.d.ts +50 -3
- package/dist/endpoint.d.ts.map +1 -1
- package/dist/endpoint.js +125 -23
- package/dist/endpoint.js.map +1 -1
- package/dist/provision.d.ts +23 -0
- package/dist/provision.d.ts.map +1 -1
- package/dist/provision.js +71 -10
- package/dist/provision.js.map +1 -1
- package/dist/remote-manager-authority.d.ts +111 -0
- package/dist/remote-manager-authority.d.ts.map +1 -1
- package/dist/remote-manager-authority.js +175 -1
- package/dist/remote-manager-authority.js.map +1 -1
- package/dist/resolve.d.ts +13 -0
- package/dist/resolve.d.ts.map +1 -1
- package/dist/resolve.js +16 -0
- package/dist/resolve.js.map +1 -1
- package/dist/schema-profile.d.ts.map +1 -1
- package/dist/schema-profile.js +87 -8
- package/dist/schema-profile.js.map +1 -1
- package/dist/streams.d.ts +21 -21
- package/dist/streams.d.ts.map +1 -1
- package/dist/streams.js +52 -29
- package/dist/streams.js.map +1 -1
- package/dist/subjects.d.ts +18 -0
- package/dist/subjects.d.ts.map +1 -1
- package/dist/subjects.js +21 -0
- package/dist/subjects.js.map +1 -1
- package/package.json +2 -2
|
@@ -89,6 +89,10 @@ export interface RemoteManagerAuthorityMaterial {
|
|
|
89
89
|
registrationProof?: string;
|
|
90
90
|
retirement?: RemoteManagerAuthorityRequest["retirement"];
|
|
91
91
|
issuedAt: number;
|
|
92
|
+
/** Earliest `exp` among the envelope's credentials, in milliseconds, as the issuer computes it.
|
|
93
|
+
* The manager never compares it with a clock: each credential is a signed JWT whose `exp` the
|
|
94
|
+
* broker verifies at connect, which is where expiry is enforced. Locally it is a coherence
|
|
95
|
+
* bound: `materialCredential` refuses a credential whose own `exp` disagrees with it. */
|
|
92
96
|
expiresAt: number;
|
|
93
97
|
actors: RemoteManagerActors;
|
|
94
98
|
identities: RemoteManagerAuthorityRequest["identities"];
|
|
@@ -248,10 +252,117 @@ export interface RemoteManagerAdminAuthorizationResult {
|
|
|
248
252
|
caller: RemoteManagerAdminAuthorizationRequest["caller"];
|
|
249
253
|
authorized: boolean;
|
|
250
254
|
}
|
|
255
|
+
/**
|
|
256
|
+
* Closed wire request for host-owned managed agent enrollment (#1972).
|
|
257
|
+
*
|
|
258
|
+
* The participant generates the standing `actorToken` locally, persists it at 0600 BEFORE the
|
|
259
|
+
* request, and sends ONLY its SHA-256 digest. The plaintext secret never leaves the participant
|
|
260
|
+
* machine. The host alone picks the lifecycle UID, so the request carries none: a participant that
|
|
261
|
+
* could name the UID could aim a fresh grant at a retired or retiring incarnation.
|
|
262
|
+
*/
|
|
263
|
+
export interface RemoteManagedAgentEnrollmentRequest {
|
|
264
|
+
v: 1;
|
|
265
|
+
kind: "manager-managed-agent-enrollment";
|
|
266
|
+
space: string;
|
|
267
|
+
/** The interactive actor whose fresh `supervise` grant authorizes this manager lifecycle. */
|
|
268
|
+
actor: string;
|
|
269
|
+
instanceId: string;
|
|
270
|
+
managerLifecycleUid: string;
|
|
271
|
+
requestId: string;
|
|
272
|
+
registrationProof: string;
|
|
273
|
+
serveEpoch: number;
|
|
274
|
+
target: {
|
|
275
|
+
actor: string;
|
|
276
|
+
/** SHA-256 hash of the locally generated actorToken. Plaintext never leaves the participant. */
|
|
277
|
+
tokenHash: string;
|
|
278
|
+
role?: string;
|
|
279
|
+
label?: string;
|
|
280
|
+
capabilities?: string[];
|
|
281
|
+
subscribe?: string[];
|
|
282
|
+
allowSubscribe?: string[];
|
|
283
|
+
allowPublish?: string[];
|
|
284
|
+
};
|
|
285
|
+
identities: RemoteManagerAuthorityRequest["identities"];
|
|
286
|
+
}
|
|
287
|
+
/** Host-issued authority material returned to the remote manager upon enrollment. */
|
|
288
|
+
export interface RemoteManagedAgentEnrollmentResult {
|
|
289
|
+
v: 1;
|
|
290
|
+
kind: "manager-managed-agent-enrollment";
|
|
291
|
+
space: string;
|
|
292
|
+
owner: string;
|
|
293
|
+
actor: string;
|
|
294
|
+
instanceId: string;
|
|
295
|
+
managerLifecycleUid: string;
|
|
296
|
+
requestId: string;
|
|
297
|
+
registrationProof: string;
|
|
298
|
+
serveEpoch: number;
|
|
299
|
+
material: {
|
|
300
|
+
owner: string;
|
|
301
|
+
actor: string;
|
|
302
|
+
lifecycleUid: string;
|
|
303
|
+
/** Space-wide callout sentinel credentials, NOT per-agent material. */
|
|
304
|
+
sentinelCreds: string;
|
|
305
|
+
subscribe: string[];
|
|
306
|
+
allowSubscribe: string[];
|
|
307
|
+
allowPublish: string[];
|
|
308
|
+
/** Pinned public auth-service base URL for agent bearer exchange. */
|
|
309
|
+
agentBearerExchangeUrl: string;
|
|
310
|
+
};
|
|
311
|
+
}
|
|
312
|
+
/**
|
|
313
|
+
* Closed wire request for host preparation of terminal managed agent retirement (#1972 P0/P1).
|
|
314
|
+
*
|
|
315
|
+
* The opId is derived from the target lifecycle UID, never selected: the participant's retries,
|
|
316
|
+
* the host's release, and the terminal auth barrier all converge on one operation.
|
|
317
|
+
*/
|
|
318
|
+
export interface RemoteManagedAgentPrepareRetirementRequest {
|
|
319
|
+
v: 1;
|
|
320
|
+
kind: "manager-managed-agent-prepare-retirement";
|
|
321
|
+
space: string;
|
|
322
|
+
actor: string;
|
|
323
|
+
instanceId: string;
|
|
324
|
+
managerLifecycleUid: string;
|
|
325
|
+
requestId: string;
|
|
326
|
+
registrationProof: string;
|
|
327
|
+
serveEpoch: number;
|
|
328
|
+
target: {
|
|
329
|
+
owner: string;
|
|
330
|
+
actor: string;
|
|
331
|
+
lifecycleUid: string;
|
|
332
|
+
};
|
|
333
|
+
opId: string;
|
|
334
|
+
identities: RemoteManagerAuthorityRequest["identities"];
|
|
335
|
+
}
|
|
336
|
+
/** Release confirmation returned once the host committed phase P1. */
|
|
337
|
+
export interface RemoteManagedAgentPrepareRetirementResult {
|
|
338
|
+
v: 1;
|
|
339
|
+
kind: "manager-managed-agent-prepare-retirement";
|
|
340
|
+
space: string;
|
|
341
|
+
owner: string;
|
|
342
|
+
actor: string;
|
|
343
|
+
instanceId: string;
|
|
344
|
+
managerLifecycleUid: string;
|
|
345
|
+
requestId: string;
|
|
346
|
+
target: RemoteManagedAgentPrepareRetirementRequest["target"];
|
|
347
|
+
opId: string;
|
|
348
|
+
prepared: true;
|
|
349
|
+
}
|
|
251
350
|
export declare function remoteManagerActors(instanceId: string): RemoteManagerActors;
|
|
252
351
|
/** Deterministic proof binding one remote Manager lifecycle to its owner, identities, and artifacts. */
|
|
253
352
|
export declare function remoteManagerRegistrationProof(owner: string, request: RemoteManagerAuthorityRequest): string;
|
|
254
353
|
/** The one terminal operation identity for a managed lifecycle. It is derived, never selected:
|
|
255
354
|
* manager retries, hosted authority issuance, and the auth barrier therefore converge on one op. */
|
|
256
355
|
export declare function managedRetirementOpId(lifecycleUid: string): string;
|
|
356
|
+
/**
|
|
357
|
+
* Parse the enrollment request without retaining unknown input fields. The host derives the
|
|
358
|
+
* lifecycle UID, the role, and the effective ACLs itself, so this parser proves only that what
|
|
359
|
+
* arrived is in-grammar and bounded; it never widens a grant.
|
|
360
|
+
*/
|
|
361
|
+
export declare function parseRemoteManagedAgentEnrollmentRequest(raw: unknown): RemoteManagedAgentEnrollmentRequest;
|
|
362
|
+
/**
|
|
363
|
+
* Parse the prepare-retirement request without retaining unknown input fields. The opId is checked
|
|
364
|
+
* against {@link managedRetirementOpId} here, so a caller cannot name a second operation for one
|
|
365
|
+
* lifecycle and split the terminal barrier in two.
|
|
366
|
+
*/
|
|
367
|
+
export declare function parseRemoteManagedAgentPrepareRetirementRequest(raw: unknown): RemoteManagedAgentPrepareRetirementRequest;
|
|
257
368
|
//# sourceMappingURL=remote-manager-authority.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"remote-manager-authority.d.ts","sourceRoot":"","sources":["../src/remote-manager-authority.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"remote-manager-authority.d.ts","sourceRoot":"","sources":["../src/remote-manager-authority.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { rawDigest } from "./canonical.js";
|
|
2
|
-
import {
|
|
2
|
+
import { EpEnvelopeError } from "./endpoint-error.js";
|
|
3
|
+
import { assertDerivedOwnerToken, assertLifecycleToken, assertValidChannel, assertValidOwnerToken } from "./subjects.js";
|
|
3
4
|
export function remoteManagerActors(instanceId) {
|
|
4
5
|
return {
|
|
5
6
|
supervisor: `manager_${instanceId}`,
|
|
@@ -28,4 +29,177 @@ export function remoteManagerRegistrationProof(owner, request) {
|
|
|
28
29
|
export function managedRetirementOpId(lifecycleUid) {
|
|
29
30
|
return rawDigest(`retire:${assertLifecycleToken(lifecycleUid)}`).slice("sha256:".length, "sha256:".length + 26);
|
|
30
31
|
}
|
|
32
|
+
const IDENTITY_NAMES = ["supervisor", "executor", "serve", "goalWriter", "sessionLedger"];
|
|
33
|
+
/** The bound on one enrollment ACL list. A grant wider than this is a configuration mistake, and a
|
|
34
|
+
* request carrying thousands of patterns is a body-size attack on the host's derivation. */
|
|
35
|
+
const MAX_ENROLLMENT_LIST = 64;
|
|
36
|
+
function enrollmentError(what, detail) {
|
|
37
|
+
throw new EpEnvelopeError("bad-request", `${what} request ${detail}`);
|
|
38
|
+
}
|
|
39
|
+
/** The envelope fields every managed-agent request shares, validated once for both parsers. */
|
|
40
|
+
function parseManagedAgentEnvelope(o, what, kind) {
|
|
41
|
+
if (o.v !== 1 || o.kind !== kind)
|
|
42
|
+
enrollmentError(what, `must carry { v: 1, kind: ${JSON.stringify(kind)} }`);
|
|
43
|
+
for (const key of ["space", "actor", "instanceId", "managerLifecycleUid", "requestId", "registrationProof"])
|
|
44
|
+
if (typeof o[key] !== "string" || o[key].length === 0)
|
|
45
|
+
enrollmentError(what, `requires non-empty ${key}`);
|
|
46
|
+
assertValidOwnerToken(o.actor);
|
|
47
|
+
assertLifecycleToken(o.instanceId, `${what} instanceId`);
|
|
48
|
+
assertLifecycleToken(o.managerLifecycleUid, `${what} lifecycleUid`);
|
|
49
|
+
if (!/^[A-Za-z0-9_-]{22,64}$/.test(o.requestId))
|
|
50
|
+
enrollmentError(what, "requestId must be a 22-64 character idempotency token");
|
|
51
|
+
if (!/^sha256:[0-9a-f]{64}$/.test(o.registrationProof))
|
|
52
|
+
enrollmentError(what, "requires a sha256 registrationProof");
|
|
53
|
+
if (typeof o.serveEpoch !== "number" || !Number.isSafeInteger(o.serveEpoch) || o.serveEpoch < 0)
|
|
54
|
+
enrollmentError(what, "serveEpoch must be a non-negative safe integer");
|
|
55
|
+
const ids = o.identities;
|
|
56
|
+
if (ids === null || typeof ids !== "object" || Array.isArray(ids))
|
|
57
|
+
enrollmentError(what, "requires identities");
|
|
58
|
+
const idObj = ids;
|
|
59
|
+
if (Object.keys(idObj).sort().join(",") !== [...IDENTITY_NAMES].sort().join(","))
|
|
60
|
+
enrollmentError(what, `identities must contain exactly ${IDENTITY_NAMES.join(", ")}`);
|
|
61
|
+
const identities = {};
|
|
62
|
+
for (const name of IDENTITY_NAMES) {
|
|
63
|
+
const item = idObj[name];
|
|
64
|
+
if (item === null || typeof item !== "object" || Array.isArray(item) || Object.keys(item).join(",") !== "id")
|
|
65
|
+
enrollmentError(what, `identities.${name} must be exactly { id }`);
|
|
66
|
+
const id = item.id;
|
|
67
|
+
if (typeof id !== "string" || !/^U[A-Z2-7]{55}$/.test(id))
|
|
68
|
+
enrollmentError(what, `identities.${name}.id must be a user nkey`);
|
|
69
|
+
identities[name] = { id };
|
|
70
|
+
}
|
|
71
|
+
return {
|
|
72
|
+
space: o.space,
|
|
73
|
+
actor: o.actor,
|
|
74
|
+
instanceId: o.instanceId,
|
|
75
|
+
managerLifecycleUid: o.managerLifecycleUid,
|
|
76
|
+
requestId: o.requestId,
|
|
77
|
+
registrationProof: o.registrationProof,
|
|
78
|
+
serveEpoch: o.serveEpoch,
|
|
79
|
+
identities,
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
/** One optional channel/pattern list on an enrollment target: bounded, string-only, in-grammar. */
|
|
83
|
+
function parseEnrollmentList(value, what, field) {
|
|
84
|
+
if (value === undefined)
|
|
85
|
+
return undefined;
|
|
86
|
+
if (!Array.isArray(value))
|
|
87
|
+
enrollmentError(what, `target.${field} must be an array of channel patterns when present`);
|
|
88
|
+
if (value.length > MAX_ENROLLMENT_LIST)
|
|
89
|
+
enrollmentError(what, `target.${field} carries ${value.length} entries, more than the ${MAX_ENROLLMENT_LIST}-entry bound`);
|
|
90
|
+
for (const item of value) {
|
|
91
|
+
if (typeof item !== "string" || item.length === 0)
|
|
92
|
+
enrollmentError(what, `target.${field} must contain only non-empty strings`);
|
|
93
|
+
assertValidChannel(item);
|
|
94
|
+
}
|
|
95
|
+
return [...value];
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Parse the enrollment request without retaining unknown input fields. The host derives the
|
|
99
|
+
* lifecycle UID, the role, and the effective ACLs itself, so this parser proves only that what
|
|
100
|
+
* arrived is in-grammar and bounded; it never widens a grant.
|
|
101
|
+
*/
|
|
102
|
+
export function parseRemoteManagedAgentEnrollmentRequest(raw) {
|
|
103
|
+
const what = "managed agent enrollment";
|
|
104
|
+
if (raw === null || typeof raw !== "object" || Array.isArray(raw))
|
|
105
|
+
enrollmentError(what, "must be an object");
|
|
106
|
+
const o = raw;
|
|
107
|
+
const allowed = new Set([
|
|
108
|
+
"v", "kind", "space", "actor", "instanceId", "managerLifecycleUid", "requestId",
|
|
109
|
+
"registrationProof", "serveEpoch", "target", "identities",
|
|
110
|
+
]);
|
|
111
|
+
for (const key of Object.keys(o))
|
|
112
|
+
if (!allowed.has(key))
|
|
113
|
+
enrollmentError(what, `carries unknown field ${JSON.stringify(key)} (the protocol is closed)`);
|
|
114
|
+
const envelope = parseManagedAgentEnvelope(o, what, "manager-managed-agent-enrollment");
|
|
115
|
+
const target = o.target;
|
|
116
|
+
if (target === null || typeof target !== "object" || Array.isArray(target))
|
|
117
|
+
enrollmentError(what, "requires a target");
|
|
118
|
+
const t = target;
|
|
119
|
+
const targetAllowed = new Set(["actor", "tokenHash", "role", "label", "capabilities", "subscribe", "allowSubscribe", "allowPublish"]);
|
|
120
|
+
for (const key of Object.keys(t))
|
|
121
|
+
if (!targetAllowed.has(key))
|
|
122
|
+
enrollmentError(what, `target carries unknown field ${JSON.stringify(key)} (the protocol is closed)`);
|
|
123
|
+
if (typeof t.actor !== "string" || t.actor.length === 0)
|
|
124
|
+
enrollmentError(what, "target requires a non-empty actor");
|
|
125
|
+
assertValidOwnerToken(t.actor);
|
|
126
|
+
// The digest, never the secret: a request that carried the plaintext standing token would put an
|
|
127
|
+
// agent's whole exchange authority on the wire and in the host's logs.
|
|
128
|
+
if (typeof t.tokenHash !== "string" || !/^[0-9a-f]{64}$/.test(t.tokenHash))
|
|
129
|
+
enrollmentError(what, "target.tokenHash must be a lowercase hex sha256 digest of the locally held actorToken");
|
|
130
|
+
if (t.role !== undefined && (typeof t.role !== "string" || !/^[A-Za-z0-9_-]{1,64}$/.test(t.role)))
|
|
131
|
+
enrollmentError(what, "target.role must be a 1-64 character role token when present");
|
|
132
|
+
if (t.label !== undefined && (typeof t.label !== "string" || t.label.length === 0 || t.label.length > 256))
|
|
133
|
+
enrollmentError(what, "target.label must be a 1-256 character string when present");
|
|
134
|
+
if (t.capabilities !== undefined) {
|
|
135
|
+
if (!Array.isArray(t.capabilities))
|
|
136
|
+
enrollmentError(what, "target.capabilities must be an array when present");
|
|
137
|
+
if (t.capabilities.length > MAX_ENROLLMENT_LIST)
|
|
138
|
+
enrollmentError(what, `target.capabilities carries ${t.capabilities.length} entries, more than the ${MAX_ENROLLMENT_LIST}-entry bound`);
|
|
139
|
+
for (const cap of t.capabilities)
|
|
140
|
+
if (typeof cap !== "string" || !/^[A-Za-z0-9_:-]{1,64}$/.test(cap))
|
|
141
|
+
enrollmentError(what, "target.capabilities must contain only 1-64 character capability tokens");
|
|
142
|
+
}
|
|
143
|
+
const subscribe = parseEnrollmentList(t.subscribe, what, "subscribe");
|
|
144
|
+
const allowSubscribe = parseEnrollmentList(t.allowSubscribe, what, "allowSubscribe");
|
|
145
|
+
const allowPublish = parseEnrollmentList(t.allowPublish, what, "allowPublish");
|
|
146
|
+
return {
|
|
147
|
+
v: 1,
|
|
148
|
+
kind: "manager-managed-agent-enrollment",
|
|
149
|
+
...envelope,
|
|
150
|
+
target: {
|
|
151
|
+
actor: t.actor,
|
|
152
|
+
tokenHash: t.tokenHash,
|
|
153
|
+
...(t.role !== undefined ? { role: t.role } : {}),
|
|
154
|
+
...(t.label !== undefined ? { label: t.label } : {}),
|
|
155
|
+
...(t.capabilities !== undefined ? { capabilities: [...t.capabilities] } : {}),
|
|
156
|
+
...(subscribe !== undefined ? { subscribe } : {}),
|
|
157
|
+
...(allowSubscribe !== undefined ? { allowSubscribe } : {}),
|
|
158
|
+
...(allowPublish !== undefined ? { allowPublish } : {}),
|
|
159
|
+
},
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Parse the prepare-retirement request without retaining unknown input fields. The opId is checked
|
|
164
|
+
* against {@link managedRetirementOpId} here, so a caller cannot name a second operation for one
|
|
165
|
+
* lifecycle and split the terminal barrier in two.
|
|
166
|
+
*/
|
|
167
|
+
export function parseRemoteManagedAgentPrepareRetirementRequest(raw) {
|
|
168
|
+
const what = "managed agent prepare-retirement";
|
|
169
|
+
if (raw === null || typeof raw !== "object" || Array.isArray(raw))
|
|
170
|
+
enrollmentError(what, "must be an object");
|
|
171
|
+
const o = raw;
|
|
172
|
+
const allowed = new Set([
|
|
173
|
+
"v", "kind", "space", "actor", "instanceId", "managerLifecycleUid", "requestId",
|
|
174
|
+
"registrationProof", "serveEpoch", "target", "opId", "identities",
|
|
175
|
+
]);
|
|
176
|
+
for (const key of Object.keys(o))
|
|
177
|
+
if (!allowed.has(key))
|
|
178
|
+
enrollmentError(what, `carries unknown field ${JSON.stringify(key)} (the protocol is closed)`);
|
|
179
|
+
const envelope = parseManagedAgentEnvelope(o, what, "manager-managed-agent-prepare-retirement");
|
|
180
|
+
const target = o.target;
|
|
181
|
+
if (target === null || typeof target !== "object" || Array.isArray(target) ||
|
|
182
|
+
Object.keys(target).sort().join(",") !== "actor,lifecycleUid,owner")
|
|
183
|
+
enrollmentError(what, "target must be exactly { owner, actor, lifecycleUid }");
|
|
184
|
+
const t = target;
|
|
185
|
+
if (typeof t.owner !== "string" || typeof t.actor !== "string" || typeof t.lifecycleUid !== "string")
|
|
186
|
+
enrollmentError(what, "target must contain string owner, actor, and lifecycleUid");
|
|
187
|
+
const parsedTarget = {
|
|
188
|
+
owner: assertDerivedOwnerToken(t.owner),
|
|
189
|
+
actor: assertValidOwnerToken(t.actor),
|
|
190
|
+
lifecycleUid: assertLifecycleToken(t.lifecycleUid, `${what} target lifecycleUid`),
|
|
191
|
+
};
|
|
192
|
+
if (typeof o.opId !== "string" || o.opId.length === 0)
|
|
193
|
+
enrollmentError(what, "requires a non-empty opId");
|
|
194
|
+
assertLifecycleToken(o.opId, `${what} opId`);
|
|
195
|
+
if (o.opId !== managedRetirementOpId(parsedTarget.lifecycleUid))
|
|
196
|
+
enrollmentError(what, `opId must be the derived terminal operation id for lifecycle ${parsedTarget.lifecycleUid}`);
|
|
197
|
+
return {
|
|
198
|
+
v: 1,
|
|
199
|
+
kind: "manager-managed-agent-prepare-retirement",
|
|
200
|
+
...envelope,
|
|
201
|
+
target: parsedTarget,
|
|
202
|
+
opId: o.opId,
|
|
203
|
+
};
|
|
204
|
+
}
|
|
31
205
|
//# sourceMappingURL=remote-manager-authority.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"remote-manager-authority.js","sourceRoot":"","sources":["../src/remote-manager-authority.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"remote-manager-authority.js","sourceRoot":"","sources":["../src/remote-manager-authority.ts"],"names":[],"mappings":"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"}
|
package/dist/resolve.d.ts
CHANGED
|
@@ -43,6 +43,19 @@ export declare class AmbiguousPeerError extends Error {
|
|
|
43
43
|
export declare function resolvePeer(roster: Presence[], target: string, opts?: {
|
|
44
44
|
selfId?: string;
|
|
45
45
|
}): Presence | undefined;
|
|
46
|
+
/** Maximum length of a display name, in UTF-16 code units.
|
|
47
|
+
*
|
|
48
|
+
* Derived from the transport budget, not picked. The client's CONNECT line carries the user JWT
|
|
49
|
+
* plus every payload the identity rides into (presence rows, message envelopes), and the broker
|
|
50
|
+
* caps that line at `max_control_line` (65536 in the generated config, provision.ts). A name is
|
|
51
|
+
* display data on that path, so an unbounded name is an unbounded CONNECT line: a 70,000-char
|
|
52
|
+
* name was accepted end to end and the connect then hung (issue #375) — the broker drops the
|
|
53
|
+
* oversized line silently and the client retries forever. 128 leaves every human name (~40 chars
|
|
54
|
+
* at the extreme) 3× headroom while keeping dozens of in-flight name-bearing rows an order of
|
|
55
|
+
* magnitude inside the 64 KB line. The grants themselves key on the principal, never the name
|
|
56
|
+
* (event-channel.ts), so this bound guards the payload side of the budget.
|
|
57
|
+
*/
|
|
58
|
+
export declare const MAX_NAME_LENGTH = 128;
|
|
46
59
|
/**
|
|
47
60
|
* Validate a display name. A name must be non-empty, single-line, and free of surrounding
|
|
48
61
|
* whitespace; `/` is reserved as the future `owner/name` separator (and already means "a path"
|
package/dist/resolve.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resolve.d.ts","sourceRoot":"","sources":["../src/resolve.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,KAAK,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAE3D;6FAC6F;AAC7F,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,cAAc,CAAC;IACvB,6CAA6C;IAC7C,EAAE,EAAE,MAAM,CAAC;CACZ;AAED;0FAC0F;AAC1F,qBAAa,kBAAmB,SAAQ,KAAK;IAEzC,QAAQ,CAAC,MAAM,EAAE,MAAM;IACvB,QAAQ,CAAC,UAAU,EAAE,aAAa,EAAE;gBAD3B,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,aAAa,EAAE;CASvC;AAMD;;;;;;;;;;;GAWG;AACH,wBAAgB,WAAW,CACzB,MAAM,EAAE,QAAQ,EAAE,EAClB,MAAM,EAAE,MAAM,EACd,IAAI,GAAE;IAAE,MAAM,CAAC,EAAE,MAAM,CAAA;CAAO,GAC7B,QAAQ,GAAG,SAAS,CAetB;AAuBD;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,
|
|
1
|
+
{"version":3,"file":"resolve.d.ts","sourceRoot":"","sources":["../src/resolve.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,KAAK,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAE3D;6FAC6F;AAC7F,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,cAAc,CAAC;IACvB,6CAA6C;IAC7C,EAAE,EAAE,MAAM,CAAC;CACZ;AAED;0FAC0F;AAC1F,qBAAa,kBAAmB,SAAQ,KAAK;IAEzC,QAAQ,CAAC,MAAM,EAAE,MAAM;IACvB,QAAQ,CAAC,UAAU,EAAE,aAAa,EAAE;gBAD3B,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,aAAa,EAAE;CASvC;AAMD;;;;;;;;;;;GAWG;AACH,wBAAgB,WAAW,CACzB,MAAM,EAAE,QAAQ,EAAE,EAClB,MAAM,EAAE,MAAM,EACd,IAAI,GAAE;IAAE,MAAM,CAAC,EAAE,MAAM,CAAA;CAAO,GAC7B,QAAQ,GAAG,SAAS,CAetB;AAuBD;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,eAAe,MAAM,CAAC;AAEnC;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAgClD"}
|
package/dist/resolve.js
CHANGED
|
@@ -66,6 +66,19 @@ function isWellFormedUtf16(s) {
|
|
|
66
66
|
}
|
|
67
67
|
return true;
|
|
68
68
|
}
|
|
69
|
+
/** Maximum length of a display name, in UTF-16 code units.
|
|
70
|
+
*
|
|
71
|
+
* Derived from the transport budget, not picked. The client's CONNECT line carries the user JWT
|
|
72
|
+
* plus every payload the identity rides into (presence rows, message envelopes), and the broker
|
|
73
|
+
* caps that line at `max_control_line` (65536 in the generated config, provision.ts). A name is
|
|
74
|
+
* display data on that path, so an unbounded name is an unbounded CONNECT line: a 70,000-char
|
|
75
|
+
* name was accepted end to end and the connect then hung (issue #375) — the broker drops the
|
|
76
|
+
* oversized line silently and the client retries forever. 128 leaves every human name (~40 chars
|
|
77
|
+
* at the extreme) 3× headroom while keeping dozens of in-flight name-bearing rows an order of
|
|
78
|
+
* magnitude inside the 64 KB line. The grants themselves key on the principal, never the name
|
|
79
|
+
* (event-channel.ts), so this bound guards the payload side of the budget.
|
|
80
|
+
*/
|
|
81
|
+
export const MAX_NAME_LENGTH = 128;
|
|
69
82
|
/**
|
|
70
83
|
* Validate a display name. A name must be non-empty, single-line, and free of surrounding
|
|
71
84
|
* whitespace; `/` is reserved as the future `owner/name` separator (and already means "a path"
|
|
@@ -75,6 +88,9 @@ function isWellFormedUtf16(s) {
|
|
|
75
88
|
export function assertValidName(name) {
|
|
76
89
|
if (name.length === 0 || name !== name.trim())
|
|
77
90
|
throw new Error(`invalid name ${JSON.stringify(name)}: must be non-empty with no surrounding whitespace`);
|
|
91
|
+
if (name.length > MAX_NAME_LENGTH)
|
|
92
|
+
throw new Error(`invalid name ${JSON.stringify(name.slice(0, 32))}…: ${name.length} characters exceeds the ` +
|
|
93
|
+
`${MAX_NAME_LENGTH}-character limit (the CONNECT line budget that carries it)`);
|
|
78
94
|
if (/[\r\n]/.test(name))
|
|
79
95
|
throw new Error(`invalid name ${JSON.stringify(name)}: must be a single line`);
|
|
80
96
|
if (name.includes("/"))
|
package/dist/resolve.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resolve.js","sourceRoot":"","sources":["../src/resolve.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"resolve.js","sourceRoot":"","sources":["../src/resolve.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schema-profile.d.ts","sourceRoot":"","sources":["../src/schema-profile.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,EAAW,KAAK,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAIlE;;6EAE6E;AAC7E,eAAO,MAAM,cAAc;IACzB,mDAAmD;;IAEnD,+EAA+E;;IAE/E,gDAAgD;;
|
|
1
|
+
{"version":3,"file":"schema-profile.d.ts","sourceRoot":"","sources":["../src/schema-profile.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,EAAW,KAAK,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAIlE;;6EAE6E;AAC7E,eAAO,MAAM,cAAc;IACzB,mDAAmD;;IAEnD,+EAA+E;;IAE/E,gDAAgD;;IAoDhD,+DAA+D;;IAE/D,sCAAsC;;IAEtC,+FAA+F;;IAE/F;;0DAEsD;;IAEtD,0EAA0E;;EAEjE,CAAC;AAuEZ;;cAEc;AACd,eAAO,MAAM,WAAW;;EAA2C,CAAC;AACpE,qFAAqF;AACrF,eAAO,MAAM,2BAA2B,QAA8B,CAAC;AACvE;8EAC8E;AAC9E,eAAO,MAAM,kBAAkB,QAA2E,CAAC;AAK3G;wFACwF;AACxF,qBAAa,oBAAqB,SAAQ,KAAK;IAC7C,QAAQ,CAAC,IAAI,EAAG,kBAAkB,CAAU;gBAChC,OAAO,EAAE,MAAM;CAI5B;AAqED;mFACmF;AACnF,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,OAAO,CAAC;IACd,8FAA8F;IAC9F,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACnC;AA0HD;;;;;;;;;;gCAUgC;AAChC,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,gBAAgB,CAAC;IAC3B,aAAa,EAAE,MAAM,CAAC;CACvB;AAaD,2FAA2F;AAC3F,wBAAgB,kBAAkB,CAAC,CAAC,EAAE,OAAO,GAAG,CAAC,IAAI,gBAAgB,CAEpE;AAED;gGACgG;AAChG,wBAAgB,sBAAsB,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,GAAG,gBAAgB,CAIjF;AA8JD;;8DAE8D;AAC9D,wBAAgB,eAAe,CAAC,MAAM,EAAE,YAAY,GAAG,gBAAgB,CAGtE;AAED,8FAA8F;AAC9F,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,YAAY,GAAG,gBAAgB,CAE5E;AAED;;;;4BAI4B;AAC5B,wBAAgB,2BAA2B,CAAC,QAAQ,GAAE,MAA4C,GAAG;IACnG,OAAO,EAAE,CAAC,MAAM,EAAE,YAAY,KAAK,gBAAgB,CAAC;IACpD,IAAI,EAAE,MAAM,MAAM,CAAC;CACpB,CAmBA"}
|
package/dist/schema-profile.js
CHANGED
|
@@ -40,11 +40,15 @@ export const SCHEMA_PROFILE = Object.freeze({
|
|
|
40
40
|
//
|
|
41
41
|
// CRASH. A 2048-node patterned-properties document was observed to RangeError in Ajv's codegen
|
|
42
42
|
// at ~186KB — inside `maxDocumentBytes` — which looked like a hard edge worth standing in front
|
|
43
|
-
// of. It is not an edge
|
|
44
|
-
//
|
|
45
|
-
// and
|
|
46
|
-
//
|
|
47
|
-
//
|
|
43
|
+
// of. It is not an edge — not because it is unstable (re-measured for #1551: the SAME 2062-
|
|
44
|
+
// property/187545-byte document RangeErrors 15/15 fresh processes at this profile's default
|
|
45
|
+
// stack, and the reported cold-then-warm-compiles pattern did not reproduce once) — but because
|
|
46
|
+
// the edge is a function of the STACK BUDGET, not the schema: it moves linearly with
|
|
47
|
+
// `--stack-size` (measured 256KB→~460, 8MB default→~2050, on the pin this profile ships;
|
|
48
|
+
// flattening ajv's codegen with `allErrors: true` moves the same edge to roughly 3.4x wider at
|
|
49
|
+
// any given stack budget, never removes it) and by a fraction of a property per extra caller
|
|
50
|
+
// frame burned before the compile call. A frozen node-count constant cannot express an edge that
|
|
51
|
+
// moves with the CALLER's stack depth, which is outside this module's control.
|
|
48
52
|
//
|
|
49
53
|
// AND THE VALUE WAS UNSAFE ON AN AXIS NOBODY MEASURED. Under `node --stack-size=256` a 512-node
|
|
50
54
|
// object RangeErrors, while 384 compiles — so the proposed `maxSchemaNodes: 512` did not hold
|
|
@@ -54,8 +58,10 @@ export const SCHEMA_PROFILE = Object.freeze({
|
|
|
54
58
|
// WHAT STANDS IN ITS PLACE is what was doing the work the whole time: `maxDocumentBytes` and
|
|
55
59
|
// `maxClosureBytes`, `maxDepth`, `maxRefChain`, `maxPatternChars`, the admitted-vocabulary
|
|
56
60
|
// refusal, and — for exactly the codegen overflow above — the compile-error catch in
|
|
57
|
-
// `compileWithinBudget`, which
|
|
58
|
-
//
|
|
61
|
+
// `compileWithinBudget`, which normalises a stack overflow to `contract-invalid` naming the
|
|
62
|
+
// COMPILER's generated-code shape and the property count that triggered it, never the caller's
|
|
63
|
+
// schema (#1551). That set refuses everything it refused before; removing an unfounded bound only
|
|
64
|
+
// LOOSENS, and
|
|
59
65
|
// loosening cannot break a contract that was already valid.
|
|
60
66
|
//
|
|
61
67
|
// BEFORE PROPOSING ONE AGAIN, run `implementations/manager/smoke/_probe-nodecount-rejected.ts`.
|
|
@@ -91,7 +97,31 @@ export const SCHEMA_PROFILE = Object.freeze({
|
|
|
91
97
|
*/
|
|
92
98
|
const AJV_PROFILE_OPTIONS = Object.freeze({
|
|
93
99
|
strict: false, // the wire accepts full 2020-12, not ajv's strict-mode dialect subset
|
|
94
|
-
|
|
100
|
+
// PINNED TRUE, not ajv's `false` default, for the flat code shape it produces (#1551).
|
|
101
|
+
// `allErrors: false` makes ajv nest one continuation `if` per property in the generated
|
|
102
|
+
// validator, so the compile of a wide object schema overflows the host call stack at a width
|
|
103
|
+
// set by the STACK BUDGET, not by any ceiling this profile enforces — every document this
|
|
104
|
+
// profile admits (bytes, depth, ref-chain, pattern length, vocabulary) can still fail to
|
|
105
|
+
// compile purely on shape. `allErrors: true` builds the same validations as a flat sequence
|
|
106
|
+
// instead, which does not remove the stack-bounded ceiling (ajv's codegen still recurses while
|
|
107
|
+
// it builds the code tree) but moves it about 3.4x wider at any given stack budget: measured on
|
|
108
|
+
// this pin, default 8MB stack SMALLEST_FAIL moved from 2055 properties to 6946, and
|
|
109
|
+
// `--stack-size=256` moved from 494 to 1769 (one host, Node 24; the ratio is the stable
|
|
110
|
+
// quantity, not the absolute counts — re-measure with a child process per candidate width, one
|
|
111
|
+
// `--stack-size` per row, per issue #1551's method).
|
|
112
|
+
//
|
|
113
|
+
// Safe to flip only because it changes NO VERDICT this profile's own checks depend on: ajv
|
|
114
|
+
// orders keyword/property evaluation identically regardless of `allErrors`, so `errors[0]` —
|
|
115
|
+
// the only field any caller-facing message reads (`endpoint-envelope.ts` firstErrorDetail,
|
|
116
|
+
// `endpoint-traits.ts` readSchema) — is byte-identical between the two settings for every
|
|
117
|
+
// schema/instance pair tried, and `packages/core/smoke/schema-profile.smoke.ts`'s full 67-check
|
|
118
|
+
// suite (every `refuses`/`ok` assertion, including the pattern safe-subset gate and the
|
|
119
|
+
// admitted-vocabulary walk) passes unchanged under either setting. Nothing on the wire ever
|
|
120
|
+
// reads ajv's full `errors` array, only its first entry, so `allErrors`'s extra collected
|
|
121
|
+
// errors are never observed by a caller. If a future change makes any of that no longer true —
|
|
122
|
+
// a caller starts reading `errors.length`, or a verdict diverges between the settings — this
|
|
123
|
+
// pin must be re-measured before it stays.
|
|
124
|
+
allErrors: true,
|
|
95
125
|
validateFormats: false,
|
|
96
126
|
loadSchema: undefined,
|
|
97
127
|
// PINNED, never inherited from Ajv's default: the safe-pattern analyzer models `/u`
|
|
@@ -401,6 +431,41 @@ function assertClosureProfile(bundle) {
|
|
|
401
431
|
throw new ContractInvalidError(`bundle carries ${extras.length} member(s) unreachable from the root (${extras.slice(0, 3).join(", ")}${extras.length > 3 ? ", …" : ""})`);
|
|
402
432
|
return contractDigest({ v: 1, root: digestOrInvalid(bundle.root, "root schema"), members: [...seen].sort() });
|
|
403
433
|
}
|
|
434
|
+
/** The size of the widest map-valued keyword (`properties`, `patternProperties`, `$defs`,
|
|
435
|
+
* `definitions`, `dependentSchemas`, `dependencies`) anywhere in one document — the shape that
|
|
436
|
+
* drives ajv's per-property codegen (SPEC §13.7). Used only to NAME a codegen overflow after it
|
|
437
|
+
* happens; every ceiling in {@link SCHEMA_PROFILE} has already admitted this document by the time
|
|
438
|
+
* anything calls this, so it never gates anything itself. */
|
|
439
|
+
function widestMapKeywordSize(doc, max = 0) {
|
|
440
|
+
if (doc === null || typeof doc !== "object" || Array.isArray(doc))
|
|
441
|
+
return max;
|
|
442
|
+
for (const [k, v] of Object.entries(doc)) {
|
|
443
|
+
if (SCHEMA_VALUED_MAP_KEYS.includes(k) && v && typeof v === "object" && !Array.isArray(v)) {
|
|
444
|
+
const size = Object.keys(v).length;
|
|
445
|
+
if (size > max)
|
|
446
|
+
max = size;
|
|
447
|
+
for (const sub of Object.values(v))
|
|
448
|
+
max = widestMapKeywordSize(sub, max);
|
|
449
|
+
}
|
|
450
|
+
else if (SCHEMA_VALUED_KEYS.includes(k)) {
|
|
451
|
+
max = widestMapKeywordSize(v, max);
|
|
452
|
+
}
|
|
453
|
+
else if (SCHEMA_VALUED_LIST_KEYS.includes(k) && Array.isArray(v)) {
|
|
454
|
+
for (const sub of v)
|
|
455
|
+
max = widestMapKeywordSize(sub, max);
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
return max;
|
|
459
|
+
}
|
|
460
|
+
/** The widest map-valued keyword across the whole closure (root plus every bundle member) — the
|
|
461
|
+
* quantity {@link widestMapKeywordSize} measures, maximised over every document a compile call
|
|
462
|
+
* actually sees. */
|
|
463
|
+
function widestClosurePropertyCount(bundle) {
|
|
464
|
+
let max = widestMapKeywordSize(bundle.root);
|
|
465
|
+
for (const member of Object.values(bundle.members ?? {}))
|
|
466
|
+
max = widestMapKeywordSize(member, max);
|
|
467
|
+
return max;
|
|
468
|
+
}
|
|
404
469
|
function compileWithinBudget(bundle) {
|
|
405
470
|
// NOTHING HERE REFUSES A SCHEMA FOR BEING EXPENSIVE, and that is deliberate rather than
|
|
406
471
|
// overlooked. The timing below is an OBSERVATION and refuses nothing; the node ceiling that was
|
|
@@ -456,6 +521,20 @@ function compileWithinBudget(bundle) {
|
|
|
456
521
|
validate = ajv.compile(bundle.root);
|
|
457
522
|
}
|
|
458
523
|
catch (e) {
|
|
524
|
+
// A `RangeError` here is the compiler's own generated code overflowing the host's call
|
|
525
|
+
// stack (SPEC §13.7) — every ceiling above already admitted this document, so the schema is
|
|
526
|
+
// not what failed. Naming the caller's schema in that case (as the generic branch below does
|
|
527
|
+
// for every other compile failure) sends the caller to rewrite something that was never
|
|
528
|
+
// wrong. Named instead: the shape that overflowed (ajv's per-property codegen), and the width
|
|
529
|
+
// that did it (the widest `properties`/`patternProperties`/`$defs`/… map anywhere in the
|
|
530
|
+
// closure) — the two facts a caller needs to know this is not their schema's fault.
|
|
531
|
+
if (e instanceof RangeError) {
|
|
532
|
+
const width = widestClosurePropertyCount(bundle);
|
|
533
|
+
throw new ContractInvalidError(`schema does not compile under the 2020-12 profile: the generated validator's code shape overflowed `
|
|
534
|
+
+ `the call stack (${e.message}) compiling a ${width}-property object, which every profile `
|
|
535
|
+
+ `ceiling (document/closure bytes, depth, ref-chain, pattern length, admitted vocabulary) had already `
|
|
536
|
+
+ `admitted; this is the compiler's generated-code shape running out of stack, not a defect in the schema`);
|
|
537
|
+
}
|
|
459
538
|
throw new ContractInvalidError(`schema does not compile under the 2020-12 profile: ${e.message}`);
|
|
460
539
|
}
|
|
461
540
|
const cpu = process.cpuUsage(startedCpu);
|