@cleocode/contracts 2026.9.25 → 2026.9.26

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.
@@ -118,7 +118,7 @@ const tasksShowOutputContract: OperationOutputContract = {
118
118
  updatedAt: {
119
119
  type: ['string', 'null'],
120
120
  description:
121
- 'Task version for optimistic concurrency: pass it to `cleo update|complete --if-match`.',
121
+ 'Task version for optimistic concurrency: pass it to `cleo update|complete --if-match`. A stale version fails with E_CONFLICT (23); E_TASK_RENAMED (26) when sync re-numbered the task you read (details.expected is its new id).',
122
122
  },
123
123
  // T12502: the human assignee and the agent claim lease are separate.
124
124
  assignee: {
@@ -1616,7 +1616,13 @@ export interface TasksUpdateQueryParams {
1616
1616
  /**
1617
1617
  * Optimistic-concurrency guard: the task `updatedAt` the caller read. When
1618
1618
  * the stored version differs, the update fails with `E_CONFLICT` and the
1619
- * current version, instead of overwriting a newer write. @task T12503
1619
+ * current version, instead of overwriting a newer write. When sync
1620
+ * re-numbered the task the caller read (a display-id collision) and the
1621
+ * version is exactly the one it had under this id, the update fails with
1622
+ * `E_TASK_RENAMED` (exit 26) instead, `details.expected` naming the task's
1623
+ * new id; nothing is written to the task that holds the id now.
1624
+ * @task T12503
1625
+ * @task T12800
1620
1626
  */
1621
1627
  expectedUpdatedAt?: string;
1622
1628
  }
@@ -1702,8 +1708,11 @@ export interface TasksCompleteQueryParams {
1702
1708
  /**
1703
1709
  * Optimistic-concurrency guard (`--if-match`): the task `updatedAt` the
1704
1710
  * caller read. When the stored version differs, completion fails with
1705
- * `E_CONFLICT` carrying the current version and the changed fields.
1711
+ * `E_CONFLICT` carrying the current version and the changed fields, or
1712
+ * with `E_TASK_RENAMED` (exit 26, `details.expected` = the new id) when
1713
+ * sync re-numbered the task the caller read.
1706
1714
  * @task T12503
1715
+ * @task T12800
1707
1716
  */
1708
1717
  expectedUpdatedAt?: string;
1709
1718
  }
package/src/task.ts CHANGED
@@ -160,6 +160,19 @@ export type VerificationGate =
160
160
  */
161
161
  | 'nexusImpact';
162
162
 
163
+ /**
164
+ * The part of a verified `pr:` atom that anchors `files:` bytes: its merge
165
+ * commit, when it merged, and what it changed (T12848).
166
+ */
167
+ export interface EvidenceMergeAnchor {
168
+ /** Merge commit SHA whose tree holds the PR's artifact bytes. */
169
+ mergeCommitSha: string;
170
+ /** ISO 8601 merge timestamp; the latest merge wins when several PRs changed a path. */
171
+ mergedAt: string;
172
+ /** Paths the PR changed. */
173
+ changedPaths?: readonly string[];
174
+ }
175
+
163
176
  /** Task and criterion scope used while validating evidence, independent of PR metadata. */
164
177
  export interface EvidenceValidationContext {
165
178
  /** Canonical current task intent; prose is never interpreted as a file declaration. */
@@ -168,8 +181,22 @@ export interface EvidenceValidationContext {
168
181
  gates: readonly VerificationGate[];
169
182
  /** Canonical criteria read for this verification operation. */
170
183
  criteria: ReadonlyArray<Pick<AcRow, 'id' | 'text' | 'updatedAt'>>;
171
- /** Verified PR merge whose immutable artifact bytes must be inspected. */
184
+ /**
185
+ * Verified PR merge whose immutable artifact bytes must be inspected.
186
+ *
187
+ * @deprecated Since T12848 no caller sets it: a single SHA cannot anchor a
188
+ * write with several `pr:` atoms. Use {@link EvidenceValidationContext.artifactPrs},
189
+ * which anchors each `files:` path at the merge of the PR that changed it.
190
+ * Still honoured when `artifactPrs` is absent.
191
+ */
172
192
  artifactCommitSha?: string;
193
+ /**
194
+ * Every verified PR in the evidence write (T12848). When non-empty, each
195
+ * `files:` path is inspected at the merge commit of the PR that changed it,
196
+ * so several `pr:` atoms in one write each anchor their own artifacts.
197
+ * Takes precedence over {@link EvidenceValidationContext.artifactCommitSha}.
198
+ */
199
+ artifactPrs?: ReadonlyArray<EvidenceMergeAnchor>;
173
200
  /**
174
201
  * Validate without persisting anything: `pr:`/`ci:` lookups write neither
175
202
  * the PR-result cache nor the branch-protection cache (T12671 review — the