jg-agent-hq 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,10 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.2.0
4
+
5
+ - Preserve coordinator-owned, revision-bound plan comparison evidence through plan operations. Expose its bounded count in status without copying review bodies into responses.
6
+ - Require the comparison collection in the coordination contract. The private coordinator owns semantic review, relevance selection and execution gates.
7
+
3
8
  ## 0.1.0
4
9
 
5
10
  - Add the shared lock API, owner-aware recovery and built-package verification.
package/README.md CHANGED
@@ -59,6 +59,8 @@ Use `jg-agent-hq request --state-root <directory>` with a closed HQ command on s
59
59
 
60
60
  Finalization assigns milestone UUIDs and returns the complete canonical sequence. Plan approval, sequence approval and scoped execution authorization are separate explicit operator actions. None sends native input or answers tool permissions. `coordination.json` holds current records beside the plan. SQLite retains write replay identities and a replaceable, paged milestone projection. Keep both when recovering interrupted writes. A pending write blocks further mutation until its original action is reconciled.
61
61
 
62
+ Coordinators can retain revision-bound compatibility reviews in that same file. Core operations preserve the records without assessing them or granting authority. The integrating coordinator owns review freshness and conflict gates.
63
+
62
64
  Begin a revision before native planning. HQ stops bound implementation threads and their owned background work, captures partial-work evidence, and keeps execution paused while the CLI revises the plan and regenerates milestones. The finalizer carries exact matches automatically and asks for one confirmation covering every unmatched completed or partial milestone. Equivalent rewording preserves the original completion evidence. Changed requirements remain pending. Present and approve the canonical sequence, then explicitly authorize the new execution scope and mode. Neither approval nor restart resumes implementation. See the [revision recovery contract](api/README.md#revision-and-progress-recovery).
63
65
 
64
66
  ## Cross-provider feedback
package/api/README.md CHANGED
@@ -192,6 +192,8 @@ Plan and milestone artifacts are bounded to 1 MiB each; coordination evidence is
192
192
 
193
193
  Mutations hold the shared metadata lock at `<coordinationRoot>/.runtime/hq.lock` (`coordinationRoot` defaults to `stateRoot`), retain a durable action identity and intended write before changing files, sync temporary files and atomically replace each artifact. Use `serve --coordination-root <directory>` when the canonical coordination lock is separate from runtime storage. Repeating an action UUID with the identical payload never reapproves revoked work. A changed payload conflicts. An interrupted write remains blocked and can be retried with its original action only when files match the recorded baseline or exact intended output. Conflicting edits are preserved. Completed write bodies are removed from SQLite while replay identity remains. The current finalization receipt retains the operator event, execution revision, canonical file hash and timestamp independently of write recovery bodies. Status reads expose `pendingActionId` for unresolved writes; they never approve or resume work.
194
194
 
195
+ `coordination.json` includes required `comparisons`, an array bounded to 1,024 records validated by `PlanComparisonSchema`. Each record binds `sourceRevision`, `targetDirectory`, `targetRevision`, a `compatible` or `contradiction` verdict, `reason`, `reviewedAt` and reviewer provenance (`provider`, `cliVersion`, nullable observed `model`, and native message `reference`). A trusted coordinator writes these records while holding the same metadata lock. Core operations preserve them; status exposes only `comparisonCount`. They never change execution digests or grant authority. The coordinator owns relevance, freshness, semantic judgments, bounded review reads and any execution gate, including contradictions. The standalone core does not assess compatibility.
196
+
195
197
  The installed `plan-status` and `plan-milestones` commands accept `--state-root` and `--directory`; the latter also accepts `--limit` and `--cursor`. Use `request` for the closed JSON mutation commands. The result is a tagged `status`, `milestones`, `reconciliation`, `reconciliation-required`, `finalized` or `execution-check` object within the outer `plan` response. A retried finalization returns current status when its finalized artifact no longer exists or has changed.
196
198
 
197
199
  ### Revision and progress recovery
@@ -2,16 +2,16 @@ import { z } from 'zod';
2
2
  export declare const ActionCommandSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
3
3
  kind: z.ZodLiteral<"thread-create">;
4
4
  provider: z.ZodEnum<{
5
- codex: "codex";
6
5
  claude: "claude";
6
+ codex: "codex";
7
7
  }>;
8
8
  workspaceRoot: z.ZodString;
9
9
  name: z.ZodString;
10
10
  }, z.core.$strict>, z.ZodObject<{
11
11
  kind: z.ZodLiteral<"thread-adopt">;
12
12
  provider: z.ZodEnum<{
13
- codex: "codex";
14
13
  claude: "claude";
14
+ codex: "codex";
15
15
  }>;
16
16
  workspaceRoot: z.ZodString;
17
17
  nativeId: z.ZodString;
@@ -158,16 +158,16 @@ export declare const ActionEnvelopeSchema: z.ZodObject<{
158
158
  command: z.ZodDiscriminatedUnion<[z.ZodObject<{
159
159
  kind: z.ZodLiteral<"thread-create">;
160
160
  provider: z.ZodEnum<{
161
- codex: "codex";
162
161
  claude: "claude";
162
+ codex: "codex";
163
163
  }>;
164
164
  workspaceRoot: z.ZodString;
165
165
  name: z.ZodString;
166
166
  }, z.core.$strict>, z.ZodObject<{
167
167
  kind: z.ZodLiteral<"thread-adopt">;
168
168
  provider: z.ZodEnum<{
169
- codex: "codex";
170
169
  claude: "claude";
170
+ codex: "codex";
171
171
  }>;
172
172
  workspaceRoot: z.ZodString;
173
173
  nativeId: z.ZodString;
@@ -455,8 +455,8 @@ export type IActionSummary = z.infer<typeof ActionSummarySchema>;
455
455
  export declare const ManagedThreadSchema: z.ZodObject<{
456
456
  id: z.ZodUUID;
457
457
  provider: z.ZodEnum<{
458
- codex: "codex";
459
458
  claude: "claude";
459
+ codex: "codex";
460
460
  }>;
461
461
  nativeId: z.ZodNullable<z.ZodString>;
462
462
  name: z.ZodString;
@@ -2,8 +2,8 @@ import { z } from 'zod';
2
2
  export declare const HandoffSourceSchema: z.ZodObject<{
3
3
  threadId: z.ZodUUID;
4
4
  provider: z.ZodEnum<{
5
- codex: "codex";
6
5
  claude: "claude";
6
+ codex: "codex";
7
7
  }>;
8
8
  nativeId: z.ZodString;
9
9
  workspaceRoot: z.ZodString;
@@ -116,8 +116,8 @@ export declare const HandoffSummarySchema: z.ZodObject<{
116
116
  source: z.ZodObject<{
117
117
  threadId: z.ZodUUID;
118
118
  provider: z.ZodEnum<{
119
- codex: "codex";
120
119
  claude: "claude";
120
+ codex: "codex";
121
121
  }>;
122
122
  nativeId: z.ZodString;
123
123
  workspaceRoot: z.ZodString;
@@ -150,8 +150,8 @@ export declare const HandoffSummarySchema: z.ZodObject<{
150
150
  targetThreadId: z.ZodNullable<z.ZodUUID>;
151
151
  targetNativeId: z.ZodNullable<z.ZodString>;
152
152
  targetProvider: z.ZodEnum<{
153
- codex: "codex";
154
153
  claude: "claude";
154
+ codex: "codex";
155
155
  }>;
156
156
  creation: z.ZodObject<{
157
157
  actionId: z.ZodNullable<z.ZodUUID>;
@@ -219,8 +219,8 @@ export declare const HandoffSchema: z.ZodObject<{
219
219
  source: z.ZodObject<{
220
220
  threadId: z.ZodUUID;
221
221
  provider: z.ZodEnum<{
222
- codex: "codex";
223
222
  claude: "claude";
223
+ codex: "codex";
224
224
  }>;
225
225
  nativeId: z.ZodString;
226
226
  workspaceRoot: z.ZodString;
@@ -253,8 +253,8 @@ export declare const HandoffSchema: z.ZodObject<{
253
253
  targetThreadId: z.ZodNullable<z.ZodUUID>;
254
254
  targetNativeId: z.ZodNullable<z.ZodString>;
255
255
  targetProvider: z.ZodEnum<{
256
- codex: "codex";
257
256
  claude: "claude";
257
+ codex: "codex";
258
258
  }>;
259
259
  creation: z.ZodObject<{
260
260
  actionId: z.ZodNullable<z.ZodUUID>;
@@ -353,8 +353,8 @@ export declare const HandoffResultSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
353
353
  source: z.ZodObject<{
354
354
  threadId: z.ZodUUID;
355
355
  provider: z.ZodEnum<{
356
- codex: "codex";
357
356
  claude: "claude";
357
+ codex: "codex";
358
358
  }>;
359
359
  nativeId: z.ZodString;
360
360
  workspaceRoot: z.ZodString;
@@ -387,8 +387,8 @@ export declare const HandoffResultSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
387
387
  targetThreadId: z.ZodNullable<z.ZodUUID>;
388
388
  targetNativeId: z.ZodNullable<z.ZodString>;
389
389
  targetProvider: z.ZodEnum<{
390
- codex: "codex";
391
390
  claude: "claude";
391
+ codex: "codex";
392
392
  }>;
393
393
  creation: z.ZodObject<{
394
394
  actionId: z.ZodNullable<z.ZodUUID>;
@@ -486,8 +486,8 @@ export declare const HandoffResultSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
486
486
  source: z.ZodObject<{
487
487
  threadId: z.ZodUUID;
488
488
  provider: z.ZodEnum<{
489
- codex: "codex";
490
489
  claude: "claude";
490
+ codex: "codex";
491
491
  }>;
492
492
  nativeId: z.ZodString;
493
493
  workspaceRoot: z.ZodString;
@@ -520,8 +520,8 @@ export declare const HandoffResultSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
520
520
  targetThreadId: z.ZodNullable<z.ZodUUID>;
521
521
  targetNativeId: z.ZodNullable<z.ZodString>;
522
522
  targetProvider: z.ZodEnum<{
523
- codex: "codex";
524
523
  claude: "claude";
524
+ codex: "codex";
525
525
  }>;
526
526
  creation: z.ZodObject<{
527
527
  actionId: z.ZodNullable<z.ZodUUID>;
@@ -5,8 +5,8 @@ export { ActionCommandSchema, ActionEnvelopeSchema, ActionReceiptSchema, ActionS
5
5
  export type { IActionCommand, IActionEnvelope, IActionReceipt, IActionSummary, IManagedThread, INativeApproval, ILifecycleEvent, } from './actions/index.js';
6
6
  export { SkillIdSchema, NativeSkillInputSchema, SkillSchema, SkillPageSchema, SkillPreviewSchema, MessageInputSchema, } from './skills/index.js';
7
7
  export type { INativeSkillInput, ISkill, ISkillPage, ISkillPreview, IMessageInput, } from './skills/index.js';
8
- export { PlanDigestSchema, PlanRevisionSchema, PlanMetadataSchema, PlanTargetSchema, PlanOperatorActionSchema, PlanCommandSchema, PlanApprovalSchema, PlanExecutionSchema, PlanFinalizationSchema, PlanCoordinationSchema, PlanMilestoneSchema, PlanStatusSchema, PlanResultSchema, } from './plans/index.js';
9
- export type { IPlanRevision, IPlanMetadata, IPlanTarget, IPlanOperatorAction, IPlanCommand, IPlanCommandInput, IPlanCoordination, IPlanMilestone, IPlanStatus, IPlanResult, } from './plans/index.js';
8
+ export { PlanDigestSchema, PlanRevisionSchema, PlanMetadataSchema, PlanTargetSchema, PlanOperatorActionSchema, PlanCommandSchema, PlanApprovalSchema, PlanExecutionSchema, PlanFinalizationSchema, PlanComparisonSchema, PlanCoordinationSchema, PlanMilestoneSchema, PlanStatusSchema, PlanResultSchema, } from './plans/index.js';
9
+ export type { IPlanRevision, IPlanMetadata, IPlanTarget, IPlanOperatorAction, IPlanCommand, IPlanCommandInput, IPlanCoordination, IPlanComparison, IPlanMilestone, IPlanStatus, IPlanResult, } from './plans/index.js';
10
10
  export { PlanCheckSchema, PlanCheckoutSchema, PlanWorktreeProofSchema, PlanCompletionSchema, PlanSnapshotMilestoneSchema, PlanCorrespondenceSchema, PlanDraftMilestoneSchema, PlanProposalSchema, PlanRevisionWorkflowSchema, PlanCorrespondenceRecordSchema, PlanCoordinationSummarySchema, } from './plans/index.js';
11
11
  export type { IPlanCheckout, IPlanWorktreeProof, IPlanCompletion, IPlanSnapshotMilestone, IPlanCorrespondence, IPlanDraftMilestone, IPlanProposal, IPlanRevisionWorkflow, IPlanCorrespondenceRecord, } from './plans/index.js';
12
12
  export { PlanCheckpointSchema } from './plans/index.js';
@@ -7,7 +7,7 @@ export { ActionCommandSchema, ActionEnvelopeSchema, ActionReceiptSchema, ActionS
7
7
  // native skills and explicit message input
8
8
  export { SkillIdSchema, NativeSkillInputSchema, SkillSchema, SkillPageSchema, SkillPreviewSchema, MessageInputSchema, } from './skills/index.js';
9
9
  // plan revisions and explicit authority
10
- export { PlanDigestSchema, PlanRevisionSchema, PlanMetadataSchema, PlanTargetSchema, PlanOperatorActionSchema, PlanCommandSchema, PlanApprovalSchema, PlanExecutionSchema, PlanFinalizationSchema, PlanCoordinationSchema, PlanMilestoneSchema, PlanStatusSchema, PlanResultSchema, } from './plans/index.js';
10
+ export { PlanDigestSchema, PlanRevisionSchema, PlanMetadataSchema, PlanTargetSchema, PlanOperatorActionSchema, PlanCommandSchema, PlanApprovalSchema, PlanExecutionSchema, PlanFinalizationSchema, PlanComparisonSchema, PlanCoordinationSchema, PlanMilestoneSchema, PlanStatusSchema, PlanResultSchema, } from './plans/index.js';
11
11
  // revision checkpoints and retained verification
12
12
  export { PlanCheckSchema, PlanCheckoutSchema, PlanWorktreeProofSchema, PlanCompletionSchema, PlanSnapshotMilestoneSchema, PlanCorrespondenceSchema, PlanDraftMilestoneSchema, PlanProposalSchema, PlanRevisionWorkflowSchema, PlanCorrespondenceRecordSchema, PlanCoordinationSummarySchema, } from './plans/index.js';
13
13
  // saved revision baseline
@@ -1,5 +1,5 @@
1
- export { PlanDigestSchema, PlanRevisionSchema, PlanMetadataSchema, PlanTargetSchema, PlanOperatorActionSchema, PlanCommandSchema, PlanApprovalSchema, PlanExecutionSchema, PlanFinalizationSchema, PlanCoordinationSchema, PlanMilestoneSchema, PlanStatusSchema, PlanResultSchema, } from './types.js';
2
- export type { IPlanRevision, IPlanMetadata, IPlanTarget, IPlanOperatorAction, IPlanCommand, IPlanCommandInput, IPlanCoordination, IPlanMilestone, IPlanStatus, IPlanResult, } from './types.js';
1
+ export { PlanDigestSchema, PlanRevisionSchema, PlanMetadataSchema, PlanTargetSchema, PlanOperatorActionSchema, PlanCommandSchema, PlanApprovalSchema, PlanExecutionSchema, PlanFinalizationSchema, PlanComparisonSchema, PlanCoordinationSchema, PlanMilestoneSchema, PlanStatusSchema, PlanResultSchema, } from './types.js';
2
+ export type { IPlanRevision, IPlanMetadata, IPlanTarget, IPlanOperatorAction, IPlanCommand, IPlanCommandInput, IPlanCoordination, IPlanComparison, IPlanMilestone, IPlanStatus, IPlanResult, } from './types.js';
3
3
  export { PlanCheckSchema, PlanCheckoutSchema, PlanWorktreeProofSchema, PlanCompletionSchema, PlanSnapshotMilestoneSchema, PlanCorrespondenceSchema, PlanDraftMilestoneSchema, PlanProposalSchema, PlanRevisionWorkflowSchema, PlanCorrespondenceRecordSchema, PlanCoordinationSummarySchema, } from './types.js';
4
4
  export type { IPlanCheckout, IPlanWorktreeProof, IPlanCompletion, IPlanSnapshotMilestone, IPlanCorrespondence, IPlanDraftMilestone, IPlanProposal, IPlanRevisionWorkflow, IPlanCorrespondenceRecord, } from './types.js';
5
5
  export { PlanCheckpointSchema } from './types.js';
@@ -1,5 +1,5 @@
1
1
  // revision, provenance and plan contracts
2
- export { PlanDigestSchema, PlanRevisionSchema, PlanMetadataSchema, PlanTargetSchema, PlanOperatorActionSchema, PlanCommandSchema, PlanApprovalSchema, PlanExecutionSchema, PlanFinalizationSchema, PlanCoordinationSchema, PlanMilestoneSchema, PlanStatusSchema, PlanResultSchema, } from './types.js';
2
+ export { PlanDigestSchema, PlanRevisionSchema, PlanMetadataSchema, PlanTargetSchema, PlanOperatorActionSchema, PlanCommandSchema, PlanApprovalSchema, PlanExecutionSchema, PlanFinalizationSchema, PlanComparisonSchema, PlanCoordinationSchema, PlanMilestoneSchema, PlanStatusSchema, PlanResultSchema, } from './types.js';
3
3
  // revision checkpoints and retained verification
4
4
  export { PlanCheckSchema, PlanCheckoutSchema, PlanWorktreeProofSchema, PlanCompletionSchema, PlanSnapshotMilestoneSchema, PlanCorrespondenceSchema, PlanDraftMilestoneSchema, PlanProposalSchema, PlanRevisionWorkflowSchema, PlanCorrespondenceRecordSchema, PlanCoordinationSummarySchema, } from './types.js';
5
5
  // saved revision baseline
@@ -760,8 +760,61 @@ export declare const PlanFinalizationSchema: z.ZodObject<{
760
760
  fileHash: z.ZodString;
761
761
  createdAt: z.ZodNumber;
762
762
  }, z.core.$strict>;
763
+ export declare const PlanComparisonSchema: z.ZodObject<{
764
+ sourceRevision: z.ZodObject<{
765
+ planDigest: z.ZodString;
766
+ breakdownDigest: z.ZodNullable<z.ZodString>;
767
+ }, z.core.$strict>;
768
+ targetDirectory: z.ZodString;
769
+ targetRevision: z.ZodObject<{
770
+ planDigest: z.ZodString;
771
+ breakdownDigest: z.ZodNullable<z.ZodString>;
772
+ }, z.core.$strict>;
773
+ verdict: z.ZodEnum<{
774
+ compatible: "compatible";
775
+ contradiction: "contradiction";
776
+ }>;
777
+ reason: z.ZodString;
778
+ reviewer: z.ZodObject<{
779
+ provider: z.ZodEnum<{
780
+ claude: "claude";
781
+ codex: "codex";
782
+ }>;
783
+ cliVersion: z.ZodString;
784
+ model: z.ZodNullable<z.ZodString>;
785
+ reference: z.ZodString;
786
+ }, z.core.$strict>;
787
+ reviewedAt: z.ZodNumber;
788
+ }, z.core.$strict>;
789
+ export type IPlanComparison = z.infer<typeof PlanComparisonSchema>;
763
790
  export declare const PlanCoordinationSchema: z.ZodObject<{
764
791
  schemaVersion: z.ZodLiteral<1>;
792
+ comparisons: z.ZodArray<z.ZodObject<{
793
+ sourceRevision: z.ZodObject<{
794
+ planDigest: z.ZodString;
795
+ breakdownDigest: z.ZodNullable<z.ZodString>;
796
+ }, z.core.$strict>;
797
+ targetDirectory: z.ZodString;
798
+ targetRevision: z.ZodObject<{
799
+ planDigest: z.ZodString;
800
+ breakdownDigest: z.ZodNullable<z.ZodString>;
801
+ }, z.core.$strict>;
802
+ verdict: z.ZodEnum<{
803
+ compatible: "compatible";
804
+ contradiction: "contradiction";
805
+ }>;
806
+ reason: z.ZodString;
807
+ reviewer: z.ZodObject<{
808
+ provider: z.ZodEnum<{
809
+ claude: "claude";
810
+ codex: "codex";
811
+ }>;
812
+ cliVersion: z.ZodString;
813
+ model: z.ZodNullable<z.ZodString>;
814
+ reference: z.ZodString;
815
+ }, z.core.$strict>;
816
+ reviewedAt: z.ZodNumber;
817
+ }, z.core.$strict>>;
765
818
  finalized: z.ZodNullable<z.ZodObject<{
766
819
  action: z.ZodObject<{
767
820
  id: z.ZodUUID;
@@ -1299,6 +1352,7 @@ export declare const PlanCoordinationSummarySchema: z.ZodObject<{
1299
1352
  closeActionId: z.ZodUUID;
1300
1353
  }, z.core.$strict>>;
1301
1354
  }, z.core.$strict>>;
1355
+ comparisonCount: z.ZodNumber;
1302
1356
  completionCount: z.ZodNumber;
1303
1357
  revision: z.ZodNullable<z.ZodObject<{
1304
1358
  createdAt: z.ZodNumber;
@@ -1515,6 +1569,7 @@ export declare const PlanStatusSchema: z.ZodObject<{
1515
1569
  closeActionId: z.ZodUUID;
1516
1570
  }, z.core.$strict>>;
1517
1571
  }, z.core.$strict>>;
1572
+ comparisonCount: z.ZodNumber;
1518
1573
  completionCount: z.ZodNumber;
1519
1574
  revision: z.ZodNullable<z.ZodObject<{
1520
1575
  createdAt: z.ZodNumber;
@@ -1899,6 +1954,7 @@ export declare const PlanResultSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
1899
1954
  closeActionId: z.ZodUUID;
1900
1955
  }, z.core.$strict>>;
1901
1956
  }, z.core.$strict>>;
1957
+ comparisonCount: z.ZodNumber;
1902
1958
  completionCount: z.ZodNumber;
1903
1959
  revision: z.ZodNullable<z.ZodObject<{
1904
1960
  createdAt: z.ZodNumber;
@@ -2118,6 +2174,7 @@ export declare const PlanResultSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
2118
2174
  closeActionId: z.ZodUUID;
2119
2175
  }, z.core.$strict>>;
2120
2176
  }, z.core.$strict>>;
2177
+ comparisonCount: z.ZodNumber;
2121
2178
  completionCount: z.ZodNumber;
2122
2179
  revision: z.ZodNullable<z.ZodObject<{
2123
2180
  createdAt: z.ZodNumber;
@@ -2461,6 +2518,7 @@ export declare const PlanResultSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
2461
2518
  closeActionId: z.ZodUUID;
2462
2519
  }, z.core.$strict>>;
2463
2520
  }, z.core.$strict>>;
2521
+ comparisonCount: z.ZodNumber;
2464
2522
  completionCount: z.ZodNumber;
2465
2523
  revision: z.ZodNullable<z.ZodObject<{
2466
2524
  createdAt: z.ZodNumber;
@@ -270,8 +270,24 @@ export const PlanFinalizationSchema = z.strictObject({
270
270
  fileHash: PlanDigestSchema,
271
271
  createdAt: z.number().int(),
272
272
  });
273
+ // coordinators own semantic review; the core preserves its exact revision-bound evidence
274
+ export const PlanComparisonSchema = z.strictObject({
275
+ sourceRevision: PlanRevisionSchema,
276
+ targetDirectory: z.string().min(1).max(4096),
277
+ targetRevision: PlanRevisionSchema,
278
+ verdict: z.enum(['compatible', 'contradiction']),
279
+ reason: z.string().min(1).max(4096),
280
+ reviewer: z.strictObject({
281
+ provider: z.enum(['claude', 'codex']),
282
+ cliVersion: z.string().min(1).max(128),
283
+ model: z.string().min(1).max(256).nullable(),
284
+ reference: z.string().min(1).max(4096),
285
+ }),
286
+ reviewedAt: z.number().int().nonnegative(),
287
+ });
273
288
  export const PlanCoordinationSchema = z.strictObject({
274
289
  schemaVersion: z.literal(1),
290
+ comparisons: z.array(PlanComparisonSchema).max(1024),
275
291
  finalized: PlanFinalizationSchema.nullable(),
276
292
  planApproval: PlanApprovalSchema.nullable(),
277
293
  sequenceApproval: PlanApprovalSchema.nullable(),
@@ -294,11 +310,13 @@ export const PlanCoordinationSchema = z.strictObject({
294
310
  });
295
311
  // collection bodies remain in the file owner and paged SQLite projections
296
312
  export const PlanCoordinationSummarySchema = PlanCoordinationSchema.omit({
313
+ comparisons: true,
297
314
  completions: true,
298
315
  correspondences: true,
299
316
  revision: true,
300
317
  baseline: true,
301
318
  }).extend({
319
+ comparisonCount: z.number().int().nonnegative(),
302
320
  completionCount: z.number().int().nonnegative(),
303
321
  revision: PlanRevisionWorkflowSchema.omit({
304
322
  checkpoint: true,