opencode-swarm 6.58.0 → 6.59.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.
@@ -123,17 +123,67 @@ export declare function appendLedgerEvent(directory: string, eventInput: LedgerE
123
123
  expectedHash?: string;
124
124
  planHashAfter?: string;
125
125
  }): Promise<LedgerEvent>;
126
+ /**
127
+ * Append a ledger event with optimistic retry on stale-writer conflicts.
128
+ *
129
+ * When another writer advances the ledger between the caller's read and
130
+ * their append, `appendLedgerEvent` throws `LedgerStaleWriterError`. This
131
+ * helper wraps that call in a bounded retry loop, refreshing the
132
+ * `expectedHash` concurrency token against the current plan.json before
133
+ * each retry.
134
+ *
135
+ * IMPORTANT: refreshing the hash is only safe when the event input is
136
+ * *still semantically valid* after the intervening write. For audit
137
+ * events computed from an in-memory plan the caller is about to persist,
138
+ * it is always valid. For `task_status_changed` events, pass a
139
+ * `verifyValid` callback that returns false when the transition no
140
+ * longer applies (e.g. the task's on-disk status already matches the
141
+ * `to_status`, or has moved past it). When `verifyValid` returns false,
142
+ * the retry loop exits and the helper returns `null` to signal that the
143
+ * event was skipped — it is not an error.
144
+ *
145
+ * @param directory - Working directory containing `.swarm/plan-ledger.jsonl`
146
+ * @param eventInput - Event to append (required fields minus auto-generated)
147
+ * @param options - Concurrency and retry configuration:
148
+ * - expectedHash: the hash of plan.json the caller observed (REQUIRED)
149
+ * - planHashAfter: precomputed hash of the mutated plan
150
+ * - maxRetries: max stale-writer retries (default: 3)
151
+ * - backoffMs: base delay in milliseconds (default: 10; exponential)
152
+ * - verifyValid: callback invoked before each retry to confirm the
153
+ * event input is still meaningful. Returning false aborts and
154
+ * resolves the helper to `null`.
155
+ * @returns The written LedgerEvent, or `null` if verifyValid aborted.
156
+ * @throws LedgerStaleWriterError if retries are exhausted.
157
+ */
158
+ export declare function appendLedgerEventWithRetry(directory: string, eventInput: LedgerEventInput, options: {
159
+ expectedHash: string;
160
+ planHashAfter?: string;
161
+ maxRetries?: number;
162
+ backoffMs?: number;
163
+ verifyValid?: () => Promise<boolean> | boolean;
164
+ }): Promise<LedgerEvent | null>;
126
165
  /**
127
166
  * Take a snapshot event and append it to the ledger.
128
167
  * The snapshot embeds the full Plan payload for ledger-only rebuild.
129
168
  *
130
169
  * @param directory - The working directory
131
170
  * @param plan - The current plan state to snapshot
132
- * @param options - Optional configuration
171
+ * @param options - Optional configuration:
172
+ * - planHashAfter: precomputed hash of the mutated plan (bypasses the
173
+ * on-disk plan.json read when available)
174
+ * - source: attribution string stored on the ledger event. Defaults to
175
+ * `'takeSnapshotEvent'`. Use `'critic_approved'` to mark a snapshot as
176
+ * the immutable phase-approved checkpoint readable by
177
+ * `loadLastApprovedPlan`.
178
+ * - approvalMetadata: optional free-form metadata embedded into the
179
+ * snapshot payload (e.g. phase number, verdict, summary) so that
180
+ * downstream readers can filter without decoding prompts.
133
181
  * @returns The LedgerEvent that was written
134
182
  */
135
183
  export declare function takeSnapshotEvent(directory: string, plan: Plan, options?: {
136
184
  planHashAfter?: string;
185
+ source?: string;
186
+ approvalMetadata?: Record<string, unknown>;
137
187
  }): Promise<LedgerEvent>;
138
188
  /**
139
189
  * Options for replayFromLedger
@@ -193,4 +243,44 @@ export declare function quarantineLedgerSuffix(directory: string, badSuffix: str
193
243
  * @returns Reconstructed Plan from ledger events, or null if replay fails
194
244
  */
195
245
  export declare function replayWithIntegrity(directory: string): Promise<Plan | null>;
246
+ /**
247
+ * Metadata describing an approved snapshot recovered from the ledger.
248
+ */
249
+ export interface ApprovedSnapshotInfo {
250
+ /** The immutable plan payload captured at critic approval time */
251
+ plan: Plan;
252
+ /** The ledger sequence number of the snapshot event */
253
+ seq: number;
254
+ /** ISO 8601 timestamp of the snapshot event */
255
+ timestamp: string;
256
+ /** Arbitrary metadata the caller attached (phase, verdict, summary, ...) */
257
+ approval?: Record<string, unknown>;
258
+ /** Hash of the plan payload at snapshot time */
259
+ payloadHash: string;
260
+ }
261
+ /**
262
+ * Find the most recent critic-approved immutable plan snapshot in the ledger.
263
+ *
264
+ * Snapshots are tagged at write time with a distinguishing `source` string
265
+ * (see `takeSnapshotEvent`). The `critic_approved` marker identifies snapshots
266
+ * persisted by the orchestrator after a phase Critic returns APPROVED. This
267
+ * function scans the ledger in reverse order and returns the first matching
268
+ * snapshot, including its embedded plan payload and approval metadata.
269
+ *
270
+ * Intended for use as a fallback when plan.json is lost, overwritten, or
271
+ * suspected of drift: the Architect can fall back to the last approved plan
272
+ * and the Critic can drift-check against it.
273
+ *
274
+ * SAFETY: when `expectedPlanId` is supplied, only snapshots whose event
275
+ * `plan_id` matches are considered. Callers MUST pass an expected identity
276
+ * whenever they have one (e.g. from the ledger's first `plan_created` anchor)
277
+ * to prevent cross-identity contamination: a stale `critic_approved` snapshot
278
+ * left in a reused directory could otherwise be resurrected as the active plan.
279
+ *
280
+ * @param directory - Working directory containing `.swarm/plan-ledger.jsonl`
281
+ * @param expectedPlanId - Optional plan identity filter. When provided, only
282
+ * snapshots whose ledger event `plan_id` matches are considered.
283
+ * @returns The most recent approved snapshot info, or null if none exists
284
+ */
285
+ export declare function loadLastApprovedPlan(directory: string, expectedPlanId?: string): Promise<ApprovedSnapshotInfo | null>;
196
286
  export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencode-swarm",
3
- "version": "6.58.0",
3
+ "version": "6.59.0",
4
4
  "description": "Architect-centric agentic swarm plugin for OpenCode - hub-and-spoke orchestration with SME consultation, code generation, and QA review",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",