@agentproto/corpus-cli 0.1.0-alpha.1 → 0.1.0-alpha.3

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.
Files changed (48) hide show
  1. package/dist/cli.mjs +43 -8
  2. package/dist/cli.mjs.map +1 -1
  3. package/dist/index.d.ts +1 -5
  4. package/dist/index.mjs +15 -4
  5. package/dist/index.mjs.map +1 -1
  6. package/dist/specs/resources/aip-10/draft/KNOWLEDGE.schema.json +457 -0
  7. package/dist/specs/resources/aip-11/draft/LESSON.schema.json +149 -0
  8. package/dist/specs/resources/aip-12/draft/PLAYBOOK.schema.json +349 -0
  9. package/dist/specs/resources/aip-13/draft/WORK_ITEM.schema.json +547 -0
  10. package/dist/specs/resources/aip-14/draft/TOOL.schema.json +169 -0
  11. package/dist/specs/resources/aip-15/draft/WORKFLOW.schema.json +356 -0
  12. package/dist/specs/resources/aip-16/draft/IO.schema.json +64 -0
  13. package/dist/specs/resources/aip-17/draft/RUNNER.schema.json +81 -0
  14. package/dist/specs/resources/aip-18/draft/COLLECTION.schema.json +436 -0
  15. package/dist/specs/resources/aip-19/draft/SECRETS.schema.json +261 -0
  16. package/dist/specs/resources/aip-20/draft/WORK.schema.json +371 -0
  17. package/dist/specs/resources/aip-21/draft/AGENCY.schema.json +454 -0
  18. package/dist/specs/resources/aip-22/draft/OFFICE.schema.json +390 -0
  19. package/dist/specs/resources/aip-23/draft/IDENTITY.schema.json +358 -0
  20. package/dist/specs/resources/aip-24/draft/ASSEMBLY.schema.json +411 -0
  21. package/dist/specs/resources/aip-25/draft/PERSONA.schema.json +257 -0
  22. package/dist/specs/resources/aip-26/draft/CODE.schema.json +172 -0
  23. package/dist/specs/resources/aip-28/draft/INTENT.schema.json +215 -0
  24. package/dist/specs/resources/aip-29/draft/CLI.schema.json +339 -0
  25. package/dist/specs/resources/aip-3/draft/SKILL.schema.json +206 -0
  26. package/dist/specs/resources/aip-30/draft/DRIVER.schema.json +237 -0
  27. package/dist/specs/resources/aip-31/draft/HTTP.schema.json +80 -0
  28. package/dist/specs/resources/aip-32/draft/MCP.schema.json +88 -0
  29. package/dist/specs/resources/aip-33/draft/SDK.schema.json +60 -0
  30. package/dist/specs/resources/aip-34/draft/WORKSPACE.schema.json +252 -0
  31. package/dist/specs/resources/aip-35/draft/STORAGE.schema.json +237 -0
  32. package/dist/specs/resources/aip-36/draft/SANDBOX.schema.json +246 -0
  33. package/dist/specs/resources/aip-38/draft/POLICY.schema.json +217 -0
  34. package/dist/specs/resources/aip-39/draft/ACTION.schema.json +134 -0
  35. package/dist/specs/resources/aip-4/draft/DESIGN.schema.json +189 -0
  36. package/dist/specs/resources/aip-40/draft/EXTENSION.schema.json +116 -0
  37. package/dist/specs/resources/aip-41/draft/ROUTINE.schema.json +345 -0
  38. package/dist/specs/resources/aip-42/draft/AGENT.schema.json +268 -0
  39. package/dist/specs/resources/aip-44/draft/ACP.schema.json +170 -0
  40. package/dist/specs/resources/aip-45/draft/AGENT-CLI.schema.json +371 -0
  41. package/dist/specs/resources/aip-47/draft/ROLE.schema.json +199 -0
  42. package/dist/specs/resources/aip-48/draft/MultiAgentRuntime.schema.json +108 -0
  43. package/dist/specs/resources/aip-5/draft/TEMPLATE.schema.json +231 -0
  44. package/dist/specs/resources/aip-6/draft/COMPANY.schema.json +268 -0
  45. package/dist/specs/resources/aip-7/draft/GOVERNANCE.schema.json +581 -0
  46. package/dist/specs/resources/aip-8/draft/AGENCY.schema.json +518 -0
  47. package/dist/specs/resources/aip-9/draft/OPERATOR.schema.json +297 -0
  48. package/package.json +2 -2
@@ -0,0 +1,581 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://agentproto.sh/schemas/aip-7/GOVERNANCE.schema.json",
4
+ "title": "agentgovernance/v1 (AIP-7)",
5
+ "description": "Validates the four AIP-7 doctypes: signature (approval event), audit-event (append-only log line), policy (declarative autonomy rule), and governance.workspace/v1 (workspace manifest, root or view). Branch on the `doctype` (or for the workspace, the `schema`) field.",
6
+ "oneOf": [
7
+ { "$ref": "#/$defs/signature" },
8
+ { "$ref": "#/$defs/auditEvent" },
9
+ { "$ref": "#/$defs/policy" },
10
+ { "$ref": "#/$defs/workspace" }
11
+ ],
12
+ "$defs": {
13
+ "schemaTag": {
14
+ "const": "agentgovernance/v1",
15
+ "description": "Doctype family. Constant across all three doctypes."
16
+ },
17
+ "isoDateTime": {
18
+ "type": "string",
19
+ "format": "date-time",
20
+ "description": "RFC 3339 / ISO 8601 timestamp with millisecond precision in UTC."
21
+ },
22
+ "principalId": {
23
+ "type": "string",
24
+ "minLength": 1,
25
+ "maxLength": 256,
26
+ "description": "Stable identifier of a principal (user id, agent id, service account). Slug or DID, never a numeric DB id."
27
+ },
28
+ "slug": {
29
+ "type": "string",
30
+ "pattern": "^[a-z][a-z0-9-]*[a-z0-9]$",
31
+ "minLength": 2,
32
+ "maxLength": 64
33
+ },
34
+ "hexHash": {
35
+ "type": "string",
36
+ "pattern": "^(GENESIS|[0-9a-f]{32,128})$",
37
+ "description": "Lowercase hex hash digest, or the literal 'GENESIS' for the first entry's prevHash."
38
+ },
39
+ "signer": {
40
+ "type": "object",
41
+ "required": ["id"],
42
+ "additionalProperties": false,
43
+ "properties": {
44
+ "id": { "$ref": "#/$defs/principalId" },
45
+ "role": { "type": "string", "maxLength": 64 },
46
+ "displayName": { "type": "string", "maxLength": 120 }
47
+ }
48
+ },
49
+ "signatureBlock": {
50
+ "type": "object",
51
+ "required": ["alg", "value"],
52
+ "additionalProperties": false,
53
+ "properties": {
54
+ "alg": {
55
+ "enum": ["Ed25519", "ECDSA-P256", "RSA-PSS-SHA256", "Sigstore"],
56
+ "description": "Cryptographic algorithm. Default Ed25519."
57
+ },
58
+ "value": {
59
+ "type": "string",
60
+ "description": "Base64url-encoded signature bytes over the canonical JSON of the signed payload."
61
+ },
62
+ "publicKeyRef": {
63
+ "type": "string",
64
+ "description": "Reference resolvable in the workspace keyring (DID, key id, JWK thumbprint)."
65
+ }
66
+ }
67
+ },
68
+ "policyRef": {
69
+ "type": "object",
70
+ "required": ["ref"],
71
+ "additionalProperties": false,
72
+ "properties": {
73
+ "ref": { "$ref": "#/$defs/slug" },
74
+ "decision": {
75
+ "enum": ["allow", "deny", "require-approval", "escalate"]
76
+ }
77
+ }
78
+ },
79
+ "redactedValue": {
80
+ "type": "object",
81
+ "required": ["$redacted"],
82
+ "additionalProperties": false,
83
+ "properties": {
84
+ "$redacted": { "const": true },
85
+ "reason": { "type": "string" }
86
+ }
87
+ },
88
+ "signature": {
89
+ "type": "object",
90
+ "title": "signature (approval event)",
91
+ "required": [
92
+ "$schema",
93
+ "doctype",
94
+ "artifact",
95
+ "decision",
96
+ "signer",
97
+ "signedAt"
98
+ ],
99
+ "additionalProperties": false,
100
+ "properties": {
101
+ "$schema": { "$ref": "#/$defs/schemaTag" },
102
+ "doctype": { "const": "signature" },
103
+ "artifact": {
104
+ "type": "string",
105
+ "description": "Slug or workspace-relative path of the artifact being approved."
106
+ },
107
+ "decision": {
108
+ "enum": ["approve", "reject", "abstain"]
109
+ },
110
+ "reason": {
111
+ "type": "string",
112
+ "maxLength": 4000,
113
+ "description": "Required when decision is 'reject'. Recommended for 'approve' in multi-signer flows."
114
+ },
115
+ "signer": { "$ref": "#/$defs/signer" },
116
+ "signedAt": { "$ref": "#/$defs/isoDateTime" },
117
+ "policy": { "$ref": "#/$defs/policyRef" },
118
+ "signature": { "$ref": "#/$defs/signatureBlock" },
119
+ "metadata": {
120
+ "type": "object",
121
+ "additionalProperties": true,
122
+ "default": {}
123
+ }
124
+ },
125
+ "allOf": [
126
+ {
127
+ "if": { "properties": { "decision": { "const": "reject" } } },
128
+ "then": { "required": ["reason"] }
129
+ }
130
+ ]
131
+ },
132
+ "auditEvent": {
133
+ "type": "object",
134
+ "title": "audit-event (append-only chain entry)",
135
+ "required": [
136
+ "$schema",
137
+ "doctype",
138
+ "seq",
139
+ "ts",
140
+ "actor",
141
+ "action",
142
+ "subject",
143
+ "prevHash",
144
+ "hash"
145
+ ],
146
+ "additionalProperties": false,
147
+ "properties": {
148
+ "$schema": { "$ref": "#/$defs/schemaTag" },
149
+ "doctype": { "const": "audit-event" },
150
+ "seq": {
151
+ "type": "integer",
152
+ "minimum": 0,
153
+ "description": "Monotonic sequence number per chain. Starts at 0; gaps are spec violations."
154
+ },
155
+ "ts": { "$ref": "#/$defs/isoDateTime" },
156
+ "actor": {
157
+ "type": "object",
158
+ "required": ["id"],
159
+ "additionalProperties": false,
160
+ "properties": {
161
+ "id": { "$ref": "#/$defs/principalId" },
162
+ "role": { "type": "string", "maxLength": 64 }
163
+ }
164
+ },
165
+ "action": {
166
+ "type": "string",
167
+ "pattern": "^[a-z][a-z0-9._-]*[a-z0-9]$",
168
+ "maxLength": 128,
169
+ "description": "Dot-separated action class: tool.call, workflow.start, workspace.write, mutation.commit, audit.note, etc."
170
+ },
171
+ "subject": {
172
+ "type": "object",
173
+ "required": ["kind"],
174
+ "additionalProperties": false,
175
+ "properties": {
176
+ "kind": { "type": "string", "maxLength": 32 },
177
+ "ref": { "type": "string", "maxLength": 256 },
178
+ "path": { "type": "string", "maxLength": 1024 }
179
+ }
180
+ },
181
+ "input": {
182
+ "description": "Input arguments (or {$redacted: true} placeholder).",
183
+ "anyOf": [{ "type": "object" }, { "$ref": "#/$defs/redactedValue" }]
184
+ },
185
+ "output": {
186
+ "description": "Output payload (or {$redacted: true} placeholder).",
187
+ "anyOf": [{ "type": "object" }, { "$ref": "#/$defs/redactedValue" }]
188
+ },
189
+ "policy": { "$ref": "#/$defs/policyRef" },
190
+ "signatures": {
191
+ "type": "array",
192
+ "items": {
193
+ "type": "string",
194
+ "description": "Workspace-relative path to a signature.json file."
195
+ },
196
+ "default": []
197
+ },
198
+ "prevHash": { "$ref": "#/$defs/hexHash" },
199
+ "hash": {
200
+ "type": "string",
201
+ "pattern": "^[0-9a-f]{32,128}$",
202
+ "description": "Hash of the canonical JSON of every other field. Recomputed on read."
203
+ },
204
+ "hashAlg": {
205
+ "enum": ["sha256", "sha512", "blake2b-256"],
206
+ "default": "sha256"
207
+ },
208
+ "metadata": {
209
+ "type": "object",
210
+ "additionalProperties": true,
211
+ "default": {}
212
+ }
213
+ }
214
+ },
215
+ "policy": {
216
+ "type": "object",
217
+ "title": "policy (declarative autonomy rule)",
218
+ "required": ["schema", "doctype", "slug", "version", "match", "decision"],
219
+ "additionalProperties": false,
220
+ "properties": {
221
+ "schema": { "$ref": "#/$defs/schemaTag" },
222
+ "doctype": { "const": "policy" },
223
+ "slug": { "$ref": "#/$defs/slug" },
224
+ "version": {
225
+ "type": "string",
226
+ "pattern": "^\\d+\\.\\d+\\.\\d+(?:[-+][a-zA-Z0-9.-]+)?$"
227
+ },
228
+ "match": {
229
+ "type": "object",
230
+ "required": ["action"],
231
+ "additionalProperties": false,
232
+ "properties": {
233
+ "action": {
234
+ "type": "string",
235
+ "pattern": "^[a-z][a-z0-9._*-]*$",
236
+ "description": "Action class to match. May contain * as a wildcard segment."
237
+ },
238
+ "subject": {
239
+ "type": "string",
240
+ "description": "Optional. Literal id, glob, or workspace path. Wildcard matches everything."
241
+ },
242
+ "risk_level_min": {
243
+ "type": "integer",
244
+ "minimum": 0,
245
+ "maximum": 3,
246
+ "default": 0
247
+ }
248
+ }
249
+ },
250
+ "decision": {
251
+ "enum": ["allow", "deny", "require-approval", "escalate"]
252
+ },
253
+ "signers": {
254
+ "type": "array",
255
+ "items": {
256
+ "type": "object",
257
+ "additionalProperties": false,
258
+ "anyOf": [
259
+ {
260
+ "required": ["role"],
261
+ "properties": { "role": { "type": "string" } }
262
+ },
263
+ {
264
+ "required": ["userId"],
265
+ "properties": { "userId": { "$ref": "#/$defs/principalId" } }
266
+ }
267
+ ],
268
+ "properties": {
269
+ "role": { "type": "string", "maxLength": 64 },
270
+ "userId": { "$ref": "#/$defs/principalId" }
271
+ }
272
+ }
273
+ },
274
+ "quorum": {
275
+ "type": "integer",
276
+ "minimum": 1,
277
+ "default": 1,
278
+ "description": "Number of approve signatures required."
279
+ },
280
+ "autonomy": {
281
+ "type": "integer",
282
+ "minimum": 0,
283
+ "maximum": 4,
284
+ "default": 2,
285
+ "description": "Maximum autonomy level at which this policy stays permissive. Above that, the policy escalates."
286
+ },
287
+ "budget": {
288
+ "type": "object",
289
+ "additionalProperties": false,
290
+ "properties": {
291
+ "max_per_hour": { "type": "integer", "minimum": 1 },
292
+ "max_per_day": { "type": "integer", "minimum": 1 },
293
+ "max_amount_cents": { "type": "integer", "minimum": 1 },
294
+ "currency": {
295
+ "type": "string",
296
+ "pattern": "^[A-Z]{3}$",
297
+ "default": "USD"
298
+ }
299
+ }
300
+ },
301
+ "metadata": {
302
+ "type": "object",
303
+ "additionalProperties": true,
304
+ "default": {}
305
+ }
306
+ },
307
+ "allOf": [
308
+ {
309
+ "if": {
310
+ "properties": { "decision": { "const": "require-approval" } }
311
+ },
312
+ "then": { "required": ["signers"] }
313
+ }
314
+ ]
315
+ },
316
+ "workspace": {
317
+ "type": "object",
318
+ "title": "governance.workspace/v1 (manifest, root or view)",
319
+ "description": "Workspace manifest doctype for AIP-7. Used both as the root manifest of a governance scope (no `extends`) and as a per-consumer view (with `extends`). The same schema validates both modes; the host distinguishes by checking whether `extends` is set. One-way switches (audit.appendOnly, signing.required) are enforced by the host at merge time and cannot be relaxed by a descendant view.",
320
+ "required": ["schema", "name", "title", "description", "version"],
321
+ "additionalProperties": false,
322
+ "properties": {
323
+ "schema": {
324
+ "const": "governance.workspace/v1",
325
+ "description": "Discriminator for the workspace manifest doctype. Note: this differs from the family-level $schema tag used by signature/audit-event/policy because the workspace doctype follows the AIP-10/AIP-13 manifest convention."
326
+ },
327
+ "name": {
328
+ "type": "string",
329
+ "minLength": 2,
330
+ "maxLength": 96,
331
+ "pattern": "^[a-z][a-z0-9-]*[a-z0-9]$",
332
+ "description": "Stable kebab-case identifier for the workspace or view."
333
+ },
334
+ "title": {
335
+ "type": "string",
336
+ "minLength": 1,
337
+ "maxLength": 200,
338
+ "description": "Human-readable workspace title."
339
+ },
340
+ "description": {
341
+ "type": "string",
342
+ "minLength": 1,
343
+ "maxLength": 2000,
344
+ "description": "One-paragraph statement of purpose: what this workspace (or view) governs and who uses it."
345
+ },
346
+ "version": {
347
+ "type": "string",
348
+ "pattern": "^[0-9]+\\.[0-9]+\\.[0-9]+(-[A-Za-z0-9.-]+)?$",
349
+ "description": "Semantic version of the WORKSPACE shape. Bump on autonomy / policies / approvers / signing / audit changes."
350
+ },
351
+ "extends": {
352
+ "type": "string",
353
+ "minLength": 1,
354
+ "maxLength": 512,
355
+ "pattern": "^(\\.\\./|\\./)[^\\s]+/GOVERNANCE\\.md$",
356
+ "description": "OPTIONAL — relative path to a parent GOVERNANCE.md. Presence of this field makes the manifest a VIEW; absence makes it a WORKSPACE ROOT. Recursive composition allowed; maximum chain depth is 8. Cycles and missing parents degrade to warnings; ONE-WAY SWITCHES (audit.appendOnly, signing.required) cannot be relaxed and produce hard refusals."
357
+ },
358
+ "appliesTo": {
359
+ "type": "array",
360
+ "items": {
361
+ "type": "string",
362
+ "pattern": "^(ws://(operators|companies|skills)/[a-z][a-z0-9-]*|\\.\\./[^\\s]+)$",
363
+ "description": "Either a ws:// ref to an AIP-9 operator / AIP-6 company / AIP-3 skill, or a relative path to a consumer workspace folder."
364
+ },
365
+ "uniqueItems": true,
366
+ "description": "OPTIONAL — list of consumers this VIEW adapts the workspace for. Hosts MUST refuse the view if any binding does not resolve. Not inherited; views declare their own scope."
367
+ },
368
+ "autonomy": {
369
+ "type": "object",
370
+ "additionalProperties": false,
371
+ "properties": {
372
+ "level": {
373
+ "type": "integer",
374
+ "minimum": 0,
375
+ "maximum": 3,
376
+ "description": "Autonomy ceiling. 0 = read-only, 1 = suggest, 2 = bounded auto, 3 = irreversible auto. Maps to the AIP-7 0-4 ladder; the workspace manifest declares the CEILING for this scope, individual policies MAY further restrict."
377
+ },
378
+ "defaultApproval": {
379
+ "type": "string",
380
+ "pattern": "^(auto|always|on-mutate|policy:[a-z][a-z0-9-]*)$",
381
+ "description": "Default approval class when no policy matches. 'auto' = no approval; 'always' = always require approval; 'on-mutate' = require approval on mutation; 'policy:<slug>' = delegate to a named policy."
382
+ },
383
+ "approvalEscalation": {
384
+ "type": "object",
385
+ "additionalProperties": false,
386
+ "required": ["from", "to"],
387
+ "properties": {
388
+ "from": { "type": "string", "maxLength": 96 },
389
+ "to": { "type": "string", "maxLength": 96 }
390
+ },
391
+ "description": "Fallback route when defaultApproval can't resolve a quorum. 'from' and 'to' name approval classes."
392
+ }
393
+ },
394
+ "description": "Autonomy posture for the scope. Each leaf field overrides independently across the chain."
395
+ },
396
+ "signing": {
397
+ "type": "object",
398
+ "additionalProperties": false,
399
+ "properties": {
400
+ "algo": {
401
+ "enum": ["ed25519", "ecdsa-p256", "rsa-pss-sha256"],
402
+ "description": "Default signing algorithm. Hosts MUST support ed25519; others are OPTIONAL."
403
+ },
404
+ "keyring": {
405
+ "type": "string",
406
+ "minLength": 1,
407
+ "maxLength": 512,
408
+ "description": "Workspace-relative path to a public-key bundle (e.g. .well-known/governance-keys.json). The host loads keys from this path to verify signatures."
409
+ },
410
+ "required": {
411
+ "type": "boolean",
412
+ "description": "ONE-WAY SWITCH. When true, every audit event MUST carry a verifiable signature. Once a parent locks this to true, no descendant view may downgrade to false; hosts MUST refuse the merge with `governance_signing_downgrade`."
413
+ }
414
+ },
415
+ "description": "Signing posture. Composes leaf-by-leaf across the chain. The `required` field is a one-way switch: parent strict → child stricter or equal."
416
+ },
417
+ "audit": {
418
+ "type": "object",
419
+ "additionalProperties": false,
420
+ "properties": {
421
+ "retention": {
422
+ "type": "string",
423
+ "pattern": "^(forever|days:[0-9]+)$",
424
+ "description": "Audit-log retention. 'forever' or 'days:<n>'."
425
+ },
426
+ "hashAlgo": {
427
+ "enum": ["sha256", "sha512", "blake3"],
428
+ "description": "Hash algorithm for the audit chain. Default sha256."
429
+ },
430
+ "appendOnly": {
431
+ "type": "boolean",
432
+ "description": "ONE-WAY SWITCH. When true, the audit log is locked append-only — no in-place edits, no truncation, no deletion. Once a parent locks this to true, no descendant view may downgrade to false; hosts MUST refuse the merge with `governance_append_only_relaxation`. This is AIP-7's defining safety property."
433
+ },
434
+ "storage": {
435
+ "type": "string",
436
+ "minLength": 1,
437
+ "maxLength": 1024,
438
+ "description": "OPTIONAL — vendor-neutral URI of the audit store (e.g. file://, s3://, https://). Informational; the canonical artifact is still audit-log.jsonl."
439
+ },
440
+ "headPointerSign": {
441
+ "type": "boolean",
442
+ "description": "OPTIONAL — when true, the host periodically publishes a signed head-pointer attestation that external verifiers can pin against."
443
+ }
444
+ },
445
+ "description": "Audit posture. Each leaf field overrides independently EXCEPT for `appendOnly`, which is a one-way switch (parent true → child cannot set false)."
446
+ },
447
+ "policies": {
448
+ "type": "array",
449
+ "items": {
450
+ "type": "object",
451
+ "required": ["id", "ref"],
452
+ "additionalProperties": false,
453
+ "properties": {
454
+ "id": {
455
+ "type": "string",
456
+ "pattern": "^[a-z][a-z0-9-]*$",
457
+ "description": "Stable kebab-case policy registry id. Merge key when composing with the extends parent."
458
+ },
459
+ "ref": {
460
+ "type": "string",
461
+ "minLength": 1,
462
+ "maxLength": 512,
463
+ "description": "Workspace-relative path to a POLICY.md file. Policies are ALWAYS file-referenced, never inlined; this keeps the policy registry editable through the same governance gate as any other artifact."
464
+ },
465
+ "appliesTo": {
466
+ "type": "string",
467
+ "pattern": "^([a-z][a-z0-9._-]*[a-z0-9]|\\*)$",
468
+ "description": "AIP-7 action class to bind this policy to (e.g. 'workspace.write', 'tool.call', 'mutates') or '*' for all actions."
469
+ },
470
+ "severity": {
471
+ "enum": ["error", "warn", "info"],
472
+ "description": "Severity when this policy is violated. 'error' = block; 'warn' = surface; 'info' = log only."
473
+ },
474
+ "params": {
475
+ "type": "object",
476
+ "additionalProperties": true,
477
+ "description": "Policy-instance parameters that the referenced POLICY.md interprets."
478
+ }
479
+ }
480
+ },
481
+ "default": [],
482
+ "description": "Registry of policies that apply in this scope. Merge-by-id against the extends parent: a child entry with the same id replaces the parent's; new ids are appended."
483
+ },
484
+ "approvers": {
485
+ "type": "array",
486
+ "items": {
487
+ "type": "object",
488
+ "required": ["id"],
489
+ "additionalProperties": false,
490
+ "properties": {
491
+ "id": {
492
+ "type": "string",
493
+ "pattern": "^[a-z][a-z0-9-]*$",
494
+ "description": "Stable kebab-case approver id. Merge key when composing with the extends parent."
495
+ },
496
+ "role": {
497
+ "type": "string",
498
+ "maxLength": 200,
499
+ "description": "Human-readable role name OR an AIP-9 ws://operators/<slug> ref. Resolved at evaluation time."
500
+ },
501
+ "canApprove": {
502
+ "type": "array",
503
+ "items": {
504
+ "type": "string",
505
+ "pattern": "^[a-z][a-z0-9._-]*[a-z0-9]$"
506
+ },
507
+ "uniqueItems": true,
508
+ "description": "Approval classes this approver is authorized for."
509
+ },
510
+ "quorum": {
511
+ "type": "string",
512
+ "pattern": "^([1-9][0-9]*|[1-9][0-9]*-of-[1-9][0-9]*)$",
513
+ "description": "Quorum requirement. '1' = single-signer; 'n-of-m' = quorum among a group of m."
514
+ }
515
+ }
516
+ },
517
+ "default": [],
518
+ "description": "Pre-declared approvers. Merge-by-id against the extends parent: a child entry with the same id replaces the parent's; new ids are appended."
519
+ },
520
+ "executor": {
521
+ "type": "string",
522
+ "pattern": "^ws://operators/[a-z][a-z0-9-]*$",
523
+ "description": "OPTIONAL — AIP-9 operator the host activates to run governance flows for this scope (apply policies, collect signatures, append audit entries)."
524
+ },
525
+ "escalateTo": {
526
+ "type": "string",
527
+ "pattern": "^ws://operators/[a-z][a-z0-9-]*$",
528
+ "description": "OPTIONAL — AIP-9 operator to escalate to when autonomy.approvalEscalation fires. Distinct from `executor`: the executor runs governance, the escalation operator decides outcomes when the executor cannot."
529
+ },
530
+ "work": {
531
+ "type": "string",
532
+ "minLength": 1,
533
+ "maxLength": 512,
534
+ "description": "OPTIONAL — AIP-13 WORK.md binding. Audit events emitted by this scope MAY also produce work-item updates in the bound work workspace."
535
+ },
536
+ "knowledge": {
537
+ "type": "string",
538
+ "minLength": 1,
539
+ "maxLength": 512,
540
+ "description": "OPTIONAL — AIP-10 KNOWLEDGE.md binding. Schema or source mutations in the bound wiki flow through this workspace's approval gate."
541
+ },
542
+ "display": {
543
+ "type": "object",
544
+ "additionalProperties": false,
545
+ "properties": {
546
+ "defaultDashboard": {
547
+ "type": "string",
548
+ "pattern": "^[a-z][a-z0-9-]*[a-z0-9]$",
549
+ "description": "OPTIONAL — slug of the dashboard a UI uses as the workspace landing surface."
550
+ },
551
+ "showRetentionWarnings": {
552
+ "type": "boolean",
553
+ "description": "OPTIONAL — when true, UIs surface a banner when retention windows are about to expire."
554
+ }
555
+ },
556
+ "description": "Display hints for UIs that render the workspace. Runtime-agnostic."
557
+ },
558
+ "metadata": {
559
+ "type": "object",
560
+ "additionalProperties": true,
561
+ "default": {},
562
+ "description": "Vendor-specific extensions, namespaced under <vendor>. Deep-merged across the extends chain."
563
+ }
564
+ },
565
+ "allOf": [
566
+ {
567
+ "description": "A view (any manifest with appliesTo set) MUST extend a parent. A workspace-root manifest has neither field.",
568
+ "if": {
569
+ "required": ["appliesTo"],
570
+ "properties": {
571
+ "appliesTo": { "type": "array", "minItems": 1 }
572
+ }
573
+ },
574
+ "then": {
575
+ "required": ["extends"]
576
+ }
577
+ }
578
+ ]
579
+ }
580
+ }
581
+ }