jg-agent-hq 0.2.0 → 0.3.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,11 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.3.0
4
+
5
+ - Publish the consumer-tested package through the configured GitHub Actions trusted publisher before deploying the website. Verify release ordering and archive integrity, and safely skip identical published versions.
6
+ - Support whole-plan approval, execution, completion and revision when no milestone breakdown is needed. Preserve an absent milestone file and require explicit reconciliation when removing a sequence.
7
+ - Keep native thread execution scope on ordinary follow-ups, enforcing revocation and the single implementation owner for whole-plan execution. Preserve explicitly requested, revision-guarded feedback assessment without restoring execution authority. Keep existing-turn permission replies and session renaming separate from new execution admission.
8
+
3
9
  ## 0.2.0
4
10
 
5
11
  - Preserve coordinator-owned, revision-bound plan comparison evidence through plan operations. Expose its bounded count in status without copying review bodies into responses.
package/README.md CHANGED
@@ -21,7 +21,7 @@ This public package provides a local controller and browser-safe contracts. Appl
21
21
 
22
22
  Use pnpm 12.4.0. Run `pnpm install`, then `pnpm check:package` to build, exercise the built API and packed consumer, typecheck and check formatting. `pnpm test:unit` and `pnpm test:integration` select their own categories after a build. The private website workspace has separate checks; install Chromium with `pnpm --dir website exec playwright install chromium`, then run `pnpm --dir website check`. `pnpm check` runs both boundaries.
23
23
 
24
- Work on `development`; reviewed changes reach `main` through a pull request. npm releases are manual and use the exact tested tarball.
24
+ Work on `development`; reviewed changes reach `main` through a pull request. After both Node checks pass on `main`, `check.yml` publishes the exact consumer-tested tarball through npm's configured trusted publisher, then deploys the website. No local npm login or token is needed. An identical published version is skipped; changed contents require a new version.
25
25
 
26
26
  ## Lock ownership
27
27
 
@@ -57,11 +57,11 @@ Use `jg-agent-hq request --state-root <directory>` with a closed HQ command on s
57
57
 
58
58
  `plan-status --directory <path>` and `plan-milestones --directory <path>` inspect a selected ordinary planning directory. No project registry is required. Mutations use the existing `request` JSON command with `kind: 'plan'`; see the [plan command reference](api/README.md#plan-coordination).
59
59
 
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.
60
+ Finalization assigns milestone UUIDs and returns the complete canonical sequence when a breakdown exists. A plan without a breakdown remains one unit: finalization returns null content, plan approval suffices, and whole-plan execution uses an empty milestone selection with a null milestone ID. No milestone file is created merely to make a small plan executable. 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
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
63
 
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).
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. Whole-plan checkpoints and completion evidence also work without a milestone file. Removing a sequence requires explicit confirmation covering its retained milestone evidence before whole-plan execution can begin. See the [revision recovery contract](api/README.md#revision-and-progress-recovery).
65
65
 
66
66
  ## Cross-provider feedback
67
67
 
@@ -87,6 +87,7 @@ Collect one completed reviewer message by its exact native turn/item reference.
87
87
  - `src/store/`: SQLite discovery metadata and the action/control ledger in one worker.
88
88
  - `src/contracts/`: browser-safe command and response contracts.
89
89
  - `scripts/package/`: build-output cleanup and packed-consumer checks.
90
+ - `scripts/release/`: registry version/integrity checks and trusted publication of the tested archive.
90
91
  - `scripts/test-support/`: disposable external CLI fixtures.
91
92
  - `vitest/`: separate unit and integration selection.
92
93
  - `api/README.md`: canonical public API reference.
package/api/README.md CHANGED
@@ -179,18 +179,20 @@ Send `{ kind: 'plan', command }` through the existing local request API. Every c
179
179
  | `reconciliation` | `target`, `collection: 'sources' \| 'drafts' \| 'evidence' \| 'correspondences'`, optional `limit` (32/128) and `cursor`. Returns retained evidence by indexed seek page. |
180
180
  | `approve` | `target`, `action`, `expected`, `scope: 'plan' \| 'sequence'`, `presentationHash`. The hash must match the exact presented plan or finalized sequence. Sequence approval also requires current plan approval. |
181
181
  | `revoke` | `target`, `action`, `expected`, `scope: 'plan' \| 'sequence' \| 'execution' \| 'all'`. Revoking a plan also revokes sequence and execution authority; revoking a sequence also revokes execution authority. |
182
- | `authorize` | `target`, `action`, `expected`, `mode: 'supervised' \| 'auto'`, selected unique `milestoneIds`. Records permission for this exact execution scope without starting an agent. |
183
- | `check-execution` | `target`, `expected`, `authorizationId`, `milestoneId`, `mode`. Rejects missing, revoked, stale, wrong-mode or out-of-scope authority. It sends no native input. |
182
+ | `authorize` | `target`, `action`, `expected`, `mode: 'supervised' \| 'auto'`, selected unique `milestoneIds` (empty only for a plan without a breakdown). Records permission for this exact execution scope without starting an agent. |
183
+ | `check-execution` | `target`, `expected`, `authorizationId`, nullable `milestoneId`, `mode`. Rejects missing, revoked, stale, wrong-mode or out-of-scope authority. It sends no native input. |
184
184
 
185
185
  `expected` is the exact `{ planDigest, breakdownDigest }` returned by inspection. Each mutating `action` has a UUID `id`, `operatorId` and `source: { kind: 'user-action' | 'user-message', reference }`. These are trusted local operator inputs. The module never infers approval from natural-language claims, an agent response or imported feedback. Its owner-only local IPC and files do not isolate hostile code executing as the same OS user. Native permissions remain separate action kinds with their own exact native request identities.
186
186
 
187
+ Milestones are optional. Finalizing a plan with no milestone file returns `content: null` and does not create a file. That unit needs plan approval and explicit execution authorization, with `milestoneIds: []`; execution checks, completion and native execution scopes select it with `milestoneId: null`. A real breakdown requires a nonempty selection of its stable IDs and its separate sequence approval. Null cannot select a milestone or bypass sequence approval. Whole-plan completion retains its exact plan contract/digest, actual check references and checkout evidence, with null shared-sequence digest. Completed work cannot be authorized again under that unchanged contract.
188
+
187
189
  A first-use sequence has one `**Milestone ID:** <uuid>` immediately below each `**Status:**` line. Blank lines may separate the heading from its status; no intervening requirement prose is allowed. The initial finalizer rejects duplicate, malformed or misplaced IDs and inconsistent framing. It refreshes existing Overview status rows and returns the complete canonical file for presentation before approval. A changed finalized contract goes through checkpoint reconciliation. A raw or changed sequence cannot inherit finalized status or sequence authority. A done marker remains visible but blocks execution without completion evidence.
188
190
 
189
191
  The milestone contract includes its stable UUID, title without its ordinal, all requirement prose, shared sequence requirements and the approval statement. Status and identity marker lines are excluded from the prose; only the derived Overview table is excluded from shared text. Prose next to that table remains contractual. Sequence order is significant. Renumbering preserves execution identity; changed requirements, dependencies, scope, reservations or order require applicable approval. Full-file hashes preserve exact UTF-8 bytes and are distinct from normalized execution revisions. Administrative frontmatter excluded by the trusted contract parser, session labels, status advancement and coordination receipts do not change execution digests.
190
192
 
191
193
  Plan and milestone artifacts are bounded to 1 MiB each; coordination evidence is bounded to 8 MiB and a sequence to 1,024 milestones. Reads do not scan planning trees. Milestone pages use ordinal seek ordering with unique ascending ordinals. Cursors bind the selected directory, page size, execution revisions and exact milestone inspection hash. Any changed artifact requires a fresh page; renumbering or status-only edits still preserve approval. A SQLite projection is rebuilt only when the selected milestone file's full hash changes. Every read verifies its source file; the projection is replaceable and never grants authority.
192
194
 
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.
195
+ 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, nullable canonical file hash and timestamp independently of write recovery bodies. Status reads expose `pendingActionId` for unresolved writes; they never approve or resume work.
194
196
 
195
197
  `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
198
 
@@ -202,11 +204,13 @@ Begin revision before invoking a planning skill. Execution admission closes unde
202
204
 
203
205
  The local host supplies checkout evidence as `{ repository, directory, claimReference, paths }`. Paths are exact relative task paths. The core streams their contents, records link targets without following them, includes missing paths as deletions, and captures the current Git branch/HEAD. It does not stage or reset files and rejects traversal, parent-link escapes, `.git` and excluded archive/backup directories. Check commands and references are trusted operator evidence; this primitive does not execute arbitrary submitted commands or treat an imported agent claim as verification.
204
206
 
205
- After native `jg-plan` removes milestones and native `jg-breakdown` regenerates them, close the planning controller before finalization. Only unique exact normalized title and complete-contract matches retain identity automatically. Every unmatched checkpoint source, including done and partial work, appears in one saved proposal. Confirmation decisions use `sourceIds`, `targetIds`, `relation` (`equivalent`, `requirements-changed`, `omitted`, `reopened`) and explicit one-to-one `retainedPairs`. One source ID cannot be assigned to multiple targets. Grouped decisions retain split/merged evidence. A complete equivalent mapping preserves verified completion or partial status; rewording does not create new checks. A changed requirement gets fresh pending identity. Explicit reopening preserves evidence while invalidating its completion credit. Unverified done markers cannot become verified through an equivalent mapping.
207
+ After native `jg-plan` revises the contract and an explicitly requested `jg-breakdown` regenerates a needed sequence, close the planning controller before finalization. Only unique exact normalized title and complete-contract matches retain identity automatically. Every unmatched checkpoint source, including done and partial work, appears in one saved proposal. Confirmation decisions use `sourceIds`, `targetIds`, `relation` (`equivalent`, `requirements-changed`, `omitted`, `reopened`) and explicit one-to-one `retainedPairs`. One source ID cannot be assigned to multiple targets. Grouped decisions retain split/merged evidence. A complete equivalent mapping preserves verified completion or partial status; rewording does not create new checks. A changed requirement gets fresh pending identity. Explicit reopening preserves evidence while invalidating its completion credit. Unverified done markers cannot become verified through an equivalent mapping.
208
+
209
+ A whole-plan checkpoint retains null milestones and an empty milestone inventory. If a revision removes a sequence because the remaining scope no longer needs one, every unmatched checkpoint milestone still requires explicit omission confirmation. Its verified evidence remains available; absence alone never resets progress or authorizes whole-plan execution.
206
210
 
207
211
  The proposal and assigned identities are persisted before the canonical file is replaced. Retry the same action and payload after a partial write; do not regenerate UUIDs or confirm a different proposal. Present the complete canonical output before sequence approval. Applicable plan and sequence approvals are required again after digest changes. Approval does not resume work: send a fresh `authorize` with the intended mode and scope. Execution authority is also bound to the current runtime epoch.
208
212
 
209
- Guided native input adds `plan: { kind: 'execution', authorizationId, milestoneId, mode, revision }` or `{ kind: 'planning', revisionId, invocationId }` to its action envelope. The controller binds this context atomically to the managed thread. Planning starts with the exact authorized native skill. A live thread cannot switch scopes; close it before an explicit resume under a different scope. Queued input retains its original scope and cannot run under stale approval or during revision. Ordinary input on a bound thread remains subject to its current gate. Native permissions are still separate exact-request replies.
213
+ Guided native input adds `plan: { kind: 'execution', authorizationId, milestoneId, mode, revision }` or `{ kind: 'planning', revisionId, invocationId }` to its action envelope. The controller binds this context atomically to the managed thread. Planning starts with the exact authorized native skill. A live thread cannot switch scopes; close it before an explicit resume under a different scope. Queued input retains its original scope and cannot run under stale approval or during revision. Ordinary input on a bound thread retains that exact scope and remains subject to its current gate, including after revocation or completion. It cannot silently become unscoped input. Renaming and explicit replies to an existing native permission/question remain separate, revision-guarded controls; neither starts a new implementation turn or restores execution authority. Native permissions still require the exact pending request.
210
214
 
211
215
  Selected status/admission/queue observations detect external contract edits or milestone deletion, persist a closed gate and request exact bound-thread interruption. These observations grant no operator authority and report uncertain in-flight effects. The finalized baseline retains identities and completion evidence for explicit reconciliation of direct CLI edits. Invalid artifacts fail explicitly. No directory scan or filesystem watcher is used. Status projects Revising, approval/breakdown requirements, Ready, In progress, Completed and Blocked independently of provider process state.
212
216
 
@@ -246,7 +250,7 @@ Creation may still be pending when its response arrives. Read `show` until its c
246
250
 
247
251
  Collection reads exactly the requested native page through the provider adapter and accepts only one non-truncated agent message from the handoff's completed reviewer turn. Finding bodies are limited to 8 KiB UTF-8, never silently shortened. To select a later page, use the same `limit`, turn filter and preceding cursor as the native items read. A different message or changed body cannot overwrite collected findings. Full histories remain with the native CLIs. Persisted reviewer references retain the exact native session, turn and item identities.
248
252
 
249
- Feedback resolves installed `jg-feedback` in the author thread and carries the selected findings with exact source, reviewer, item, revision and commit references. Source contract or selected Git HEAD changes invalidate an unsent preview. The action's optional `expectedPlan` guards the author's captured revision under the existing plan lock; explicit `null` requires an unbound thread. This guard applies only to `message` and `queue`, grants no execution scope, and cannot answer tool permissions. Known native identities cannot be reassigned; existing control admission preserves the exact author for queued feedback. Existing revision gates pause stale queued feedback. Neither handoff delivery nor a completed assessment turn means recommendations were accepted or implementation was authorized.
253
+ Feedback resolves installed `jg-feedback` in the author thread and carries the selected findings with exact source, reviewer, item, revision and commit references. Source contract or selected Git HEAD changes invalidate an unsent preview. The action's optional `expectedPlan` guards the author's captured revision under the existing plan lock; explicit `null` requires an unbound thread. This guard applies only to `message` and `queue`, grants no execution scope, and cannot answer tool permissions. An explicitly selected native `jg-feedback` skill with a matching `expectedPlan` uses a neutral revision guard, so assessment remains available after execution is revoked or completed. It preserves the thread's existing implementation binding; ordinary input still requires valid execution authority. Queued assessment keeps that same revision guard at automatic or explicit dispatch. Known native identities cannot be reassigned; existing control admission preserves the exact author for queued feedback. Existing revision gates pause stale queued feedback. Neither handoff delivery nor a completed assessment turn means recommendations were accepted or implementation was authorized.
250
254
 
251
255
  Delivery is `prepared`, `queued`, `submitted`, `delivered`, `uncertain`, `failed` or `canceled`; native `completion` is separately null, `completed`, `failed` or `interrupted`. Acknowledgement alone becomes `delivered`. Busy destinations use native next-turn queues, including while waiting for permissions; feedback is never written as a permission answer. Pending native permissions remain explicit actions on their own channels. No automatic feedback, response loop, approval or publication follows collection.
252
256
 
@@ -112,7 +112,7 @@ export type IActionCommand = z.infer<typeof ActionCommandSchema>;
112
112
  export declare const PlanActionScopeSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
113
113
  kind: z.ZodLiteral<"execution">;
114
114
  authorizationId: z.ZodUUID;
115
- milestoneId: z.ZodUUID;
115
+ milestoneId: z.ZodNullable<z.ZodUUID>;
116
116
  mode: z.ZodEnum<{
117
117
  supervised: "supervised";
118
118
  auto: "auto";
@@ -132,7 +132,7 @@ export declare const ActionPlanContextSchema: z.ZodObject<{
132
132
  scope: z.ZodNullable<z.ZodDiscriminatedUnion<[z.ZodObject<{
133
133
  kind: z.ZodLiteral<"execution">;
134
134
  authorizationId: z.ZodUUID;
135
- milestoneId: z.ZodUUID;
135
+ milestoneId: z.ZodNullable<z.ZodUUID>;
136
136
  mode: z.ZodEnum<{
137
137
  supervised: "supervised";
138
138
  auto: "auto";
@@ -267,7 +267,7 @@ export declare const ActionEnvelopeSchema: z.ZodObject<{
267
267
  plan: z.ZodOptional<z.ZodDiscriminatedUnion<[z.ZodObject<{
268
268
  kind: z.ZodLiteral<"execution">;
269
269
  authorizationId: z.ZodUUID;
270
- milestoneId: z.ZodUUID;
270
+ milestoneId: z.ZodNullable<z.ZodUUID>;
271
271
  mode: z.ZodEnum<{
272
272
  supervised: "supervised";
273
273
  auto: "auto";
@@ -286,7 +286,7 @@ export declare const ActionEnvelopeSchema: z.ZodObject<{
286
286
  scope: z.ZodNullable<z.ZodDiscriminatedUnion<[z.ZodObject<{
287
287
  kind: z.ZodLiteral<"execution">;
288
288
  authorizationId: z.ZodUUID;
289
- milestoneId: z.ZodUUID;
289
+ milestoneId: z.ZodNullable<z.ZodUUID>;
290
290
  mode: z.ZodEnum<{
291
291
  supervised: "supervised";
292
292
  auto: "auto";
@@ -354,7 +354,7 @@ export declare const ActionReceiptSchema: z.ZodObject<{
354
354
  scope: z.ZodNullable<z.ZodDiscriminatedUnion<[z.ZodObject<{
355
355
  kind: z.ZodLiteral<"execution">;
356
356
  authorizationId: z.ZodUUID;
357
- milestoneId: z.ZodUUID;
357
+ milestoneId: z.ZodNullable<z.ZodUUID>;
358
358
  mode: z.ZodEnum<{
359
359
  supervised: "supervised";
360
360
  auto: "auto";
@@ -430,7 +430,7 @@ export declare const ActionSummarySchema: z.ZodObject<{
430
430
  scope: z.ZodNullable<z.ZodDiscriminatedUnion<[z.ZodObject<{
431
431
  kind: z.ZodLiteral<"execution">;
432
432
  authorizationId: z.ZodUUID;
433
- milestoneId: z.ZodUUID;
433
+ milestoneId: z.ZodNullable<z.ZodUUID>;
434
434
  mode: z.ZodEnum<{
435
435
  supervised: "supervised";
436
436
  auto: "auto";
@@ -78,7 +78,7 @@ export const PlanActionScopeSchema = z.discriminatedUnion('kind', [
78
78
  z.strictObject({
79
79
  kind: z.literal('execution'),
80
80
  authorizationId: z.uuid(),
81
- milestoneId: z.uuid(),
81
+ milestoneId: z.uuid().nullable(),
82
82
  mode: z.enum(['supervised', 'auto']),
83
83
  revision: PlanRevisionSchema,
84
84
  }),
@@ -12,7 +12,7 @@ export declare const HandoffSourceSchema: z.ZodObject<{
12
12
  scope: z.ZodNullable<z.ZodDiscriminatedUnion<[z.ZodObject<{
13
13
  kind: z.ZodLiteral<"execution">;
14
14
  authorizationId: z.ZodUUID;
15
- milestoneId: z.ZodUUID;
15
+ milestoneId: z.ZodNullable<z.ZodUUID>;
16
16
  mode: z.ZodEnum<{
17
17
  supervised: "supervised";
18
18
  auto: "auto";
@@ -126,7 +126,7 @@ export declare const HandoffSummarySchema: z.ZodObject<{
126
126
  scope: z.ZodNullable<z.ZodDiscriminatedUnion<[z.ZodObject<{
127
127
  kind: z.ZodLiteral<"execution">;
128
128
  authorizationId: z.ZodUUID;
129
- milestoneId: z.ZodUUID;
129
+ milestoneId: z.ZodNullable<z.ZodUUID>;
130
130
  mode: z.ZodEnum<{
131
131
  supervised: "supervised";
132
132
  auto: "auto";
@@ -229,7 +229,7 @@ export declare const HandoffSchema: z.ZodObject<{
229
229
  scope: z.ZodNullable<z.ZodDiscriminatedUnion<[z.ZodObject<{
230
230
  kind: z.ZodLiteral<"execution">;
231
231
  authorizationId: z.ZodUUID;
232
- milestoneId: z.ZodUUID;
232
+ milestoneId: z.ZodNullable<z.ZodUUID>;
233
233
  mode: z.ZodEnum<{
234
234
  supervised: "supervised";
235
235
  auto: "auto";
@@ -363,7 +363,7 @@ export declare const HandoffResultSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
363
363
  scope: z.ZodNullable<z.ZodDiscriminatedUnion<[z.ZodObject<{
364
364
  kind: z.ZodLiteral<"execution">;
365
365
  authorizationId: z.ZodUUID;
366
- milestoneId: z.ZodUUID;
366
+ milestoneId: z.ZodNullable<z.ZodUUID>;
367
367
  mode: z.ZodEnum<{
368
368
  supervised: "supervised";
369
369
  auto: "auto";
@@ -496,7 +496,7 @@ export declare const HandoffResultSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
496
496
  scope: z.ZodNullable<z.ZodDiscriminatedUnion<[z.ZodObject<{
497
497
  kind: z.ZodLiteral<"execution">;
498
498
  authorizationId: z.ZodUUID;
499
- milestoneId: z.ZodUUID;
499
+ milestoneId: z.ZodNullable<z.ZodUUID>;
500
500
  mode: z.ZodEnum<{
501
501
  supervised: "supervised";
502
502
  auto: "auto";
@@ -81,7 +81,7 @@ export declare const PlanCompletionSchema: z.ZodObject<{
81
81
  reference: z.ZodString;
82
82
  }, z.core.$strict>;
83
83
  }, z.core.$strict>;
84
- milestoneId: z.ZodUUID;
84
+ milestoneId: z.ZodNullable<z.ZodUUID>;
85
85
  revision: z.ZodObject<{
86
86
  planDigest: z.ZodString;
87
87
  breakdownDigest: z.ZodNullable<z.ZodString>;
@@ -89,7 +89,7 @@ export declare const PlanCompletionSchema: z.ZodObject<{
89
89
  contractDigest: z.ZodString;
90
90
  title: z.ZodString;
91
91
  contract: z.ZodString;
92
- sharedDigest: z.ZodString;
92
+ sharedDigest: z.ZodNullable<z.ZodString>;
93
93
  checkouts: z.ZodArray<z.ZodObject<{
94
94
  repository: z.ZodString;
95
95
  directory: z.ZodString;
@@ -128,7 +128,7 @@ export declare const PlanCheckpointSchema: z.ZodObject<{
128
128
  breakdownDigest: z.ZodNullable<z.ZodString>;
129
129
  }, z.core.$strict>;
130
130
  plan: z.ZodString;
131
- milestones: z.ZodString;
131
+ milestones: z.ZodNullable<z.ZodString>;
132
132
  entries: z.ZodArray<z.ZodObject<{
133
133
  ordinal: z.ZodNumber;
134
134
  title: z.ZodString;
@@ -192,7 +192,7 @@ export declare const PlanProposalSchema: z.ZodObject<{
192
192
  planDigest: z.ZodString;
193
193
  breakdownDigest: z.ZodNullable<z.ZodString>;
194
194
  }, z.core.$strict>;
195
- inspectionHash: z.ZodString;
195
+ inspectionHash: z.ZodNullable<z.ZodString>;
196
196
  drafts: z.ZodArray<z.ZodObject<{
197
197
  ordinal: z.ZodNumber;
198
198
  title: z.ZodString;
@@ -285,7 +285,7 @@ export declare const PlanRevisionWorkflowSchema: z.ZodObject<{
285
285
  breakdownDigest: z.ZodNullable<z.ZodString>;
286
286
  }, z.core.$strict>;
287
287
  plan: z.ZodString;
288
- milestones: z.ZodString;
288
+ milestones: z.ZodNullable<z.ZodString>;
289
289
  entries: z.ZodArray<z.ZodObject<{
290
290
  ordinal: z.ZodNumber;
291
291
  title: z.ZodString;
@@ -335,7 +335,7 @@ export declare const PlanRevisionWorkflowSchema: z.ZodObject<{
335
335
  planDigest: z.ZodString;
336
336
  breakdownDigest: z.ZodNullable<z.ZodString>;
337
337
  }, z.core.$strict>;
338
- inspectionHash: z.ZodString;
338
+ inspectionHash: z.ZodNullable<z.ZodString>;
339
339
  drafts: z.ZodArray<z.ZodObject<{
340
340
  ordinal: z.ZodNumber;
341
341
  title: z.ZodString;
@@ -482,7 +482,7 @@ export declare const PlanCommandSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
482
482
  }, z.core.$strict>;
483
483
  kind: z.ZodLiteral<"finalize">;
484
484
  }, z.core.$strict>, z.ZodObject<{
485
- milestoneId: z.ZodUUID;
485
+ milestoneId: z.ZodNullable<z.ZodUUID>;
486
486
  checks: z.ZodArray<z.ZodObject<{
487
487
  command: z.ZodString;
488
488
  outcome: z.ZodLiteral<"passed">;
@@ -668,7 +668,7 @@ export declare const PlanCommandSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
668
668
  breakdownDigest: z.ZodNullable<z.ZodString>;
669
669
  }, z.core.$strict>;
670
670
  authorizationId: z.ZodUUID;
671
- milestoneId: z.ZodUUID;
671
+ milestoneId: z.ZodNullable<z.ZodUUID>;
672
672
  mode: z.ZodEnum<{
673
673
  supervised: "supervised";
674
674
  auto: "auto";
@@ -757,7 +757,7 @@ export declare const PlanFinalizationSchema: z.ZodObject<{
757
757
  planDigest: z.ZodString;
758
758
  breakdownDigest: z.ZodNullable<z.ZodString>;
759
759
  }, z.core.$strict>;
760
- fileHash: z.ZodString;
760
+ fileHash: z.ZodNullable<z.ZodString>;
761
761
  createdAt: z.ZodNumber;
762
762
  }, z.core.$strict>;
763
763
  export declare const PlanComparisonSchema: z.ZodObject<{
@@ -831,7 +831,7 @@ export declare const PlanCoordinationSchema: z.ZodObject<{
831
831
  planDigest: z.ZodString;
832
832
  breakdownDigest: z.ZodNullable<z.ZodString>;
833
833
  }, z.core.$strict>;
834
- fileHash: z.ZodString;
834
+ fileHash: z.ZodNullable<z.ZodString>;
835
835
  createdAt: z.ZodNumber;
836
836
  }, z.core.$strict>>;
837
837
  planApproval: z.ZodNullable<z.ZodObject<{
@@ -943,7 +943,7 @@ export declare const PlanCoordinationSchema: z.ZodObject<{
943
943
  reference: z.ZodString;
944
944
  }, z.core.$strict>;
945
945
  }, z.core.$strict>;
946
- milestoneId: z.ZodUUID;
946
+ milestoneId: z.ZodNullable<z.ZodUUID>;
947
947
  revision: z.ZodObject<{
948
948
  planDigest: z.ZodString;
949
949
  breakdownDigest: z.ZodNullable<z.ZodString>;
@@ -951,7 +951,7 @@ export declare const PlanCoordinationSchema: z.ZodObject<{
951
951
  contractDigest: z.ZodString;
952
952
  title: z.ZodString;
953
953
  contract: z.ZodString;
954
- sharedDigest: z.ZodString;
954
+ sharedDigest: z.ZodNullable<z.ZodString>;
955
955
  checkouts: z.ZodArray<z.ZodObject<{
956
956
  repository: z.ZodString;
957
957
  directory: z.ZodString;
@@ -1065,7 +1065,7 @@ export declare const PlanCoordinationSchema: z.ZodObject<{
1065
1065
  breakdownDigest: z.ZodNullable<z.ZodString>;
1066
1066
  }, z.core.$strict>;
1067
1067
  plan: z.ZodString;
1068
- milestones: z.ZodString;
1068
+ milestones: z.ZodNullable<z.ZodString>;
1069
1069
  entries: z.ZodArray<z.ZodObject<{
1070
1070
  ordinal: z.ZodNumber;
1071
1071
  title: z.ZodString;
@@ -1115,7 +1115,7 @@ export declare const PlanCoordinationSchema: z.ZodObject<{
1115
1115
  planDigest: z.ZodString;
1116
1116
  breakdownDigest: z.ZodNullable<z.ZodString>;
1117
1117
  }, z.core.$strict>;
1118
- inspectionHash: z.ZodString;
1118
+ inspectionHash: z.ZodNullable<z.ZodString>;
1119
1119
  drafts: z.ZodArray<z.ZodObject<{
1120
1120
  ordinal: z.ZodNumber;
1121
1121
  title: z.ZodString;
@@ -1168,7 +1168,7 @@ export declare const PlanCoordinationSchema: z.ZodObject<{
1168
1168
  breakdownDigest: z.ZodNullable<z.ZodString>;
1169
1169
  }, z.core.$strict>;
1170
1170
  plan: z.ZodString;
1171
- milestones: z.ZodString;
1171
+ milestones: z.ZodNullable<z.ZodString>;
1172
1172
  entries: z.ZodArray<z.ZodObject<{
1173
1173
  ordinal: z.ZodNumber;
1174
1174
  title: z.ZodString;
@@ -1269,7 +1269,7 @@ export declare const PlanCoordinationSummarySchema: z.ZodObject<{
1269
1269
  planDigest: z.ZodString;
1270
1270
  breakdownDigest: z.ZodNullable<z.ZodString>;
1271
1271
  }, z.core.$strict>;
1272
- fileHash: z.ZodString;
1272
+ fileHash: z.ZodNullable<z.ZodString>;
1273
1273
  createdAt: z.ZodNumber;
1274
1274
  }, z.core.$strict>>;
1275
1275
  planApproval: z.ZodNullable<z.ZodObject<{
@@ -1486,7 +1486,7 @@ export declare const PlanStatusSchema: z.ZodObject<{
1486
1486
  planDigest: z.ZodString;
1487
1487
  breakdownDigest: z.ZodNullable<z.ZodString>;
1488
1488
  }, z.core.$strict>;
1489
- fileHash: z.ZodString;
1489
+ fileHash: z.ZodNullable<z.ZodString>;
1490
1490
  createdAt: z.ZodNumber;
1491
1491
  }, z.core.$strict>>;
1492
1492
  planApproval: z.ZodNullable<z.ZodObject<{
@@ -1716,7 +1716,7 @@ export declare const PlanReconciliationEntrySchema: z.ZodDiscriminatedUnion<[z.Z
1716
1716
  reference: z.ZodString;
1717
1717
  }, z.core.$strict>;
1718
1718
  }, z.core.$strict>;
1719
- milestoneId: z.ZodUUID;
1719
+ milestoneId: z.ZodNullable<z.ZodUUID>;
1720
1720
  revision: z.ZodObject<{
1721
1721
  planDigest: z.ZodString;
1722
1722
  breakdownDigest: z.ZodNullable<z.ZodString>;
@@ -1724,7 +1724,7 @@ export declare const PlanReconciliationEntrySchema: z.ZodDiscriminatedUnion<[z.Z
1724
1724
  contractDigest: z.ZodString;
1725
1725
  title: z.ZodString;
1726
1726
  contract: z.ZodString;
1727
- sharedDigest: z.ZodString;
1727
+ sharedDigest: z.ZodNullable<z.ZodString>;
1728
1728
  checkouts: z.ZodArray<z.ZodObject<{
1729
1729
  repository: z.ZodString;
1730
1730
  directory: z.ZodString;
@@ -1871,7 +1871,7 @@ export declare const PlanResultSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
1871
1871
  planDigest: z.ZodString;
1872
1872
  breakdownDigest: z.ZodNullable<z.ZodString>;
1873
1873
  }, z.core.$strict>;
1874
- fileHash: z.ZodString;
1874
+ fileHash: z.ZodNullable<z.ZodString>;
1875
1875
  createdAt: z.ZodNumber;
1876
1876
  }, z.core.$strict>>;
1877
1877
  planApproval: z.ZodNullable<z.ZodObject<{
@@ -2091,7 +2091,7 @@ export declare const PlanResultSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
2091
2091
  planDigest: z.ZodString;
2092
2092
  breakdownDigest: z.ZodNullable<z.ZodString>;
2093
2093
  }, z.core.$strict>;
2094
- fileHash: z.ZodString;
2094
+ fileHash: z.ZodNullable<z.ZodString>;
2095
2095
  createdAt: z.ZodNumber;
2096
2096
  }, z.core.$strict>>;
2097
2097
  planApproval: z.ZodNullable<z.ZodObject<{
@@ -2279,7 +2279,7 @@ export declare const PlanResultSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
2279
2279
  reference: z.ZodString;
2280
2280
  }, z.core.$strict>;
2281
2281
  }, z.core.$strict>;
2282
- milestoneId: z.ZodUUID;
2282
+ milestoneId: z.ZodNullable<z.ZodUUID>;
2283
2283
  revision: z.ZodObject<{
2284
2284
  planDigest: z.ZodString;
2285
2285
  breakdownDigest: z.ZodNullable<z.ZodString>;
@@ -2287,7 +2287,7 @@ export declare const PlanResultSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
2287
2287
  contractDigest: z.ZodString;
2288
2288
  title: z.ZodString;
2289
2289
  contract: z.ZodString;
2290
- sharedDigest: z.ZodString;
2290
+ sharedDigest: z.ZodNullable<z.ZodString>;
2291
2291
  checkouts: z.ZodArray<z.ZodObject<{
2292
2292
  repository: z.ZodString;
2293
2293
  directory: z.ZodString;
@@ -2435,7 +2435,7 @@ export declare const PlanResultSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
2435
2435
  planDigest: z.ZodString;
2436
2436
  breakdownDigest: z.ZodNullable<z.ZodString>;
2437
2437
  }, z.core.$strict>;
2438
- fileHash: z.ZodString;
2438
+ fileHash: z.ZodNullable<z.ZodString>;
2439
2439
  createdAt: z.ZodNumber;
2440
2440
  }, z.core.$strict>>;
2441
2441
  planApproval: z.ZodNullable<z.ZodObject<{
@@ -2574,7 +2574,7 @@ export declare const PlanResultSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
2574
2574
  }, z.core.$strict>>;
2575
2575
  }, z.core.$strict>;
2576
2576
  }, z.core.$strip>;
2577
- content: z.ZodString;
2577
+ content: z.ZodNullable<z.ZodString>;
2578
2578
  }, z.core.$strip>, z.ZodObject<{
2579
2579
  kind: z.ZodLiteral<"milestones">;
2580
2580
  result: z.ZodObject<{
@@ -64,12 +64,12 @@ export const PlanWorktreeProofSchema = PlanCheckoutSchema.extend({
64
64
  export const PlanCompletionSchema = z.strictObject({
65
65
  id: z.uuid(),
66
66
  action: PlanOperatorActionSchema,
67
- milestoneId: z.uuid(),
67
+ milestoneId: z.uuid().nullable(),
68
68
  revision: PlanRevisionSchema,
69
69
  contractDigest: PlanDigestSchema,
70
70
  title: z.string().min(1).max(4096),
71
71
  contract: z.string().max(1_048_576),
72
- sharedDigest: PlanDigestSchema,
72
+ sharedDigest: PlanDigestSchema.nullable(),
73
73
  checkouts: z.array(PlanWorktreeProofSchema).max(128),
74
74
  checks: z.array(PlanCheckSchema).min(1).max(32),
75
75
  completedAt: z.number().int(),
@@ -84,7 +84,7 @@ export const PlanSnapshotMilestoneSchema = PlanMilestoneSchema.extend({
84
84
  export const PlanCheckpointSchema = z.strictObject({
85
85
  revision: PlanRevisionSchema,
86
86
  plan: z.string().max(1_048_576),
87
- milestones: z.string().max(1_048_576),
87
+ milestones: z.string().max(1_048_576).nullable(),
88
88
  entries: z.array(PlanSnapshotMilestoneSchema).max(1024),
89
89
  checkouts: z.array(PlanWorktreeProofSchema).max(128),
90
90
  threadIds: z.array(z.uuid()).max(32),
@@ -111,7 +111,7 @@ export const PlanDraftMilestoneSchema = PlanSnapshotMilestoneSchema.extend({
111
111
  export const PlanProposalSchema = z.strictObject({
112
112
  id: z.uuid(),
113
113
  revision: PlanRevisionSchema,
114
- inspectionHash: PlanDigestSchema,
114
+ inspectionHash: PlanDigestSchema.nullable(),
115
115
  drafts: z.array(PlanDraftMilestoneSchema).max(1024),
116
116
  unmatchedSourceIds: z.array(z.uuid()).max(1024),
117
117
  confirmation: z
@@ -193,7 +193,7 @@ export const PlanCommandSchema = z.discriminatedUnion('kind', [
193
193
  z.strictObject({
194
194
  kind: z.literal('complete'),
195
195
  ...MutationFields,
196
- milestoneId: z.uuid(),
196
+ milestoneId: z.uuid().nullable(),
197
197
  checks: z.array(PlanCheckSchema).min(1).max(32),
198
198
  checkouts: z.array(PlanCheckoutSchema).max(128),
199
199
  }),
@@ -234,7 +234,6 @@ export const PlanCommandSchema = z.discriminatedUnion('kind', [
234
234
  mode: z.enum(['supervised', 'auto']),
235
235
  milestoneIds: z
236
236
  .array(z.uuid())
237
- .min(1)
238
237
  .max(1024)
239
238
  .refine((ids) => new Set(ids).size === ids.length),
240
239
  }),
@@ -243,7 +242,7 @@ export const PlanCommandSchema = z.discriminatedUnion('kind', [
243
242
  target: PlanTargetSchema,
244
243
  expected: PlanRevisionSchema,
245
244
  authorizationId: z.uuid(),
246
- milestoneId: z.uuid(),
245
+ milestoneId: z.uuid().nullable(),
247
246
  mode: z.enum(['supervised', 'auto']),
248
247
  }),
249
248
  ]);
@@ -259,7 +258,7 @@ export const PlanExecutionSchema = z.strictObject({
259
258
  action: PlanOperatorActionSchema,
260
259
  revision: PlanRevisionSchema,
261
260
  mode: z.enum(['supervised', 'auto']),
262
- milestoneIds: z.array(z.uuid()).min(1).max(1024),
261
+ milestoneIds: z.array(z.uuid()).max(1024),
263
262
  createdAt: z.number().int(),
264
263
  revokedBy: PlanOperatorActionSchema.nullable(),
265
264
  });
@@ -267,7 +266,7 @@ export const PlanExecutionSchema = z.strictObject({
267
266
  export const PlanFinalizationSchema = z.strictObject({
268
267
  action: PlanOperatorActionSchema,
269
268
  revision: PlanRevisionSchema,
270
- fileHash: PlanDigestSchema,
269
+ fileHash: PlanDigestSchema.nullable(),
271
270
  createdAt: z.number().int(),
272
271
  });
273
272
  // coordinators own semantic review; the core preserves its exact revision-bound evidence
@@ -385,7 +384,7 @@ export const PlanResultSchema = z.discriminatedUnion('kind', [
385
384
  z.object({
386
385
  kind: z.literal('finalized'),
387
386
  result: PlanStatusSchema,
388
- content: z.string().max(1_048_576),
387
+ content: z.string().max(1_048_576).nullable(),
389
388
  }),
390
389
  z.object({
391
390
  kind: z.literal('milestones'),