@cleocode/contracts 2026.5.121 → 2026.5.122
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/__tests__/satisfies-atom.test.d.ts +24 -0
- package/dist/__tests__/satisfies-atom.test.d.ts.map +1 -0
- package/dist/__tests__/satisfies-atom.test.js +302 -0
- package/dist/__tests__/satisfies-atom.test.js.map +1 -0
- package/dist/__tests__/validator-types.test.d.ts +13 -0
- package/dist/__tests__/validator-types.test.d.ts.map +1 -0
- package/dist/__tests__/validator-types.test.js +293 -0
- package/dist/__tests__/validator-types.test.js.map +1 -0
- package/dist/config.d.ts +56 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/data-accessor.d.ts +117 -0
- package/dist/data-accessor.d.ts.map +1 -1
- package/dist/data-accessor.js.map +1 -1
- package/dist/evidence-atom-schema.d.ts +91 -0
- package/dist/evidence-atom-schema.d.ts.map +1 -1
- package/dist/evidence-atom-schema.js +162 -1
- package/dist/evidence-atom-schema.js.map +1 -1
- package/dist/exit-codes.d.ts +41 -1
- package/dist/exit-codes.d.ts.map +1 -1
- package/dist/exit-codes.js +40 -0
- package/dist/exit-codes.js.map +1 -1
- package/dist/index.d.ts +7 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -1
- package/dist/index.js.map +1 -1
- package/dist/operations/tasks.d.ts +49 -0
- package/dist/operations/tasks.d.ts.map +1 -1
- package/dist/operations/tasks.js.map +1 -1
- package/dist/task.d.ts +38 -0
- package/dist/task.d.ts.map +1 -1
- package/dist/validator/index.d.ts +375 -0
- package/dist/validator/index.d.ts.map +1 -0
- package/dist/validator/index.js +162 -0
- package/dist/validator/index.js.map +1 -0
- package/package.json +2 -2
- package/src/__tests__/satisfies-atom.test.ts +363 -0
- package/src/__tests__/validator-types.test.ts +359 -0
- package/src/config.ts +58 -0
- package/src/data-accessor.ts +120 -0
- package/src/evidence-atom-schema.ts +188 -1
- package/src/exit-codes.ts +42 -0
- package/src/index.ts +37 -0
- package/src/operations/tasks.ts +50 -0
- package/src/task.ts +39 -0
- package/src/validator/index.ts +385 -0
|
@@ -195,6 +195,117 @@ export const callsiteCoverageAtomSchema = z.object({
|
|
|
195
195
|
.min(1, 'callsite-coverage atom requires a non-empty relativeSourcePath'),
|
|
196
196
|
});
|
|
197
197
|
|
|
198
|
+
// ---------------------------------------------------------------------------
|
|
199
|
+
// ADR-079-r2: satisfies atom — cross-task AC binding
|
|
200
|
+
// ---------------------------------------------------------------------------
|
|
201
|
+
|
|
202
|
+
/**
|
|
203
|
+
* Strict UUIDv4 regex (lowercase, hyphenated 8-4-4-4-12 with the `4` major
|
|
204
|
+
* version nibble and `[89ab]` variant nibble) per ADR-079-r2 §2.1 ABNF
|
|
205
|
+
* (`ac-uuid` production) and RFC 9562 §5.4. Used by the `satisfies:` atom
|
|
206
|
+
* to validate the target-AC UUID form.
|
|
207
|
+
*
|
|
208
|
+
* Validators MUST reject mixed-case to prevent silent dedupe failures — the
|
|
209
|
+
* canonical column casing is lowercase per ADR-079-r1 §2.1.
|
|
210
|
+
*
|
|
211
|
+
* @task T10506
|
|
212
|
+
* @adr ADR-079-r2 §2.1
|
|
213
|
+
*/
|
|
214
|
+
export const AC_UUID_REGEX =
|
|
215
|
+
/^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/;
|
|
216
|
+
|
|
217
|
+
/**
|
|
218
|
+
* Positional-alias regex for `satisfies:` atom target-AC identifiers per
|
|
219
|
+
* ADR-079-r2 §2.1 ABNF (`ac-alias` production). Format: `AC<1-4 digits>`
|
|
220
|
+
* (capped at AC9999 — three orders of magnitude above realistic per-task AC
|
|
221
|
+
* counts).
|
|
222
|
+
*
|
|
223
|
+
* @task T10506
|
|
224
|
+
* @adr ADR-079-r2 §2.1
|
|
225
|
+
*/
|
|
226
|
+
export const AC_ALIAS_REGEX = /^AC[0-9]{1,4}$/;
|
|
227
|
+
|
|
228
|
+
/**
|
|
229
|
+
* Task-id regex for `satisfies:` atom target-task identifiers per ADR-079-r2
|
|
230
|
+
* §2.1 ABNF (`task-id` production). Format: `T<1-7 digits>` (capped at
|
|
231
|
+
* T9999999 — three orders of magnitude above current CLEO task IDs as of
|
|
232
|
+
* 2026-05-24).
|
|
233
|
+
*
|
|
234
|
+
* @task T10506
|
|
235
|
+
* @adr ADR-079-r2 §2.1
|
|
236
|
+
*/
|
|
237
|
+
export const SATISFIES_TASK_ID_REGEX = /^T[0-9]{1,7}$/;
|
|
238
|
+
|
|
239
|
+
/**
|
|
240
|
+
* Version-pin regex for `satisfies:` atom optional `@<ts>` suffix per
|
|
241
|
+
* ADR-079-r2 §2.1 ABNF (`version-pin` production). Format: `YYYYMMDDhhmmss`
|
|
242
|
+
* (ISO-8601-basic timestamp, 14 digits).
|
|
243
|
+
*
|
|
244
|
+
* @task T10506
|
|
245
|
+
* @adr ADR-079-r2 §2.1
|
|
246
|
+
*/
|
|
247
|
+
export const SATISFIES_VERSION_PIN_REGEX = /^[0-9]{14}$/;
|
|
248
|
+
|
|
249
|
+
/**
|
|
250
|
+
* `satisfies:<task-id>#<ac-id>[@<version-pin>]` atom — cross-task AC binding
|
|
251
|
+
* per ADR-079-r2 §2.1 (full grammar) and ADR-079-r1 §2.4 (basic shape).
|
|
252
|
+
*
|
|
253
|
+
* Format:
|
|
254
|
+
*
|
|
255
|
+
* - `satisfies:T1234#a1b2c3d4-5e6f-4890-abcd-ef1234567890` — canonical
|
|
256
|
+
* UUID form (preferred for long-lived specs).
|
|
257
|
+
* - `satisfies:T1234#AC2` — positional
|
|
258
|
+
* alias form (preferred in fresh PRs where the target task's AC list
|
|
259
|
+
* is stable).
|
|
260
|
+
* - `satisfies:T1234#AC2@20260524223045` — alias +
|
|
261
|
+
* optional version-pin (Validator emissions where pin-on-mint is
|
|
262
|
+
* required by ADR-079-r2 §3.4).
|
|
263
|
+
*
|
|
264
|
+
* Exactly ONE of `targetAcId` (UUID form) or `targetAcAlias` (alias form)
|
|
265
|
+
* is populated per parsed atom. `versionPin` is always optional.
|
|
266
|
+
*
|
|
267
|
+
* ## Scope
|
|
268
|
+
*
|
|
269
|
+
* This Zod schema covers PARSING ONLY. The runtime validator semantics —
|
|
270
|
+
* the 5-check accept/reject pipeline (target exists, target not terminal,
|
|
271
|
+
* AC exists, same-saga scope rule) — ship in T10507 alongside the
|
|
272
|
+
* `evidence_satisfies_bindings` side-effect table.
|
|
273
|
+
*
|
|
274
|
+
* Per ADR-079-r2 §2.2 the maximum atom length is 120 chars; the schema does
|
|
275
|
+
* NOT enforce length here because the per-field regexes already cap the
|
|
276
|
+
* surface (`satisfies:` + 8-char T+digits + `#` + 36-char UUID + `@` +
|
|
277
|
+
* 14-char pin = 78 chars max — well under 120).
|
|
278
|
+
*
|
|
279
|
+
* @task T10506
|
|
280
|
+
* @adr ADR-079-r2 §2.1
|
|
281
|
+
* @adr ADR-079-r1 §2.4
|
|
282
|
+
*/
|
|
283
|
+
export const satisfiesAtomSchema = z.object({
|
|
284
|
+
kind: z.literal('satisfies'),
|
|
285
|
+
/** Target task ID — `T<1-7 digits>` per ADR-079-r2 §2.1. */
|
|
286
|
+
targetTaskId: z
|
|
287
|
+
.string()
|
|
288
|
+
.regex(SATISFIES_TASK_ID_REGEX, 'satisfies atom targetTaskId must match /^T[0-9]{1,7}$/'),
|
|
289
|
+
/** Lowercase UUIDv4 — populated for the canonical form; undefined for alias form. */
|
|
290
|
+
targetAcId: z
|
|
291
|
+
.string()
|
|
292
|
+
.regex(AC_UUID_REGEX, 'satisfies atom targetAcId must be a lowercase UUIDv4')
|
|
293
|
+
.optional(),
|
|
294
|
+
/** Positional alias `AC<1-4 digits>` — populated for alias form; undefined for UUID form. */
|
|
295
|
+
targetAcAlias: z
|
|
296
|
+
.string()
|
|
297
|
+
.regex(AC_ALIAS_REGEX, 'satisfies atom targetAcAlias must match /^AC[0-9]{1,4}$/')
|
|
298
|
+
.optional(),
|
|
299
|
+
/** Optional `@<14-digit YYYYMMDDhhmmss>` pin captured at mint time. */
|
|
300
|
+
versionPin: z
|
|
301
|
+
.string()
|
|
302
|
+
.regex(
|
|
303
|
+
SATISFIES_VERSION_PIN_REGEX,
|
|
304
|
+
'satisfies atom versionPin must be 14 digits (YYYYMMDDhhmmss)',
|
|
305
|
+
)
|
|
306
|
+
.optional(),
|
|
307
|
+
});
|
|
308
|
+
|
|
198
309
|
// ---------------------------------------------------------------------------
|
|
199
310
|
// Discriminated union
|
|
200
311
|
// ---------------------------------------------------------------------------
|
|
@@ -218,6 +329,8 @@ export const callsiteCoverageAtomSchema = z.object({
|
|
|
218
329
|
* - `pr` — merged-PR retroactive proof (T9764 / T9838)
|
|
219
330
|
* - `loc-drop` — engine-migration LOC reduction (T1604)
|
|
220
331
|
* - `callsite-coverage` — exported-symbol production callsite (T1605)
|
|
332
|
+
* - `satisfies` — cross-task AC binding (T10506 / ADR-079-r2;
|
|
333
|
+
* validator semantics ship in T10507)
|
|
221
334
|
*
|
|
222
335
|
* @task T10337
|
|
223
336
|
* @adr ADR-051
|
|
@@ -233,6 +346,7 @@ export const EvidenceAtomSchema = z.discriminatedUnion('kind', [
|
|
|
233
346
|
prAtomSchema,
|
|
234
347
|
locDropAtomSchema,
|
|
235
348
|
callsiteCoverageAtomSchema,
|
|
349
|
+
satisfiesAtomSchema,
|
|
236
350
|
]);
|
|
237
351
|
|
|
238
352
|
/**
|
|
@@ -383,6 +497,7 @@ const ATOM_EXAMPLES: Readonly<Record<EvidenceAtomKind, string>> = Object.freeze(
|
|
|
383
497
|
pr: 'pr:357',
|
|
384
498
|
'loc-drop': 'loc-drop:<fromLines>:<toLines>',
|
|
385
499
|
'callsite-coverage': 'callsite-coverage:<symbolName>:<relativeSourcePath>',
|
|
500
|
+
satisfies: 'satisfies:T1234#AC2',
|
|
386
501
|
});
|
|
387
502
|
|
|
388
503
|
/**
|
|
@@ -718,6 +833,78 @@ export function parseEvidenceString(raw: string): EvidenceAtom[] {
|
|
|
718
833
|
atoms.push({ kind: 'callsite-coverage', symbolName, relativeSourcePath });
|
|
719
834
|
break;
|
|
720
835
|
}
|
|
836
|
+
case 'satisfies': {
|
|
837
|
+
// ADR-079-r2 §2.1 ABNF:
|
|
838
|
+
// satisfies-atom = "satisfies:" task-id "#" ac-id [ "@" version-pin ]
|
|
839
|
+
// Payload shape: <task-id>#<ac-id>[@<version-pin>]
|
|
840
|
+
//
|
|
841
|
+
// PARSING ONLY per T10506 — runtime validator semantics (5-check
|
|
842
|
+
// accept pipeline + same-saga scope rule) ship in T10507.
|
|
843
|
+
const hashIdx = payload.indexOf('#');
|
|
844
|
+
if (hashIdx < 1 || hashIdx === payload.length - 1) {
|
|
845
|
+
throw new EvidenceParseError(
|
|
846
|
+
`Malformed satisfies atom: "${chunk}" (expected satisfies:<task-id>#<ac-id>[@<version-pin>])`,
|
|
847
|
+
'Use format: satisfies:T1234#AC2 or satisfies:T1234#<uuid> e.g. satisfies:T10506#AC1',
|
|
848
|
+
);
|
|
849
|
+
}
|
|
850
|
+
const targetTaskId = payload.slice(0, hashIdx).trim();
|
|
851
|
+
const acAndPin = payload.slice(hashIdx + 1).trim();
|
|
852
|
+
|
|
853
|
+
// task-id must match strict ABNF /^T[0-9]{1,7}$/
|
|
854
|
+
if (!SATISFIES_TASK_ID_REGEX.test(targetTaskId)) {
|
|
855
|
+
throw new EvidenceParseError(
|
|
856
|
+
`satisfies atom targetTaskId "${targetTaskId}" must match /^T[0-9]{1,7}$/ in "${chunk}"`,
|
|
857
|
+
'Use format: satisfies:T<digits>#<ac-id> e.g. satisfies:T1234#AC2',
|
|
858
|
+
);
|
|
859
|
+
}
|
|
860
|
+
|
|
861
|
+
// Split optional version-pin (after `@`)
|
|
862
|
+
const atIdx = acAndPin.indexOf('@');
|
|
863
|
+
let acIdRaw: string;
|
|
864
|
+
let versionPin: string | undefined;
|
|
865
|
+
if (atIdx === -1) {
|
|
866
|
+
acIdRaw = acAndPin;
|
|
867
|
+
versionPin = undefined;
|
|
868
|
+
} else {
|
|
869
|
+
if (atIdx < 1 || atIdx === acAndPin.length - 1) {
|
|
870
|
+
throw new EvidenceParseError(
|
|
871
|
+
`Malformed satisfies atom version-pin in "${chunk}" (expected <ac-id>@<14-digit YYYYMMDDhhmmss>)`,
|
|
872
|
+
'Use format: satisfies:T1234#AC2@20260524223045',
|
|
873
|
+
);
|
|
874
|
+
}
|
|
875
|
+
acIdRaw = acAndPin.slice(0, atIdx).trim();
|
|
876
|
+
versionPin = acAndPin.slice(atIdx + 1).trim();
|
|
877
|
+
if (!SATISFIES_VERSION_PIN_REGEX.test(versionPin)) {
|
|
878
|
+
throw new EvidenceParseError(
|
|
879
|
+
`satisfies atom versionPin "${versionPin}" must be 14 digits (YYYYMMDDhhmmss) in "${chunk}"`,
|
|
880
|
+
'Use format: satisfies:T1234#AC2@<YYYYMMDDhhmmss> e.g. satisfies:T1234#AC2@20260524223045',
|
|
881
|
+
);
|
|
882
|
+
}
|
|
883
|
+
}
|
|
884
|
+
|
|
885
|
+
// ac-id is EITHER a strict UUIDv4 OR an AC<digits> alias — exactly one.
|
|
886
|
+
let targetAcId: string | undefined;
|
|
887
|
+
let targetAcAlias: string | undefined;
|
|
888
|
+
if (AC_UUID_REGEX.test(acIdRaw)) {
|
|
889
|
+
targetAcId = acIdRaw;
|
|
890
|
+
} else if (AC_ALIAS_REGEX.test(acIdRaw)) {
|
|
891
|
+
targetAcAlias = acIdRaw;
|
|
892
|
+
} else {
|
|
893
|
+
throw new EvidenceParseError(
|
|
894
|
+
`satisfies atom ac-id "${acIdRaw}" must be either a lowercase UUIDv4 or AC<1-4 digits> in "${chunk}"`,
|
|
895
|
+
'Use format: satisfies:T1234#AC2 (alias) or satisfies:T1234#<lowercase-uuidv4> (canonical)',
|
|
896
|
+
);
|
|
897
|
+
}
|
|
898
|
+
|
|
899
|
+
atoms.push({
|
|
900
|
+
kind: 'satisfies',
|
|
901
|
+
targetTaskId,
|
|
902
|
+
...(targetAcId !== undefined ? { targetAcId } : {}),
|
|
903
|
+
...(targetAcAlias !== undefined ? { targetAcAlias } : {}),
|
|
904
|
+
...(versionPin !== undefined ? { versionPin } : {}),
|
|
905
|
+
});
|
|
906
|
+
break;
|
|
907
|
+
}
|
|
721
908
|
case 'state': {
|
|
722
909
|
// T9838: explicit-form modifier for the preceding pr: atom.
|
|
723
910
|
// Format: pr:<num>;state:MERGED. The resolver always requires
|
|
@@ -743,7 +930,7 @@ export function parseEvidenceString(raw: string): EvidenceAtom[] {
|
|
|
743
930
|
default:
|
|
744
931
|
throw new EvidenceParseError(
|
|
745
932
|
`Unknown evidence kind: "${kind}" in atom "${chunk}"`,
|
|
746
|
-
'Valid kinds: commit, files, test-run, tool, url, note, loc-drop, callsite-coverage, decision, pr, state',
|
|
933
|
+
'Valid kinds: commit, files, test-run, tool, url, note, loc-drop, callsite-coverage, decision, pr, satisfies, state',
|
|
747
934
|
);
|
|
748
935
|
}
|
|
749
936
|
}
|
package/src/exit-codes.ts
CHANGED
|
@@ -224,6 +224,29 @@ export enum ExitCode {
|
|
|
224
224
|
* @task T9230
|
|
225
225
|
*/
|
|
226
226
|
LEAD_BYPASS_DETECTED = 107,
|
|
227
|
+
|
|
228
|
+
/**
|
|
229
|
+
* `cleo complete <tid>` was rejected because one or more acceptance criteria
|
|
230
|
+
* on the task have no `evidence_ac_bindings` rows pointing at them. The
|
|
231
|
+
* coverage gate is the load-bearing IVTR closure piece — every AC the task
|
|
232
|
+
* declared MUST be backed by a `direct`, `satisfies`, or `coverage` binding
|
|
233
|
+
* before completion is allowed.
|
|
234
|
+
*
|
|
235
|
+
* `error.details.unsatisfied` carries the list of offending ACs (each row
|
|
236
|
+
* has `acId`, `alias` (`AC<n>`), and `text`). Recovery options:
|
|
237
|
+
* 1. Add programmatic evidence that resolves the AC via `cleo verify` so
|
|
238
|
+
* a binding row is written.
|
|
239
|
+
* 2. Pass `--waive-ac "<csv>" --waive-reason "<text>"` on `cleo complete`
|
|
240
|
+
* to record an audited waiver (`.cleo/audit/ac-waiver.jsonl`).
|
|
241
|
+
* 3. Set `CLEO_OWNER_OVERRIDE=1` + `CLEO_OWNER_OVERRIDE_REASON=<text>` for
|
|
242
|
+
* a full bypass (logged to `.cleo/audit/force-bypass.jsonl`).
|
|
243
|
+
*
|
|
244
|
+
* @codeName E_AC_COVERAGE_INCOMPLETE
|
|
245
|
+
* @task T10509
|
|
246
|
+
* @saga T10377 (SG-IVTR-AC-BINDING)
|
|
247
|
+
* @adr ADR-079-r4
|
|
248
|
+
*/
|
|
249
|
+
AC_COVERAGE_INCOMPLETE = 108,
|
|
227
250
|
}
|
|
228
251
|
|
|
229
252
|
// ---------------------------------------------------------------------------
|
|
@@ -362,6 +385,25 @@ export const E_INVALID_SEVERITY_VALUE = 'E_INVALID_SEVERITY_VALUE' as const;
|
|
|
362
385
|
*/
|
|
363
386
|
export const E_INVALID_PIPELINE_STAGE = 'E_INVALID_PIPELINE_STAGE' as const;
|
|
364
387
|
|
|
388
|
+
/**
|
|
389
|
+
* E_AC_COVERAGE_INCOMPLETE — `cleo complete <tid>` was rejected because at
|
|
390
|
+
* least one acceptance criterion on the task has no `evidence_ac_bindings`
|
|
391
|
+
* row. The coverage gate is the load-bearing IVTR closure piece — every AC
|
|
392
|
+
* the task declared MUST be backed by a binding (`direct`, `satisfies`, or
|
|
393
|
+
* `coverage`) before completion is allowed.
|
|
394
|
+
*
|
|
395
|
+
* `error.details.unsatisfied` carries the offending ACs (each entry has
|
|
396
|
+
* `acId`, `alias`, and `text`). Recovery options live on the {@link ExitCode.AC_COVERAGE_INCOMPLETE}
|
|
397
|
+
* JSDoc.
|
|
398
|
+
*
|
|
399
|
+
* Maps to {@link ExitCode.AC_COVERAGE_INCOMPLETE} (108) at the CLI boundary.
|
|
400
|
+
*
|
|
401
|
+
* @task T10509
|
|
402
|
+
* @saga T10377 (SG-IVTR-AC-BINDING)
|
|
403
|
+
* @adr ADR-079-r4
|
|
404
|
+
*/
|
|
405
|
+
export const E_AC_COVERAGE_INCOMPLETE = 'E_AC_COVERAGE_INCOMPLETE' as const;
|
|
406
|
+
|
|
365
407
|
/** Check if an exit code represents an error (1-99). */
|
|
366
408
|
export function isErrorCode(code: ExitCode): boolean {
|
|
367
409
|
return code >= 1 && code < 100;
|
package/src/index.ts
CHANGED
|
@@ -257,6 +257,8 @@ export type {
|
|
|
257
257
|
DepsRequiredAt,
|
|
258
258
|
EnforcementProfile,
|
|
259
259
|
HierarchyConfig,
|
|
260
|
+
LeadRollupConfig,
|
|
261
|
+
LeadRollupMode,
|
|
260
262
|
LifecycleConfig,
|
|
261
263
|
LifecycleEnforcementMode,
|
|
262
264
|
LlmConfig,
|
|
@@ -288,6 +290,8 @@ export type {
|
|
|
288
290
|
export { parseClaudeCodeCredentials } from './credentials.js';
|
|
289
291
|
// === DataAccessor Interface ===
|
|
290
292
|
export type {
|
|
293
|
+
AcBindingRow,
|
|
294
|
+
AcRow,
|
|
291
295
|
ArchiveFields,
|
|
292
296
|
ArchiveFile,
|
|
293
297
|
DataAccessor,
|
|
@@ -480,6 +484,8 @@ export type {
|
|
|
480
484
|
GateEvidenceRequirement,
|
|
481
485
|
} from './evidence-atom-schema.js';
|
|
482
486
|
export {
|
|
487
|
+
AC_ALIAS_REGEX,
|
|
488
|
+
AC_UUID_REGEX,
|
|
483
489
|
callsiteCoverageAtomSchema,
|
|
484
490
|
commitAtomSchema,
|
|
485
491
|
decisionAtomSchema,
|
|
@@ -493,6 +499,9 @@ export {
|
|
|
493
499
|
noteAtomSchema,
|
|
494
500
|
parseEvidenceString,
|
|
495
501
|
prAtomSchema,
|
|
502
|
+
SATISFIES_TASK_ID_REGEX,
|
|
503
|
+
SATISFIES_VERSION_PIN_REGEX,
|
|
504
|
+
satisfiesAtomSchema,
|
|
496
505
|
testRunAtomSchema,
|
|
497
506
|
toolAtomSchema,
|
|
498
507
|
urlAtomSchema,
|
|
@@ -527,6 +536,8 @@ export {
|
|
|
527
536
|
} from './evidence-record-schema.js';
|
|
528
537
|
// === Exit Codes ===
|
|
529
538
|
export {
|
|
539
|
+
// T10509 / Saga T10377 — AC-coverage gate at cleo complete (IVTR closure)
|
|
540
|
+
E_AC_COVERAGE_INCOMPLETE,
|
|
530
541
|
// T10105 / Saga T10099 — fail-loud changeset parse
|
|
531
542
|
E_CHANGESET_YAML_INVALID,
|
|
532
543
|
// SPEC-T9345 release pipeline v2 error code names (T9525)
|
|
@@ -1275,6 +1286,7 @@ export type {
|
|
|
1275
1286
|
DepGraphIssue,
|
|
1276
1287
|
DepsTreeEdge,
|
|
1277
1288
|
DepsTreeNode,
|
|
1289
|
+
TaskShowAcRowEntry,
|
|
1278
1290
|
TaskShowAttachmentEntry,
|
|
1279
1291
|
TasksAddBatchEntry,
|
|
1280
1292
|
TasksAddBatchParams,
|
|
@@ -1994,6 +2006,31 @@ export type {
|
|
|
1994
2006
|
Transport,
|
|
1995
2007
|
TransportConnectConfig,
|
|
1996
2008
|
} from './transport.js';
|
|
2009
|
+
// === Validator Role Contracts (T10510 / Saga T10377 SG-IVTR-AC-BINDING) ===
|
|
2010
|
+
// Canonical AgentRole enum + per-AC ValidatorFinding + ValidatorAttestation /
|
|
2011
|
+
// ValidatorRejection envelopes + ValidatorVerdict discriminated union. Consumed
|
|
2012
|
+
// by SDK tools (T10511) and the Max-N runtime (T10512) under Epic T10383
|
|
2013
|
+
// E-VALIDATOR-ROLE.
|
|
2014
|
+
export type {
|
|
2015
|
+
AgentRole,
|
|
2016
|
+
ValidatorAttestation,
|
|
2017
|
+
ValidatorFinding,
|
|
2018
|
+
ValidatorFindingStatus,
|
|
2019
|
+
ValidatorRejection,
|
|
2020
|
+
ValidatorVerdict,
|
|
2021
|
+
} from './validator/index.js';
|
|
2022
|
+
export {
|
|
2023
|
+
AGENT_ROLES,
|
|
2024
|
+
isAgentRole,
|
|
2025
|
+
isValidatorAttestation,
|
|
2026
|
+
isValidatorRejection,
|
|
2027
|
+
isValidatorVerdict,
|
|
2028
|
+
VALIDATOR_ID_REGEX,
|
|
2029
|
+
validatorAttestationSchema,
|
|
2030
|
+
validatorFindingSchema,
|
|
2031
|
+
validatorRejectionSchema,
|
|
2032
|
+
validatorVerdictSchema,
|
|
2033
|
+
} from './validator/index.js';
|
|
1997
2034
|
// === WarpChain Types ===
|
|
1998
2035
|
export type {
|
|
1999
2036
|
ChainShape,
|
package/src/operations/tasks.ts
CHANGED
|
@@ -237,6 +237,38 @@ export interface TasksShowResult {
|
|
|
237
237
|
* @task T9966
|
|
238
238
|
*/
|
|
239
239
|
attachments: TaskShowAttachmentEntry[];
|
|
240
|
+
/**
|
|
241
|
+
* Acceptance-criterion rows hydrated from the `task_acceptance_criteria`
|
|
242
|
+
* table (T10502). Each entry carries the stable UUID `id`, the
|
|
243
|
+
* `AC<ordinal>` alias, the ordinal itself, and the canonical AC text.
|
|
244
|
+
*
|
|
245
|
+
* Optional — undefined when the task has no rows in the table (e.g.
|
|
246
|
+
* legacy tasks not yet backfilled by T10505). Consumers should fall
|
|
247
|
+
* back to `task.acceptance` (the legacy JSON string) in that case.
|
|
248
|
+
*
|
|
249
|
+
* @task T10508
|
|
250
|
+
* @epic T10381
|
|
251
|
+
*/
|
|
252
|
+
acRows?: TaskShowAcRowEntry[];
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
/**
|
|
256
|
+
* One acceptance-criterion entry in {@link TasksShowResult.acRows}.
|
|
257
|
+
*
|
|
258
|
+
* Mirrors the `AcDetail` shape from `@cleocode/core/tasks/show.js` but
|
|
259
|
+
* lives in contracts so dispatch-layer consumers don't depend on core.
|
|
260
|
+
*
|
|
261
|
+
* @task T10508
|
|
262
|
+
*/
|
|
263
|
+
export interface TaskShowAcRowEntry {
|
|
264
|
+
/** UUIDv4 stable identifier, immutable for the AC's lifetime. */
|
|
265
|
+
id: string;
|
|
266
|
+
/** Display alias derived from ordinal — `AC1`, `AC2`, etc. */
|
|
267
|
+
alias: string;
|
|
268
|
+
/** 1-based ordinal — never reused per task (gaps remain on shrink). */
|
|
269
|
+
ordinal: number;
|
|
270
|
+
/** The AC statement text. Structured gates round-trip as JSON. */
|
|
271
|
+
text: string;
|
|
240
272
|
}
|
|
241
273
|
|
|
242
274
|
// tasks.tree dispatch params (with optional withBlockers flag — dispatch alias)
|
|
@@ -926,6 +958,24 @@ export interface TasksCompleteQueryParams {
|
|
|
926
958
|
overrideReason?: string;
|
|
927
959
|
/** Reason for acknowledging CRITICAL nexus impact risk (bypasses nexusImpact gate). */
|
|
928
960
|
acknowledgeRisk?: string;
|
|
961
|
+
/**
|
|
962
|
+
* Comma-separated AC tokens (UUIDs or `AC<n>` aliases) waived from the
|
|
963
|
+
* AC-coverage gate (T10509). MUST be paired with {@link waiveReason} —
|
|
964
|
+
* the gate rejects the call when one is set without the other.
|
|
965
|
+
*
|
|
966
|
+
* Waivers are recorded to `.cleo/audit/ac-waiver.jsonl` per ADR-079-r4 §4.
|
|
967
|
+
*
|
|
968
|
+
* @task T10509
|
|
969
|
+
* @saga T10377 (SG-IVTR-AC-BINDING)
|
|
970
|
+
*/
|
|
971
|
+
waiveAc?: string;
|
|
972
|
+
/**
|
|
973
|
+
* Justification text for the {@link waiveAc} waiver. Mandatory whenever
|
|
974
|
+
* `waiveAc` is non-empty.
|
|
975
|
+
*
|
|
976
|
+
* @task T10509
|
|
977
|
+
*/
|
|
978
|
+
waiveReason?: string;
|
|
929
979
|
}
|
|
930
980
|
/**
|
|
931
981
|
* Result of `tasks.complete` — completion confirmation with unblocked tasks.
|
package/src/task.ts
CHANGED
|
@@ -306,6 +306,45 @@ export type EvidenceAtom =
|
|
|
306
306
|
successCount: number;
|
|
307
307
|
/** Total number of checks evaluated in the rollup. */
|
|
308
308
|
totalChecks: number;
|
|
309
|
+
}
|
|
310
|
+
| {
|
|
311
|
+
/**
|
|
312
|
+
* Satisfies atom — cross-task acceptance-criterion binding per
|
|
313
|
+
* ADR-079-r2.
|
|
314
|
+
*
|
|
315
|
+
* Carries the parsed form (one of `targetAcId` UUID or
|
|
316
|
+
* `targetAcAlias` `AC<digits>` will be populated; optional
|
|
317
|
+
* `versionPin` captures the target AC's `updated_at` at mint time)
|
|
318
|
+
* plus the validator-canonical `resolvedAcUuid` populated by the
|
|
319
|
+
* T10507 5-check pipeline (target exists, not terminal, AC exists,
|
|
320
|
+
* same-saga scope). T10506 only ships the parser — the validated
|
|
321
|
+
* form is reserved here so consumers of `EvidenceAtom` (sentinel
|
|
322
|
+
* tables, gate-checkers, audit logs) can pattern-match on
|
|
323
|
+
* `kind === 'satisfies'` from day one.
|
|
324
|
+
*
|
|
325
|
+
* Format: `satisfies:<task-id>#<ac-id>[@<version-pin>]`
|
|
326
|
+
* - `satisfies:T1234#a1b2c3d4-5e6f-4890-abcd-ef1234567890` (UUID)
|
|
327
|
+
* - `satisfies:T1234#AC2` (alias)
|
|
328
|
+
* - `satisfies:T1234#AC2@20260524223045` (pin)
|
|
329
|
+
*
|
|
330
|
+
* @task T10506
|
|
331
|
+
* @adr ADR-079-r2
|
|
332
|
+
*/
|
|
333
|
+
kind: 'satisfies';
|
|
334
|
+
/** Target task ID — `T<1-7 digits>` per ADR-079-r2 §2.1. */
|
|
335
|
+
targetTaskId: string;
|
|
336
|
+
/** Lowercase UUIDv4 — populated for canonical form; undefined for alias form. */
|
|
337
|
+
targetAcId?: string;
|
|
338
|
+
/** `AC<1-4 digits>` alias — populated for alias form; undefined for UUID form. */
|
|
339
|
+
targetAcAlias?: string;
|
|
340
|
+
/** Optional `@<YYYYMMDDhhmmss>` pin captured at mint time. */
|
|
341
|
+
versionPin?: string;
|
|
342
|
+
/**
|
|
343
|
+
* Canonical UUID resolved by the T10507 validator from `targetAcId`
|
|
344
|
+
* (already canonical) or by looking up `(targetTaskId, alias-ordinal)`.
|
|
345
|
+
* Reserved here for forward compatibility; undefined under T10506.
|
|
346
|
+
*/
|
|
347
|
+
resolvedAcUuid?: string;
|
|
309
348
|
};
|
|
310
349
|
|
|
311
350
|
/**
|