@cleocode/contracts 2026.5.121 → 2026.5.123

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 (128) hide show
  1. package/dist/__tests__/completion-operation-contracts.test.d.ts +8 -0
  2. package/dist/__tests__/completion-operation-contracts.test.d.ts.map +1 -0
  3. package/dist/__tests__/completion-operation-contracts.test.js +114 -0
  4. package/dist/__tests__/completion-operation-contracts.test.js.map +1 -0
  5. package/dist/__tests__/operation-envelope-validation.test.d.ts +8 -0
  6. package/dist/__tests__/operation-envelope-validation.test.d.ts.map +1 -0
  7. package/dist/__tests__/operation-envelope-validation.test.js +105 -0
  8. package/dist/__tests__/operation-envelope-validation.test.js.map +1 -0
  9. package/dist/__tests__/satisfies-atom.test.d.ts +24 -0
  10. package/dist/__tests__/satisfies-atom.test.d.ts.map +1 -0
  11. package/dist/__tests__/satisfies-atom.test.js +320 -0
  12. package/dist/__tests__/satisfies-atom.test.js.map +1 -0
  13. package/dist/__tests__/validator-types.test.d.ts +13 -0
  14. package/dist/__tests__/validator-types.test.d.ts.map +1 -0
  15. package/dist/__tests__/validator-types.test.js +293 -0
  16. package/dist/__tests__/validator-types.test.js.map +1 -0
  17. package/dist/__tests__/workgraph-context-scaffold-contracts.test.d.ts +8 -0
  18. package/dist/__tests__/workgraph-context-scaffold-contracts.test.d.ts.map +1 -0
  19. package/dist/__tests__/workgraph-context-scaffold-contracts.test.js +188 -0
  20. package/dist/__tests__/workgraph-context-scaffold-contracts.test.js.map +1 -0
  21. package/dist/__tests__/workgraph-operation-contracts.test.d.ts +8 -0
  22. package/dist/__tests__/workgraph-operation-contracts.test.d.ts.map +1 -0
  23. package/dist/__tests__/workgraph-operation-contracts.test.js +115 -0
  24. package/dist/__tests__/workgraph-operation-contracts.test.js.map +1 -0
  25. package/dist/config.d.ts +56 -0
  26. package/dist/config.d.ts.map +1 -1
  27. package/dist/data-accessor.d.ts +194 -0
  28. package/dist/data-accessor.d.ts.map +1 -1
  29. package/dist/data-accessor.js.map +1 -1
  30. package/dist/dispatch/__tests__/docs-update-registry.test.d.ts +2 -0
  31. package/dist/dispatch/__tests__/docs-update-registry.test.d.ts.map +1 -0
  32. package/dist/dispatch/__tests__/docs-update-registry.test.js +27 -0
  33. package/dist/dispatch/__tests__/docs-update-registry.test.js.map +1 -0
  34. package/dist/dispatch/__tests__/operation-envelope-snapshots.test.d.ts +2 -0
  35. package/dist/dispatch/__tests__/operation-envelope-snapshots.test.d.ts.map +1 -0
  36. package/dist/dispatch/__tests__/operation-envelope-snapshots.test.js +265 -0
  37. package/dist/dispatch/__tests__/operation-envelope-snapshots.test.js.map +1 -0
  38. package/dist/dispatch/operations-registry.d.ts.map +1 -1
  39. package/dist/dispatch/operations-registry.js +487 -7
  40. package/dist/dispatch/operations-registry.js.map +1 -1
  41. package/dist/evidence-atom-schema.d.ts +91 -0
  42. package/dist/evidence-atom-schema.d.ts.map +1 -1
  43. package/dist/evidence-atom-schema.js +162 -1
  44. package/dist/evidence-atom-schema.js.map +1 -1
  45. package/dist/exit-codes.d.ts +41 -1
  46. package/dist/exit-codes.d.ts.map +1 -1
  47. package/dist/exit-codes.js +40 -0
  48. package/dist/exit-codes.js.map +1 -1
  49. package/dist/index.d.ts +17 -9
  50. package/dist/index.d.ts.map +1 -1
  51. package/dist/index.js +12 -1
  52. package/dist/index.js.map +1 -1
  53. package/dist/operation-envelope-validation.d.ts +79 -0
  54. package/dist/operation-envelope-validation.d.ts.map +1 -0
  55. package/dist/operation-envelope-validation.js +219 -0
  56. package/dist/operation-envelope-validation.js.map +1 -0
  57. package/dist/operations/__tests__/agent-operation-contract.test.d.ts +2 -0
  58. package/dist/operations/__tests__/agent-operation-contract.test.d.ts.map +1 -0
  59. package/dist/operations/__tests__/agent-operation-contract.test.js +128 -0
  60. package/dist/operations/__tests__/agent-operation-contract.test.js.map +1 -0
  61. package/dist/operations/__tests__/tasks-input-contracts.test.js +15 -0
  62. package/dist/operations/__tests__/tasks-input-contracts.test.js.map +1 -1
  63. package/dist/operations/agent-operation-contract.d.ts +227 -0
  64. package/dist/operations/agent-operation-contract.d.ts.map +1 -0
  65. package/dist/operations/agent-operation-contract.js +38 -0
  66. package/dist/operations/agent-operation-contract.js.map +1 -0
  67. package/dist/operations/docs.d.ts +19 -1
  68. package/dist/operations/docs.d.ts.map +1 -1
  69. package/dist/operations/docs.js +20 -0
  70. package/dist/operations/docs.js.map +1 -1
  71. package/dist/operations/focus.d.ts +1 -1
  72. package/dist/operations/index.d.ts +1 -0
  73. package/dist/operations/index.d.ts.map +1 -1
  74. package/dist/operations/index.js +1 -0
  75. package/dist/operations/index.js.map +1 -1
  76. package/dist/operations/orchestrate.d.ts +66 -0
  77. package/dist/operations/orchestrate.d.ts.map +1 -1
  78. package/dist/operations/tasks.d.ts +617 -11
  79. package/dist/operations/tasks.d.ts.map +1 -1
  80. package/dist/operations/tasks.js +22 -3
  81. package/dist/operations/tasks.js.map +1 -1
  82. package/dist/task-record.d.ts +15 -0
  83. package/dist/task-record.d.ts.map +1 -1
  84. package/dist/task.d.ts +52 -5
  85. package/dist/task.d.ts.map +1 -1
  86. package/dist/task.js.map +1 -1
  87. package/dist/tasks.d.ts +944 -0
  88. package/dist/tasks.d.ts.map +1 -1
  89. package/dist/tasks.js +198 -1
  90. package/dist/tasks.js.map +1 -1
  91. package/dist/validator/index.d.ts +375 -0
  92. package/dist/validator/index.d.ts.map +1 -0
  93. package/dist/validator/index.js +162 -0
  94. package/dist/validator/index.js.map +1 -0
  95. package/dist/workgraph.d.ts +1950 -0
  96. package/dist/workgraph.d.ts.map +1 -0
  97. package/dist/workgraph.js +449 -0
  98. package/dist/workgraph.js.map +1 -0
  99. package/package.json +10 -2
  100. package/src/__tests__/__snapshots__/operations-registry.test.ts.snap +1 -1
  101. package/src/__tests__/completion-operation-contracts.test.ts +154 -0
  102. package/src/__tests__/operation-envelope-validation.test.ts +140 -0
  103. package/src/__tests__/satisfies-atom.test.ts +383 -0
  104. package/src/__tests__/validator-types.test.ts +359 -0
  105. package/src/__tests__/workgraph-context-scaffold-contracts.test.ts +232 -0
  106. package/src/__tests__/workgraph-operation-contracts.test.ts +151 -0
  107. package/src/config.ts +58 -0
  108. package/src/data-accessor.ts +213 -0
  109. package/src/dispatch/__tests__/docs-update-registry.test.ts +35 -0
  110. package/src/dispatch/__tests__/operation-envelope-snapshots.test.ts +283 -0
  111. package/src/dispatch/operations-registry.ts +502 -7
  112. package/src/evidence-atom-schema.ts +188 -1
  113. package/src/exit-codes.ts +42 -0
  114. package/src/index.ts +230 -2
  115. package/src/operation-envelope-validation.ts +319 -0
  116. package/src/operations/__tests__/agent-operation-contract.test.ts +161 -0
  117. package/src/operations/__tests__/tasks-input-contracts.test.ts +30 -0
  118. package/src/operations/agent-operation-contract.ts +253 -0
  119. package/src/operations/docs.ts +27 -7
  120. package/src/operations/focus.ts +1 -1
  121. package/src/operations/index.ts +1 -0
  122. package/src/operations/orchestrate.ts +71 -0
  123. package/src/operations/tasks.ts +662 -15
  124. package/src/task-record.ts +16 -0
  125. package/src/task.ts +54 -5
  126. package/src/tasks.ts +558 -0
  127. package/src/validator/index.ts +385 -0
  128. package/src/workgraph.ts +1153 -0
@@ -0,0 +1,385 @@
1
+ /**
2
+ * Validator role contracts — types consumed by the SDK tools (T10511) and the
3
+ * Max-N runtime (T10512) to express the verdict a Validator agent returns
4
+ * after reviewing a Worker submission against a task's acceptance criteria.
5
+ *
6
+ * The Validator is a NEW canonical role in the orchestration hierarchy,
7
+ * orthogonal to the existing Orchestrator → Lead → Worker triad. A Validator
8
+ * does NOT execute work and does NOT spawn other agents — it ONLY attests or
9
+ * rejects work claimed-done by another agent, per-AC.
10
+ *
11
+ * Identity triad:
12
+ * - `agentId` follows the pattern `validator-<discriminator>` (e.g.
13
+ * `validator-prime`, `validator-sec-001`).
14
+ * - `role` is `'validator'` (see {@link AgentRole}).
15
+ * - `sigilCard` is reused as-is from the existing peer/memory layer when
16
+ * the Validator is registered as a CANT-defined persona.
17
+ *
18
+ * Design constraints (ADR-055 / D028 boundary rules):
19
+ * - Lives in `packages/contracts/` — ZERO runtime dependencies (Zod only).
20
+ * - Consumed by `packages/cleo-sdk-tools/` (T10511) and `packages/core/` (T10512).
21
+ * - No cross-package relative imports.
22
+ *
23
+ * @module validator
24
+ * @task T10510
25
+ * @epic T10383 (E-VALIDATOR-ROLE)
26
+ * @saga T10377 (SG-IVTR-AC-BINDING)
27
+ */
28
+
29
+ import { z } from 'zod';
30
+
31
+ // ============================================================================
32
+ // AgentRole — canonical role enum with Validator extension
33
+ // ============================================================================
34
+
35
+ /**
36
+ * Canonical agent role classification across the CLEO orchestration hierarchy.
37
+ *
38
+ * Mirrors the three-tier model in {@link PeerKind} / {@link AgentSpawnCapability}
39
+ * with an additional `validator` tier introduced by Saga T10377
40
+ * SG-IVTR-AC-BINDING:
41
+ *
42
+ * - `orchestrator` — coordinates multi-agent workflows; may spawn leads and workers
43
+ * - `lead` — specialist; dispatches workers only
44
+ * - `worker` — terminal executor; may not spawn
45
+ * - `validator` — terminal reviewer; attests or rejects another agent's
46
+ * work against the task's acceptance criteria. Does NOT
47
+ * execute work and does NOT spawn other agents.
48
+ *
49
+ * This type is ADDITIVE to the existing per-file role unions
50
+ * (`PeerKind` in `peer.ts`, `AgentSpawnCapability` in `agent-registry-v3.ts`,
51
+ * `CLEO_AGENT_ROLE` in `branch-lock.ts`, etc.). Existing unions are
52
+ * intentionally UNCHANGED — call sites that need the Validator role
53
+ * import {@link AgentRole} from this module.
54
+ *
55
+ * @task T10510
56
+ * @epic T10383
57
+ */
58
+ export type AgentRole = 'orchestrator' | 'lead' | 'worker' | 'validator';
59
+
60
+ /**
61
+ * Frozen list of canonical {@link AgentRole} values for runtime iteration
62
+ * (e.g. CLI flag validation, registry seeding).
63
+ *
64
+ * @task T10510
65
+ * @epic T10383
66
+ */
67
+ export const AGENT_ROLES = ['orchestrator', 'lead', 'worker', 'validator'] as const;
68
+
69
+ /**
70
+ * Type guard for {@link AgentRole}. Returns `true` when `value` is one of the
71
+ * four canonical role strings.
72
+ *
73
+ * @task T10510
74
+ */
75
+ export function isAgentRole(value: unknown): value is AgentRole {
76
+ return typeof value === 'string' && (AGENT_ROLES as readonly string[]).includes(value);
77
+ }
78
+
79
+ // ============================================================================
80
+ // ValidatorFinding — per-AC reasoning row
81
+ // ============================================================================
82
+
83
+ /**
84
+ * Status of a single Validator finding against one acceptance criterion.
85
+ *
86
+ * - `pass` — the AC is satisfied by the Worker's submission
87
+ * - `fail` — the AC is NOT satisfied; the Validator rejects this AC
88
+ * - `inconclusive` — the Validator cannot determine pass/fail from the
89
+ * evidence presented (e.g. missing artifact, ambiguous
90
+ * wording). A Verdict containing any `inconclusive`
91
+ * finding is treated as a {@link ValidatorRejection} —
92
+ * the Worker MUST clarify and re-submit.
93
+ *
94
+ * @task T10510
95
+ */
96
+ export type ValidatorFindingStatus = 'pass' | 'fail' | 'inconclusive';
97
+
98
+ /**
99
+ * Single Validator finding scoped to one acceptance criterion.
100
+ *
101
+ * Produced per-AC during validator review and aggregated into either a
102
+ * {@link ValidatorAttestation} (all pass) or {@link ValidatorRejection}
103
+ * (any fail or inconclusive). Each finding carries the AC's stable UUID
104
+ * (matching `task_acceptance_criteria.id` — see {@link AcRow}) so downstream
105
+ * persistence (T10503 / T10509 AC-bindings) can join findings to ACs
106
+ * without depending on ordinal position.
107
+ *
108
+ * @task T10510
109
+ * @epic T10383
110
+ */
111
+ export interface ValidatorFinding {
112
+ /**
113
+ * Stable AC identifier (UUIDv4) matching
114
+ * `task_acceptance_criteria.id`. See {@link AcRow.id}.
115
+ */
116
+ acId: string;
117
+ /** Pass / fail / inconclusive verdict for this AC. */
118
+ status: ValidatorFindingStatus;
119
+ /**
120
+ * Free-text reasoning explaining the verdict. Required for `fail` and
121
+ * `inconclusive`; recommended (but optional via the runtime guard) for
122
+ * `pass` so reviewers can audit the chain-of-thought later.
123
+ */
124
+ reasoning: string;
125
+ /**
126
+ * Optional evidence references that backed this finding — e.g. test
127
+ * file paths, commit shas, doc URLs. Free-form strings; the schema
128
+ * intentionally does NOT validate format here so the SDK tools layer
129
+ * (T10511) can shape its own evidence-atom narrowing.
130
+ */
131
+ evidenceRefs?: string[];
132
+ /** ISO-8601 timestamp at which this finding was recorded. */
133
+ checkedAt: string;
134
+ }
135
+
136
+ // ============================================================================
137
+ // ValidatorAttestation — accept verdict envelope
138
+ // ============================================================================
139
+
140
+ /**
141
+ * Envelope returned by a Validator when the Worker's submission passes
142
+ * EVERY acceptance criterion on the task.
143
+ *
144
+ * Discriminated by `verdict: 'attest'`. When at least one finding has
145
+ * status `'fail'` or `'inconclusive'`, the Validator MUST emit a
146
+ * {@link ValidatorRejection} instead — never a partial-pass attestation.
147
+ *
148
+ * @task T10510
149
+ * @epic T10383
150
+ */
151
+ export interface ValidatorAttestation {
152
+ /** Discriminant — always `'attest'`. */
153
+ verdict: 'attest';
154
+ /** Task being attested. Matches `tasks.id`. */
155
+ taskId: string;
156
+ /**
157
+ * Stable Validator agent identifier following the pattern
158
+ * `validator-<discriminator>` (e.g. `validator-prime`).
159
+ */
160
+ validatorId: string;
161
+ /**
162
+ * Per-AC findings. MUST contain one entry per AC on the task; EVERY
163
+ * entry MUST have `status: 'pass'`. The runtime validator
164
+ * ({@link isValidatorAttestation}) enforces this invariant.
165
+ */
166
+ findings: ValidatorFinding[];
167
+ /**
168
+ * Optional summary paragraph the Validator may include to capture
169
+ * holistic observations (e.g. "all 5 ACs pass; the implementation
170
+ * also tightened the error message in foo.ts which I checked").
171
+ */
172
+ summary?: string;
173
+ /** ISO-8601 timestamp at which the verdict was finalized. */
174
+ attestedAt: string;
175
+ /**
176
+ * Schema version for forward-compatible evolution. Pin to `'1'` for
177
+ * the initial T10510 contract.
178
+ */
179
+ schemaVersion: '1';
180
+ }
181
+
182
+ // ============================================================================
183
+ // ValidatorRejection — refuse verdict envelope
184
+ // ============================================================================
185
+
186
+ /**
187
+ * Envelope returned by a Validator when at least one acceptance criterion
188
+ * fails or is inconclusive.
189
+ *
190
+ * Discriminated by `verdict: 'reject'`. The `findings` array MUST contain
191
+ * AT LEAST ONE entry with status `'fail'` or `'inconclusive'`; otherwise
192
+ * the Validator should have emitted a {@link ValidatorAttestation}.
193
+ *
194
+ * @task T10510
195
+ * @epic T10383
196
+ */
197
+ export interface ValidatorRejection {
198
+ /** Discriminant — always `'reject'`. */
199
+ verdict: 'reject';
200
+ /** Task being rejected. Matches `tasks.id`. */
201
+ taskId: string;
202
+ /**
203
+ * Stable Validator agent identifier following the pattern
204
+ * `validator-<discriminator>` (e.g. `validator-prime`).
205
+ */
206
+ validatorId: string;
207
+ /**
208
+ * Per-AC findings. MUST contain one entry per AC on the task; AT
209
+ * LEAST ONE entry MUST have `status: 'fail'` or `'inconclusive'`.
210
+ */
211
+ findings: ValidatorFinding[];
212
+ /**
213
+ * Required summary paragraph describing the high-level reason for
214
+ * rejection. Distinct from per-AC `reasoning` — this is the
215
+ * human-facing message shown when the Worker is told to revise.
216
+ */
217
+ summary: string;
218
+ /**
219
+ * Suggested remediation steps. Free-form list of strings — the SDK
220
+ * tools layer (T10511) is responsible for any structured shape.
221
+ */
222
+ remediationHints?: string[];
223
+ /** ISO-8601 timestamp at which the verdict was finalized. */
224
+ rejectedAt: string;
225
+ /**
226
+ * Schema version for forward-compatible evolution. Pin to `'1'` for
227
+ * the initial T10510 contract.
228
+ */
229
+ schemaVersion: '1';
230
+ }
231
+
232
+ // ============================================================================
233
+ // ValidatorVerdict — discriminated union
234
+ // ============================================================================
235
+
236
+ /**
237
+ * Discriminated union over the two Validator outcomes. Narrow via the
238
+ * `verdict` discriminant:
239
+ *
240
+ * ```ts
241
+ * function handle(v: ValidatorVerdict) {
242
+ * if (v.verdict === 'attest') {
243
+ * // v is ValidatorAttestation — every finding passes
244
+ * } else {
245
+ * // v is ValidatorRejection — summary + remediationHints available
246
+ * }
247
+ * }
248
+ * ```
249
+ *
250
+ * @task T10510
251
+ * @epic T10383
252
+ */
253
+ export type ValidatorVerdict = ValidatorAttestation | ValidatorRejection;
254
+
255
+ // ============================================================================
256
+ // Zod schemas — runtime validation
257
+ // ============================================================================
258
+
259
+ /**
260
+ * Regex validating the canonical Validator agentId pattern
261
+ * `validator-<discriminator>`. The discriminator is `[a-z0-9][a-z0-9-]*`
262
+ * (lowercase alphanumeric + hyphens, must start with alphanum).
263
+ *
264
+ * Examples that MATCH: `validator-prime`, `validator-sec-001`, `validator-a`.
265
+ * Examples that DO NOT match: `validator-`, `Validator-prime`, `validator--x`.
266
+ *
267
+ * @task T10510
268
+ */
269
+ export const VALIDATOR_ID_REGEX = /^validator-[a-z0-9][a-z0-9-]*$/;
270
+
271
+ /**
272
+ * Zod schema for {@link ValidatorFinding}. Enforces the AC-id presence,
273
+ * status enum, non-empty reasoning, and ISO-8601 timestamp shape.
274
+ *
275
+ * @task T10510
276
+ */
277
+ export const validatorFindingSchema = z.object({
278
+ acId: z.string().min(1, 'acId must be non-empty'),
279
+ status: z.enum(['pass', 'fail', 'inconclusive']),
280
+ reasoning: z.string().min(1, 'reasoning must be non-empty'),
281
+ evidenceRefs: z.array(z.string()).optional(),
282
+ checkedAt: z.string().min(1, 'checkedAt must be a non-empty ISO-8601 string'),
283
+ });
284
+
285
+ /**
286
+ * Zod schema for {@link ValidatorAttestation}. Enforces:
287
+ * - `verdict === 'attest'`
288
+ * - `validatorId` matches {@link VALIDATOR_ID_REGEX}
289
+ * - `findings` non-empty AND every entry has `status === 'pass'`
290
+ * - `schemaVersion === '1'`
291
+ *
292
+ * @task T10510
293
+ */
294
+ export const validatorAttestationSchema = z.object({
295
+ verdict: z.literal('attest'),
296
+ taskId: z.string().min(1),
297
+ validatorId: z
298
+ .string()
299
+ .regex(VALIDATOR_ID_REGEX, 'validatorId must match the pattern validator-<discriminator>'),
300
+ findings: z
301
+ .array(validatorFindingSchema)
302
+ .min(1, 'attestation must contain at least one finding')
303
+ .refine(
304
+ (findings) => findings.every((f) => f.status === 'pass'),
305
+ 'attestation requires every finding to have status="pass"',
306
+ ),
307
+ summary: z.string().optional(),
308
+ attestedAt: z.string().min(1),
309
+ schemaVersion: z.literal('1'),
310
+ });
311
+
312
+ /**
313
+ * Zod schema for {@link ValidatorRejection}. Enforces:
314
+ * - `verdict === 'reject'`
315
+ * - `validatorId` matches {@link VALIDATOR_ID_REGEX}
316
+ * - `findings` non-empty AND at least one entry has `status !== 'pass'`
317
+ * - `summary` non-empty (rejection rationale is mandatory)
318
+ * - `schemaVersion === '1'`
319
+ *
320
+ * @task T10510
321
+ */
322
+ export const validatorRejectionSchema = z.object({
323
+ verdict: z.literal('reject'),
324
+ taskId: z.string().min(1),
325
+ validatorId: z
326
+ .string()
327
+ .regex(VALIDATOR_ID_REGEX, 'validatorId must match the pattern validator-<discriminator>'),
328
+ findings: z
329
+ .array(validatorFindingSchema)
330
+ .min(1, 'rejection must contain at least one finding')
331
+ .refine(
332
+ (findings) => findings.some((f) => f.status !== 'pass'),
333
+ 'rejection requires at least one finding with status "fail" or "inconclusive"',
334
+ ),
335
+ summary: z.string().min(1, 'rejection summary must be non-empty'),
336
+ remediationHints: z.array(z.string()).optional(),
337
+ rejectedAt: z.string().min(1),
338
+ schemaVersion: z.literal('1'),
339
+ });
340
+
341
+ /**
342
+ * Zod schema for the {@link ValidatorVerdict} discriminated union.
343
+ * Routes parsing through the `verdict` discriminant.
344
+ *
345
+ * @task T10510
346
+ */
347
+ export const validatorVerdictSchema = z.discriminatedUnion('verdict', [
348
+ validatorAttestationSchema,
349
+ validatorRejectionSchema,
350
+ ]);
351
+
352
+ // ============================================================================
353
+ // Type guards
354
+ // ============================================================================
355
+
356
+ /**
357
+ * Type guard validating that `value` conforms to {@link ValidatorAttestation}.
358
+ * Internally uses {@link validatorAttestationSchema}.
359
+ *
360
+ * @task T10510
361
+ */
362
+ export function isValidatorAttestation(value: unknown): value is ValidatorAttestation {
363
+ return validatorAttestationSchema.safeParse(value).success;
364
+ }
365
+
366
+ /**
367
+ * Type guard validating that `value` conforms to {@link ValidatorRejection}.
368
+ * Internally uses {@link validatorRejectionSchema}.
369
+ *
370
+ * @task T10510
371
+ */
372
+ export function isValidatorRejection(value: unknown): value is ValidatorRejection {
373
+ return validatorRejectionSchema.safeParse(value).success;
374
+ }
375
+
376
+ /**
377
+ * Type guard validating that `value` conforms to {@link ValidatorVerdict}
378
+ * (either an attestation or a rejection). Internally uses
379
+ * {@link validatorVerdictSchema}.
380
+ *
381
+ * @task T10510
382
+ */
383
+ export function isValidatorVerdict(value: unknown): value is ValidatorVerdict {
384
+ return validatorVerdictSchema.safeParse(value).success;
385
+ }