okstra 0.31.0 → 0.32.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.
Files changed (51) hide show
  1. package/package.json +1 -1
  2. package/runtime/BUILD.json +2 -2
  3. package/runtime/agents/SKILL.md +3 -3
  4. package/runtime/agents/workers/report-writer-worker.md +45 -67
  5. package/runtime/bin/okstra-render-final-report.py +101 -0
  6. package/runtime/bin/okstra-render-report-views.py +17 -10
  7. package/runtime/bin/okstra-token-usage.py +3 -1
  8. package/runtime/python/okstra_ctl/final_report_schema.py +253 -0
  9. package/runtime/python/okstra_ctl/render_final_report.py +201 -0
  10. package/runtime/python/okstra_ctl/report_views.py +108 -305
  11. package/runtime/python/okstra_token_usage/__init__.py +5 -1
  12. package/runtime/python/okstra_token_usage/cli.py +66 -36
  13. package/runtime/python/okstra_token_usage/report.py +148 -65
  14. package/runtime/python/okstra_vendor/__init__.py +37 -0
  15. package/runtime/python/okstra_vendor/jinja2/__init__.py +38 -0
  16. package/runtime/python/okstra_vendor/jinja2/_identifier.py +6 -0
  17. package/runtime/python/okstra_vendor/jinja2/async_utils.py +99 -0
  18. package/runtime/python/okstra_vendor/jinja2/bccache.py +408 -0
  19. package/runtime/python/okstra_vendor/jinja2/compiler.py +1998 -0
  20. package/runtime/python/okstra_vendor/jinja2/constants.py +20 -0
  21. package/runtime/python/okstra_vendor/jinja2/debug.py +191 -0
  22. package/runtime/python/okstra_vendor/jinja2/defaults.py +48 -0
  23. package/runtime/python/okstra_vendor/jinja2/environment.py +1672 -0
  24. package/runtime/python/okstra_vendor/jinja2/exceptions.py +166 -0
  25. package/runtime/python/okstra_vendor/jinja2/ext.py +870 -0
  26. package/runtime/python/okstra_vendor/jinja2/filters.py +1873 -0
  27. package/runtime/python/okstra_vendor/jinja2/idtracking.py +318 -0
  28. package/runtime/python/okstra_vendor/jinja2/lexer.py +868 -0
  29. package/runtime/python/okstra_vendor/jinja2/loaders.py +693 -0
  30. package/runtime/python/okstra_vendor/jinja2/meta.py +112 -0
  31. package/runtime/python/okstra_vendor/jinja2/nativetypes.py +130 -0
  32. package/runtime/python/okstra_vendor/jinja2/nodes.py +1206 -0
  33. package/runtime/python/okstra_vendor/jinja2/optimizer.py +48 -0
  34. package/runtime/python/okstra_vendor/jinja2/parser.py +1049 -0
  35. package/runtime/python/okstra_vendor/jinja2/py.typed +0 -0
  36. package/runtime/python/okstra_vendor/jinja2/runtime.py +1062 -0
  37. package/runtime/python/okstra_vendor/jinja2/sandbox.py +436 -0
  38. package/runtime/python/okstra_vendor/jinja2/tests.py +256 -0
  39. package/runtime/python/okstra_vendor/jinja2/utils.py +766 -0
  40. package/runtime/python/okstra_vendor/jinja2/visitor.py +92 -0
  41. package/runtime/python/okstra_vendor/markupsafe/__init__.py +396 -0
  42. package/runtime/python/okstra_vendor/markupsafe/_native.py +8 -0
  43. package/runtime/python/okstra_vendor/markupsafe/py.typed +0 -0
  44. package/runtime/schemas/final-report-v1.0.schema.json +1391 -0
  45. package/runtime/skills/okstra-report-writer/SKILL.md +29 -28
  46. package/runtime/templates/reports/final-report.template.md +370 -411
  47. package/runtime/templates/reports/report.css +12 -6
  48. package/runtime/validators/lib/fixtures.sh +7 -7
  49. package/runtime/validators/validate-report-views.py +24 -153
  50. package/runtime/validators/validate-run.py +102 -19
  51. package/src/install.mjs +20 -1
@@ -0,0 +1,1391 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://okstra.dev/schemas/final-report-v1.0.json",
4
+ "title": "OKSTRA Final Report Data (v1.0)",
5
+ "description": "JSON SSOT for okstra final-report generation. Written by report-writer-worker in Phase 6, consumed by okstra-render-final-report.py to produce the canonical markdown.",
6
+ "type": "object",
7
+ "required": [
8
+ "schemaVersion",
9
+ "frontmatter",
10
+ "header",
11
+ "verdictCard",
12
+ "summary",
13
+ "executionStatus",
14
+ "tokenUsage",
15
+ "crossVerification",
16
+ "finalVerdict",
17
+ "evidence",
18
+ "missingInformation",
19
+ "clarificationItems",
20
+ "recommendedNextSteps",
21
+ "followUpTasks"
22
+ ],
23
+ "additionalProperties": false,
24
+ "properties": {
25
+ "schemaVersion": {
26
+ "const": "1.0",
27
+ "description": "Schema version. Renderer refuses to process unknown versions."
28
+ },
29
+
30
+ "frontmatter": {
31
+ "type": "object",
32
+ "required": [
33
+ "title",
34
+ "id",
35
+ "tags",
36
+ "status",
37
+ "aliases",
38
+ "date",
39
+ "taskId",
40
+ "taskGroup",
41
+ "projectId",
42
+ "taskType",
43
+ "workerId"
44
+ ],
45
+ "additionalProperties": false,
46
+ "properties": {
47
+ "title": { "type": "string", "minLength": 1 },
48
+ "id": { "type": "string", "minLength": 1 },
49
+ "tags": {
50
+ "type": "array",
51
+ "items": { "type": "string" },
52
+ "minItems": 1
53
+ },
54
+ "status": { "enum": ["in-progress", "completed", "draft"] },
55
+ "aliases": {
56
+ "type": "array",
57
+ "items": { "type": "string" }
58
+ },
59
+ "date": {
60
+ "type": "string",
61
+ "description": "ISO 8601 date or datetime. Renderer emits verbatim."
62
+ },
63
+ "taskId": { "type": "string", "minLength": 1 },
64
+ "taskGroup": { "type": "string", "minLength": 1 },
65
+ "projectId": { "type": "string", "minLength": 1 },
66
+ "taskType": { "$ref": "#/$defs/TaskType" },
67
+ "workerId": { "const": "report-writer" }
68
+ }
69
+ },
70
+
71
+ "header": {
72
+ "type": "object",
73
+ "required": [
74
+ "taskKey",
75
+ "createdAt",
76
+ "taskType",
77
+ "reportOwner",
78
+ "reportAuthor",
79
+ "leadModel",
80
+ "okstraVersion"
81
+ ],
82
+ "additionalProperties": false,
83
+ "properties": {
84
+ "taskKey": { "type": "string", "minLength": 1 },
85
+ "createdAt": { "type": "string", "minLength": 1 },
86
+ "taskType": { "$ref": "#/$defs/TaskType" },
87
+ "reportOwner": { "const": "Claude lead" },
88
+ "reportAuthor": {
89
+ "enum": ["Report writer worker", "Claude lead"],
90
+ "description": "Lead-authored fallback is only valid for release-handoff or recorded report-writer dispatch failure."
91
+ },
92
+ "leadModel": { "type": "string", "minLength": 1 },
93
+ "okstraVersion": { "type": "string", "minLength": 1 }
94
+ }
95
+ },
96
+
97
+ "approvalBlock": {
98
+ "type": "object",
99
+ "description": "RENDER_IF taskType == implementation-planning. Renderer emits the User Approval Request section.",
100
+ "required": ["approved"],
101
+ "additionalProperties": false,
102
+ "properties": {
103
+ "approved": {
104
+ "type": "boolean",
105
+ "description": "When true, renders `- [x] Approved`; when false, `- [ ] Approved`. Plan Body Verification gate decides which."
106
+ }
107
+ }
108
+ },
109
+
110
+ "clarificationCarryIn": {
111
+ "type": "object",
112
+ "description": "RENDER_IF non-empty. Carry-in clarifications from the previous run.",
113
+ "required": ["sourceFile"],
114
+ "additionalProperties": false,
115
+ "properties": {
116
+ "sourceFile": {
117
+ "type": "string",
118
+ "minLength": 1,
119
+ "description": "Project-relative path to the prior run's clarification-response sidecar."
120
+ }
121
+ }
122
+ },
123
+
124
+ "verdictCard": {
125
+ "type": "object",
126
+ "description": "Top-of-report at-a-glance card. Values MUST byte-match finalVerdict and recommendedNextSteps[0]; renderer fills both from this data structure so divergence is impossible.",
127
+ "required": [
128
+ "finalConclusion",
129
+ "verdictToken",
130
+ "direction",
131
+ "approvalRequired",
132
+ "nextStep"
133
+ ],
134
+ "additionalProperties": false,
135
+ "properties": {
136
+ "finalConclusion": { "type": "string", "minLength": 1 },
137
+ "verdictToken": { "$ref": "#/$defs/VerdictToken" },
138
+ "direction": { "$ref": "#/$defs/Direction" },
139
+ "approvalRequired": { "type": "boolean" },
140
+ "nextStep": { "type": "string", "minLength": 1 }
141
+ }
142
+ },
143
+
144
+ "summary": {
145
+ "type": "array",
146
+ "description": "## Summary of the Problem or Verification Target. 3-5 rows.",
147
+ "minItems": 1,
148
+ "maxItems": 8,
149
+ "items": { "$ref": "#/$defs/SummaryRow" }
150
+ },
151
+
152
+ "ticketCoverage": {
153
+ "oneOf": [
154
+ {
155
+ "type": "object",
156
+ "description": "Single-ticket run: one-line `- Single ticket run: <ticket>`.",
157
+ "required": ["singleTicket"],
158
+ "additionalProperties": false,
159
+ "properties": {
160
+ "singleTicket": { "type": "string", "minLength": 1 }
161
+ }
162
+ },
163
+ {
164
+ "type": "object",
165
+ "description": "Multi-ticket run: reverse index table.",
166
+ "required": ["rows"],
167
+ "additionalProperties": false,
168
+ "properties": {
169
+ "rows": {
170
+ "type": "array",
171
+ "minItems": 1,
172
+ "items": { "$ref": "#/$defs/TicketCoverageRow" }
173
+ }
174
+ }
175
+ },
176
+ {
177
+ "type": "object",
178
+ "description": "Omit Ticket Coverage entirely (release-handoff / final-verification).",
179
+ "required": ["omit"],
180
+ "additionalProperties": false,
181
+ "properties": {
182
+ "omit": { "const": true }
183
+ }
184
+ }
185
+ ]
186
+ },
187
+
188
+ "executionStatus": {
189
+ "type": "array",
190
+ "description": "## Execution Status by Agent. One row per worker incl. lead. Token cells stay null until Phase 7 token-usage step fills them.",
191
+ "minItems": 1,
192
+ "items": { "$ref": "#/$defs/ExecutionStatusRow" }
193
+ },
194
+
195
+ "tokenUsage": {
196
+ "type": "object",
197
+ "description": "## Token Usage Summary. All numeric cells are null in Phase 6 and filled by Phase 7 token-usage step.",
198
+ "required": ["lead", "worker", "grand", "cli"],
199
+ "additionalProperties": false,
200
+ "properties": {
201
+ "lead": { "$ref": "#/$defs/TokenUsageRow" },
202
+ "worker": { "$ref": "#/$defs/TokenUsageRow" },
203
+ "grand": { "$ref": "#/$defs/TokenUsageRow" },
204
+ "cli": {
205
+ "type": "object",
206
+ "additionalProperties": false,
207
+ "required": ["costUsd"],
208
+ "properties": {
209
+ "costUsd": {
210
+ "oneOf": [
211
+ { "type": "number", "minimum": 0 },
212
+ { "type": "null" }
213
+ ]
214
+ }
215
+ }
216
+ }
217
+ }
218
+ },
219
+
220
+ "crossVerification": {
221
+ "type": "object",
222
+ "required": ["consensus", "differences"],
223
+ "additionalProperties": false,
224
+ "properties": {
225
+ "roundHistory": {
226
+ "oneOf": [
227
+ {
228
+ "type": "object",
229
+ "description": "Convergence-enabled run.",
230
+ "required": ["rounds", "round2SkippedReason"],
231
+ "additionalProperties": false,
232
+ "properties": {
233
+ "rounds": {
234
+ "type": "array",
235
+ "items": { "$ref": "#/$defs/RoundHistoryRow" }
236
+ },
237
+ "round2SkippedReason": {
238
+ "enum": [
239
+ "queue-empty",
240
+ "max-rounds-1",
241
+ "all-reverify-non-result",
242
+ "not-skipped",
243
+ "convergence-disabled",
244
+ "single-analyser-only"
245
+ ]
246
+ }
247
+ }
248
+ },
249
+ {
250
+ "type": "object",
251
+ "description": "Convergence disabled (omit the sub-table entirely).",
252
+ "required": ["disabled"],
253
+ "additionalProperties": false,
254
+ "properties": {
255
+ "disabled": { "const": true }
256
+ }
257
+ }
258
+ ]
259
+ },
260
+ "consensus": {
261
+ "type": "array",
262
+ "items": { "$ref": "#/$defs/ConsensusRow" }
263
+ },
264
+ "differences": {
265
+ "type": "array",
266
+ "items": { "$ref": "#/$defs/DifferenceRow" }
267
+ }
268
+ }
269
+ },
270
+
271
+ "finalVerdict": {
272
+ "type": "object",
273
+ "required": [
274
+ "finalConclusion",
275
+ "verdictToken",
276
+ "direction",
277
+ "rationaleRowIds",
278
+ "nextStep"
279
+ ],
280
+ "additionalProperties": false,
281
+ "properties": {
282
+ "finalConclusion": { "type": "string", "minLength": 1 },
283
+ "verdictToken": { "$ref": "#/$defs/VerdictToken" },
284
+ "direction": { "$ref": "#/$defs/Direction" },
285
+ "rationaleRowIds": {
286
+ "type": "array",
287
+ "items": { "type": "string" },
288
+ "minItems": 1
289
+ },
290
+ "nextStep": { "type": "string", "minLength": 1 }
291
+ }
292
+ },
293
+
294
+ "evidence": {
295
+ "type": "object",
296
+ "required": ["primary"],
297
+ "additionalProperties": false,
298
+ "properties": {
299
+ "primary": {
300
+ "type": "array",
301
+ "items": { "$ref": "#/$defs/PrimaryEvidenceRow" }
302
+ },
303
+ "secondary": {
304
+ "type": "array",
305
+ "items": { "$ref": "#/$defs/SecondaryEvidenceRow" }
306
+ }
307
+ }
308
+ },
309
+
310
+ "missingInformation": {
311
+ "type": "array",
312
+ "items": { "$ref": "#/$defs/RiskRow" }
313
+ },
314
+
315
+ "implementationPlanning": {
316
+ "type": "object",
317
+ "description": "RENDER_IF taskType == implementation-planning. §4.5 deliverables.",
318
+ "required": [
319
+ "optionCandidates",
320
+ "tradeoffMatrix",
321
+ "recommendedOption",
322
+ "stepwiseExecution",
323
+ "dependencyMigrationRisk",
324
+ "validationChecklist",
325
+ "rollbackStrategy",
326
+ "planBodyVerification"
327
+ ],
328
+ "additionalProperties": false,
329
+ "properties": {
330
+ "optionCandidates": {
331
+ "type": "array",
332
+ "minItems": 2,
333
+ "items": { "$ref": "#/$defs/OptionCandidate" }
334
+ },
335
+ "tradeoffMatrix": {
336
+ "type": "array",
337
+ "minItems": 1,
338
+ "items": { "$ref": "#/$defs/TradeoffRow" }
339
+ },
340
+ "recommendedOption": { "$ref": "#/$defs/RecommendedOption" },
341
+ "stepwiseExecution": {
342
+ "type": "array",
343
+ "minItems": 1,
344
+ "items": { "$ref": "#/$defs/StepRow" }
345
+ },
346
+ "dependencyMigrationRisk": {
347
+ "type": "array",
348
+ "items": { "$ref": "#/$defs/DependencyRow" }
349
+ },
350
+ "validationChecklist": {
351
+ "type": "array",
352
+ "minItems": 1,
353
+ "items": { "$ref": "#/$defs/ValidationCheckRow" }
354
+ },
355
+ "rollbackStrategy": {
356
+ "type": "array",
357
+ "minItems": 1,
358
+ "items": { "$ref": "#/$defs/RollbackRow" }
359
+ },
360
+ "planBodyVerification": { "$ref": "#/$defs/PlanBodyVerification" }
361
+ }
362
+ },
363
+
364
+ "releaseHandoff": {
365
+ "type": "object",
366
+ "description": "RENDER_IF taskType == release-handoff. §4.6 deliverables.",
367
+ "required": [
368
+ "sourceVerificationReport",
369
+ "featureBranchState",
370
+ "userSelections",
371
+ "executedCommands",
372
+ "commitList",
373
+ "mergeConflictProbe",
374
+ "pullRequestOutcome",
375
+ "routingRecommendation"
376
+ ],
377
+ "additionalProperties": false,
378
+ "properties": {
379
+ "sourceVerificationReport": {
380
+ "type": "object",
381
+ "required": ["path", "verdictTokenQuote"],
382
+ "additionalProperties": false,
383
+ "properties": {
384
+ "path": { "type": "string", "minLength": 1 },
385
+ "verdictTokenQuote": { "type": "string", "minLength": 1 }
386
+ }
387
+ },
388
+ "featureBranchState": {
389
+ "type": "object",
390
+ "required": ["branchName", "gitStatusShort", "existingPrUrl"],
391
+ "additionalProperties": false,
392
+ "properties": {
393
+ "branchName": { "type": "string", "minLength": 1 },
394
+ "gitStatusShort": { "type": "string" },
395
+ "existingPrUrl": { "type": "string" }
396
+ }
397
+ },
398
+ "userSelections": {
399
+ "type": "object",
400
+ "required": ["h1", "h3"],
401
+ "additionalProperties": false,
402
+ "properties": {
403
+ "h1": { "enum": ["local only", "push + PR", "skip"] },
404
+ "h2": { "type": "string" },
405
+ "h3": { "enum": ["use as-is", "edit then proceed", "cancel"] }
406
+ }
407
+ },
408
+ "executedCommands": {
409
+ "type": "array",
410
+ "items": { "$ref": "#/$defs/ExecutedCommandRow" }
411
+ },
412
+ "commitList": {
413
+ "oneOf": [
414
+ {
415
+ "type": "array",
416
+ "items": { "$ref": "#/$defs/CommitRow" }
417
+ },
418
+ {
419
+ "type": "object",
420
+ "required": ["empty"],
421
+ "additionalProperties": false,
422
+ "properties": { "empty": { "const": true } }
423
+ }
424
+ ]
425
+ },
426
+ "mergeConflictProbe": {
427
+ "type": "object",
428
+ "required": ["kind"],
429
+ "additionalProperties": false,
430
+ "properties": {
431
+ "kind": {
432
+ "enum": ["not-run", "clean", "conflicts"]
433
+ },
434
+ "baseBranch": { "type": "string" },
435
+ "baseSha": { "type": "string" },
436
+ "userChoice": { "type": "string" },
437
+ "conflictingPaths": {
438
+ "type": "array",
439
+ "items": { "type": "string" }
440
+ }
441
+ }
442
+ },
443
+ "pullRequestOutcome": {
444
+ "type": "object",
445
+ "required": ["kind"],
446
+ "additionalProperties": false,
447
+ "properties": {
448
+ "kind": {
449
+ "enum": ["no-action", "created", "reused", "skipped"]
450
+ },
451
+ "url": { "type": "string" },
452
+ "title": { "type": "string" },
453
+ "baseBranch": { "type": "string" },
454
+ "reason": { "type": "string" }
455
+ }
456
+ },
457
+ "routingRecommendation": { "type": "string", "minLength": 1 }
458
+ }
459
+ },
460
+
461
+ "implementation": {
462
+ "type": "object",
463
+ "description": "RENDER_IF taskType == implementation. §4.7 deliverables.",
464
+ "required": [
465
+ "approvedPlanReference",
466
+ "commitList",
467
+ "diffSummary",
468
+ "outOfPlanEdits",
469
+ "validationEvidence",
470
+ "verifierResults",
471
+ "rollbackVerification",
472
+ "routingRecommendation"
473
+ ],
474
+ "additionalProperties": false,
475
+ "properties": {
476
+ "approvedPlanReference": {
477
+ "type": "object",
478
+ "required": ["planFile", "approvalEvidence", "executorWorktreePath", "baseRefSha"],
479
+ "additionalProperties": false,
480
+ "properties": {
481
+ "planFile": { "type": "string", "minLength": 1 },
482
+ "approvalEvidence": { "type": "string", "minLength": 1 },
483
+ "executorWorktreePath": { "type": "string", "minLength": 1 },
484
+ "baseRefSha": { "type": "string", "minLength": 1 }
485
+ }
486
+ },
487
+ "commitList": {
488
+ "type": "array",
489
+ "items": { "$ref": "#/$defs/CommitWithStepRow" }
490
+ },
491
+ "diffSummary": {
492
+ "type": "object",
493
+ "required": ["rawStat", "files"],
494
+ "additionalProperties": false,
495
+ "properties": {
496
+ "rawStat": { "type": "string" },
497
+ "files": {
498
+ "type": "array",
499
+ "items": { "$ref": "#/$defs/DiffFileRow" }
500
+ }
501
+ }
502
+ },
503
+ "outOfPlanEdits": {
504
+ "type": "array",
505
+ "items": { "$ref": "#/$defs/OutOfPlanEditRow" }
506
+ },
507
+ "validationEvidence": {
508
+ "type": "array",
509
+ "minItems": 1,
510
+ "items": { "$ref": "#/$defs/ValidationEvidenceRow" }
511
+ },
512
+ "verifierResults": {
513
+ "type": "array",
514
+ "minItems": 1,
515
+ "items": { "$ref": "#/$defs/VerifierResultBlock" }
516
+ },
517
+ "rollbackVerification": {
518
+ "type": "array",
519
+ "minItems": 1,
520
+ "items": { "$ref": "#/$defs/RollbackVerificationRow" }
521
+ },
522
+ "routingRecommendation": { "type": "string", "minLength": 1 }
523
+ }
524
+ },
525
+
526
+ "finalVerification": {
527
+ "type": "object",
528
+ "description": "RENDER_IF taskType == final-verification. §4.8 deliverables.",
529
+ "required": [
530
+ "sourceImplementationReport",
531
+ "acceptanceBlockers",
532
+ "residualRisk",
533
+ "validationEvidence",
534
+ "readonlyCommandLog",
535
+ "routingRecommendation"
536
+ ],
537
+ "additionalProperties": false,
538
+ "properties": {
539
+ "sourceImplementationReport": {
540
+ "type": "object",
541
+ "required": ["path", "commitListQuote", "worktreePath", "baseHeadSha", "gitStatusShort"],
542
+ "additionalProperties": false,
543
+ "properties": {
544
+ "path": { "type": "string" },
545
+ "commitListQuote": { "type": "string" },
546
+ "worktreePath": { "type": "string" },
547
+ "baseHeadSha": { "type": "string" },
548
+ "gitStatusShort": { "type": "string" }
549
+ }
550
+ },
551
+ "acceptanceBlockers": {
552
+ "type": "array",
553
+ "items": { "$ref": "#/$defs/AcceptanceBlockerRow" }
554
+ },
555
+ "residualRisk": {
556
+ "type": "array",
557
+ "items": { "$ref": "#/$defs/ResidualRiskRow" }
558
+ },
559
+ "validationEvidence": {
560
+ "type": "array",
561
+ "items": { "$ref": "#/$defs/RequirementCoverageRow" }
562
+ },
563
+ "readonlyCommandLog": {
564
+ "type": "array",
565
+ "items": { "$ref": "#/$defs/ReadonlyCommandRow" }
566
+ },
567
+ "routingRecommendation": { "type": "string", "minLength": 1 }
568
+ }
569
+ },
570
+
571
+ "clarificationItems": {
572
+ "type": "array",
573
+ "items": { "$ref": "#/$defs/ClarificationRow" }
574
+ },
575
+
576
+ "recommendedNextSteps": {
577
+ "type": "array",
578
+ "minItems": 1,
579
+ "items": { "$ref": "#/$defs/RecommendedStep" }
580
+ },
581
+
582
+ "followUpTasks": {
583
+ "type": "array",
584
+ "items": { "$ref": "#/$defs/FollowUpRow" }
585
+ }
586
+ },
587
+
588
+ "allOf": [
589
+ {
590
+ "description": "implementation-planning task-type requires §4.5 block.",
591
+ "if": {
592
+ "properties": { "header": { "properties": { "taskType": { "const": "implementation-planning" } } } },
593
+ "required": ["header"]
594
+ },
595
+ "then": {
596
+ "required": ["implementationPlanning", "approvalBlock"]
597
+ }
598
+ },
599
+ {
600
+ "description": "release-handoff task-type requires §4.6 block.",
601
+ "if": {
602
+ "properties": { "header": { "properties": { "taskType": { "const": "release-handoff" } } } },
603
+ "required": ["header"]
604
+ },
605
+ "then": {
606
+ "required": ["releaseHandoff"]
607
+ }
608
+ },
609
+ {
610
+ "description": "implementation task-type requires §4.7 block.",
611
+ "if": {
612
+ "properties": { "header": { "properties": { "taskType": { "const": "implementation" } } } },
613
+ "required": ["header"]
614
+ },
615
+ "then": {
616
+ "required": ["implementation"]
617
+ }
618
+ },
619
+ {
620
+ "description": "final-verification task-type requires §4.8 block.",
621
+ "if": {
622
+ "properties": { "header": { "properties": { "taskType": { "const": "final-verification" } } } },
623
+ "required": ["header"]
624
+ },
625
+ "then": {
626
+ "required": ["finalVerification"]
627
+ }
628
+ },
629
+ {
630
+ "description": "Non-terminal task-types MUST emit one phase-continuation row in followUpTasks.",
631
+ "if": {
632
+ "properties": {
633
+ "header": {
634
+ "properties": {
635
+ "taskType": {
636
+ "enum": [
637
+ "requirements-discovery",
638
+ "implementation-planning",
639
+ "error-analysis",
640
+ "implementation",
641
+ "final-verification"
642
+ ]
643
+ }
644
+ }
645
+ }
646
+ },
647
+ "required": ["header"]
648
+ },
649
+ "then": {
650
+ "properties": {
651
+ "followUpTasks": {
652
+ "type": "array",
653
+ "minItems": 1,
654
+ "contains": {
655
+ "type": "object",
656
+ "properties": {
657
+ "origin": { "const": "phase-continuation" }
658
+ },
659
+ "required": ["origin"]
660
+ }
661
+ }
662
+ }
663
+ }
664
+ },
665
+ {
666
+ "description": "final-verification verdict token must be one of accepted / conditional-accept / blocked.",
667
+ "if": {
668
+ "properties": { "header": { "properties": { "taskType": { "const": "final-verification" } } } },
669
+ "required": ["header"]
670
+ },
671
+ "then": {
672
+ "properties": {
673
+ "finalVerdict": {
674
+ "properties": {
675
+ "verdictToken": { "enum": ["accepted", "conditional-accept", "blocked"] }
676
+ }
677
+ }
678
+ }
679
+ }
680
+ },
681
+ {
682
+ "description": "Non-final-verification verdict token must be `not-applicable`.",
683
+ "if": {
684
+ "properties": {
685
+ "header": {
686
+ "properties": {
687
+ "taskType": { "not": { "const": "final-verification" } }
688
+ }
689
+ }
690
+ },
691
+ "required": ["header"]
692
+ },
693
+ "then": {
694
+ "properties": {
695
+ "finalVerdict": {
696
+ "properties": {
697
+ "verdictToken": { "const": "not-applicable" }
698
+ }
699
+ }
700
+ }
701
+ }
702
+ }
703
+ ],
704
+
705
+ "$defs": {
706
+ "TaskType": {
707
+ "enum": [
708
+ "requirements-discovery",
709
+ "error-analysis",
710
+ "implementation-planning",
711
+ "implementation",
712
+ "final-verification",
713
+ "release-handoff",
714
+ "quick"
715
+ ]
716
+ },
717
+
718
+ "VerdictToken": {
719
+ "enum": ["accepted", "conditional-accept", "blocked", "not-applicable"]
720
+ },
721
+
722
+ "Direction": {
723
+ "enum": [
724
+ "continue-investigation",
725
+ "begin-implementation",
726
+ "approve",
727
+ "reject",
728
+ "hold"
729
+ ]
730
+ },
731
+
732
+ "TicketId": {
733
+ "type": "string",
734
+ "minLength": 1,
735
+ "description": "Ticket key (external) or task-fallback (task-id verbatim) or literal `unknown` when truly unidentified. Empty string is never valid."
736
+ },
737
+
738
+ "Priority": {
739
+ "enum": ["P0", "P1", "P2"]
740
+ },
741
+
742
+ "FollowUpOrigin": {
743
+ "enum": [
744
+ "phase-continuation",
745
+ "out-of-plan",
746
+ "verifier-concern",
747
+ "scope-boundary",
748
+ "open-question",
749
+ "manual"
750
+ ]
751
+ },
752
+
753
+ "ClarificationKind": {
754
+ "enum": ["material", "decision", "data-point"]
755
+ },
756
+
757
+ "ClarificationBlocks": {
758
+ "enum": ["approval", "next-phase", "none"]
759
+ },
760
+
761
+ "ClarificationStatus": {
762
+ "enum": ["open", "answered", "resolved", "obsolete"]
763
+ },
764
+
765
+ "WorkerStatus": {
766
+ "enum": ["completed", "error", "timeout", "not-run", "synthesis-only"]
767
+ },
768
+
769
+ "SourceItem": {
770
+ "type": "string",
771
+ "pattern": "^[a-z][a-z-]*:[A-Za-z0-9._-]+$",
772
+ "description": "Source-item reference in the form `<worker>:<item-id>`, e.g. `claude:F-001`, `codex:1.1`, `lead:mcp-1`. Bare worker-name lists are deprecated; every source must carry its origin item ID."
773
+ },
774
+
775
+ "SummaryRow": {
776
+ "type": "object",
777
+ "required": ["id", "ticketId", "summary", "source"],
778
+ "additionalProperties": false,
779
+ "properties": {
780
+ "id": { "type": "string", "pattern": "^P-\\d{3,}$" },
781
+ "ticketId": { "$ref": "#/$defs/TicketId" },
782
+ "summary": { "type": "string", "minLength": 1 },
783
+ "source": { "type": "string", "minLength": 1 }
784
+ }
785
+ },
786
+
787
+ "TicketCoverageRow": {
788
+ "type": "object",
789
+ "required": ["ticketId", "sections", "relatedIds"],
790
+ "additionalProperties": false,
791
+ "properties": {
792
+ "ticketId": { "$ref": "#/$defs/TicketId" },
793
+ "sections": { "type": "string", "minLength": 1 },
794
+ "relatedIds": { "type": "string", "minLength": 1 }
795
+ }
796
+ },
797
+
798
+ "ExecutionStatusRow": {
799
+ "type": "object",
800
+ "required": ["agent", "role", "model", "status", "summary"],
801
+ "additionalProperties": false,
802
+ "properties": {
803
+ "agent": { "enum": ["Claude Code", "Codex", "Gemini"] },
804
+ "role": { "type": "string", "minLength": 1 },
805
+ "model": { "type": "string", "minLength": 1 },
806
+ "status": { "$ref": "#/$defs/WorkerStatus" },
807
+ "summary": { "type": "string", "minLength": 1 },
808
+ "totalTokens": {
809
+ "oneOf": [
810
+ { "type": "integer", "minimum": 0 },
811
+ { "type": "null" }
812
+ ]
813
+ },
814
+ "billableTokens": {
815
+ "oneOf": [
816
+ { "type": "integer", "minimum": 0 },
817
+ { "type": "null" }
818
+ ]
819
+ },
820
+ "costUsd": {
821
+ "oneOf": [
822
+ { "type": "number", "minimum": 0 },
823
+ { "type": "null" }
824
+ ]
825
+ },
826
+ "cliTotalTokens": {
827
+ "oneOf": [
828
+ { "type": "integer", "minimum": 0 },
829
+ { "type": "null" }
830
+ ]
831
+ },
832
+ "cliCostUsd": {
833
+ "oneOf": [
834
+ { "type": "number", "minimum": 0 },
835
+ { "type": "null" }
836
+ ]
837
+ },
838
+ "durationMs": {
839
+ "oneOf": [
840
+ { "type": "integer", "minimum": 0 },
841
+ { "type": "null" }
842
+ ]
843
+ }
844
+ }
845
+ },
846
+
847
+ "TokenUsageRow": {
848
+ "type": "object",
849
+ "required": ["totalTokens", "billableTokens", "costUsd"],
850
+ "additionalProperties": false,
851
+ "properties": {
852
+ "totalTokens": {
853
+ "oneOf": [
854
+ { "type": "integer", "minimum": 0 },
855
+ { "type": "null" }
856
+ ]
857
+ },
858
+ "billableTokens": {
859
+ "oneOf": [
860
+ { "type": "integer", "minimum": 0 },
861
+ { "type": "null" }
862
+ ]
863
+ },
864
+ "costUsd": {
865
+ "oneOf": [
866
+ { "type": "number", "minimum": 0 },
867
+ { "type": "null" }
868
+ ]
869
+ }
870
+ }
871
+ },
872
+
873
+ "RoundHistoryRow": {
874
+ "type": "object",
875
+ "required": [
876
+ "round",
877
+ "inputQueueSize",
878
+ "resolvedCount",
879
+ "carriedForwardCount",
880
+ "dispatches",
881
+ "skippedWorkers"
882
+ ],
883
+ "additionalProperties": false,
884
+ "properties": {
885
+ "round": { "type": "integer", "minimum": 0 },
886
+ "inputQueueSize": { "type": "integer", "minimum": 0 },
887
+ "resolvedCount": { "type": "integer", "minimum": 0 },
888
+ "carriedForwardCount": { "type": "integer", "minimum": 0 },
889
+ "dispatches": { "type": "string" },
890
+ "skippedWorkers": { "type": "string" }
891
+ }
892
+ },
893
+
894
+ "ConsensusRow": {
895
+ "type": "object",
896
+ "required": ["id", "ticketId", "statement", "sourceItems", "evidence"],
897
+ "additionalProperties": false,
898
+ "properties": {
899
+ "id": { "type": "string", "pattern": "^C-\\d{3,}$" },
900
+ "ticketId": { "$ref": "#/$defs/TicketId" },
901
+ "statement": { "type": "string", "minLength": 1 },
902
+ "sourceItems": {
903
+ "type": "array",
904
+ "minItems": 1,
905
+ "items": { "$ref": "#/$defs/SourceItem" }
906
+ },
907
+ "evidence": { "type": "string", "minLength": 1 }
908
+ }
909
+ },
910
+
911
+ "DifferenceRow": {
912
+ "type": "object",
913
+ "required": ["id", "ticketId", "disagreement", "workersPosition", "evidence"],
914
+ "additionalProperties": false,
915
+ "properties": {
916
+ "id": { "type": "string", "pattern": "^D-\\d{3,}$" },
917
+ "ticketId": { "$ref": "#/$defs/TicketId" },
918
+ "disagreement": { "type": "string", "minLength": 1 },
919
+ "workersPosition": {
920
+ "type": "array",
921
+ "minItems": 1,
922
+ "items": {
923
+ "type": "object",
924
+ "required": ["worker", "itemId", "position"],
925
+ "additionalProperties": false,
926
+ "properties": {
927
+ "worker": { "type": "string", "minLength": 1 },
928
+ "itemId": { "type": "string" },
929
+ "position": { "type": "string", "minLength": 1 }
930
+ }
931
+ }
932
+ },
933
+ "evidence": { "type": "string", "minLength": 1 }
934
+ }
935
+ },
936
+
937
+ "PrimaryEvidenceRow": {
938
+ "type": "object",
939
+ "required": ["id", "ticketId", "evidence", "sourceItems", "source"],
940
+ "additionalProperties": false,
941
+ "properties": {
942
+ "id": { "type": "string", "pattern": "^E-\\d{3,}$" },
943
+ "ticketId": { "$ref": "#/$defs/TicketId" },
944
+ "evidence": { "type": "string", "minLength": 1 },
945
+ "sourceItems": {
946
+ "type": "array",
947
+ "minItems": 1,
948
+ "items": { "$ref": "#/$defs/SourceItem" }
949
+ },
950
+ "source": { "type": "string", "minLength": 1 }
951
+ }
952
+ },
953
+
954
+ "SecondaryEvidenceRow": {
955
+ "type": "object",
956
+ "required": ["id", "ticketId", "hypothesis", "confidence"],
957
+ "additionalProperties": false,
958
+ "properties": {
959
+ "id": { "type": "string", "pattern": "^S-\\d{3,}$" },
960
+ "ticketId": { "$ref": "#/$defs/TicketId" },
961
+ "hypothesis": { "type": "string", "minLength": 1 },
962
+ "confidence": { "type": "string", "minLength": 1 }
963
+ }
964
+ },
965
+
966
+ "RiskRow": {
967
+ "type": "object",
968
+ "required": ["id", "ticketId", "item", "risk", "owner"],
969
+ "additionalProperties": false,
970
+ "properties": {
971
+ "id": { "type": "string", "pattern": "^R-\\d{3,}$" },
972
+ "ticketId": { "$ref": "#/$defs/TicketId" },
973
+ "item": { "type": "string", "minLength": 1 },
974
+ "risk": { "type": "string", "minLength": 1 },
975
+ "owner": { "type": "string", "minLength": 1 },
976
+ "source": { "type": "string" }
977
+ }
978
+ },
979
+
980
+ "OptionCandidate": {
981
+ "type": "object",
982
+ "required": ["name", "fileStructure", "interfaces", "blastRadius"],
983
+ "additionalProperties": false,
984
+ "properties": {
985
+ "name": { "type": "string", "minLength": 1 },
986
+ "fileStructure": {
987
+ "type": "array",
988
+ "items": {
989
+ "type": "object",
990
+ "required": ["id", "ticketId", "action", "path", "summary"],
991
+ "additionalProperties": false,
992
+ "properties": {
993
+ "id": { "type": "string", "pattern": "^OF-\\d{3,}$" },
994
+ "ticketId": { "$ref": "#/$defs/TicketId" },
995
+ "action": { "enum": ["Create", "Modify", "Delete"] },
996
+ "path": { "type": "string", "minLength": 1 },
997
+ "summary": { "type": "string", "minLength": 1 }
998
+ }
999
+ }
1000
+ },
1001
+ "interfaces": { "type": "string" },
1002
+ "blastRadius": { "type": "string" }
1003
+ }
1004
+ },
1005
+
1006
+ "TradeoffRow": {
1007
+ "type": "object",
1008
+ "required": ["option", "complexity", "risk", "reversibility", "testCoverageCost", "rolloutCost"],
1009
+ "additionalProperties": false,
1010
+ "properties": {
1011
+ "option": { "type": "string", "minLength": 1 },
1012
+ "complexity": { "type": "string", "minLength": 1 },
1013
+ "risk": { "type": "string", "minLength": 1 },
1014
+ "reversibility": { "type": "string", "minLength": 1 },
1015
+ "testCoverageCost": { "type": "string", "minLength": 1 },
1016
+ "rolloutCost": { "type": "string", "minLength": 1 }
1017
+ }
1018
+ },
1019
+
1020
+ "RecommendedOption": {
1021
+ "type": "object",
1022
+ "required": ["name", "coreReason", "rationale", "rejectedSummary"],
1023
+ "additionalProperties": false,
1024
+ "properties": {
1025
+ "name": { "type": "string", "minLength": 1 },
1026
+ "coreReason": { "type": "string", "minLength": 1 },
1027
+ "rationale": { "type": "string", "minLength": 1 },
1028
+ "rejectedSummary": { "type": "string", "minLength": 1 }
1029
+ }
1030
+ },
1031
+
1032
+ "StepRow": {
1033
+ "type": "object",
1034
+ "required": ["step", "ticketId", "action", "files", "commandOrTest", "expectedOutcome"],
1035
+ "additionalProperties": false,
1036
+ "properties": {
1037
+ "step": { "type": "integer", "minimum": 1 },
1038
+ "ticketId": { "$ref": "#/$defs/TicketId" },
1039
+ "action": { "type": "string", "minLength": 1 },
1040
+ "files": { "type": "string", "minLength": 1 },
1041
+ "commandOrTest": { "type": "string", "minLength": 1 },
1042
+ "expectedOutcome": { "type": "string", "minLength": 1 }
1043
+ }
1044
+ },
1045
+
1046
+ "DependencyRow": {
1047
+ "type": "object",
1048
+ "required": ["id", "kind", "item", "impact", "mitigation"],
1049
+ "additionalProperties": false,
1050
+ "properties": {
1051
+ "id": { "type": "string", "pattern": "^DM-\\d{3,}$" },
1052
+ "kind": {
1053
+ "enum": ["order", "backfill", "flag-precondition", "repo-sequencing", "other"]
1054
+ },
1055
+ "item": { "type": "string", "minLength": 1 },
1056
+ "impact": { "type": "string", "minLength": 1 },
1057
+ "mitigation": { "type": "string", "minLength": 1 }
1058
+ }
1059
+ },
1060
+
1061
+ "ValidationCheckRow": {
1062
+ "type": "object",
1063
+ "required": ["phase", "ticketId", "check", "commandOrObservation", "expectedOutcome"],
1064
+ "additionalProperties": false,
1065
+ "properties": {
1066
+ "phase": { "enum": ["pre", "mid", "post"] },
1067
+ "ticketId": { "$ref": "#/$defs/TicketId" },
1068
+ "check": { "type": "string", "minLength": 1 },
1069
+ "commandOrObservation": { "type": "string", "minLength": 1 },
1070
+ "expectedOutcome": { "type": "string", "minLength": 1 }
1071
+ }
1072
+ },
1073
+
1074
+ "RollbackRow": {
1075
+ "type": "object",
1076
+ "required": ["id", "step", "action", "triggerSignal", "verificationMethod"],
1077
+ "additionalProperties": false,
1078
+ "properties": {
1079
+ "id": { "type": "string", "pattern": "^RB-\\d{3,}$" },
1080
+ "step": { "type": "integer", "minimum": 1 },
1081
+ "action": { "type": "string", "minLength": 1 },
1082
+ "triggerSignal": { "type": "string", "minLength": 1 },
1083
+ "verificationMethod": { "type": "string", "minLength": 1 }
1084
+ }
1085
+ },
1086
+
1087
+ "PlanBodyVerification": {
1088
+ "type": "object",
1089
+ "required": ["roundCount", "gateResult", "verdictSummary", "verdictDetails", "dissentLog"],
1090
+ "additionalProperties": false,
1091
+ "properties": {
1092
+ "roundCount": { "type": "integer", "minimum": 0 },
1093
+ "gateResult": {
1094
+ "enum": [
1095
+ "passed",
1096
+ "passed-with-dissent",
1097
+ "blocked-by-disagreement",
1098
+ "aborted-non-result"
1099
+ ]
1100
+ },
1101
+ "verdictSummary": {
1102
+ "type": "array",
1103
+ "items": {
1104
+ "type": "object",
1105
+ "required": ["planItem", "ticketId", "section", "classification"],
1106
+ "additionalProperties": false,
1107
+ "properties": {
1108
+ "planItem": {
1109
+ "type": "string",
1110
+ "pattern": "^P-(Opt|Step|Dep|Val|Rb)-\\d+$"
1111
+ },
1112
+ "ticketId": { "$ref": "#/$defs/TicketId" },
1113
+ "section": { "type": "string", "minLength": 1 },
1114
+ "classification": {
1115
+ "type": "string",
1116
+ "pattern": "^(full-consensus|partial-consensus|worker-unique|majority-disagree → C-\\d+)$"
1117
+ }
1118
+ }
1119
+ }
1120
+ },
1121
+ "verdictDetails": {
1122
+ "type": "array",
1123
+ "items": {
1124
+ "type": "object",
1125
+ "required": ["planItem", "worker", "verdict"],
1126
+ "additionalProperties": false,
1127
+ "properties": {
1128
+ "planItem": { "type": "string", "minLength": 1 },
1129
+ "worker": { "type": "string", "minLength": 1 },
1130
+ "verdict": {
1131
+ "enum": ["AGREE", "DISAGREE", "SUPPLEMENT", "verification-error"]
1132
+ },
1133
+ "breakageKind": { "type": "string" },
1134
+ "note": { "type": "string" }
1135
+ }
1136
+ }
1137
+ },
1138
+ "dissentLog": {
1139
+ "type": "array",
1140
+ "items": {
1141
+ "type": "object",
1142
+ "required": ["planItem", "workerRole", "body"],
1143
+ "additionalProperties": false,
1144
+ "properties": {
1145
+ "planItem": { "type": "string", "minLength": 1 },
1146
+ "workerRole": { "type": "string", "minLength": 1 },
1147
+ "body": { "type": "string", "minLength": 1 }
1148
+ }
1149
+ }
1150
+ }
1151
+ }
1152
+ },
1153
+
1154
+ "ExecutedCommandRow": {
1155
+ "type": "object",
1156
+ "required": ["number", "command", "exitCode", "outputSummary"],
1157
+ "additionalProperties": false,
1158
+ "properties": {
1159
+ "number": { "type": "integer", "minimum": 1 },
1160
+ "command": { "type": "string", "minLength": 1 },
1161
+ "exitCode": { "type": "integer" },
1162
+ "outputSummary": { "type": "string" }
1163
+ }
1164
+ },
1165
+
1166
+ "CommitRow": {
1167
+ "type": "object",
1168
+ "required": ["shortSha", "fullSha", "subject", "files"],
1169
+ "additionalProperties": false,
1170
+ "properties": {
1171
+ "shortSha": { "type": "string", "minLength": 7 },
1172
+ "fullSha": { "type": "string", "minLength": 40 },
1173
+ "subject": { "type": "string", "minLength": 1 },
1174
+ "files": { "type": "string" }
1175
+ }
1176
+ },
1177
+
1178
+ "CommitWithStepRow": {
1179
+ "type": "object",
1180
+ "required": ["number", "shortSha", "fullSha", "planStep", "subject", "files"],
1181
+ "additionalProperties": false,
1182
+ "properties": {
1183
+ "number": { "type": "integer", "minimum": 1 },
1184
+ "shortSha": { "type": "string", "minLength": 7 },
1185
+ "fullSha": { "type": "string", "minLength": 40 },
1186
+ "planStep": { "type": "string", "minLength": 1 },
1187
+ "subject": { "type": "string", "minLength": 1 },
1188
+ "files": { "type": "string" }
1189
+ }
1190
+ },
1191
+
1192
+ "DiffFileRow": {
1193
+ "type": "object",
1194
+ "required": ["file", "action", "lines", "planStep"],
1195
+ "additionalProperties": false,
1196
+ "properties": {
1197
+ "file": { "type": "string", "minLength": 1 },
1198
+ "action": { "enum": ["created", "modified", "deleted"] },
1199
+ "lines": { "type": "string", "minLength": 1 },
1200
+ "planStep": { "type": "string", "minLength": 1 }
1201
+ }
1202
+ },
1203
+
1204
+ "OutOfPlanEditRow": {
1205
+ "type": "object",
1206
+ "required": ["id", "file", "rationale", "trigger"],
1207
+ "additionalProperties": false,
1208
+ "properties": {
1209
+ "id": { "type": "string", "pattern": "^OOP-\\d{3,}$" },
1210
+ "file": { "type": "string", "minLength": 1 },
1211
+ "rationale": { "type": "string", "minLength": 1 },
1212
+ "trigger": { "type": "string", "minLength": 1 }
1213
+ }
1214
+ },
1215
+
1216
+ "ValidationEvidenceRow": {
1217
+ "type": "object",
1218
+ "required": ["phase", "command", "exitCode", "outputTail"],
1219
+ "additionalProperties": false,
1220
+ "properties": {
1221
+ "phase": { "enum": ["pre", "mid", "post"] },
1222
+ "command": { "type": "string", "minLength": 1 },
1223
+ "exitCode": { "type": "integer" },
1224
+ "outputTail": { "type": "string" },
1225
+ "tddEvidence": { "type": "string" }
1226
+ }
1227
+ },
1228
+
1229
+ "VerifierResultBlock": {
1230
+ "type": "object",
1231
+ "required": ["verifier", "verdict", "readOnlyCommandLog", "independentValidationRerun"],
1232
+ "additionalProperties": false,
1233
+ "properties": {
1234
+ "verifier": { "type": "string", "minLength": 1 },
1235
+ "verdict": { "enum": ["PASS", "CONCERNS", "FAIL"] },
1236
+ "readOnlyCommandLog": { "type": "string" },
1237
+ "independentValidationRerun": { "type": "string" },
1238
+ "styleLintTypecheck": { "type": "string" },
1239
+ "declinedFixRecommendations": { "type": "string" },
1240
+ "discrepancy": { "type": "string" }
1241
+ }
1242
+ },
1243
+
1244
+ "RollbackVerificationRow": {
1245
+ "type": "object",
1246
+ "required": ["category", "rollbackCommand", "verification", "result"],
1247
+ "additionalProperties": false,
1248
+ "properties": {
1249
+ "category": {
1250
+ "enum": ["Pure code", "Feature-flag-gated", "Schema/config/stateful"]
1251
+ },
1252
+ "rollbackCommand": { "type": "string", "minLength": 1 },
1253
+ "verification": { "type": "string", "minLength": 1 },
1254
+ "result": {
1255
+ "enum": ["ok", "unable — route back to planning"]
1256
+ }
1257
+ }
1258
+ },
1259
+
1260
+ "AcceptanceBlockerRow": {
1261
+ "type": "object",
1262
+ "required": ["id", "severity", "statement", "evidence", "followUpPhase"],
1263
+ "additionalProperties": false,
1264
+ "properties": {
1265
+ "id": { "type": "string", "pattern": "^AB-\\d{3,}$" },
1266
+ "severity": { "enum": ["critical", "major", "minor"] },
1267
+ "statement": { "type": "string", "minLength": 1 },
1268
+ "evidence": { "type": "string", "minLength": 1 },
1269
+ "followUpPhase": { "type": "string", "minLength": 1 }
1270
+ }
1271
+ },
1272
+
1273
+ "ResidualRiskRow": {
1274
+ "type": "object",
1275
+ "required": ["id", "item", "owner", "escalationTrigger"],
1276
+ "additionalProperties": false,
1277
+ "properties": {
1278
+ "id": { "type": "string", "pattern": "^RR-\\d{3,}$" },
1279
+ "item": { "type": "string", "minLength": 1 },
1280
+ "owner": { "type": "string", "minLength": 1 },
1281
+ "escalationTrigger": { "type": "string", "minLength": 1 }
1282
+ }
1283
+ },
1284
+
1285
+ "RequirementCoverageRow": {
1286
+ "type": "object",
1287
+ "required": ["id", "requirement", "artifact", "status"],
1288
+ "additionalProperties": false,
1289
+ "properties": {
1290
+ "id": { "type": "string", "pattern": "^VE-\\d{3,}$" },
1291
+ "requirement": { "type": "string", "minLength": 1 },
1292
+ "artifact": { "type": "string", "minLength": 1 },
1293
+ "status": {
1294
+ "type": "string",
1295
+ "pattern": "^(covered|blocker AB-\\d{3,}|gap)$"
1296
+ }
1297
+ }
1298
+ },
1299
+
1300
+ "ReadonlyCommandRow": {
1301
+ "type": "object",
1302
+ "required": ["number", "tier", "command", "exitCode", "outputTail"],
1303
+ "additionalProperties": false,
1304
+ "properties": {
1305
+ "number": { "type": "integer", "minimum": 1 },
1306
+ "tier": { "enum": [1, 2] },
1307
+ "command": { "type": "string", "minLength": 1 },
1308
+ "exitCode": { "type": "integer" },
1309
+ "outputTail": { "type": "string" }
1310
+ }
1311
+ },
1312
+
1313
+ "ClarificationRow": {
1314
+ "type": "object",
1315
+ "required": ["id", "ticketId", "kind", "statement", "expectedForm", "blocks", "status"],
1316
+ "additionalProperties": false,
1317
+ "properties": {
1318
+ "id": { "type": "string", "pattern": "^C-\\d{3,}$" },
1319
+ "ticketId": { "$ref": "#/$defs/TicketId" },
1320
+ "kind": { "$ref": "#/$defs/ClarificationKind" },
1321
+ "statement": { "type": "string", "minLength": 1 },
1322
+ "expectedForm": { "type": "string", "minLength": 1 },
1323
+ "blocks": { "$ref": "#/$defs/ClarificationBlocks" },
1324
+ "status": { "$ref": "#/$defs/ClarificationStatus" },
1325
+ "userInput": { "type": "string" }
1326
+ }
1327
+ },
1328
+
1329
+ "RecommendedStep": {
1330
+ "type": "object",
1331
+ "required": ["text"],
1332
+ "additionalProperties": false,
1333
+ "properties": {
1334
+ "text": { "type": "string", "minLength": 1 },
1335
+ "commands": {
1336
+ "type": "array",
1337
+ "items": {
1338
+ "type": "object",
1339
+ "required": ["label", "claudeCode", "terminal"],
1340
+ "additionalProperties": false,
1341
+ "properties": {
1342
+ "label": { "type": "string", "minLength": 1 },
1343
+ "claudeCode": { "type": "string", "minLength": 1 },
1344
+ "terminal": { "type": "string", "minLength": 1 }
1345
+ }
1346
+ }
1347
+ }
1348
+ }
1349
+ },
1350
+
1351
+ "FollowUpRow": {
1352
+ "type": "object",
1353
+ "required": [
1354
+ "id",
1355
+ "ticketId",
1356
+ "origin",
1357
+ "newTaskId",
1358
+ "title",
1359
+ "suggestedTaskType",
1360
+ "scope",
1361
+ "reason",
1362
+ "priority",
1363
+ "autoSpawn"
1364
+ ],
1365
+ "additionalProperties": false,
1366
+ "properties": {
1367
+ "id": { "type": "string", "pattern": "^FU-\\d{3,}$" },
1368
+ "ticketId": { "$ref": "#/$defs/TicketId" },
1369
+ "origin": { "$ref": "#/$defs/FollowUpOrigin" },
1370
+ "newTaskId": { "type": "string", "minLength": 1 },
1371
+ "title": { "type": "string", "minLength": 1 },
1372
+ "suggestedTaskType": { "$ref": "#/$defs/TaskType" },
1373
+ "scope": { "type": "string", "minLength": 1 },
1374
+ "reason": { "type": "string", "minLength": 1 },
1375
+ "priority": { "$ref": "#/$defs/Priority" },
1376
+ "autoSpawn": { "enum": ["yes", "no"] }
1377
+ },
1378
+ "allOf": [
1379
+ {
1380
+ "description": "phase-continuation rows MUST have autoSpawn=no (advances via /okstra-run, no new dir).",
1381
+ "if": {
1382
+ "properties": { "origin": { "const": "phase-continuation" } }
1383
+ },
1384
+ "then": {
1385
+ "properties": { "autoSpawn": { "const": "no" } }
1386
+ }
1387
+ }
1388
+ ]
1389
+ }
1390
+ }
1391
+ }