@shapeshift-labs/frontier-swarm 0.2.0 → 0.4.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/README.md CHANGED
@@ -36,7 +36,7 @@ The published Frontier package family is generated from one shared package catal
36
36
  - [`@shapeshift-labs/frontier-workflow`](https://www.npmjs.com/package/@shapeshift-labs/frontier-workflow): Serializable durable workflow/process manifests for Frontier apps, including steps, waits, approvals, timers, retries, expected patches, compensation, records, timelines, and registry graph output.
37
37
  - [`@shapeshift-labs/frontier-worker`](https://www.npmjs.com/package/@shapeshift-labs/frontier-worker): Serializable worker and edge task descriptors for Frontier apps, including queues, idempotency keys, retry and timeout policy, declared reads/writes/effects, snapshots, patch outputs, produced assets, execution records, logs, trace links, proof hashes, dedupe indexes, and registry graph output.
38
38
  - [`@shapeshift-labs/frontier-queue`](https://www.npmjs.com/package/@shapeshift-labs/frontier-queue): Serializable durable queue state, leases, retries, dedupe keys, patch-carrying jobs, dead-letter records, replay evidence, and queue inspection for Frontier apps.
39
- - [`@shapeshift-labs/frontier-swarm-codex`](https://www.npmjs.com/package/@shapeshift-labs/frontier-swarm-codex): Node Codex CLI adapter for Frontier swarm plans, including prompt rendering, worktree and snapshot workspaces, Codex argument construction, JSONL capture, verification commands, and result artifacts.
39
+ - [`@shapeshift-labs/frontier-swarm-codex`](https://www.npmjs.com/package/@shapeshift-labs/frontier-swarm-codex): Node Codex CLI adapter for Frontier swarm plans, including prompt rendering, worktree and snapshot workspaces, Codex argument compatibility, JSONL capture, verification commands, pid-backed stop, collect/apply workflows, merge indexes, queue overlays, merge bundles, and result artifacts.
40
40
  - [`@shapeshift-labs/frontier-kv`](https://www.npmjs.com/package/@shapeshift-labs/frontier-kv): Serializable in-memory key/value state for Frontier apps, including TTL, versioned compare-and-set, batched patch mutations, scans, watchers, snapshots, JSONL event evidence, and replay verification.
41
41
  - [`@shapeshift-labs/frontier-kv-locks`](https://www.npmjs.com/package/@shapeshift-labs/frontier-kv-locks): Lease-style lock records on top of Frontier KV, including acquire, renew, release, fencing tokens, expiration, owner evidence, and replayable lock events.
42
42
  - [`@shapeshift-labs/frontier-kv-rate-limit`](https://www.npmjs.com/package/@shapeshift-labs/frontier-kv-rate-limit): Patch-native rate limit buckets for Frontier KV, including fixed windows, sliding windows, token buckets, deterministic refill, consume evidence, and reset records.
@@ -211,10 +211,13 @@ Large swarms need a control plane, not just a flat worker loop. `frontier-swarm`
211
211
  import {
212
212
  checkSwarmBudget,
213
213
  createSwarmArtifactIndex,
214
+ createSwarmEventStream,
214
215
  createSwarmLeases,
215
216
  createSwarmMergePlan,
217
+ createSwarmQueueSnapshot,
216
218
  createSwarmReviewPlan,
217
- createSwarmSchedule
219
+ createSwarmSchedule,
220
+ routeSwarmEventToMailboxes
218
221
  } from '@shapeshift-labs/frontier-swarm';
219
222
 
220
223
  const schedule = createSwarmSchedule({
@@ -237,10 +240,27 @@ The scale APIs are runtime-neutral and serializable:
237
240
  - dependency DAGs are compiled into `plan.graph`,
238
241
  - `createSwarmSchedule` returns ready, blocked, running, completed, and failed jobs under lane/compute/contention limits,
239
242
  - `createSwarmLeases` gives workers expiring leases with fencing tokens,
243
+ - lane/task `capabilities` and `resourceRequirements` can reserve browser work with lower concurrency, port pools, profile directories, and explicit capability checks,
244
+ - `createSwarmQueueSnapshot` and run checkpoints give durable queue/run-store adapters a stable serialization shape,
245
+ - `createSwarmEventStream` and `routeSwarmEventToMailboxes` route global, lane, task, and worker events into coordinator-facing JSONL streams,
240
246
  - `checkSwarmBudget` records token/cost/time/retry budget decisions,
241
247
  - `createSwarmArtifactIndex` groups evidence, timelines, logs, and produced files,
242
248
  - `createSwarmReviewPlan` samples or requires reviewer assignments,
243
249
  - `createSwarmMergePlan` blocks jobs with failed checks, required reviews, ownership violations, or conflicting changed paths,
250
+ - job results include merge-readiness classification: `discovery-only`, `patch-candidate`, `verified-patch`, `rejected`, or `blocked`,
251
+ - `ownershipRegions` allow hot files to be split into semantic regions such as `content.docs.*` or `adminSettings.quota.*`; merge conflict detection compares explicit changed regions when both sides report them and falls back to path conflicts when either side omits regions,
252
+ - `createSwarmMergeBundle` builds a compact worker `merge.json` shape with touched owned files, patch path, evidence, verification, queue items satisfied, risk, and disposition,
253
+ - `createSwarmQueueOverlay` and `deriveSwarmQueueStatus` keep central queue files immutable while deriving status from worker result overlays,
254
+ - `createSwarmMergeIndex` records stale/patch status and region-aware conflicts so coordinators can review ready bundles before reading every worker directory,
255
+ - `checkSwarmRegionOwnership` makes semantic region ownership enforceable instead of only advisory,
256
+ - `createSwarmHotspotReport` highlights repeatedly touched files and suggests module/region splits for merge throughput,
257
+ - `createSwarmReviewerLanePlan` turns risky/conflicting merge bundles into reviewer-lane tasks,
258
+ - `createSwarmRunStoreShards` describes sharded event/result/checkpoint paths for large run stores,
259
+ - `createSwarmMergeAdmission` limits ready merges by count, touched paths/regions, and risk budget,
260
+ - `createSwarmPatchStackPlan` clusters compatible bundles into candidate patch stacks by lane, path, region, disposition, and risk so reviewers can evaluate batches instead of individual worker directories,
261
+ - `createSwarmContextPack` gives workers compact task context: relevant files, API maps, known failures, focused/oracle commands, expected evidence, exclusions, evidence schema, playbooks, and explicit dead ends to avoid,
262
+ - `createSwarmOracleCorpus` indexes deterministic reference artifacts such as traces, snapshots, classifications, expected outputs, or fixtures without assuming a project domain,
263
+ - `createSwarmLanePlaybook` turns successful prior bundles into persistent lane-specific guidance with commands, hot paths, evidence patterns, and avoid-investigating notes,
244
264
  - `decomposeSwarmFeature` creates an initial task queue for feature work across lanes.
245
265
 
246
266
  ## Hierarchical Compute
@@ -260,11 +280,22 @@ That lets a parent swarm route implementation jobs to a deep model while evidenc
260
280
  - `defineSwarmManifest`, `createSwarmManifest`
261
281
  - `defineSwarmTasks`
262
282
  - `compileSwarm`, `validateSwarmManifest`
283
+ - `createSwarmTaskSelection`
263
284
  - `createSwarmPlan`, `createSwarmRun`
264
285
  - `createSwarmSchedule`, `createSwarmLeases`
286
+ - `createSwarmQueueSnapshot`, `createSwarmRunCheckpoint`
287
+ - `createSwarmQueueOverlay`, `deriveSwarmQueueStatus`
288
+ - `createSwarmEventStream`, `createSwarmMailbox`, `routeSwarmEventToMailboxes`
265
289
  - `checkSwarmBudget`
266
290
  - `createSwarmArtifactIndex`
267
- - `createSwarmReviewPlan`, `createSwarmMergePlan`
291
+ - `createSwarmReviewPlan`, `createSwarmReviewerLanePlan`, `createSwarmMergePlan`
292
+ - `createSwarmMergeBundle`
293
+ - `createSwarmMergeIndex`, `createSwarmMergeAdmission`
294
+ - `createSwarmHotspotReport`, `createSwarmRunStoreShards`
295
+ - `createSwarmPatchStackPlan`
296
+ - `createSwarmContextPack`, `createSwarmOracleCorpus`, `createSwarmLanePlaybook`
297
+ - `classifySwarmMergeReadiness`, `classifySwarmMergeDisposition`
298
+ - `resolveSwarmChangedRegions`, `checkSwarmRegionOwnership`
268
299
  - `decomposeSwarmFeature`
269
300
  - `recordSwarmEvent`, `completeSwarmJob`
270
301
  - `resolveSwarmCompute`
@@ -280,7 +311,7 @@ Run the package-local benchmark:
280
311
  npm run bench
281
312
  ```
282
313
 
283
- The benchmark writes `benchmarks/results/frontier-swarm-package-bench-latest.json` when run from the monorepo. These are Frontier-only package measurements for plan creation, manifest validation, hierarchical compute resolution, ownership checks, run creation, JSONL, and proof hashing.
314
+ The benchmark writes `benchmarks/results/frontier-swarm-package-bench-latest.json` when run from the monorepo. These are Frontier-only package measurements for plan creation, manifest validation, hierarchical compute resolution, ownership checks, scheduling/leases, queue snapshots, queue overlays, merge bundles, merge indexes, merge admission, hotspot reports, context packs, oracle corpora, lane playbooks, patch stack plans, event routing, run checkpoints, JSONL, and proof hashing.
284
315
 
285
316
  ## Source Repository
286
317
 
@@ -4,13 +4,28 @@ import { performance } from 'node:perf_hooks';
4
4
  import { fileURLToPath } from 'node:url';
5
5
  import {
6
6
  checkSwarmOwnership,
7
+ createSwarmContextPack,
8
+ createSwarmHotspotReport,
9
+ createSwarmLanePlaybook,
10
+ createSwarmMergeAdmission,
7
11
  createSwarmManifest,
12
+ createSwarmEventStream,
13
+ createSwarmLeases,
14
+ createSwarmMergeBundle,
15
+ createSwarmMergeIndex,
16
+ createSwarmOracleCorpus,
17
+ createSwarmPatchStackPlan,
8
18
  createSwarmPlan,
9
19
  createSwarmProof,
20
+ createSwarmQueueOverlay,
21
+ createSwarmQueueSnapshot,
10
22
  createSwarmRun,
23
+ createSwarmRunCheckpoint,
24
+ createSwarmSchedule,
11
25
  decodeSwarmJsonl,
12
26
  defineSwarmTasks,
13
27
  encodeSwarmJsonl,
28
+ routeSwarmEventToMailboxes,
14
29
  resolveSwarmCompute,
15
30
  validateSwarmManifest
16
31
  } from '../dist/index.js';
@@ -31,6 +46,11 @@ let plan = createSwarmPlan(manifest, tasks, { limit: 64 });
31
46
  let run = createSwarmRun({ plan });
32
47
  let jsonl = encodeSwarmJsonl([plan, run]);
33
48
  let cursor = 0;
49
+ let schedule = createSwarmSchedule({ plan, maxReadyJobs: 128 });
50
+ let leases = createSwarmLeases({ schedule, workerId: 'bench-worker', now: 1000, leaseMs: 60000, count: 16 });
51
+ let eventStream = createSwarmEventStream({ runId: 'bench', root: 'agent-runs/bench/streams', lanes: manifest.lanes });
52
+ let bundles = makeBundles(plan, 32);
53
+ let mergeIndex = createSwarmMergeIndex({ bundles });
34
54
 
35
55
  const rows = [
36
56
  measure('create-plan-' + taskCount, 8, () => {
@@ -49,7 +69,70 @@ const rows = [
49
69
  return jsonl.length;
50
70
  }),
51
71
  measure('jsonl-decode', 16, () => decodeSwarmJsonl(jsonl).length),
52
- measure('proof', 16, () => createSwarmProof(plan).hash.length)
72
+ measure('proof', 16, () => createSwarmProof(plan).hash.length),
73
+ measure('schedule-lease-' + taskCount, 8, () => {
74
+ schedule = createSwarmSchedule({ plan, maxReadyJobs: 128, maxComputeConcurrency: { fast: 64, deep: 32 } });
75
+ leases = createSwarmLeases({ schedule, workerId: 'bench-worker', now: 1000 + cursor++, leaseMs: 60000, count: 16 });
76
+ return schedule.ready.length + leases.length;
77
+ }),
78
+ measure('queue-snapshot-' + taskCount, 8, () => {
79
+ const snapshot = createSwarmQueueSnapshot({ plan, run, leases, generatedAt: 2000 + cursor++ });
80
+ return snapshot.summary.jobCount + snapshot.summary.leaseCount;
81
+ }),
82
+ measure('run-checkpoint-' + taskCount, 16, () => createSwarmRunCheckpoint({ run, sequence: cursor++ }).hash.length),
83
+ measure('merge-bundle-' + taskCount, 32, () => createSwarmMergeBundle({
84
+ job: plan.jobs[cursor % plan.jobs.length],
85
+ result: {
86
+ jobId: plan.jobs[cursor++ % plan.jobs.length].id,
87
+ status: 'completed',
88
+ changedPaths: ['src/runtime/file.ts'],
89
+ verification: [{ status: 0 }]
90
+ },
91
+ patchPath: 'agent-runs/bench/changes.patch'
92
+ }).id.length),
93
+ measure('queue-overlay-' + taskCount, 16, () => createSwarmQueueOverlay({ bundles, generatedAt: 3000 + cursor++ }).summary.entryCount),
94
+ measure('merge-index-' + taskCount, 8, () => {
95
+ bundles = makeBundles(plan, 32);
96
+ mergeIndex = createSwarmMergeIndex({ bundles, generatedAt: 4000 + cursor++ });
97
+ return mergeIndex.summary.entryCount + mergeIndex.summary.conflictCount;
98
+ }),
99
+ measure('merge-admission-' + taskCount, 16, () => createSwarmMergeAdmission({ index: mergeIndex, maxReady: 8, maxChangedPaths: 16 }).summary.admittedCount),
100
+ measure('hotspot-report-' + taskCount, 16, () => createSwarmHotspotReport({ bundles, threshold: 3 }).summary.recommendationCount),
101
+ measure('context-pack-' + taskCount, 32, () => createSwarmContextPack({
102
+ job: plan.jobs[cursor % plan.jobs.length],
103
+ files: ['src/runtime/file.ts', 'test/runtime-smoke.mjs'],
104
+ apiMap: {
105
+ runtime: ['createRuntime', 'stepRuntime'],
106
+ tests: ['runtime smoke gate']
107
+ },
108
+ knownFailures: ['shared renderer gate is noisy on old snapshots'],
109
+ oracleCommands: [{ name: 'focused-gate', command: 'npm', args: ['test'], required: true }],
110
+ evidenceSchema: { type: 'object', required: ['ok', 'commands'] },
111
+ avoidInvestigating: ['unrelated route snapshots'],
112
+ playbookIds: ['runtime-playbook']
113
+ }).files.length),
114
+ measure('oracle-corpus-' + taskCount, 32, () => createSwarmOracleCorpus({
115
+ artifacts: [
116
+ { id: 'trace-runtime', path: 'oracles/runtime-trace.jsonl', kind: 'trace', tags: ['runtime', 'reference'], hash: 'fnv1a32:trace' },
117
+ { id: 'snapshot-routing', path: 'oracles/routing-snapshot.json', kind: 'snapshot', tags: ['routing', 'reference'] }
118
+ ]
119
+ }).summary.artifactCount),
120
+ measure('lane-playbook-' + taskCount, 16, () => createSwarmLanePlaybook({
121
+ lane: 'runtime',
122
+ successfulBundles: bundles,
123
+ notes: ['prefer narrow patches with focused evidence'],
124
+ commands: [{ name: 'runtime-smoke', command: 'npm', args: ['test'], required: true }],
125
+ avoidInvestigating: ['generated fixtures unless task owns them'],
126
+ evidencePatterns: ['evidence.json', 'commands.md']
127
+ }).successfulJobIds.length),
128
+ measure('patch-stack-plan-' + taskCount, 16, () => createSwarmPatchStackPlan({
129
+ index: mergeIndex,
130
+ maxStackSize: 8
131
+ }).summary.stackCount),
132
+ measure('event-route-' + taskCount, 64, () => {
133
+ eventStream = createSwarmEventStream({ runId: 'bench', root: 'agent-runs/bench/streams', lanes: manifest.lanes });
134
+ return routeSwarmEventToMailboxes(eventStream, { type: 'agent.evidence', jobId: plan.jobs[cursor++ % plan.jobs.length].id, lane: 'runtime' }).length;
135
+ })
53
136
  ];
54
137
 
55
138
  const report = {
@@ -112,6 +195,25 @@ function makeTasks(count) {
112
195
  return tasks;
113
196
  }
114
197
 
198
+ function makeBundles(plan, count) {
199
+ const bundles = [];
200
+ for (let i = 0; i < Math.min(count, plan.jobs.length); i += 1) {
201
+ const job = plan.jobs[i];
202
+ bundles.push(createSwarmMergeBundle({
203
+ job,
204
+ result: {
205
+ jobId: job.id,
206
+ status: 'verified',
207
+ changedPaths: [job.task.targetRefs[0] ?? `src/runtime/file-${i}.ts`],
208
+ changedRegions: i % 2 === 0 ? [`region.${i}`] : [],
209
+ verification: [{ status: 0 }]
210
+ },
211
+ patchPath: `agent-runs/bench/${job.id}/changes.patch`
212
+ }));
213
+ }
214
+ return bundles;
215
+ }
216
+
115
217
  function measure(fixture, operationsPerRound, fn) {
116
218
  const samples = [];
117
219
  let checksum = 0;