@brightbeamai/chap-coordinator-mcp 0.2.12 → 0.3.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/schemas.cjs CHANGED
@@ -39,17 +39,37 @@ var TASK_ID = {
39
39
  type: "string",
40
40
  description: "Task identifier returned by chap.task.create."
41
41
  };
42
+ var decimalStringNote = (example) => `Written as a decimal string, e.g. "${example}". CHAP canonicalisation accepts integers only, so a JSON number with a fractional part is refused with -32602.`;
42
43
  var ROUTING_HINTS = {
43
44
  type: "object",
44
- description: "Optional signals for the routing/1.0 profile.",
45
+ description: "Signals recorded on the task and read by the routing/1.0 methods: task.route, review.depth and escalate.auto. Recording a hint has no effect on its own; it is consulted only when one of those methods is called.",
45
46
  properties: {
46
- criticality: { type: "string", enum: ["low", "medium", "high", "critical"] },
47
- deadline: { type: "string", description: "ISO 8601 timestamp." },
48
- risk_tier: { type: "string" },
49
- max_cost_usd: { type: "number" }
47
+ criticality: {
48
+ type: "string",
49
+ enum: ["low", "medium", "high", "critical"],
50
+ description: "How costly a wrong answer would be. The default review-depth policy reads it: 'critical' gives a full review, and 'high' with confidence below 0.7 does the same. The default assignee policy does not read it."
51
+ },
52
+ deadline: { type: "string", description: "When the work is needed by, as an ISO 8601 timestamp. Recorded on the task; the coordinator does not act on it." },
53
+ risk_tier: { type: "string", description: "Operator-defined risk band, e.g. 'regulated' or 'internal'. No built-in policy reads it; it is available to an operator-supplied routing policy." },
54
+ max_cost_usd: { type: "string", description: `Budget ceiling for this task in US dollars. ${decimalStringNote("12.50")} No built-in policy reads it.` }
50
55
  },
51
56
  additionalProperties: true
52
57
  };
58
+ var COMMENT = {
59
+ type: "string",
60
+ description: "The reviewer's note on this decision. Recorded in the audit entry for the decision."
61
+ };
62
+ var TAGS = {
63
+ type: "array",
64
+ items: { type: "string" },
65
+ description: "Workspace-defined labels for this decision, e.g. ['tone', 'unsupported-claim']. Recorded in the audit entry. chap.audit.read does not filter on tags, so grouping by tag is done by the reader."
66
+ };
67
+ var ARTEFACT_DIGEST = {
68
+ type: "string",
69
+ pattern: "^sha256:[0-9a-f]{64}$",
70
+ description: "Optional. SHA-256 over the JCS canonicalisation of the artefact under review, in the form `sha256:<hex>`. When present it binds the decision to the exact content reviewed, and a mismatch is refused with -32074."
71
+ };
72
+ var STRUCTURED_PAYLOAD_NOTE = "Pass a JSON object or array. A JSON-encoded string is parsed back to the structured value before dispatch, so patches in chap.decide.override apply against a real object.";
53
73
  var SCHEMAS = {
54
74
  "chap.workspace.create": {
55
75
  type: "object",
@@ -58,10 +78,20 @@ var SCHEMAS = {
58
78
  profiles: {
59
79
  type: "array",
60
80
  items: { type: "string" },
61
- description: "Profile identifiers to enable, e.g. ['core/1.0', 'review/1.0']."
81
+ description: "Profile identifiers to enable, e.g. ['core/1.0', 'review/1.0']. Recorded on the workspace. Two profiles change behaviour by being present: modes/1.0, under which a trial-mode task requires review, and audit-scitt/1.0, which turns on the hash-linked chain."
82
+ },
83
+ mode: {
84
+ type: "string",
85
+ enum: ["shadow", "trial", "production"],
86
+ default: "trial",
87
+ description: "Default mode for tasks created here. Under modes/1.0 a trial-mode task has review_required set to true whatever the caller passes. 'shadow' and 'production' are recorded on the task and carry no further behaviour in this implementation."
62
88
  },
63
- mode: { type: "string", enum: ["shadow", "trial", "production"], default: "trial" },
64
- mode_ceiling: { type: "string", enum: ["shadow", "trial", "production"], default: "production" }
89
+ mode_ceiling: {
90
+ type: "string",
91
+ enum: ["shadow", "trial", "production"],
92
+ default: "production",
93
+ description: "Highest mode a task in this workspace may request. A task.create above the ceiling is refused with -32040. The ceiling can be changed afterwards with chap.control.set_mode_ceiling."
94
+ }
65
95
  },
66
96
  additionalProperties: false
67
97
  },
@@ -74,7 +104,11 @@ var SCHEMAS = {
74
104
  type: "object",
75
105
  properties: {
76
106
  workspace: WORKSPACE_ID,
77
- profiles: { type: "array", items: { type: "string" } }
107
+ profiles: {
108
+ type: "array",
109
+ items: { type: "string" },
110
+ description: "The complete profile set to enable, replacing the current one. Adding audit-scitt/1.0 to a workspace that already has entries leaves those entries unchained and outside chain verification."
111
+ }
78
112
  },
79
113
  required: ["workspace", "profiles"]
80
114
  },
@@ -83,9 +117,13 @@ var SCHEMAS = {
83
117
  properties: {
84
118
  workspace: WORKSPACE_ID,
85
119
  from: PARTICIPANT_URI,
86
- type: { type: "string", enum: ["human", "agent", "service", "group", "workspace"] },
87
- role: { type: "string", description: "Operator-defined role, e.g. 'reviewer' or 'drafter'." },
88
- display_name: { type: "string" }
120
+ type: {
121
+ type: "string",
122
+ enum: ["human", "agent", "service", "group", "workspace"],
123
+ description: "The kind of participant. Only members of type 'human' are eligible for the review that chap.task.complete opens on a task marked review_required, and a completion with no eligible human is refused with -32011."
124
+ },
125
+ role: { type: "string", description: "Operator-defined role, e.g. 'reviewer' or 'drafter'. One value is read by the coordinator: 'admin' permits revoking another member's key." },
126
+ display_name: { type: "string", description: "Human-readable name for interfaces. Not used in authorisation." }
89
127
  },
90
128
  required: ["workspace", "from", "type"]
91
129
  },
@@ -98,12 +136,25 @@ var SCHEMAS = {
98
136
  type: "object",
99
137
  properties: {
100
138
  workspace: WORKSPACE_ID,
101
- from: { ...PARTICIPANT_URI, description: "Delegator URI." },
102
- kind: { type: "string", description: "Task kind, e.g. 'draft_response' or 'review'." },
103
- assignee: { ...PARTICIPANT_URI, description: "Who the task is assigned to. Must be a workspace member." },
139
+ from: { ...PARTICIPANT_URI, description: "The delegator. Must be a workspace member." },
140
+ kind: { type: "string", description: "Task kind, e.g. 'draft_response' or 'review'. Free text; the coordinator records it without interpreting it." },
141
+ assignee: { ...PARTICIPANT_URI, description: "Who the task is assigned to. Must be a workspace member, and must not be paused: assigning to a paused member is refused with -32063." },
104
142
  input: { type: "object", description: "Task-specific input payload.", additionalProperties: true },
105
143
  routing_hints: ROUTING_HINTS,
106
- mode: { type: "string", enum: ["shadow", "trial", "production"] }
144
+ mode: {
145
+ type: "string",
146
+ enum: ["shadow", "trial", "production"],
147
+ description: "Mode for this task, defaulting to the workspace mode. A mode above the workspace ceiling is refused with -32040."
148
+ },
149
+ review_required: {
150
+ type: "boolean",
151
+ description: "When true, chap.task.complete opens a review instead of completing: the output becomes the artefact under review, and the task reaches 'completed' only on a reviewer decision. chap.task.update cannot complete such a task. Under modes/1.0 a trial-mode task has this set to true whatever is passed here."
152
+ },
153
+ deadline: { type: "string", description: "When the task is due, as an ISO 8601 timestamp. Recorded on the task; the coordinator does not act on it." },
154
+ idempotency_key: {
155
+ type: "string",
156
+ description: "Caller-chosen key for safe retries. A second create carrying a key already seen in this workspace returns the original task and records nothing further. The workspace retains the 10,000 most recent keys."
157
+ }
107
158
  },
108
159
  required: ["workspace", "from", "kind", "assignee", "input"]
109
160
  },
@@ -113,8 +164,12 @@ var SCHEMAS = {
113
164
  workspace: WORKSPACE_ID,
114
165
  from: PARTICIPANT_URI,
115
166
  task_id: TASK_ID,
116
- state: { type: "string", enum: ["in_progress", "review_requested", "declined", "paused", "cancelled", "completed"] },
117
- progress_note: { type: "string" }
167
+ state: {
168
+ type: "string",
169
+ enum: ["in_progress", "declined", "cancelled", "completed"],
170
+ description: "The state to move the task to. Only the transitions in SPECIFICATION.md 8.1 are legal from the task's current state; others are refused with -32602. A review opens with chap.review.request, or with chap.task.complete on a task that requires one, so 'review_requested' is not a target here. A task marked review_required cannot be moved to 'completed' here: submit the output with chap.task.complete, which opens the review."
171
+ },
172
+ progress_note: { type: "string", description: "Short note on what changed, kept in the task's history." }
118
173
  },
119
174
  required: ["workspace", "from", "task_id", "state"]
120
175
  },
@@ -124,8 +179,8 @@ var SCHEMAS = {
124
179
  workspace: WORKSPACE_ID,
125
180
  from: PARTICIPANT_URI,
126
181
  task_id: TASK_ID,
127
- output: { description: "The task's output artefact. Pass as a JSON object or array, not a JSON-encoded string." },
128
- confidence: { type: "number", description: "Self-reported confidence (0-1), where supported." },
182
+ output: { description: `The task's output artefact. ${STRUCTURED_PAYLOAD_NOTE}` },
183
+ confidence: { type: "string", description: `Self-reported confidence in the output, between 0 and 1. ${decimalStringNote("0.86")}` },
129
184
  routing_hints: ROUTING_HINTS
130
185
  },
131
186
  required: ["workspace", "from", "task_id"]
@@ -136,17 +191,24 @@ var SCHEMAS = {
136
191
  workspace: WORKSPACE_ID,
137
192
  range: {
138
193
  type: "object",
194
+ description: "Sequence window to return. Omit for the whole log.",
139
195
  properties: {
140
- from_seq: { type: "integer", description: "Start sequence number (inclusive)." },
141
- to_seq: { type: "integer", description: "End sequence number (exclusive)." }
196
+ from_seq: { type: "integer", description: "Start sequence number, inclusive." },
197
+ to_seq: { type: "integer", description: "End sequence number, exclusive." }
142
198
  }
143
199
  },
144
200
  filter: {
145
201
  type: "object",
202
+ description: "Narrows the entries returned. Conditions combine with AND, and are applied within the sequence window rather than before it.",
146
203
  properties: {
147
- method: { type: "string" },
148
- from: { type: "string" },
149
- task_id: { type: "string" }
204
+ method: { type: "string", description: "Return only entries for this CHAP method, e.g. 'decide.override'. Matched in full, without the 'chap.' tool-name prefix." },
205
+ from: { type: "string", description: "Return only entries whose actor is this participant URI." },
206
+ task_id: { type: "string", description: "Return only entries about this task." },
207
+ outcome: {
208
+ type: "string",
209
+ enum: ["accepted", "refused"],
210
+ description: "Return only accepted calls, or only the refused attempts the coordinator recorded. Omit for both."
211
+ }
150
212
  }
151
213
  }
152
214
  },
@@ -163,15 +225,16 @@ var SCHEMAS = {
163
225
  task_id: TASK_ID,
164
226
  to: {
165
227
  oneOf: [PARTICIPANT_URI, { type: "array", items: PARTICIPANT_URI }],
166
- description: "One or more reviewers. A single URI string, or a JSON array of URI strings (not a JSON-encoded string)."
228
+ description: "One or more reviewers, as a single URI string or an array of URI strings. Only a workspace member can go on to decide, so a review addressed elsewhere cannot be closed by its recipient."
167
229
  },
168
230
  rule: {
169
231
  type: "string",
170
232
  enum: ["any_one_approves", "all_approve", "quorum:2", "quorum:3"],
171
- default: "any_one_approves"
233
+ default: "any_one_approves",
234
+ description: "How many of the addressed reviewers must approve before the task completes. quorum:N is accepted for any N of 1 or more. The rule is fixed once the review is open: a later request naming a different one is refused with -32014. Omitting it on a later request leaves the rule alone, which is how reviewers are added to an open review."
172
235
  },
173
- artefact: { description: "The draft being submitted for review. Pass as a JSON object or array, not a JSON-encoded string." },
174
- deadline: { type: "string" }
236
+ artefact: { description: `The draft being submitted for review. ${STRUCTURED_PAYLOAD_NOTE} Re-requesting with the same artefact widens the reviewer set; a different artefact on an open review is refused with -32014.` },
237
+ deadline: { type: "string", description: "When the review is needed by, as an ISO 8601 timestamp. Recorded on the review; the coordinator does not act on it." }
175
238
  },
176
239
  required: ["workspace", "from", "task_id", "to", "artefact"]
177
240
  },
@@ -181,13 +244,9 @@ var SCHEMAS = {
181
244
  workspace: WORKSPACE_ID,
182
245
  from: PARTICIPANT_URI,
183
246
  task_id: TASK_ID,
184
- approved_artefact_digest: {
185
- type: "string",
186
- pattern: "^sha256:[0-9a-f]{64}$",
187
- description: "Optional. SHA-256 over the JCS canonicalisation of the artefact under review, as `sha256:<hex>`. Binds the decision to the exact content reviewed; refused with -32074 on mismatch."
188
- },
189
- comment: { type: "string" },
190
- tags: { type: "array", items: { type: "string" } }
247
+ approved_artefact_digest: ARTEFACT_DIGEST,
248
+ comment: COMMENT,
249
+ tags: TAGS
191
250
  },
192
251
  required: ["workspace", "from", "task_id"]
193
252
  },
@@ -197,47 +256,49 @@ var SCHEMAS = {
197
256
  workspace: WORKSPACE_ID,
198
257
  from: PARTICIPANT_URI,
199
258
  task_id: TASK_ID,
200
- approved_artefact_digest: {
201
- type: "string",
202
- pattern: "^sha256:[0-9a-f]{64}$",
203
- description: "Optional. SHA-256 over the JCS canonicalisation of the artefact under review, as `sha256:<hex>`. Binds the decision to the exact content reviewed; refused with -32074 on mismatch."
204
- },
205
- comment: { type: "string" },
206
- tags: { type: "array", items: { type: "string" } },
207
- request_revision: { type: "boolean", description: "If true, task returns to in_progress instead of declined." }
259
+ approved_artefact_digest: ARTEFACT_DIGEST,
260
+ comment: COMMENT,
261
+ tags: TAGS,
262
+ request_revision: { type: "boolean", description: "When true the task returns to 'in_progress' rather than 'declined', so the assignee can revise and resubmit." }
208
263
  },
209
264
  required: ["workspace", "from", "task_id"]
210
265
  },
211
266
  "chap.decide.override": {
212
267
  type: "object",
213
268
  properties: {
214
- approved_artefact_digest: {
215
- type: "string",
216
- pattern: "^sha256:[0-9a-f]{64}$",
217
- description: "Optional. SHA-256 over the JCS canonicalisation of the artefact under review, as `sha256:<hex>`. Binds the decision to the exact content reviewed; refused with -32074 on mismatch."
218
- },
269
+ approved_artefact_digest: ARTEFACT_DIGEST,
219
270
  workspace: WORKSPACE_ID,
220
271
  from: PARTICIPANT_URI,
221
272
  task_id: TASK_ID,
222
273
  diff: {
223
274
  type: "array",
224
- description: "RFC 6902 JSON Patch operations applied to the artefact under review.",
275
+ description: "RFC 6902 JSON Patch operations applied to the artefact under review. The patched artefact becomes the task output; a patch that does not apply is refused with -32012.",
225
276
  items: {
226
277
  type: "object",
227
278
  properties: {
228
- op: { type: "string", enum: ["add", "replace", "remove", "copy", "move", "test"] },
229
- path: { type: "string" },
230
- value: {},
231
- from: { type: "string" }
279
+ op: { type: "string", enum: ["add", "replace", "remove", "copy", "move", "test"], description: "The patch operation to apply." },
280
+ path: { type: "string", description: "JSON Pointer into the artefact, e.g. '/body' or '/items/0/severity'." },
281
+ value: { description: "The new value, for add, replace and test." },
282
+ from: { type: "string", description: "Source JSON Pointer, for copy and move." }
232
283
  },
233
284
  required: ["op", "path"]
234
285
  }
235
286
  },
236
- rationale: { type: "string", description: "Why the override was applied. Required for the structured-override audit trail." },
237
- tags: { type: "array", items: { type: "string" } },
238
- policy_refs: { type: "array", items: { type: "string" } },
239
- logical_id: { type: "string" },
240
- intent_preserved: { type: "boolean" }
287
+ rationale: { type: "string", description: "Why the correction was made. Required on every override and recorded in the audit entry, since the diff shows what changed but not why." },
288
+ tags: TAGS,
289
+ policy_refs: {
290
+ type: "array",
291
+ items: { type: "string" },
292
+ description: "Identifiers of the policies or guidelines this correction applies, e.g. ['policy:no-delivery-promises']. Recorded in the audit entry."
293
+ },
294
+ logical_id: {
295
+ type: "string",
296
+ description: "Caller-chosen identifier for the item being decided, stable across revisions and overrides of the same underlying content. Recorded in the audit entry."
297
+ },
298
+ intent_preserved: {
299
+ type: "boolean",
300
+ description: "True when the edit refines the decision the draft was making, false when it substitutes a different one. Recorded in the audit entry."
301
+ }
241
302
  },
242
303
  required: ["workspace", "from", "task_id", "diff", "rationale"]
243
304
  },
@@ -247,8 +308,12 @@ var SCHEMAS = {
247
308
  workspace: WORKSPACE_ID,
248
309
  from: PARTICIPANT_URI,
249
310
  task_id: TASK_ID,
250
- reason: { type: "string" },
251
- category: { type: "string", enum: ["conflict_of_interest", "insufficient_context", "out_of_scope", "other"] }
311
+ reason: { type: "string", description: "Why this reviewer is standing aside. Recorded in the audit entry." },
312
+ category: {
313
+ type: "string",
314
+ enum: ["conflict_of_interest", "insufficient_context", "out_of_scope", "other"],
315
+ description: "The kind of abstention. Recorded in the audit entry."
316
+ }
252
317
  },
253
318
  required: ["workspace", "from", "task_id", "reason"]
254
319
  },
@@ -257,13 +322,15 @@ var SCHEMAS = {
257
322
  properties: {
258
323
  workspace: WORKSPACE_ID,
259
324
  from: PARTICIPANT_URI,
260
- original_task_id: TASK_ID,
325
+ original_task_id: { ...TASK_ID, description: "The task being escalated. It moves to 'escalated' and is linked to the successor. A completed, cancelled or superseded task cannot be escalated." },
261
326
  new_task: {
262
327
  type: "object",
328
+ description: "The successor task to open for the escalation target.",
263
329
  properties: {
264
- kind: { type: "string" },
265
- assignee: PARTICIPANT_URI,
266
- input: { type: "object", additionalProperties: true }
330
+ kind: { type: "string", description: "Task kind for the successor. Defaults to the original's kind." },
331
+ assignee: { ...PARTICIPANT_URI, description: "Who the escalation goes to. Must be a workspace member who is not paused: a paused assignee is refused with -32063." },
332
+ input: { type: "object", additionalProperties: true, description: "Input payload for the successor. It defaults to an empty object rather than the original's input, so anything the new assignee needs has to be restated here." },
333
+ mode: { type: "string", enum: ["shadow", "trial", "production"], description: "Mode for the successor, defaulting to the original's. A mode above the workspace's current ceiling is refused with -32040, so after the ceiling is lowered a task is escalated by naming a mode within it." }
267
334
  },
268
335
  required: ["assignee"]
269
336
  }
@@ -280,15 +347,27 @@ var SCHEMAS = {
280
347
  from: PARTICIPANT_URI,
281
348
  task_id: TASK_ID,
282
349
  to: { type: "array", items: PARTICIPANT_URI, description: "Who is being asked." },
283
- question: { type: "string" },
350
+ question: { type: "string", description: "The question being put. A whisper is answered on its own, without the recipient opening the task." },
284
351
  options: {
285
352
  type: "array",
286
- items: { type: "object", properties: { id: { type: "string" }, label: { type: "string" } }, required: ["id"] },
287
- description: "Optional multiple-choice options. If present, answer_option must be one of these ids."
353
+ items: {
354
+ type: "object",
355
+ properties: {
356
+ id: { type: "string", description: "Stable identifier that an answer refers to." },
357
+ label: { type: "string", description: "What the option says to the person answering." }
358
+ },
359
+ required: ["id"]
360
+ },
361
+ description: "Multiple-choice options. When present, an answer must name one of these ids in answer_option; any other id is refused with -32022."
288
362
  },
289
- deadline_ms: { type: "integer", description: "Time-to-live in milliseconds from now." },
290
- default_if_lapsed: { description: "Value applied if the whisper lapses without an answer." },
291
- urgency: { type: "string", enum: ["low", "medium", "high"], default: "low" }
363
+ deadline_ms: { type: "integer", description: "How long the whisper stays open, in milliseconds from now. Once it passes, the whisper lapses and default_if_lapsed is applied." },
364
+ default_if_lapsed: { description: "The value applied if the deadline passes with no answer. Required, so that a lapsed whisper still has a defined outcome." },
365
+ urgency: {
366
+ type: "string",
367
+ enum: ["low", "medium", "high"],
368
+ default: "low",
369
+ description: "How urgent the question is. Recorded and passed on to the client; it does not change the deadline or the lapse behaviour."
370
+ }
292
371
  },
293
372
  required: ["workspace", "from", "task_id", "to", "question", "deadline_ms", "default_if_lapsed"]
294
373
  },
@@ -297,10 +376,10 @@ var SCHEMAS = {
297
376
  properties: {
298
377
  workspace: WORKSPACE_ID,
299
378
  from: PARTICIPANT_URI,
300
- whisper_id: { type: "string" },
301
- answer_option: { type: "string", description: "Option id (required when the whisper has options)." },
302
- answer: { type: "string", description: "Free-text answer (when no options)." },
303
- comment: { type: "string" }
379
+ whisper_id: { type: "string", description: "Identifier returned by chap.whisper.ask. A whisper that has already been answered is refused with -32020, and one past its deadline with -32021." },
380
+ answer_option: { type: "string", description: "The id of the chosen option. Required when the whisper carried options." },
381
+ answer: { type: "string", description: "Free-text answer, for a whisper with no options." },
382
+ comment: { type: "string", description: "Anything else the answerer wants recorded alongside the answer." }
304
383
  },
305
384
  required: ["workspace", "from", "whisper_id"]
306
385
  },
@@ -312,16 +391,16 @@ var SCHEMAS = {
312
391
  properties: {
313
392
  workspace: WORKSPACE_ID,
314
393
  from: PARTICIPANT_URI,
315
- to: { type: "array", items: PARTICIPANT_URI, description: "Deliberation participants." },
394
+ to: { type: "array", items: PARTICIPANT_URI, description: "The participants entitled to vote. A vote from anyone else is refused with -32030." },
316
395
  task_id: TASK_ID,
317
396
  rule: {
318
397
  type: "string",
319
- description: "Voting rule. Examples: any_one_approves, all_approve, quorum:N, weighted_vote:T, weighted_vote_with_veto:T."
398
+ description: "How the outcome is decided when the deliberation closes: any_one_approves, all_approve, quorum:N, weighted_vote:T or weighted_vote_with_veto:T. An unrecognised rule is refused at open with -32033."
320
399
  },
321
- question: { type: "string" },
322
- weights: { type: "object", additionalProperties: { type: "number" }, description: "Voter -> weight map (for weighted rules)." },
323
- veto: { type: "object", additionalProperties: { type: "boolean" }, description: "Voter -> can-veto map." },
324
- deadline: { type: "string" }
400
+ question: { type: "string", description: "What the group is deciding. State it so that a yea or a nay is unambiguous." },
401
+ weights: { type: "object", additionalProperties: { type: "integer" }, description: "Voter to weight map, read by the weighted rules. A voter with no entry counts as 1. Weights must be integers: a JSON number with a fractional part is refused with -32602." },
402
+ veto: { type: "object", additionalProperties: { type: "boolean" }, description: "Voter to can-veto map. A veto is honoured only under weighted_vote_with_veto, and only from a voter listed true here." },
403
+ deadline: { type: "string", description: "When voting is intended to close, as an ISO 8601 timestamp. Recorded on the deliberation; closing is done by chap.deliberate.close and the coordinator does not close on the deadline." }
325
404
  },
326
405
  required: ["workspace", "from", "to", "rule"]
327
406
  },
@@ -330,8 +409,8 @@ var SCHEMAS = {
330
409
  properties: {
331
410
  workspace: WORKSPACE_ID,
332
411
  from: PARTICIPANT_URI,
333
- deliberation_id: { type: "string" },
334
- comment: { type: "string" }
412
+ deliberation_id: { type: "string", description: "Identifier returned by chap.deliberate.open. A closed deliberation is refused with -32032." },
413
+ comment: { type: "string", description: "The contribution to record. Comments are kept with the deliberation and in the audit log, so the reasoning survives the vote." }
335
414
  },
336
415
  required: ["workspace", "from", "deliberation_id", "comment"]
337
416
  },
@@ -340,11 +419,11 @@ var SCHEMAS = {
340
419
  properties: {
341
420
  workspace: WORKSPACE_ID,
342
421
  from: PARTICIPANT_URI,
343
- deliberation_id: { type: "string" },
344
- vote: { type: "string", enum: ["yea", "nay", "abstain"] },
345
- weight: { type: "number" },
346
- comment: { type: "string" },
347
- veto_invoked: { type: "boolean" }
422
+ deliberation_id: { type: "string", description: "Identifier returned by chap.deliberate.open. A closed deliberation is refused with -32032, and a second vote from the same voter with -32031." },
423
+ vote: { type: "string", enum: ["yea", "nay", "abstain"], description: "This voter's position. An abstention is recorded but counts as neither a yea nor a nay, so under all_approve or quorum:N it withholds the approval those rules need." },
424
+ weight: { type: "integer", description: "Recorded with the vote. The tally uses the weights map given at chap.deliberate.open, not this value." },
425
+ comment: { type: "string", description: "Why the vote went this way. Recorded with it." },
426
+ veto_invoked: { type: "boolean", description: "Blocks the outcome regardless of the tally. Honoured only under weighted_vote_with_veto, and only when the voter is listed true in the veto map given at open." }
348
427
  },
349
428
  required: ["workspace", "from", "deliberation_id", "vote"]
350
429
  },
@@ -353,7 +432,7 @@ var SCHEMAS = {
353
432
  properties: {
354
433
  workspace: WORKSPACE_ID,
355
434
  from: PARTICIPANT_URI,
356
- deliberation_id: { type: "string" }
435
+ deliberation_id: { type: "string", description: "Identifier returned by chap.deliberate.open. Closing computes the outcome from the votes cast; closing an already closed deliberation returns the outcome unchanged." }
357
436
  },
358
437
  required: ["workspace", "from", "deliberation_id"]
359
438
  },
@@ -365,23 +444,24 @@ var SCHEMAS = {
365
444
  properties: {
366
445
  workspace: WORKSPACE_ID,
367
446
  from: PARTICIPANT_URI,
368
- to: { type: "string", description: "Recipient (URI or 'group:...')." },
447
+ to: { type: "string", description: "Recipient, as a participant URI or a group URI such as 'group:support-team'. A recipient who is not a workspace member is refused with -32052." },
369
448
  tasks: {
370
449
  type: "array",
450
+ description: "The work being handed over, one entry per task. Every task must currently be assigned to the proposer; otherwise the proposal is refused with -32050.",
371
451
  items: {
372
452
  type: "object",
373
453
  properties: {
374
454
  task_id: TASK_ID,
375
- title: { type: "string" },
376
- status_summary: { type: "string" },
377
- next_action: { type: "string" },
378
- blockers: { type: "array", items: { type: "string" } }
455
+ title: { type: "string", description: "Short label for the task." },
456
+ status_summary: { type: "string", description: "Where the work has reached, and what has already been tried." },
457
+ next_action: { type: "string", description: "What the recipient should do first." },
458
+ blockers: { type: "array", items: { type: "string" }, description: "What is preventing progress, if anything." }
379
459
  },
380
460
  required: ["task_id"]
381
461
  }
382
462
  },
383
- summary: { type: "string" },
384
- context_links: { type: "array", items: { type: "string" } }
463
+ summary: { type: "string", description: "Covering note for the handover as a whole, above the per-task detail." },
464
+ context_links: { type: "array", items: { type: "string" }, description: "URLs to threads, tickets or documents the recipient will need." }
385
465
  },
386
466
  required: ["workspace", "from", "to", "tasks"]
387
467
  },
@@ -390,9 +470,9 @@ var SCHEMAS = {
390
470
  properties: {
391
471
  workspace: WORKSPACE_ID,
392
472
  from: PARTICIPANT_URI,
393
- handoff_id: { type: "string" },
394
- accepted_task_ids: { type: "array", items: TASK_ID, description: "If omitted, all proposed tasks are accepted." },
395
- comment: { type: "string" }
473
+ handoff_id: { type: "string", description: "Identifier returned by chap.handoff.propose. A handoff already accepted or declined is refused with -32051." },
474
+ accepted_task_ids: { type: "array", items: TASK_ID, description: "Which of the proposed tasks are being accepted. If omitted, all of them are." },
475
+ comment: { type: "string", description: "Anything the recipient wants recorded when taking the work on." }
396
476
  },
397
477
  required: ["workspace", "from", "handoff_id"]
398
478
  },
@@ -401,9 +481,9 @@ var SCHEMAS = {
401
481
  properties: {
402
482
  workspace: WORKSPACE_ID,
403
483
  from: PARTICIPANT_URI,
404
- handoff_id: { type: "string" },
405
- reason: { type: "string" },
406
- suggested_target: PARTICIPANT_URI
484
+ handoff_id: { type: "string", description: "Identifier returned by chap.handoff.propose. A handoff already accepted or declined is refused with -32051." },
485
+ reason: { type: "string", description: "Why the handover is refused. Recorded so the proposer can route it elsewhere." },
486
+ suggested_target: { ...PARTICIPANT_URI, description: "Who should take it instead, if the decliner knows." }
407
487
  },
408
488
  required: ["workspace", "from", "handoff_id"]
409
489
  },
@@ -415,11 +495,20 @@ var SCHEMAS = {
415
495
  properties: {
416
496
  workspace: WORKSPACE_ID,
417
497
  from: PARTICIPANT_URI,
418
- scope: { type: "string", enum: ["task", "participant", "workspace"], default: "task" },
498
+ scope: {
499
+ type: "string",
500
+ enum: ["task", "participant", "workspace"],
501
+ default: "task",
502
+ description: "What the pause applies to. 'task' moves one task to 'paused'; a task that is completed, declined, cancelled or superseded is refused with -32061. 'participant' stops new tasks being assigned to that member and leaves their existing work running. 'workspace' refuses every method except workspace.create, workspace.describe, control.resume, audit.read, participant.join and participant.leave."
503
+ },
419
504
  task_id: TASK_ID,
420
- participant_uri: PARTICIPANT_URI,
421
- in_flight_policy: { type: "string", enum: ["allow_to_complete", "interrupt"] },
422
- reason: { type: "string" }
505
+ participant_uri: { ...PARTICIPANT_URI, description: "Whose work to pause, when scope is 'participant'. Must be a workspace member." },
506
+ in_flight_policy: {
507
+ type: "string",
508
+ enum: ["allow_to_complete", "interrupt"],
509
+ description: "Recorded with the request, and echoed back when scope is 'participant'. The coordinator does not act on it: under either value, work already under way is left alone."
510
+ },
511
+ reason: { type: "string", description: "Why the pause was applied. Recorded in the audit entry." }
423
512
  },
424
513
  required: ["workspace", "from"]
425
514
  },
@@ -428,9 +517,14 @@ var SCHEMAS = {
428
517
  properties: {
429
518
  workspace: WORKSPACE_ID,
430
519
  from: PARTICIPANT_URI,
431
- scope: { type: "string", enum: ["task", "participant", "workspace"], default: "task" },
520
+ scope: {
521
+ type: "string",
522
+ enum: ["task", "participant", "workspace"],
523
+ default: "task",
524
+ description: "What the resume applies to. 'task' returns a paused task to the state it held at the pause; a task that is not paused is refused with -32061. 'participant' allows that member to be assigned tasks again. 'workspace' returns the workspace to active."
525
+ },
432
526
  task_id: TASK_ID,
433
- participant_uri: PARTICIPANT_URI
527
+ participant_uri: { ...PARTICIPANT_URI, description: "Whose work to resume, when scope is 'participant'. Must be a workspace member." }
434
528
  },
435
529
  required: ["workspace", "from"]
436
530
  },
@@ -439,8 +533,8 @@ var SCHEMAS = {
439
533
  properties: {
440
534
  workspace: WORKSPACE_ID,
441
535
  from: PARTICIPANT_URI,
442
- task_id: TASK_ID,
443
- reason: { type: "string" }
536
+ task_id: { ...TASK_ID, description: "The task to cancel. A task that is completed, declined, cancelled or superseded is refused with -32061." },
537
+ reason: { type: "string", description: "Why the task was cancelled. Recorded in the audit entry." }
444
538
  },
445
539
  required: ["workspace", "from", "task_id"]
446
540
  },
@@ -449,8 +543,8 @@ var SCHEMAS = {
449
543
  properties: {
450
544
  workspace: WORKSPACE_ID,
451
545
  from: PARTICIPANT_URI,
452
- label: { type: "string" },
453
- include: { type: "array", items: { type: "string" }, description: "Aspects to snapshot, e.g. ['members', 'open_tasks', 'mode_ceiling']." }
546
+ label: { type: "string", description: "Name for this snapshot, recorded on the artefact. chap.control.rollback identifies a snapshot by its artefact id, not by label." },
547
+ include: { type: "array", items: { type: "string" }, description: "Which aspects of the workspace to capture. Recognised values are 'members', 'open_tasks', 'mode_ceiling', 'policy' and 'audit'. Defaults to members, open_tasks and mode_ceiling." }
454
548
  },
455
549
  required: ["workspace", "from"]
456
550
  },
@@ -459,9 +553,9 @@ var SCHEMAS = {
459
553
  properties: {
460
554
  workspace: WORKSPACE_ID,
461
555
  from: PARTICIPANT_URI,
462
- to_snapshot_artefact_id: { type: "string" },
463
- what_to_restore: { type: "array", items: { type: "string" } },
464
- reason: { type: "string" }
556
+ to_snapshot_artefact_id: { type: "string", description: "Artefact id returned by chap.control.snapshot. An id with no matching snapshot is refused with -32062." },
557
+ what_to_restore: { type: "array", items: { type: "string" }, description: "Which captured aspects to apply. Only 'mode_ceiling' and 'members' are restored; the others are held in the snapshot and not reapplied. Restoring members resets role and scopes on members still present, and does not re-add members who have left. Defaults to the snapshot's include list." },
558
+ reason: { type: "string", description: "Why the rollback was performed. The rollback is itself an audit entry; earlier entries are not rewritten." }
465
559
  },
466
560
  required: ["workspace", "from", "to_snapshot_artefact_id"]
467
561
  },
@@ -470,17 +564,20 @@ var SCHEMAS = {
470
564
  properties: {
471
565
  workspace: WORKSPACE_ID,
472
566
  from: PARTICIPANT_URI,
473
- task_id: TASK_ID,
567
+ task_id: { ...TASK_ID, description: "The task being replaced. It moves to 'superseded' and is linked to the successor rather than deleted." },
474
568
  successor_task: {
475
569
  type: "object",
570
+ description: "The replacement task.",
476
571
  properties: {
477
- kind: { type: "string" },
478
- assignee: PARTICIPANT_URI,
479
- input: { type: "object", additionalProperties: true }
572
+ kind: { type: "string", description: "Task kind for the successor. Required." },
573
+ assignee: { ...PARTICIPANT_URI, description: "Who takes the replacement on. Defaults to the superseded task's assignee, and must be a workspace member who is not paused." },
574
+ input: { type: "object", additionalProperties: true, description: "Input payload for the successor. Defaults to an empty object." },
575
+ mode: { type: "string", enum: ["shadow", "trial", "production"], description: "Mode for the successor, defaulting to the superseded task's. A mode above the workspace's current ceiling is refused with -32040." },
576
+ review_required: { type: "boolean", description: "Whether completing the successor needs a reviewer decision. A successor of a task that requires review requires it whatever is passed here, and under modes/1.0 so does a trial-mode successor." }
480
577
  },
481
578
  required: ["kind"]
482
579
  },
483
- reason: { type: "string" }
580
+ reason: { type: "string", description: "Why the original is being replaced. Recorded in the audit entry." }
484
581
  },
485
582
  required: ["workspace", "from", "task_id", "successor_task"]
486
583
  },
@@ -489,8 +586,12 @@ var SCHEMAS = {
489
586
  properties: {
490
587
  workspace: WORKSPACE_ID,
491
588
  from: PARTICIPANT_URI,
492
- new_ceiling: { type: "string", enum: ["shadow", "trial", "production"] },
493
- reason: { type: "string" }
589
+ new_ceiling: {
590
+ type: "string",
591
+ enum: ["shadow", "trial", "production"],
592
+ description: "The highest mode tasks in this workspace may request from now on. Existing tasks keep the mode they were created with. Where the coordinator is configured to enforce step-up authentication this method is one of the privileged ones and a call without step-up is refused with -32402."
593
+ },
594
+ reason: { type: "string", description: "Why the ceiling is being changed. Recorded in the audit entry." }
494
595
  },
495
596
  required: ["workspace", "from", "new_ceiling"]
496
597
  },
@@ -503,7 +604,7 @@ var SCHEMAS = {
503
604
  workspace: WORKSPACE_ID,
504
605
  from: PARTICIPANT_URI,
505
606
  task_id: TASK_ID,
506
- candidates: { type: "array", items: PARTICIPANT_URI, description: "Candidate assignees." }
607
+ candidates: { type: "array", items: PARTICIPANT_URI, description: "Candidate assignees. An empty list is refused with -32513. The default policy takes the first candidate that is a workspace member and is not paused, and refuses the call with -32510 when there is none. An operator-supplied routing policy may select on any basis; a choice that is not a member is refused with -32510, and one who is paused with -32063." }
507
608
  },
508
609
  required: ["workspace", "from", "task_id", "candidates"]
509
610
  },
@@ -515,7 +616,7 @@ var SCHEMAS = {
515
616
  task_id: TASK_ID,
516
617
  artefact_routing_hints: {
517
618
  type: "object",
518
- description: "Per-artefact signals like confidence, model_id, cost_consumed_usd.",
619
+ description: `Per-artefact signals such as confidence, model_id and cost_consumed_usd, merged over the task's routing_hints for this call. The default policy reads criticality and confidence. If the merged set is empty the call is refused with -32514. Fractional values are written as decimal strings, e.g. "confidence": "0.86".`,
519
620
  additionalProperties: true
520
621
  }
521
622
  },
@@ -527,7 +628,7 @@ var SCHEMAS = {
527
628
  workspace: WORKSPACE_ID,
528
629
  from: PARTICIPANT_URI,
529
630
  task_id: TASK_ID,
530
- default_escalation_target: PARTICIPANT_URI
631
+ default_escalation_target: { ...PARTICIPANT_URI, description: "Who to escalate to when the policy decides to escalate and names no target of its own. It must be a workspace member or a group URI; if the policy escalates with no usable target the call is refused with -32516." }
531
632
  },
532
633
  required: ["workspace", "from", "task_id"]
533
634
  },
@@ -539,8 +640,8 @@ var SCHEMAS = {
539
640
  properties: {
540
641
  workspace: WORKSPACE_ID,
541
642
  from: PARTICIPANT_URI,
542
- old_kid: { type: "string" },
543
- new_jwk: { type: "object", additionalProperties: true }
643
+ old_kid: { type: "string", description: "Key id being retired. It is given a valid_until timestamp and stays in the member's key history, so signatures made before the rotation still verify. A key id that is unknown is refused with -32071, and one already revoked with -32072." },
644
+ new_jwk: { type: "object", additionalProperties: true, description: "The replacement public key as a JWK. It must carry a 'kid'. Whether the request itself has to be signed with the old key is decided at dispatch, and only where the coordinator is configured to require signatures." }
544
645
  },
545
646
  required: ["workspace", "from", "old_kid", "new_jwk"]
546
647
  },
@@ -549,9 +650,9 @@ var SCHEMAS = {
549
650
  properties: {
550
651
  workspace: WORKSPACE_ID,
551
652
  from: PARTICIPANT_URI,
552
- target_uri: PARTICIPANT_URI,
553
- kid: { type: "string" },
554
- reason: { type: "string" }
653
+ target_uri: { ...PARTICIPANT_URI, description: "Whose key is being revoked. Revoking another member's key requires the caller to hold the role 'admin'; otherwise the call is refused with -32011." },
654
+ kid: { type: "string", description: "Key id to revoke. It is marked revoked with a timestamp and a reason, and signatures presented with it are refused from then on. A key id that is unknown is refused with -32071." },
655
+ reason: { type: "string", description: "Why the key was revoked, e.g. 'laptop lost'. Recorded on the key and in the audit entry." }
555
656
  },
556
657
  required: ["workspace", "from", "target_uri", "kid"]
557
658
  },
@@ -565,12 +666,13 @@ var SCHEMAS = {
565
666
  from: PARTICIPANT_URI,
566
667
  range: {
567
668
  type: "object",
669
+ description: "Sequence window to anchor. Omit to submit the whole chain.",
568
670
  properties: {
569
- from_seq: { type: "integer" },
570
- to_seq: { type: "integer" }
671
+ from_seq: { type: "integer", description: "Start sequence number, inclusive." },
672
+ to_seq: { type: "integer", description: "End sequence number, exclusive." }
571
673
  }
572
674
  },
573
- issuer: { type: "string" }
675
+ issuer: { type: "string", description: "Issuer identifier placed on each SCITT signed statement, naming who vouches for the chain. Defaults to 'service:coordinator'. Where no submitter is configured the statements are returned unsigned for the deployment to submit out of band." }
574
676
  },
575
677
  required: ["workspace"]
576
678
  },
@@ -579,7 +681,7 @@ var SCHEMAS = {
579
681
  properties: {
580
682
  workspace: WORKSPACE_ID,
581
683
  from: PARTICIPANT_URI,
582
- receipt: { type: "object", additionalProperties: true }
684
+ receipt: { type: "object", additionalProperties: true, description: "The SCITT receipt to check, as returned by the transparency service. Verification is delegated to a hook supplied by the deployment, and fails closed with -32082 where no hook is configured." }
583
685
  },
584
686
  required: ["workspace", "receipt"]
585
687
  },