@sealkeeper/schema 0.4.3 → 0.4.5
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/agent-name.d.ts +1 -1
- package/dist/agent-name.js +4 -4
- package/dist/api.d.ts +744 -27
- package/dist/api.js +232 -43
- package/dist/badge.d.ts +1 -0
- package/dist/badge.js +7 -0
- package/dist/credential.d.ts +186 -1
- package/dist/credential.js +55 -8
- package/dist/db/agents.d.ts +70 -0
- package/dist/db/agents.js +18 -0
- package/dist/db/client.d.ts +398 -0
- package/dist/db/client.js +2 -0
- package/dist/db/events.js +7 -0
- package/dist/db/index.d.ts +17 -1
- package/dist/db/index.js +5 -1
- package/dist/db/migrate.js +5 -1
- package/dist/db/migrator.d.ts +3 -1
- package/dist/db/migrator.js +8 -2
- package/dist/db/operator-identities.d.ts +211 -0
- package/dist/db/operator-identities.js +49 -0
- package/dist/db/operator-level-grants.d.ts +109 -0
- package/dist/db/operator-level-grants.js +30 -0
- package/dist/db/operator-slugs.d.ts +92 -0
- package/dist/db/operator-slugs.js +25 -0
- package/dist/db/operators.d.ts +119 -0
- package/dist/db/operators.js +30 -2
- package/dist/db/standing.d.ts +36 -0
- package/dist/db/standing.js +5 -0
- package/dist/db/task-claim-failures.d.ts +143 -0
- package/dist/db/task-claim-failures.js +37 -0
- package/dist/db/task-outcomes.d.ts +19 -0
- package/dist/db/task-outcomes.js +8 -1
- package/dist/db/tasks.d.ts +79 -0
- package/dist/db/tasks.js +19 -1
- package/dist/envelope.d.ts +3 -0
- package/dist/envelope.js +16 -11
- package/dist/goal.d.ts +149 -0
- package/dist/goal.js +171 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +6 -0
- package/dist/moderation.d.ts +28 -0
- package/dist/moderation.js +450 -0
- package/dist/operator-domains.d.ts +104 -0
- package/dist/operator-domains.js +85 -0
- package/dist/policy.d.ts +4 -0
- package/dist/policy.js +10 -0
- package/dist/runtime.d.ts +17 -0
- package/dist/runtime.js +61 -0
- package/dist/seal-conformance.js +32 -1
- package/dist/standing.d.ts +68 -0
- package/dist/standing.js +132 -6
- package/dist/tasks.d.ts +23 -1
- package/dist/tasks.js +29 -5
- package/package.json +1 -1
package/dist/credential.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
+
import { CountedCounts } from './standing.js';
|
|
2
3
|
export declare const CREDENTIAL_ISSUER = "sealkeeper.run";
|
|
3
4
|
export declare const LEGACY_ISSUERS: readonly ['vouched.run'];
|
|
4
5
|
export declare const LEGACY_ISSUER_UNTIL: number;
|
|
@@ -13,6 +14,7 @@ export declare const CREDENTIAL_EXTENSION_URI = "https://vouched.run/ext/credent
|
|
|
13
14
|
export declare const LEGACY_SEAL_EXTENSION_URIS: readonly string[];
|
|
14
15
|
export declare const SEAL_EXTENSION_URIS: readonly string[];
|
|
15
16
|
export declare const SEAL_VERSION = 1;
|
|
17
|
+
export declare const SEAL_VERSIONS: readonly [1, 2];
|
|
16
18
|
export declare const LEGACY_UNTIL: number;
|
|
17
19
|
export declare const IdentityKind: z.ZodUnion<readonly [z.ZodEnum<{
|
|
18
20
|
kya: "kya";
|
|
@@ -94,6 +96,65 @@ export declare const CredentialPayload: z.ZodObject<{
|
|
|
94
96
|
dormant_days: z.ZodNullable<z.ZodInt>;
|
|
95
97
|
}, z.core.$strict>;
|
|
96
98
|
export type CredentialPayload = z.infer<typeof CredentialPayload>;
|
|
99
|
+
export declare const CredentialPayloadV2: z.ZodObject<{
|
|
100
|
+
iss: z.ZodLiteral<"sealkeeper.run">;
|
|
101
|
+
sub: z.ZodString;
|
|
102
|
+
ver: z.ZodLiteral<2>;
|
|
103
|
+
iat: z.ZodInt;
|
|
104
|
+
exp: z.ZodInt;
|
|
105
|
+
agent_version: z.ZodString;
|
|
106
|
+
version: z.ZodString;
|
|
107
|
+
level: z.ZodEnum<{
|
|
108
|
+
bronze: "bronze";
|
|
109
|
+
gold: "gold";
|
|
110
|
+
none: "none";
|
|
111
|
+
silver: "silver";
|
|
112
|
+
}>;
|
|
113
|
+
scores: z.ZodRecord<z.ZodUnion<readonly [z.ZodEnum<{
|
|
114
|
+
cost_latency: "cost_latency";
|
|
115
|
+
provenance: "provenance";
|
|
116
|
+
reliability: "reliability";
|
|
117
|
+
safety: "safety";
|
|
118
|
+
}>, z.ZodTemplateLiteral<`competence:${string}`>]> & z.core.$partial, z.ZodNullable<z.ZodNumber>>;
|
|
119
|
+
counts: z.ZodObject<{
|
|
120
|
+
events: z.ZodInt;
|
|
121
|
+
history_days: z.ZodInt;
|
|
122
|
+
verified_tasks: z.ZodInt;
|
|
123
|
+
seed_tasks: z.ZodInt;
|
|
124
|
+
server_checked_tasks: z.ZodInt;
|
|
125
|
+
confirmed_tasks: z.ZodInt;
|
|
126
|
+
distinct_operators: z.ZodInt;
|
|
127
|
+
safety_incidents_90d: z.ZodInt;
|
|
128
|
+
}, z.core.$strict>;
|
|
129
|
+
counted: z.ZodObject<{
|
|
130
|
+
verified_tasks: z.ZodInt;
|
|
131
|
+
seed_tasks: z.ZodInt;
|
|
132
|
+
server_checked_tasks: z.ZodInt;
|
|
133
|
+
confirmed_tasks: z.ZodInt;
|
|
134
|
+
}, z.core.$strict>;
|
|
135
|
+
operator: z.ZodObject<{
|
|
136
|
+
verified: z.ZodBoolean;
|
|
137
|
+
}, z.core.$strict>;
|
|
138
|
+
identity: z.ZodArray<z.ZodObject<{
|
|
139
|
+
provider: z.ZodURL;
|
|
140
|
+
kind: z.ZodUnion<readonly [z.ZodEnum<{
|
|
141
|
+
kya: "kya";
|
|
142
|
+
oidc: "oidc";
|
|
143
|
+
saml: "saml";
|
|
144
|
+
verifiable_credential: "verifiable_credential";
|
|
145
|
+
}>, z.ZodURL]>;
|
|
146
|
+
ref: z.ZodString;
|
|
147
|
+
subject_hash: z.ZodString;
|
|
148
|
+
attested_at: z.ZodInt;
|
|
149
|
+
scope: z.ZodEnum<{
|
|
150
|
+
agent: "agent";
|
|
151
|
+
operator: "operator";
|
|
152
|
+
}>;
|
|
153
|
+
}, z.core.$strict>>;
|
|
154
|
+
last_active: z.ZodNullable<z.ZodInt>;
|
|
155
|
+
dormant_days: z.ZodNullable<z.ZodInt>;
|
|
156
|
+
}, z.core.$strict>;
|
|
157
|
+
export type CredentialPayloadV2 = z.infer<typeof CredentialPayloadV2>;
|
|
97
158
|
export declare const LegacyCredentialPayload: z.ZodObject<{
|
|
98
159
|
iss: z.ZodLiteral<"sealkeeper.run">;
|
|
99
160
|
sub: z.ZodString;
|
|
@@ -169,6 +230,68 @@ export declare const VerifiedCredentialPayload: z.ZodObject<{
|
|
|
169
230
|
dormant_days: z.ZodNullable<z.ZodInt>;
|
|
170
231
|
}, z.core.$strict>;
|
|
171
232
|
export type VerifiedCredentialPayload = z.infer<typeof VerifiedCredentialPayload>;
|
|
233
|
+
export declare const VerifiedCredentialPayloadV2: z.ZodObject<{
|
|
234
|
+
iss: z.ZodEnum<{
|
|
235
|
+
"sealkeeper.run": "sealkeeper.run";
|
|
236
|
+
"vouched.run": "vouched.run";
|
|
237
|
+
}>;
|
|
238
|
+
sub: z.ZodString;
|
|
239
|
+
ver: z.ZodLiteral<2>;
|
|
240
|
+
iat: z.ZodInt;
|
|
241
|
+
exp: z.ZodInt;
|
|
242
|
+
agent_version: z.ZodString;
|
|
243
|
+
version: z.ZodString;
|
|
244
|
+
level: z.ZodEnum<{
|
|
245
|
+
bronze: "bronze";
|
|
246
|
+
gold: "gold";
|
|
247
|
+
none: "none";
|
|
248
|
+
silver: "silver";
|
|
249
|
+
}>;
|
|
250
|
+
scores: z.ZodRecord<z.ZodUnion<readonly [z.ZodEnum<{
|
|
251
|
+
cost_latency: "cost_latency";
|
|
252
|
+
provenance: "provenance";
|
|
253
|
+
reliability: "reliability";
|
|
254
|
+
safety: "safety";
|
|
255
|
+
}>, z.ZodTemplateLiteral<`competence:${string}`>]> & z.core.$partial, z.ZodNullable<z.ZodNumber>>;
|
|
256
|
+
counts: z.ZodObject<{
|
|
257
|
+
events: z.ZodInt;
|
|
258
|
+
history_days: z.ZodInt;
|
|
259
|
+
verified_tasks: z.ZodInt;
|
|
260
|
+
seed_tasks: z.ZodInt;
|
|
261
|
+
server_checked_tasks: z.ZodInt;
|
|
262
|
+
confirmed_tasks: z.ZodInt;
|
|
263
|
+
distinct_operators: z.ZodInt;
|
|
264
|
+
safety_incidents_90d: z.ZodInt;
|
|
265
|
+
}, z.core.$strict>;
|
|
266
|
+
counted: z.ZodObject<{
|
|
267
|
+
verified_tasks: z.ZodInt;
|
|
268
|
+
seed_tasks: z.ZodInt;
|
|
269
|
+
server_checked_tasks: z.ZodInt;
|
|
270
|
+
confirmed_tasks: z.ZodInt;
|
|
271
|
+
}, z.core.$strict>;
|
|
272
|
+
operator: z.ZodObject<{
|
|
273
|
+
verified: z.ZodBoolean;
|
|
274
|
+
}, z.core.$strict>;
|
|
275
|
+
identity: z.ZodArray<z.ZodObject<{
|
|
276
|
+
provider: z.ZodURL;
|
|
277
|
+
kind: z.ZodUnion<readonly [z.ZodEnum<{
|
|
278
|
+
kya: "kya";
|
|
279
|
+
oidc: "oidc";
|
|
280
|
+
saml: "saml";
|
|
281
|
+
verifiable_credential: "verifiable_credential";
|
|
282
|
+
}>, z.ZodURL]>;
|
|
283
|
+
ref: z.ZodString;
|
|
284
|
+
subject_hash: z.ZodString;
|
|
285
|
+
attested_at: z.ZodInt;
|
|
286
|
+
scope: z.ZodEnum<{
|
|
287
|
+
agent: "agent";
|
|
288
|
+
operator: "operator";
|
|
289
|
+
}>;
|
|
290
|
+
}, z.core.$strict>>;
|
|
291
|
+
last_active: z.ZodNullable<z.ZodInt>;
|
|
292
|
+
dormant_days: z.ZodNullable<z.ZodInt>;
|
|
293
|
+
}, z.core.$strict>;
|
|
294
|
+
export type VerifiedCredentialPayloadV2 = z.infer<typeof VerifiedCredentialPayloadV2>;
|
|
172
295
|
export declare const VerifiedLegacyCredentialPayload: z.ZodObject<{
|
|
173
296
|
iss: z.ZodEnum<{
|
|
174
297
|
"sealkeeper.run": "sealkeeper.run";
|
|
@@ -245,6 +368,66 @@ export declare const SealPayload: z.ZodUnion<readonly [z.ZodObject<{
|
|
|
245
368
|
}, z.core.$strict>>;
|
|
246
369
|
last_active: z.ZodNullable<z.ZodInt>;
|
|
247
370
|
dormant_days: z.ZodNullable<z.ZodInt>;
|
|
371
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
372
|
+
iss: z.ZodEnum<{
|
|
373
|
+
"sealkeeper.run": "sealkeeper.run";
|
|
374
|
+
"vouched.run": "vouched.run";
|
|
375
|
+
}>;
|
|
376
|
+
sub: z.ZodString;
|
|
377
|
+
ver: z.ZodLiteral<2>;
|
|
378
|
+
iat: z.ZodInt;
|
|
379
|
+
exp: z.ZodInt;
|
|
380
|
+
agent_version: z.ZodString;
|
|
381
|
+
version: z.ZodString;
|
|
382
|
+
level: z.ZodEnum<{
|
|
383
|
+
bronze: "bronze";
|
|
384
|
+
gold: "gold";
|
|
385
|
+
none: "none";
|
|
386
|
+
silver: "silver";
|
|
387
|
+
}>;
|
|
388
|
+
scores: z.ZodRecord<z.ZodUnion<readonly [z.ZodEnum<{
|
|
389
|
+
cost_latency: "cost_latency";
|
|
390
|
+
provenance: "provenance";
|
|
391
|
+
reliability: "reliability";
|
|
392
|
+
safety: "safety";
|
|
393
|
+
}>, z.ZodTemplateLiteral<`competence:${string}`>]> & z.core.$partial, z.ZodNullable<z.ZodNumber>>;
|
|
394
|
+
counts: z.ZodObject<{
|
|
395
|
+
events: z.ZodInt;
|
|
396
|
+
history_days: z.ZodInt;
|
|
397
|
+
verified_tasks: z.ZodInt;
|
|
398
|
+
seed_tasks: z.ZodInt;
|
|
399
|
+
server_checked_tasks: z.ZodInt;
|
|
400
|
+
confirmed_tasks: z.ZodInt;
|
|
401
|
+
distinct_operators: z.ZodInt;
|
|
402
|
+
safety_incidents_90d: z.ZodInt;
|
|
403
|
+
}, z.core.$strict>;
|
|
404
|
+
counted: z.ZodObject<{
|
|
405
|
+
verified_tasks: z.ZodInt;
|
|
406
|
+
seed_tasks: z.ZodInt;
|
|
407
|
+
server_checked_tasks: z.ZodInt;
|
|
408
|
+
confirmed_tasks: z.ZodInt;
|
|
409
|
+
}, z.core.$strict>;
|
|
410
|
+
operator: z.ZodObject<{
|
|
411
|
+
verified: z.ZodBoolean;
|
|
412
|
+
}, z.core.$strict>;
|
|
413
|
+
identity: z.ZodArray<z.ZodObject<{
|
|
414
|
+
provider: z.ZodURL;
|
|
415
|
+
kind: z.ZodUnion<readonly [z.ZodEnum<{
|
|
416
|
+
kya: "kya";
|
|
417
|
+
oidc: "oidc";
|
|
418
|
+
saml: "saml";
|
|
419
|
+
verifiable_credential: "verifiable_credential";
|
|
420
|
+
}>, z.ZodURL]>;
|
|
421
|
+
ref: z.ZodString;
|
|
422
|
+
subject_hash: z.ZodString;
|
|
423
|
+
attested_at: z.ZodInt;
|
|
424
|
+
scope: z.ZodEnum<{
|
|
425
|
+
agent: "agent";
|
|
426
|
+
operator: "operator";
|
|
427
|
+
}>;
|
|
428
|
+
}, z.core.$strict>>;
|
|
429
|
+
last_active: z.ZodNullable<z.ZodInt>;
|
|
430
|
+
dormant_days: z.ZodNullable<z.ZodInt>;
|
|
248
431
|
}, z.core.$strict>, z.ZodObject<{
|
|
249
432
|
iss: z.ZodEnum<{
|
|
250
433
|
"sealkeeper.run": "sealkeeper.run";
|
|
@@ -267,7 +450,9 @@ export declare const SealPayload: z.ZodUnion<readonly [z.ZodObject<{
|
|
|
267
450
|
}, z.core.$strict>;
|
|
268
451
|
}, z.core.$strict>]>;
|
|
269
452
|
export type SealPayload = z.infer<typeof SealPayload>;
|
|
270
|
-
export
|
|
453
|
+
export type VersionedSealPayload = VerifiedCredentialPayload | VerifiedCredentialPayloadV2;
|
|
454
|
+
export declare const isSealV1: (p: SealPayload) => p is VersionedSealPayload;
|
|
455
|
+
export declare const sealCounted: (p: SealPayload) => CountedCounts | null;
|
|
271
456
|
export declare function sealVersionProblem(raw: unknown, nowSeconds: number): 'unsupported_version' | null;
|
|
272
457
|
export declare function sealIatProblem(iat: number, nowSeconds: number): 'not_yet_valid' | null;
|
|
273
458
|
export type SealPayloadResult = {
|
package/dist/credential.js
CHANGED
|
@@ -3,7 +3,7 @@ import { AgentId, Ed25519PublicKey } from './agent-id.js';
|
|
|
3
3
|
import { Dimension } from './dimensions.js';
|
|
4
4
|
import { Jws } from './envelope.js';
|
|
5
5
|
import { Version } from './events.js';
|
|
6
|
-
import { Level, StandingCounts } from './standing.js';
|
|
6
|
+
import { CountedCounts, Level, StandingCounts } from './standing.js';
|
|
7
7
|
// The issuer every SEAL carries as iss from the SealKeeper cutover on.
|
|
8
8
|
export const CREDENTIAL_ISSUER = 'sealkeeper.run';
|
|
9
9
|
// Issuers a verifier still accepts for a while after the cutover. A SEAL
|
|
@@ -50,6 +50,12 @@ const Seconds = z.int().min(0);
|
|
|
50
50
|
const Count = z.int().min(0);
|
|
51
51
|
// The version of the SEAL standard this issuer writes, carried as ver.
|
|
52
52
|
export const SEAL_VERSION = 1;
|
|
53
|
+
// Every version a verifier understands. Version 2 is version 1 plus
|
|
54
|
+
// `counted`, the counted evidence the level read (VOU-139). CLIs 0.4.x
|
|
55
|
+
// understand version 1 only and refuse any other ver, so the issuer keeps
|
|
56
|
+
// writing version 1 until they are gone, and verifiers from this release
|
|
57
|
+
// on accept both. SEAL standard section 9.
|
|
58
|
+
export const SEAL_VERSIONS = [1, 2];
|
|
53
59
|
// SEALs issued before version 1 carry no ver. Verifiers accept them as
|
|
54
60
|
// legacy until the end of 25 September 2026 UTC, which is past the 24 hour
|
|
55
61
|
// life of any SEAL issued before the deploy. From then on a SEAL without
|
|
@@ -125,6 +131,35 @@ const v1Payload = (iss) => z
|
|
|
125
131
|
.refine((c) => c.exp > c.iat, 'exp must be after iat')
|
|
126
132
|
.refine(withinMaxTtl, MAX_TTL_MESSAGE)
|
|
127
133
|
.refine((c) => c.version === c.agent_version, 'version must equal agent_version');
|
|
134
|
+
/*
|
|
135
|
+
* Version 2. Every version 1 field with the same meaning, plus counted, the
|
|
136
|
+
* counted evidence the level read (CountedCounts). counts stay the raw
|
|
137
|
+
* facts. Each counted value is at most its raw count.
|
|
138
|
+
*/
|
|
139
|
+
const v2Payload = (iss) => z
|
|
140
|
+
.strictObject({
|
|
141
|
+
iss,
|
|
142
|
+
sub: AgentId,
|
|
143
|
+
ver: z.literal(2),
|
|
144
|
+
iat: Seconds,
|
|
145
|
+
exp: Seconds,
|
|
146
|
+
agent_version: Version,
|
|
147
|
+
version: Version,
|
|
148
|
+
level: Level,
|
|
149
|
+
scores: Scores,
|
|
150
|
+
counts: StandingCounts,
|
|
151
|
+
counted: CountedCounts,
|
|
152
|
+
operator: z.strictObject({ verified: z.boolean() }),
|
|
153
|
+
identity: z.array(IdentityReference).max(16),
|
|
154
|
+
last_active: Seconds.nullable(),
|
|
155
|
+
dormant_days: Count.nullable(),
|
|
156
|
+
})
|
|
157
|
+
.refine((c) => c.exp > c.iat, 'exp must be after iat')
|
|
158
|
+
.refine(withinMaxTtl, MAX_TTL_MESSAGE)
|
|
159
|
+
.refine((c) => c.version === c.agent_version, 'version must equal agent_version')
|
|
160
|
+
.refine((c) => c.counted.seed_tasks <= c.counts.seed_tasks &&
|
|
161
|
+
c.counted.server_checked_tasks <= c.counts.server_checked_tasks &&
|
|
162
|
+
c.counted.confirmed_tasks <= c.counts.confirmed_tasks, 'counted must not exceed counts');
|
|
128
163
|
// The payload issued before version 1, with no ver. Accepted by verifiers
|
|
129
164
|
// until LEGACY_UNTIL, never issued again. seed_tasks is optional because a
|
|
130
165
|
// SEAL issued before it was added has none.
|
|
@@ -146,25 +181,31 @@ const legacyPayload = (iss) => z
|
|
|
146
181
|
.refine(withinMaxTtl, MAX_TTL_MESSAGE);
|
|
147
182
|
// The issuer side. iss is CREDENTIAL_ISSUER only.
|
|
148
183
|
export const CredentialPayload = v1Payload(IssuedIssuer);
|
|
184
|
+
export const CredentialPayloadV2 = v2Payload(IssuedIssuer);
|
|
149
185
|
export const LegacyCredentialPayload = legacyPayload(IssuedIssuer);
|
|
150
186
|
// The verifier side. iss may also be a LEGACY_ISSUERS entry. The shape has
|
|
151
187
|
// no clock, so read these through parseSealPayload, never on their own.
|
|
152
188
|
export const VerifiedCredentialPayload = v1Payload(VerifiedIssuer);
|
|
189
|
+
export const VerifiedCredentialPayloadV2 = v2Payload(VerifiedIssuer);
|
|
153
190
|
export const VerifiedLegacyCredentialPayload = legacyPayload(VerifiedIssuer);
|
|
154
|
-
// Any payload a verifier accepts today, version 1 or legacy,
|
|
155
|
-
// current issuer or a legacy one.
|
|
191
|
+
// Any payload a verifier accepts today, version 1, version 2 or legacy,
|
|
192
|
+
// from the current issuer or a legacy one.
|
|
156
193
|
export const SealPayload = z.union([
|
|
157
194
|
VerifiedCredentialPayload,
|
|
195
|
+
VerifiedCredentialPayloadV2,
|
|
158
196
|
VerifiedLegacyCredentialPayload,
|
|
159
197
|
]);
|
|
160
|
-
// A
|
|
161
|
-
//
|
|
198
|
+
// A versioned payload carries every legacy field too, so the guard is on
|
|
199
|
+
// ver, the narrower of the two. Its false branch is the legacy shape. The
|
|
200
|
+
// name is kept from when version 1 was the only one.
|
|
162
201
|
export const isSealV1 = (p) => 'ver' in p;
|
|
202
|
+
// The counted evidence a SEAL carries, version 2 on, null before.
|
|
203
|
+
export const sealCounted = (p) => 'counted' in p ? p.counted : null;
|
|
163
204
|
const hasVer = (raw) => typeof raw === 'object' && raw !== null && 'ver' in raw;
|
|
164
205
|
/*
|
|
165
206
|
* Whether a verifier understands the version of a signed payload. Read
|
|
166
207
|
* after the signature and the issuer check out and before the shape. ver 1
|
|
167
|
-
*
|
|
208
|
+
* and 2 (SEAL_VERSIONS) are understood. Any other ver is unsupported_version, as section 9 of the
|
|
168
209
|
* standard says, never valid with an unknown meaning. No ver at all is a
|
|
169
210
|
* legacy SEAL, accepted before LEGACY_UNTIL and unsupported_version from
|
|
170
211
|
* then on. Anything that is not an object is left to the shape check.
|
|
@@ -173,7 +214,9 @@ export function sealVersionProblem(raw, nowSeconds) {
|
|
|
173
214
|
if (typeof raw !== 'object' || raw === null)
|
|
174
215
|
return null;
|
|
175
216
|
if (hasVer(raw)) {
|
|
176
|
-
return raw.ver
|
|
217
|
+
return SEAL_VERSIONS.includes(raw.ver)
|
|
218
|
+
? null
|
|
219
|
+
: 'unsupported_version';
|
|
177
220
|
}
|
|
178
221
|
return nowSeconds < LEGACY_UNTIL ? null : 'unsupported_version';
|
|
179
222
|
}
|
|
@@ -202,7 +245,11 @@ export function parseSealPayload(raw, nowSeconds) {
|
|
|
202
245
|
const problem = sealVersionProblem(raw, nowSeconds);
|
|
203
246
|
if (problem)
|
|
204
247
|
return { ok: false, reason: problem };
|
|
205
|
-
const parsed = (hasVer(raw)
|
|
248
|
+
const parsed = (!hasVer(raw)
|
|
249
|
+
? VerifiedLegacyCredentialPayload
|
|
250
|
+
: raw.ver === 2
|
|
251
|
+
? VerifiedCredentialPayloadV2
|
|
252
|
+
: VerifiedCredentialPayload).safeParse(raw);
|
|
206
253
|
return parsed.success
|
|
207
254
|
? { ok: true, payload: parsed.data }
|
|
208
255
|
: { ok: false, reason: 'malformed' };
|
package/dist/db/agents.d.ts
CHANGED
|
@@ -138,6 +138,42 @@ export declare const agents: import("drizzle-orm/pg-core").PgTableWithColumns<{
|
|
|
138
138
|
identity: undefined;
|
|
139
139
|
generated: undefined;
|
|
140
140
|
}, {}, {}>;
|
|
141
|
+
runtime: import("drizzle-orm/pg-core").PgColumn<{
|
|
142
|
+
name: "runtime";
|
|
143
|
+
tableName: "agents";
|
|
144
|
+
dataType: "string";
|
|
145
|
+
columnType: "PgText";
|
|
146
|
+
data: "claude-code" | "codex" | "cursor" | "gemini-cli" | "mastra" | "openclaw" | "other" | "unknown";
|
|
147
|
+
driverParam: string;
|
|
148
|
+
notNull: true;
|
|
149
|
+
hasDefault: true;
|
|
150
|
+
isPrimaryKey: false;
|
|
151
|
+
isAutoincrement: false;
|
|
152
|
+
hasRuntimeDefault: false;
|
|
153
|
+
enumValues: [string, ...string[]];
|
|
154
|
+
baseColumn: never;
|
|
155
|
+
identity: undefined;
|
|
156
|
+
generated: undefined;
|
|
157
|
+
}, {}, {
|
|
158
|
+
$type: "claude-code" | "codex" | "cursor" | "gemini-cli" | "mastra" | "openclaw" | "other" | "unknown";
|
|
159
|
+
}>;
|
|
160
|
+
runtimeIssuedAt: import("drizzle-orm/pg-core").PgColumn<{
|
|
161
|
+
name: "runtime_issued_at";
|
|
162
|
+
tableName: "agents";
|
|
163
|
+
dataType: "date";
|
|
164
|
+
columnType: "PgTimestamp";
|
|
165
|
+
data: Date;
|
|
166
|
+
driverParam: string;
|
|
167
|
+
notNull: false;
|
|
168
|
+
hasDefault: false;
|
|
169
|
+
isPrimaryKey: false;
|
|
170
|
+
isAutoincrement: false;
|
|
171
|
+
hasRuntimeDefault: false;
|
|
172
|
+
enumValues: undefined;
|
|
173
|
+
baseColumn: never;
|
|
174
|
+
identity: undefined;
|
|
175
|
+
generated: undefined;
|
|
176
|
+
}, {}, {}>;
|
|
141
177
|
dirtySince: import("drizzle-orm/pg-core").PgColumn<{
|
|
142
178
|
name: "dirty_since";
|
|
143
179
|
tableName: "agents";
|
|
@@ -189,6 +225,40 @@ export declare const agents: import("drizzle-orm/pg-core").PgTableWithColumns<{
|
|
|
189
225
|
identity: undefined;
|
|
190
226
|
generated: undefined;
|
|
191
227
|
}, {}, {}>;
|
|
228
|
+
termsVersion: import("drizzle-orm/pg-core").PgColumn<{
|
|
229
|
+
name: "terms_version";
|
|
230
|
+
tableName: "agents";
|
|
231
|
+
dataType: "string";
|
|
232
|
+
columnType: "PgText";
|
|
233
|
+
data: string;
|
|
234
|
+
driverParam: string;
|
|
235
|
+
notNull: false;
|
|
236
|
+
hasDefault: false;
|
|
237
|
+
isPrimaryKey: false;
|
|
238
|
+
isAutoincrement: false;
|
|
239
|
+
hasRuntimeDefault: false;
|
|
240
|
+
enumValues: [string, ...string[]];
|
|
241
|
+
baseColumn: never;
|
|
242
|
+
identity: undefined;
|
|
243
|
+
generated: undefined;
|
|
244
|
+
}, {}, {}>;
|
|
245
|
+
privacyVersion: import("drizzle-orm/pg-core").PgColumn<{
|
|
246
|
+
name: "privacy_version";
|
|
247
|
+
tableName: "agents";
|
|
248
|
+
dataType: "string";
|
|
249
|
+
columnType: "PgText";
|
|
250
|
+
data: string;
|
|
251
|
+
driverParam: string;
|
|
252
|
+
notNull: false;
|
|
253
|
+
hasDefault: false;
|
|
254
|
+
isPrimaryKey: false;
|
|
255
|
+
isAutoincrement: false;
|
|
256
|
+
hasRuntimeDefault: false;
|
|
257
|
+
enumValues: [string, ...string[]];
|
|
258
|
+
baseColumn: never;
|
|
259
|
+
identity: undefined;
|
|
260
|
+
generated: undefined;
|
|
261
|
+
}, {}, {}>;
|
|
192
262
|
};
|
|
193
263
|
dialect: 'pg';
|
|
194
264
|
}>;
|
package/dist/db/agents.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { sql } from 'drizzle-orm';
|
|
2
2
|
import { bigint, check, index, jsonb, pgTable, text, timestamp, uniqueIndex, uuid, } from 'drizzle-orm/pg-core';
|
|
3
|
+
import { RUNTIMES } from '../runtime.js';
|
|
3
4
|
import { operators } from './operators.js';
|
|
4
5
|
import { timestamps } from './timestamps.js';
|
|
5
6
|
// How a Drizzle table is declared.
|
|
@@ -31,6 +32,15 @@ export const agents = pgTable('agents', {
|
|
|
31
32
|
// sent again cannot move the version back.
|
|
32
33
|
versionIssuedAt: timestamp('version_issued_at', { withTimezone: true }),
|
|
33
34
|
card: jsonb('card'),
|
|
35
|
+
// What the agent runs in, one of RUNTIMES. Set by the signed
|
|
36
|
+
// registration payload and changed by the signed PATCH, unknown until
|
|
37
|
+
// then. Migration 0024 backfilled unknown for every agent, since events
|
|
38
|
+
// do not say which adapter sent them.
|
|
39
|
+
runtime: text('runtime').$type().notNull().default('unknown'),
|
|
40
|
+
// The signed issuedAt of the last runtime change, null until the first.
|
|
41
|
+
// Same rule as versionIssuedAt, so an old envelope sent again cannot
|
|
42
|
+
// move the runtime back.
|
|
43
|
+
runtimeIssuedAt: timestamp('runtime_issued_at', { withTimezone: true }),
|
|
34
44
|
// When the agent was first marked dirty since the scoring run last
|
|
35
45
|
// cleared it. Every write that can move the agent's standing marks it,
|
|
36
46
|
// in the same transaction as that write, but a mark sets this only when
|
|
@@ -47,9 +57,17 @@ export const agents = pgTable('agents', {
|
|
|
47
57
|
// standing, a dormancy rung or evidence leaving the window. Written by
|
|
48
58
|
// the scoring run only, null when nothing is due.
|
|
49
59
|
recomputeAt: timestamp('recompute_at', { withTimezone: true }),
|
|
60
|
+
// The POLICY_VERSIONS the operator accepted by registering this agent,
|
|
61
|
+
// stamped by the API at registration, never sent by the client
|
|
62
|
+
// (VOU-121). Null for agents registered before.
|
|
63
|
+
termsVersion: text('terms_version'),
|
|
64
|
+
privacyVersion: text('privacy_version'),
|
|
50
65
|
...timestamps,
|
|
51
66
|
}, (t) => [
|
|
52
67
|
check('agents_id_length', sql `length(${t.id}) = 43`),
|
|
68
|
+
// Built from RUNTIMES, so a runtime added there shows up as a changed
|
|
69
|
+
// check in the next drizzle-kit generate.
|
|
70
|
+
check('agents_runtime', sql `${t.runtime} in (${sql.raw(RUNTIMES.map((r) => `'${r}'`).join(', '))})`),
|
|
53
71
|
// The handle login/name points at one agent. Names are lowercase, so a
|
|
54
72
|
// plain unique index is enough.
|
|
55
73
|
uniqueIndex('agents_operator_name_unique').on(t.operatorId, t.name),
|