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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/dist/cli.mjs +26 -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 +4 -4
@@ -0,0 +1,411 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://agentproto.sh/schemas/aip-24/ASSEMBLY.schema.json",
4
+ "title": "agentassembly/v1 frontmatter (AIP-24)",
5
+ "description": "Validates the YAML frontmatter portion of an AIP-24 ASSEMBLY.md (workspace root or per-context view). The single doctype 'assembly.workspace/v1' is used in both modes; the host distinguishes by checking whether `extends` is set. The discriminating field is `mode` — advisory | voting | peer | hierarchy — each selecting a different synthesis substrate. The `members[]` array references AIP-25 personas; AIP-24 does NOT define a member-as-doctype.",
6
+ "type": "object",
7
+ "required": ["schema", "name", "title", "description", "version", "mode"],
8
+ "additionalProperties": false,
9
+ "properties": {
10
+ "schema": {
11
+ "const": "assembly.workspace/v1",
12
+ "description": "Discriminator for the AIP-24 workspace doctype."
13
+ },
14
+ "name": {
15
+ "type": "string",
16
+ "minLength": 2,
17
+ "maxLength": 96,
18
+ "pattern": "^[a-z][a-z0-9-]*[a-z0-9]$",
19
+ "description": "Stable kebab-case identifier for the assembly or view."
20
+ },
21
+ "title": {
22
+ "type": "string",
23
+ "minLength": 1,
24
+ "maxLength": 200,
25
+ "description": "Human-readable assembly title."
26
+ },
27
+ "description": {
28
+ "type": "string",
29
+ "minLength": 1,
30
+ "maxLength": 2000,
31
+ "description": "One-paragraph statement of purpose: what this assembly is, who it serves, why this mode is the right pattern."
32
+ },
33
+ "version": {
34
+ "type": "string",
35
+ "pattern": "^[0-9]+\\.[0-9]+\\.[0-9]+(-[A-Za-z0-9.-]+)?$",
36
+ "description": "Semantic version of the WORKSPACE shape. Bump on member roster / synthesis rule / locked-trait / audit policy changes. Independent of the assembly's content version."
37
+ },
38
+ "extends": {
39
+ "type": "string",
40
+ "minLength": 1,
41
+ "maxLength": 512,
42
+ "pattern": "^(\\.\\./|\\./)[^\\s]+/ASSEMBLY\\.md$",
43
+ "description": "OPTIONAL — relative path to a parent ASSEMBLY.md. Presence makes the manifest a VIEW; absence makes it a WORKSPACE ROOT. Recursive composition; maximum chain depth is 8."
44
+ },
45
+ "appliesTo": {
46
+ "type": "array",
47
+ "items": {
48
+ "type": "string",
49
+ "pattern": "^(ws://(operators|companies|workspaces|skills)/[a-z][a-z0-9-]*|\\.\\./[^\\s]+)$",
50
+ "description": "Either a ws:// ref to an AIP-9 operator, AIP-22 company, AIP-20 work workspace, or AIP-3 skill, or a relative path to a consumer workspace folder."
51
+ },
52
+ "uniqueItems": true,
53
+ "description": "OPTIONAL — list of consumers this VIEW adapts the assembly for. Hosts MUST refuse the view if any binding does not resolve. Not inherited; views declare their own scope."
54
+ },
55
+ "mode": {
56
+ "enum": ["advisory", "voting", "peer", "hierarchy"],
57
+ "description": "The collaboration pattern. ONE-WAY SWITCH: once set at any ancestor, descendants MUST NOT change to a different mode. Refusal: assembly_mode_change (HARD). 'advisory' = silent overlay producing persona fragments (the implemented anchor — Simone's Council); 'voting' = quorum decision body; 'peer' = network of equals exchanging messages; 'hierarchy' = reporting tree with bottom-up aggregation."
58
+ },
59
+ "members": {
60
+ "type": "array",
61
+ "items": { "$ref": "#/$defs/member" },
62
+ "default": [],
63
+ "description": "Member roster. Each member is a ref to an AIP-25 persona with assembly-specific role config. Merge-by-id (the role id, not the persona ref) across the extends chain."
64
+ },
65
+ "synthesis": {
66
+ "type": "object",
67
+ "additionalProperties": false,
68
+ "properties": {
69
+ "rules": {
70
+ "type": "array",
71
+ "items": { "$ref": "#/$defs/synthesisRule" },
72
+ "default": [],
73
+ "description": "Synthesis rules in declaration order. A rule MAY declare itself terminal to short-circuit further rule processing. Merge-by-id with parent."
74
+ },
75
+ "riskLevels": {
76
+ "type": "array",
77
+ "items": { "$ref": "#/$defs/riskLevel" },
78
+ "description": "Severity-to-risk-level mapping. Severity ranges MUST be monotonic non-overlapping integer intervals. Whole-array override across the extends chain (child's mapping replaces parent's)."
79
+ }
80
+ },
81
+ "description": "How member outputs combine into a single guidance / decision / message log / hierarchy output."
82
+ },
83
+ "lockedTraits": {
84
+ "type": "array",
85
+ "items": {
86
+ "type": "string",
87
+ "minLength": 1,
88
+ "maxLength": 200
89
+ },
90
+ "uniqueItems": true,
91
+ "default": [],
92
+ "description": "Anti-poisoning floor. Substrings (or regexes / semantic patterns per matchMode) that an output's text MUST NOT contain. UNION across the extends chain — additive only, child cannot remove parent's entries. Refusal: assembly_locked_trait_removed (HARD)."
93
+ },
94
+ "matchMode": {
95
+ "enum": ["substring", "regex", "semantic"],
96
+ "default": "substring",
97
+ "description": "Algorithm used to check outputs against lockedTraits. 'substring' (default, matches Simone v1) — case-insensitive substring match. 'regex' — RFC-3987-ish regex. 'semantic' — embedding match against the trait's semantic neighborhood; hosts that don't support semantic MUST fall back to substring with assembly_locked_trait_match_mode_unsupported warning."
98
+ },
99
+ "audit": {
100
+ "type": "object",
101
+ "additionalProperties": false,
102
+ "properties": {
103
+ "consultations": {
104
+ "type": "object",
105
+ "additionalProperties": false,
106
+ "properties": {
107
+ "enabled": {
108
+ "type": "boolean",
109
+ "default": true,
110
+ "description": "Whether each member invocation is persisted as a consultation row. ONE-WAY SWITCH: once true at any ancestor, descendants MUST NOT set false. Refusal: assembly_audit_disable (HARD)."
111
+ },
112
+ "retention": {
113
+ "type": "string",
114
+ "pattern": "^(forever|days:[1-9][0-9]*)$",
115
+ "default": "forever",
116
+ "description": "Retention policy for consultation rows. 'forever' — never evicted. 'days:<n>' — evict rows older than n days."
117
+ }
118
+ },
119
+ "description": "Consultation persistence policy."
120
+ },
121
+ "overlays": {
122
+ "type": "object",
123
+ "additionalProperties": false,
124
+ "properties": {
125
+ "enabled": {
126
+ "type": "boolean",
127
+ "default": true,
128
+ "description": "Whether overlay fragments (advisory) / decision records (voting) / message log entries (peer) / rolled-up outputs (hierarchy) are persisted. ONE-WAY SWITCH: once true at any ancestor, descendants MUST NOT set false. Refusal: assembly_audit_disable (HARD)."
129
+ },
130
+ "maxActive": {
131
+ "type": "integer",
132
+ "minimum": 1,
133
+ "maximum": 100,
134
+ "default": 10,
135
+ "description": "Cap on concurrent active artifacts (typically advisory overlay fragments). Older artifacts are evicted on write to keep the count under the cap."
136
+ },
137
+ "defaultTtl": {
138
+ "type": "string",
139
+ "pattern": "^P(?!$)((\\d+Y)?(\\d+M)?(\\d+W)?(\\d+D)?)?(T(\\d+H)?(\\d+M)?(\\d+S)?)?$",
140
+ "default": "P14D",
141
+ "description": "ISO 8601 duration applied as default TTL to advisory overlay fragments that don't specify their own. Examples: P14D (14 days), P3D (3 days), PT1H (1 hour)."
142
+ }
143
+ },
144
+ "description": "Overlay artifact persistence policy."
145
+ },
146
+ "signing": {
147
+ "enum": ["required", "optional", "none"],
148
+ "default": "optional",
149
+ "description": "Signing posture, composing with AIP-7 governance. 'required' — every artifact MUST carry a signature; 'optional' — signatures permitted; 'none' — no signing. ONE-WAY SWITCH on downgrade: once 'required' at any ancestor, descendants MUST NOT downgrade. Refusal: assembly_signing_downgrade (HARD)."
150
+ }
151
+ },
152
+ "description": "Audit policy. Composes with AIP-7 governance for signing. The runtime tables (consultations, overlays, decisions, message logs) are host-side data shaped by this policy; AIP-24 does not prescribe table names."
153
+ },
154
+ "identity": {
155
+ "type": "string",
156
+ "pattern": "^ws://identities/[a-z][a-z0-9-]*$",
157
+ "description": "OPTIONAL — AIP-23 base identity ref. The identity the assembly modulates (advisory) or attributes to (voting / peer / hierarchy)."
158
+ },
159
+ "governance": {
160
+ "type": "string",
161
+ "minLength": 1,
162
+ "maxLength": 512,
163
+ "description": "OPTIONAL — AIP-7 policy or audit binding. May be a path to an AIP-7 policy file or a ws:// ref. Approval gates, signing keys, and audit retention compose with audit.signing and the workspace's one-way switches."
164
+ },
165
+ "work": {
166
+ "type": "string",
167
+ "pattern": "^ws://workspaces/[a-z][a-z0-9-]*$",
168
+ "description": "OPTIONAL — AIP-20 work workspace the assembly's artifacts attach to. Advisory overlays describe the agent's behavior on items in this workspace; voting decisions approve work items; hierarchy outputs roll up severity from work-item reviews."
169
+ },
170
+ "executor": {
171
+ "type": "string",
172
+ "pattern": "^ws://operators/[a-z][a-z0-9-]*$",
173
+ "description": "OPTIONAL — AIP-9 default executor operator. The runtime that calls defineAssemblyWorkspace, runs the member-execution pipeline, and persists the artifacts."
174
+ },
175
+ "defaults": {
176
+ "type": "object",
177
+ "additionalProperties": false,
178
+ "properties": {
179
+ "triggerHeuristic": {
180
+ "type": "string",
181
+ "pattern": "^(every-n-messages|on-mode-change|manual|periodic|custom:[A-Za-z0-9_./:-]+)$",
182
+ "description": "OPTIONAL — default trigger heuristic for invoking the assembly. 'every-n-messages' — sample every N user messages; 'on-mode-change' — invoke when the conversation's mode changes; 'manual' — invoke only on explicit request; 'periodic' — invoke on triggerInterval_ms cadence; 'custom:<id>' — host-defined."
183
+ },
184
+ "triggerInterval_ms": {
185
+ "type": "integer",
186
+ "minimum": 1000,
187
+ "maximum": 86400000,
188
+ "description": "OPTIONAL — interval in milliseconds for periodic mode. Required when triggerHeuristic = 'periodic'."
189
+ }
190
+ },
191
+ "description": "Trigger defaults. Per-member overrides live on the members[] entries."
192
+ },
193
+ "display": {
194
+ "type": "object",
195
+ "additionalProperties": false,
196
+ "properties": {
197
+ "defaultGrouping": {
198
+ "enum": ["phase", "role", "severity"],
199
+ "description": "OPTIONAL — default grouping for assembly views. 'phase' (advisory), 'role' (any mode), 'severity' (advisory / hierarchy)."
200
+ }
201
+ },
202
+ "description": "Display hints for UIs that render the assembly. Runtime-agnostic."
203
+ },
204
+ "metadata": {
205
+ "type": "object",
206
+ "additionalProperties": true,
207
+ "default": {},
208
+ "description": "Vendor-specific extensions, namespaced under <vendor>. Deep-merged across the extends chain. MUST NOT change the meaning of any spec field. The four one-way switches are spec-level invariants; vendor namespaces cannot bypass them."
209
+ }
210
+ },
211
+ "allOf": [
212
+ {
213
+ "description": "A view (any manifest with appliesTo set) MUST extend a parent. A workspace-root manifest has neither field.",
214
+ "if": {
215
+ "required": ["appliesTo"],
216
+ "properties": {
217
+ "appliesTo": { "type": "array", "minItems": 1 }
218
+ }
219
+ },
220
+ "then": {
221
+ "required": ["extends"]
222
+ }
223
+ },
224
+ {
225
+ "description": "When defaults.triggerHeuristic = 'periodic', defaults.triggerInterval_ms MUST be set.",
226
+ "if": {
227
+ "properties": {
228
+ "defaults": {
229
+ "properties": {
230
+ "triggerHeuristic": { "const": "periodic" }
231
+ },
232
+ "required": ["triggerHeuristic"]
233
+ }
234
+ },
235
+ "required": ["defaults"]
236
+ },
237
+ "then": {
238
+ "properties": {
239
+ "defaults": { "required": ["triggerInterval_ms"] }
240
+ }
241
+ }
242
+ }
243
+ ],
244
+ "$defs": {
245
+ "member": {
246
+ "type": "object",
247
+ "required": ["id", "persona", "role"],
248
+ "additionalProperties": false,
249
+ "properties": {
250
+ "id": {
251
+ "type": "string",
252
+ "minLength": 2,
253
+ "maxLength": 64,
254
+ "pattern": "^[a-z][a-z0-9-]*[a-z0-9]$",
255
+ "description": "Stable kebab-case role id within the assembly. Merge key. MUST be unique within a single manifest layer; collisions within one layer refuse with assembly_member_id_collision (HARD). Across layers, child replaces parent's by id."
256
+ },
257
+ "persona": {
258
+ "type": "string",
259
+ "pattern": "^ws://personas/[a-z][a-z0-9-]*$",
260
+ "description": "AIP-25 persona ref. Required. Hosts MUST resolve the persona at load time; unresolvable refs refuse with assembly_member_persona_unresolvable (HARD)."
261
+ },
262
+ "role": {
263
+ "type": "string",
264
+ "minLength": 1,
265
+ "maxLength": 200,
266
+ "description": "Human-readable role label (e.g. Therapist, Sentinel, CFO, Brand Critic, Department Head)."
267
+ },
268
+ "phase": {
269
+ "type": "string",
270
+ "minLength": 1,
271
+ "maxLength": 64,
272
+ "description": "OPTIONAL — for advisory mode. Built-in: 'session' (per-message review), 'standing' (periodic deep dive), 'sentinel' (safety pre-filter). Custom phase ids are permitted; the host filters members to the active phase before invocation."
273
+ },
274
+ "triggers": {
275
+ "type": "array",
276
+ "items": {
277
+ "type": "string",
278
+ "enum": [
279
+ "sample",
280
+ "sentinel-match",
281
+ "scheduled",
282
+ "manual",
283
+ "periodic"
284
+ ]
285
+ },
286
+ "uniqueItems": true,
287
+ "description": "OPTIONAL — which trigger kinds invoke this member. When omitted, the member is invoked on every assembly trigger."
288
+ },
289
+ "weight": {
290
+ "type": "number",
291
+ "exclusiveMinimum": 0,
292
+ "maximum": 100,
293
+ "description": "OPTIONAL — for voting mode. Multiplier on the cast vote. Default 1.0. Higher for senior reviewers, lower for junior. Quorum thresholds compute against the sum of weights in the voteClass."
294
+ },
295
+ "voteClass": {
296
+ "type": "array",
297
+ "items": {
298
+ "type": "string",
299
+ "minLength": 1,
300
+ "maxLength": 64,
301
+ "pattern": "^[a-z][a-z0-9-]*$"
302
+ },
303
+ "uniqueItems": true,
304
+ "description": "OPTIONAL — for voting mode. Which proposal classes this member is empowered to vote on. Examples: ['budget', 'security', 'architecture']. When omitted, the member votes on every class."
305
+ },
306
+ "parent": {
307
+ "type": "string",
308
+ "minLength": 2,
309
+ "maxLength": 64,
310
+ "pattern": "^[a-z][a-z0-9-]*[a-z0-9]$",
311
+ "description": "OPTIONAL — for hierarchy mode. Reporting parent's role id. Outputs cascade bottom-up; the parent receives this member's output as input. The host MUST detect cycles (assembly_hierarchy_cycle, HARD) and refuse parents that don't resolve to a member id (assembly_hierarchy_invalid_parent, HARD)."
312
+ },
313
+ "timeout_ms": {
314
+ "type": "integer",
315
+ "minimum": 100,
316
+ "maximum": 600000,
317
+ "default": 30000,
318
+ "description": "OPTIONAL — per-member execution cap in milliseconds. The host MUST cancel the member's invocation when the timeout elapses; cancelled invocations produce no output (treated as missing in synthesis)."
319
+ },
320
+ "gatherInput": {
321
+ "type": "object",
322
+ "required": ["strategy"],
323
+ "additionalProperties": false,
324
+ "properties": {
325
+ "strategy": {
326
+ "type": "string",
327
+ "pattern": "^(working-memory|recent-messages|digest|last-message-only|custom:[A-Za-z0-9_./:-]+)$",
328
+ "description": "Built-in: 'working-memory' (the agent's working memory for the current user/thread), 'recent-messages' (last N raw messages), 'digest' (a multi-day summary), 'last-message-only' (just the last user message). 'custom:<id>' delegates to a host-registered gather strategy."
329
+ },
330
+ "params": {
331
+ "type": "object",
332
+ "additionalProperties": true,
333
+ "default": {},
334
+ "description": "Strategy-specific parameters. Examples: { limit: 20 } for recent-messages; { window_days: 7 } for digest."
335
+ }
336
+ },
337
+ "description": "OPTIONAL — input-gathering configuration. When omitted, the host uses 'working-memory' with no params."
338
+ }
339
+ },
340
+ "description": "One member of the assembly. Carries the persona ref (the unit of identity) and the assembly-specific role config (phase / weight / voteClass / parent — depending on mode)."
341
+ },
342
+ "synthesisRule": {
343
+ "type": "object",
344
+ "required": ["id", "kind"],
345
+ "additionalProperties": false,
346
+ "properties": {
347
+ "id": {
348
+ "type": "string",
349
+ "minLength": 2,
350
+ "maxLength": 96,
351
+ "pattern": "^[a-z][a-z0-9-]*[a-z0-9]$",
352
+ "description": "Stable kebab-case rule id. Merge key. Same id across the extends chain → child replaces parent's; new ids appended."
353
+ },
354
+ "kind": {
355
+ "type": "string",
356
+ "minLength": 1,
357
+ "maxLength": 96,
358
+ "description": "Built-in: 'terminal' | 'priority' | 'aggregate' | 'quorum' | 'majority' | 'unanimity' | 'escalate-on-severity'. Custom kinds are free-form strings resolved through the host's rule registry; unregistered kinds refuse with assembly_synthesis_rule_invalid (HARD)."
359
+ },
360
+ "appliesTo": {
361
+ "oneOf": [
362
+ { "type": "string", "const": "*" },
363
+ {
364
+ "type": "array",
365
+ "items": {
366
+ "type": "string",
367
+ "minLength": 2,
368
+ "maxLength": 64,
369
+ "pattern": "^[a-z][a-z0-9-]*[a-z0-9]$"
370
+ },
371
+ "uniqueItems": true,
372
+ "minItems": 1
373
+ }
374
+ ],
375
+ "description": "OPTIONAL — '*' (all members) or an array of member ids the rule applies to. Members listed MUST exist in the merged members[] array; unresolvable ids refuse with assembly_synthesis_unknown_member (HARD)."
376
+ },
377
+ "params": {
378
+ "type": "object",
379
+ "additionalProperties": true,
380
+ "default": {},
381
+ "description": "Kind-specific parameters. Examples: { triggerSeverity: 9 } for terminal; { triggerKind: sycophancy } for priority; { threshold: 0.66 } for quorum; { topN: 2 } for aggregate; { tieBreaker: chair-vote } for majority."
382
+ }
383
+ },
384
+ "description": "One synthesis rule. Rules apply in declaration order; a rule MAY declare itself terminal (via params or kind) to short-circuit further rule processing."
385
+ },
386
+ "riskLevel": {
387
+ "type": "object",
388
+ "required": ["range", "label"],
389
+ "additionalProperties": false,
390
+ "properties": {
391
+ "range": {
392
+ "type": "array",
393
+ "items": {
394
+ "type": "integer",
395
+ "minimum": 0,
396
+ "maximum": 10
397
+ },
398
+ "minItems": 2,
399
+ "maxItems": 2,
400
+ "description": "Closed integer interval [min, max]. Severity values within the interval map to this level. Intervals across the riskLevels[] array MUST be monotonic non-overlapping."
401
+ },
402
+ "label": {
403
+ "type": "string",
404
+ "enum": ["ok", "watch", "intervene", "escalate"],
405
+ "description": "Risk-level label. The four built-in labels match the working Council implementation."
406
+ }
407
+ },
408
+ "description": "One severity-to-risk-level mapping entry."
409
+ }
410
+ }
411
+ }
@@ -0,0 +1,257 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://agentproto.sh/schemas/aip-25/PERSONA.schema.json",
4
+ "title": "PERSONA.md frontmatter (AIP-25)",
5
+ "description": "Validates the YAML frontmatter portion of an AIP-25 PERSONA.md manifest. Single-doc, no oneOf — every persona is the same shape. The body is markdown and not validated by this schema.",
6
+ "type": "object",
7
+ "required": ["schema", "name", "title", "description", "version"],
8
+ "additionalProperties": false,
9
+ "properties": {
10
+ "schema": {
11
+ "const": "persona/v1",
12
+ "description": "Schema dispatch tag. MUST be 'persona/v1' for this version of AIP-25."
13
+ },
14
+ "name": {
15
+ "type": "string",
16
+ "minLength": 2,
17
+ "maxLength": 64,
18
+ "pattern": "^[a-z][a-z0-9-]*[a-z0-9]$",
19
+ "description": "Machine identifier. Lowercase, digits, dashes. Must start with a letter, end with a letter or digit. Unique within the registry that hosts the persona."
20
+ },
21
+ "title": {
22
+ "type": "string",
23
+ "minLength": 1,
24
+ "maxLength": 120,
25
+ "description": "Human-readable display title, sentence case."
26
+ },
27
+ "description": {
28
+ "type": "string",
29
+ "minLength": 1,
30
+ "maxLength": 2000,
31
+ "description": "One-paragraph elevator pitch. The persona's purpose, audience, and shape."
32
+ },
33
+ "version": {
34
+ "type": "string",
35
+ "pattern": "^\\d+\\.\\d+\\.\\d+(?:[-+][a-zA-Z0-9.-]+)?$",
36
+ "description": "Semver. Bump on breaking change to identity, voice, or boundaries."
37
+ },
38
+ "extends": {
39
+ "type": "string",
40
+ "pattern": "^(\\.{1,2}/)[^\\s]+PERSONA\\.md$",
41
+ "description": "Relative path to a parent PERSONA.md. Triggers composition. Path MUST end in 'PERSONA.md'."
42
+ },
43
+ "avatar": {
44
+ "type": "string",
45
+ "minLength": 1,
46
+ "description": "Public visual face. URL, data URI, or 'ws://avatars/<slug>' ref. Schema does not validate scheme; the loader resolves."
47
+ },
48
+ "backstory": {
49
+ "type": "object",
50
+ "additionalProperties": false,
51
+ "properties": {
52
+ "oneLineHook": {
53
+ "type": "string",
54
+ "minLength": 1,
55
+ "maxLength": 280,
56
+ "description": "Punchy elevator hook. One sentence the catalog can show next to the persona name."
57
+ },
58
+ "background": {
59
+ "type": "string",
60
+ "minLength": 1,
61
+ "description": "Long-form lore prose, in markdown. The character's history, motivations, and context."
62
+ },
63
+ "archetypes": {
64
+ "type": "array",
65
+ "items": { "type": "string", "pattern": "^[a-z][a-z0-9-]*[a-z0-9]$" },
66
+ "uniqueItems": true,
67
+ "default": [],
68
+ "maxItems": 12,
69
+ "description": "Categorical archetype labels. Lowercase kebab-case. Examples: mentor, craftsman, sentinel, trickster. The catalog MAY cluster by these."
70
+ },
71
+ "era": {
72
+ "type": "string",
73
+ "minLength": 1,
74
+ "maxLength": 80,
75
+ "description": "Free-form era label. Conventional values: 'contemporary', 'timeless', '<year>', '<year>-<year>', '<period>'. Free-form to accept any setting."
76
+ },
77
+ "setting": {
78
+ "type": "string",
79
+ "minLength": 1,
80
+ "maxLength": 120,
81
+ "description": "Free-form setting label. Conventional values: 'real-world', 'fictional-<universe>'. Free-form to accept any setting."
82
+ }
83
+ },
84
+ "default": {}
85
+ },
86
+ "voice": {
87
+ "type": "object",
88
+ "additionalProperties": false,
89
+ "properties": {
90
+ "register": {
91
+ "type": "string",
92
+ "minLength": 1,
93
+ "maxLength": 80,
94
+ "description": "Voice register. Conventional values: warm-direct, playful, terse, academic. Custom values welcome — free-form to accept any author label."
95
+ },
96
+ "signaturePhrases": {
97
+ "type": "array",
98
+ "items": { "type": "string", "minLength": 1, "maxLength": 200 },
99
+ "uniqueItems": true,
100
+ "default": [],
101
+ "maxItems": 24,
102
+ "description": "Catchphrases the character uses. Append-and-dedupe under extends — lineage accumulates phrases."
103
+ },
104
+ "tonality": {
105
+ "type": "array",
106
+ "items": { "type": "string", "minLength": 1, "maxLength": 60 },
107
+ "uniqueItems": true,
108
+ "default": [],
109
+ "maxItems": 16,
110
+ "description": "Tonal adjectives. Examples: rigorous, encouraging, dry, warm. Append-and-dedupe under extends."
111
+ },
112
+ "formality": {
113
+ "type": "integer",
114
+ "minimum": 0,
115
+ "maximum": 10,
116
+ "description": "Formality scale, 0 (extremely casual) to 10 (extremely formal). Optional."
117
+ },
118
+ "emojiUsage": {
119
+ "enum": ["never", "sparing", "frequent"],
120
+ "description": "Emoji posture. 'never' = no emojis ever; 'sparing' = occasional, intentional; 'frequent' = part of the voice."
121
+ },
122
+ "signOff": {
123
+ "type": "string",
124
+ "minLength": 1,
125
+ "maxLength": 200,
126
+ "description": "Sign-off the persona uses to close messages. Examples: '—M.', 'Yours, Marcus', 'Until next time'."
127
+ }
128
+ },
129
+ "default": {}
130
+ },
131
+ "boundaries": {
132
+ "type": "object",
133
+ "additionalProperties": false,
134
+ "properties": {
135
+ "refuses": {
136
+ "type": "array",
137
+ "items": { "type": "string", "minLength": 1, "maxLength": 200 },
138
+ "uniqueItems": true,
139
+ "default": [],
140
+ "description": "Topics the persona refuses outright. Free-form prose; the persona body SHOULD demonstrate the refusal posture in voice samples. Append-and-dedupe under extends."
141
+ },
142
+ "defers": {
143
+ "type": "array",
144
+ "items": { "type": "string", "minLength": 1, "maxLength": 200 },
145
+ "uniqueItems": true,
146
+ "default": [],
147
+ "description": "Topics the persona defers to a specialist on. Append-and-dedupe under extends."
148
+ },
149
+ "redirects": {
150
+ "type": "array",
151
+ "default": [],
152
+ "items": {
153
+ "type": "object",
154
+ "required": ["topic", "to"],
155
+ "additionalProperties": false,
156
+ "properties": {
157
+ "topic": {
158
+ "type": "string",
159
+ "minLength": 1,
160
+ "maxLength": 200,
161
+ "description": "The topic the persona redirects."
162
+ },
163
+ "to": {
164
+ "type": "string",
165
+ "pattern": "^(ws://(personas|operators|skills)/[^\\s]+|\\.{1,2}/[^\\s]+)$",
166
+ "description": "Redirect target. ws:// ref to a persona/operator/skill, or a relative path."
167
+ },
168
+ "notes": {
169
+ "type": "string",
170
+ "minLength": 1,
171
+ "maxLength": 500,
172
+ "description": "Optional prose describing why the redirect exists."
173
+ }
174
+ }
175
+ },
176
+ "description": "Topic-to-target redirects. Merge-by-`topic` under extends — child entry with same topic replaces parent's."
177
+ }
178
+ },
179
+ "default": {}
180
+ },
181
+ "defaultLocale": {
182
+ "type": "string",
183
+ "pattern": "^[a-z]{2,3}(-[A-Z][a-zA-Z0-9]+)*(-[A-Z]{2})?(-[a-zA-Z0-9]+)*$",
184
+ "description": "BCP-47 locale tag. Examples: 'en', 'en-US', 'fr-FR', 'pt-BR'."
185
+ },
186
+ "multilingual": {
187
+ "type": "array",
188
+ "items": {
189
+ "type": "string",
190
+ "pattern": "^[a-z]{2,3}(-[A-Z][a-zA-Z0-9]+)*(-[A-Z]{2})?(-[a-zA-Z0-9]+)*$"
191
+ },
192
+ "uniqueItems": true,
193
+ "default": [],
194
+ "maxItems": 32,
195
+ "description": "Fallback locales. BCP-47. Append-and-dedupe under extends."
196
+ },
197
+ "relationships": {
198
+ "type": "array",
199
+ "default": [],
200
+ "items": {
201
+ "type": "object",
202
+ "required": ["persona", "kind"],
203
+ "additionalProperties": false,
204
+ "properties": {
205
+ "persona": {
206
+ "type": "string",
207
+ "pattern": "^ws://personas/[^\\s]+$",
208
+ "description": "ws:// ref to another persona/v1 manifest in the registry."
209
+ },
210
+ "kind": {
211
+ "type": "string",
212
+ "minLength": 1,
213
+ "maxLength": 60,
214
+ "description": "Relationship kind. Conventional values: mentor-of, peer-of, mentee-of, rival-of, partner-of. Free-form to accept any author label."
215
+ },
216
+ "notes": {
217
+ "type": "string",
218
+ "minLength": 1,
219
+ "maxLength": 1000,
220
+ "description": "Optional prose describing the relationship."
221
+ }
222
+ }
223
+ },
224
+ "description": "Named relationships to other personas. Merge-by-`persona` under extends — child entry with same ref replaces parent's."
225
+ },
226
+ "identity": {
227
+ "type": "string",
228
+ "pattern": "^ws://identities/[^\\s]+$",
229
+ "description": "Optional AIP-23 identity workspace ref. The persona's inner substance."
230
+ },
231
+ "appliesTo": {
232
+ "type": "array",
233
+ "default": [],
234
+ "items": {
235
+ "type": "string",
236
+ "pattern": "^(ws://(operators|skills|assemblies/[a-z0-9-]+|personas)/[^\\s]+|\\.\\./[^\\s]+)$",
237
+ "description": "Cross-AIP ref. Operator (AIP-9), skill (AIP-3), assembly seat (AIP-24), or relative path."
238
+ },
239
+ "uniqueItems": true,
240
+ "description": "Bind this persona to specific consumers. Local-only — not inherited under extends."
241
+ },
242
+ "tags": {
243
+ "type": "array",
244
+ "items": { "type": "string", "pattern": "^[a-z][a-z0-9-]*$" },
245
+ "uniqueItems": true,
246
+ "default": [],
247
+ "maxItems": 16,
248
+ "description": "Catalog tags. Lowercase kebab-case. Append-and-dedupe under extends."
249
+ },
250
+ "metadata": {
251
+ "type": "object",
252
+ "additionalProperties": true,
253
+ "default": {},
254
+ "description": "Vendor extensions, namespaced under <vendor>. Hosts MUST tolerate unknown keys; vendor namespaces MUST NOT override the meaning of fields defined in this AIP."
255
+ }
256
+ }
257
+ }