From 8ddc2f9d9e9fcf0504ad4bd76e8d7e0b1da8d299 Mon Sep 17 00:00:00 2001 From: Will Washburn Date: Mon, 25 May 2026 11:54:43 -0400 Subject: [PATCH 01/19] Document harness runtime plan --- docs/harness-runtime-plan.md | 184 +++++++++++++++++++++++++++++++++ web/content/docs/harnesses.mdx | 144 ++++++++++++++++++++++++++ web/lib/docs-nav.ts | 1 + 3 files changed, 329 insertions(+) create mode 100644 docs/harness-runtime-plan.md create mode 100644 web/content/docs/harnesses.mdx diff --git a/docs/harness-runtime-plan.md b/docs/harness-runtime-plan.md new file mode 100644 index 000000000..dc0caf875 --- /dev/null +++ b/docs/harness-runtime-plan.md @@ -0,0 +1,184 @@ +# Harness Runtime Plan + +## Goal + +Harnesses should be user-extensible without requiring Rust changes for normal +agent CLIs. The Rust broker should own durable runtime execution, lifecycle +tracking, routing, delivery queues, retries, and observability. SDKs should be +able to define named harnesses that resolve to broker-executable JSON plans. + +## Core Model + +The broker supports two runtime executors first: + +- `pty`: runs a command inside a PTY and manages terminal-oriented delivery. +- `app_server`: talks to an existing or broker-owned app-server session. + +Named harnesses such as `codex`, `qwen`, or `opencode-server` resolve to one of +those executable shapes. + +## Plan Shapes + +PTY plans are process and terminal backed: + +```ts +type PtyHarnessPlan = { + runtime: 'pty'; + command: string; + args: string[]; + cwd?: string; + env?: Record; + sessionId?: string; + delivery?: { + mode: 'pty-injection'; + format?: 'relay-block'; + }; + metadata?: Record; +}; +``` + +App-server plans are session backed: + +```ts +type AppServerHarnessPlan = { + runtime: 'app_server'; + protocol: 'opencode' | string; + endpoint: string; + sessionId: string; + auth?: { + type: 'bearer' | 'basic' | 'none'; + token?: string; + username?: string; + password?: string; + }; + host?: { + ownership: 'broker-owned' | 'attached'; + pid?: number; + }; + release?: 'abort' | 'detach' | 'delete'; + metadata?: Record; +}; +``` + +The broker runs the returned plan. It does not need to understand arbitrary +TypeScript or Python logic. + +## Harness Definition Classes + +Static harness definitions are JSON-compatible and work in attached or detached +brokers: + +```ts +const harnesses = { + qwen: { + runtime: 'pty', + command: 'qwen', + args: ['run', '{modelArgs}', '{args}'], + modelArgs: ['-m', '{model}'], + searchPaths: ['~/.local/bin'], + }, +}; +``` + +Dynamic harness resolvers are SDK functions and are attached-only. They can run +pre-spawn logic, such as creating a provider session, then return a concrete +plan: + +```ts +const harnesses = { + codex: async (ctx) => { + const sessionId = await createCodexSession(ctx); + return { + runtime: 'pty', + command: 'codex', + args: ['resume', sessionId, ...ctx.args], + env: ctx.env, + sessionId, + }; + }, +}; +``` + +Detached brokers must reject dynamic in-process resolvers because the SDK +process may exit while the broker and agents continue. + +## Broker Lifetime + +Broker lifetime should be explicit: + +```ts +broker: { + lifetime: 'attached' | 'detached'; +} +``` + +Attached brokers are owned by the SDK process. Dynamic resolvers and in-process +decision hooks are allowed because the broker exits if the SDK control +connection exits. + +Detached brokers survive SDK callers. They only accept static harness plans, +built-in Rust adapters, and durable extension hosts. + +## Broker Responsibilities + +The broker owns: + +- Agent registry and name uniqueness. +- Spawn, release, and future fork lifecycle. +- Relay routing and local-vs-remote delivery. +- Delivery queues, retry, ack, failure, and manual flush semantics. +- Process and server supervision for broker-owned runtimes. +- Capability checks for PTY-only routes. +- Event emission, metrics, logs, and replay buffers. + +The broker does not own custom user logic unless that logic is built into Rust. + +## PTY Runtime + +The PTY executor consumes a concrete PTY plan. It handles process spawn, +terminal streaming, raw input, resize, snapshot, release, and PTY message +injection. + +This lets users add a CLI like Qwen Code locally with config only. A Rust +contribution is only needed when Relay wants a built-in with tested defaults or +the CLI needs broker-side behavior. + +## App-Server Runtime + +The app-server executor consumes an app-server plan. For OpenCode, the adapter +can attach to a local or remote `opencode serve` endpoint, create or receive a +session id, deliver Relay messages through the session message API, and release +by aborting, detaching, or deleting the session. + +App-server runtimes do not expose PTY input, resize, or snapshot capabilities. + +## Hooks + +Event hooks are non-blocking subscriptions: + +```ts +relay.on('agent.spawned', async (event) => { + await posthog.capture(...); +}); +``` + +Decision hooks are request-response calls over an attached SDK control +connection: + +- `resolveHarness` +- `beforeSpawn` +- `authorizeSpawn` + +Detached brokers must use static config, built-in sinks, HTTP webhooks, or a +durable extension host for decision-making. + +## Implementation Phases + +1. Add shared plan schema and SDK types. +2. Add static SDK harness resolution to PTY plans. +3. Teach the broker to accept and execute resolved PTY plans. +4. Add an app-server plan path with an OpenCode protocol driver. +5. Add capability-aware runtime checks for PTY-only operations. +6. Add attached broker control RPCs for dynamic resolvers. +7. Add detached-mode validation for dynamic resolvers and in-process decision hooks. +8. Document static Qwen, dynamic Codex, and OpenCode app-server examples. diff --git a/web/content/docs/harnesses.mdx b/web/content/docs/harnesses.mdx new file mode 100644 index 000000000..e5efc3293 --- /dev/null +++ b/web/content/docs/harnesses.mdx @@ -0,0 +1,144 @@ +--- +title: Harnesses +description: Define custom PTY and app-server harnesses for Agent Relay. +--- + +A harness tells Relay how to control an agent runtime. The broker executes two +runtime shapes: `pty` for terminal-backed agents and `app_server` for +session-backed agent servers. Named harnesses such as `codex`, `qwen`, or +`opencode-server` resolve to one of those shapes. + +The important boundary is that the Rust broker runs durable execution plans. SDKs +can define names and resolve them into JSON, but the broker should not depend on +an in-memory SDK callback unless the broker lifetime is explicitly attached to +that SDK process. + +## Static PTY Harnesses + +Most CLI agents only need a PTY plan. Static harnesses are JSON-compatible and +work with attached or detached brokers. + +```typescript file="qwen-harness.ts" +import { AgentRelay } from '@agent-relay/sdk'; + +const relay = new AgentRelay({ + harnesses: { + qwen: { + runtime: 'pty', + command: 'qwen', + args: ['run', '{modelArgs}', '{args}'], + modelArgs: ['-m', '{model}'], + searchPaths: ['~/.local/bin'], + }, + }, +}); + +await relay.spawn('QwenReviewer', 'qwen', 'Review the current diff.', { + model: 'qwen3-coder', + args: ['--verbose'], + channels: ['dev'], +}); +``` + +The SDK resolves that definition to a broker-executable plan: + +```json +{ + "runtime": "pty", + "command": "qwen", + "args": ["run", "-m", "qwen3-coder", "--verbose"] +} +``` + +The broker owns the PTY process, terminal stream, raw input, resize, snapshot, +release, and Relay message injection. + +## App-Server Harnesses + +App-server harnesses control a session through HTTP instead of typing into a +terminal. OpenCode's `opencode serve` mode is the first target shape. + +```typescript file="opencode-server-harness.ts" +import { AgentRelay } from '@agent-relay/sdk'; + +const relay = new AgentRelay({ + harnesses: { + 'opencode-server': { + runtime: 'app_server', + protocol: 'opencode', + endpoint: 'http://127.0.0.1:4096', + sessionId: 'ses_123', + release: 'abort', + }, + }, +}); + +await relay.spawn('OpenCodeServerWorker', 'opencode-server', 'Inspect the repo.'); +``` + +For app-server plans, `sessionId` identifies the native runtime session. `pid` +only exists when the broker owns a local server process; remote or already +running servers may not have one. + +## Dynamic Resolvers + +Some harnesses need pre-spawn work. Codex PTY spawning is the motivating +example: a resolver can call Codex app-server to create a resumable thread, then +return a PTY plan that resumes that thread. + +```typescript file="codex-resolver.ts" +const relay = new AgentRelay({ + broker: { lifetime: 'attached' }, + harnesses: { + codex: async (ctx) => { + const sessionId = await createCodexSession(ctx); + + return { + runtime: 'pty', + command: 'codex', + args: ['resume', sessionId, ...ctx.args], + env: ctx.env, + sessionId, + }; + }, + }, +}); +``` + +Dynamic resolvers require an attached broker because the SDK process is part of +the control path. Detached brokers should use static plans, built-in Rust +adapters, HTTP webhooks, or a durable extension host. + +## Runtime Capabilities + +Harness capabilities determine which broker routes are valid. + +| Capability | PTY | App server | +| --- | --- | --- | +| Relay message delivery | Yes | Yes | +| Release | Yes | Yes | +| Fork | No | Protocol-dependent | +| Terminal stream | Yes | No | +| Raw PTY input | Yes | No | +| PTY resize | Yes | No | +| PTY snapshot | Yes | No | +| Session messages | No | Protocol-dependent | + +PTY-only routes such as `sendInput`, `resizePty`, and `snapshotPty` fail when +the target harness does not expose PTY capabilities. + +## Broker Lifetime + +Attached brokers are owned by the SDK process. They can use in-process dynamic +resolvers and decision hooks because the broker exits when the SDK control +connection exits. + +Detached brokers survive SDK callers. They can be reached later by another SDK, +the CLI, the dashboard, or agent-triggered spawn requests, so they require +durable plans and durable hooks. + +## See Also + +- [Spawning an agent](/docs/spawning-an-agent) - High-level spawn APIs +- [Event handlers](/docs/event-handlers) - SDK event subscriptions +- [Broker HTTP / WS API](/docs/reference-broker-api) - Broker API routes diff --git a/web/lib/docs-nav.ts b/web/lib/docs-nav.ts index 404751ff1..35f822c9b 100644 --- a/web/lib/docs-nav.ts +++ b/web/lib/docs-nav.ts @@ -20,6 +20,7 @@ export const docsNav: NavGroup[] = [ title: 'Basics', items: [ { title: 'Spawning an agent', slug: 'spawning-an-agent' }, + { title: 'Harnesses', slug: 'harnesses' }, { title: 'Sending messages', slug: 'sending-messages' }, { title: 'Event handlers', slug: 'event-handlers' }, { title: 'Channels', slug: 'channels' }, From 84d87355ef3a727947607690dd0df7bb0e158f5d Mon Sep 17 00:00:00 2001 From: Will Washburn Date: Mon, 25 May 2026 12:23:17 -0400 Subject: [PATCH 02/19] Implement harness runtime plans --- .../completed/2026-05/traj_i2pjnx3dll5b.json | 26 + .../completed/2026-05/traj_i2pjnx3dll5b.md | 21 + .../2026-05/traj_i2pjnx3dll5b.trace.json | 59 + .trajectories/index.json | 1126 +++++++++++++++++ CHANGELOG.md | 2 + crates/broker/src/cli/mod.rs | 23 + crates/broker/src/listen_api.rs | 34 +- crates/broker/src/protocol.rs | 212 +++- crates/broker/src/runtime/api.rs | 120 +- crates/broker/src/runtime/app_server.rs | 411 ++++++ crates/broker/src/runtime/mod.rs | 7 +- crates/broker/src/runtime/relaycast_events.rs | 4 + crates/broker/src/runtime/spawn_spec.rs | 38 +- crates/broker/src/runtime/tests.rs | 71 +- crates/broker/src/runtime/worker_events.rs | 8 +- crates/broker/src/supervisor.rs | 2 + crates/broker/src/worker.rs | 325 +++-- packages/sdk/src/__tests__/harness.test.ts | 95 ++ packages/sdk/src/client.ts | 27 +- packages/sdk/src/harness.ts | 224 ++++ packages/sdk/src/index.ts | 1 + packages/sdk/src/lifecycle-hooks.ts | 11 +- packages/sdk/src/protocol.ts | 9 +- packages/sdk/src/relay.ts | 157 ++- packages/sdk/src/types.ts | 13 +- 25 files changed, 2859 insertions(+), 167 deletions(-) create mode 100644 .trajectories/completed/2026-05/traj_i2pjnx3dll5b.json create mode 100644 .trajectories/completed/2026-05/traj_i2pjnx3dll5b.md create mode 100644 .trajectories/completed/2026-05/traj_i2pjnx3dll5b.trace.json create mode 100644 .trajectories/index.json create mode 100644 crates/broker/src/runtime/app_server.rs create mode 100644 packages/sdk/src/__tests__/harness.test.ts create mode 100644 packages/sdk/src/harness.ts diff --git a/.trajectories/completed/2026-05/traj_i2pjnx3dll5b.json b/.trajectories/completed/2026-05/traj_i2pjnx3dll5b.json new file mode 100644 index 000000000..be920a3ab --- /dev/null +++ b/.trajectories/completed/2026-05/traj_i2pjnx3dll5b.json @@ -0,0 +1,26 @@ +{ + "id": "traj_i2pjnx3dll5b", + "version": 1, + "task": { + "title": "Fresh harness runtime plan and implementation" + }, + "status": "completed", + "startedAt": "2026-05-25T15:49:27.102Z", + "completedAt": "2026-05-25T16:22:35.339Z", + "agents": [], + "chapters": [], + "retrospective": { + "summary": "Documented and implemented harness runtime plans with SDK static/dynamic resolution, broker PTY plan execution, and OpenCode app-server delivery.", + "approach": "Standard approach", + "confidence": 0.84 + }, + "commits": ["8ddc2f9d"], + "filesChanged": ["docs/harness-runtime-plan.md", "web/content/docs/harnesses.mdx", "web/lib/docs-nav.ts"], + "projectId": "/private/tmp/relay-harness-runtime-plans", + "tags": [], + "_trace": { + "startRef": "ff1d4da534c314ece4f3a0f66d29de59c3363232", + "endRef": "8ddc2f9d9e9fcf0504ad4bd76e8d7e0b1da8d299", + "traceId": "bb0dfc23-cfa6-4d25-9d72-4d0448733f1f" + } +} diff --git a/.trajectories/completed/2026-05/traj_i2pjnx3dll5b.md b/.trajectories/completed/2026-05/traj_i2pjnx3dll5b.md new file mode 100644 index 000000000..1b4401285 --- /dev/null +++ b/.trajectories/completed/2026-05/traj_i2pjnx3dll5b.md @@ -0,0 +1,21 @@ +# Trajectory: Fresh harness runtime plan and implementation + +> **Status:** ✅ Completed +> **Confidence:** 84% +> **Started:** May 25, 2026 at 11:49 AM +> **Completed:** May 25, 2026 at 12:22 PM + +--- + +## Summary + +Documented and implemented harness runtime plans with SDK static/dynamic resolution, broker PTY plan execution, and OpenCode app-server delivery. + +**Approach:** Standard approach + +--- + +## Artifacts + +**Commits:** 8ddc2f9d +**Files changed:** 3 diff --git a/.trajectories/completed/2026-05/traj_i2pjnx3dll5b.trace.json b/.trajectories/completed/2026-05/traj_i2pjnx3dll5b.trace.json new file mode 100644 index 000000000..04c1b1af0 --- /dev/null +++ b/.trajectories/completed/2026-05/traj_i2pjnx3dll5b.trace.json @@ -0,0 +1,59 @@ +{ + "version": "1.0.0", + "id": "bb0dfc23-cfa6-4d25-9d72-4d0448733f1f", + "timestamp": "2026-05-25T16:22:35.421Z", + "trajectory": "traj_i2pjnx3dll5b", + "files": [ + { + "path": "docs/harness-runtime-plan.md", + "conversations": [ + { + "contributor": { + "type": "ai" + }, + "ranges": [ + { + "start_line": 1, + "end_line": 184, + "revision": "8ddc2f9d9e9fcf0504ad4bd76e8d7e0b1da8d299" + } + ] + } + ] + }, + { + "path": "web/content/docs/harnesses.mdx", + "conversations": [ + { + "contributor": { + "type": "ai" + }, + "ranges": [ + { + "start_line": 1, + "end_line": 144, + "revision": "8ddc2f9d9e9fcf0504ad4bd76e8d7e0b1da8d299" + } + ] + } + ] + }, + { + "path": "web/lib/docs-nav.ts", + "conversations": [ + { + "contributor": { + "type": "ai" + }, + "ranges": [ + { + "start_line": 20, + "end_line": 26, + "revision": "8ddc2f9d9e9fcf0504ad4bd76e8d7e0b1da8d299" + } + ] + } + ] + } + ] +} diff --git a/.trajectories/index.json b/.trajectories/index.json new file mode 100644 index 000000000..d75b73b7e --- /dev/null +++ b/.trajectories/index.json @@ -0,0 +1,1126 @@ +{ + "version": 1, + "lastUpdated": "2026-05-25T16:22:35.521Z", + "trajectories": { + "traj_05xg7j388bc4": { + "title": "Add browser workflow step integration", + "status": "completed", + "startedAt": "2026-04-10T14:56:33.229Z", + "completedAt": "2026-04-10T15:05:14.660Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-04/traj_05xg7j388bc4.json" + }, + "traj_0t92gxaz6igh": { + "title": "Move docs sidebar into the mobile hamburger menu", + "status": "completed", + "startedAt": "2026-04-10T16:29:40.674Z", + "completedAt": "2026-04-10T16:32:14.544Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-04/traj_0t92gxaz6igh.json" + }, + "traj_1776105620545_9dcebb3d": { + "title": "fix-inbox-agent-flag-workflow", + "status": "completed", + "startedAt": "2026-04-13T18:40:20.545Z", + "completedAt": "2026-04-13T18:41:52.831Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-04/traj_1776105620545_9dcebb3d.json" + }, + "traj_1776105988184_29f1270c": { + "title": "fix-inbox-agent-flag-workflow", + "status": "completed", + "startedAt": "2026-04-13T18:46:28.184Z", + "completedAt": "2026-04-13T20:23:54.308Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-04/traj_1776105988184_29f1270c.json" + }, + "traj_222ha5671idc": { + "title": "validate-cloud-connect-e2e-workflow", + "status": "completed", + "startedAt": "2026-04-15T21:32:51.980Z", + "completedAt": "2026-04-15T21:45:41.024Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-04/traj_222ha5671idc.json" + }, + "traj_3b3p1z4y7qlo": { + "title": "add-mcp-args-subcommand-workflow", + "status": "completed", + "startedAt": "2026-04-20T13:16:22.009Z", + "completedAt": "2026-04-20T13:26:35.142Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-04/traj_3b3p1z4y7qlo.json" + }, + "traj_4zqhfqw7g28l": { + "title": "Investigate GitHub Actions failure for run 24255758219 job 70826792063", + "status": "completed", + "startedAt": "2026-04-10T17:48:33.502Z", + "completedAt": "2026-04-10T17:49:14.485Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-04/traj_4zqhfqw7g28l.json" + }, + "traj_530xmbfeljyb": { + "title": "Implement GitHub primitive adapter base layer", + "status": "completed", + "startedAt": "2026-04-10T15:16:25.682Z", + "completedAt": "2026-04-10T15:25:16.937Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-04/traj_530xmbfeljyb.json" + }, + "traj_703m7sqyq89t": { + "title": "Fix production docs loader using build-machine absolute MDX paths", + "status": "completed", + "startedAt": "2026-04-10T16:33:10.601Z", + "completedAt": "2026-04-10T16:35:33.660Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-04/traj_703m7sqyq89t.json" + }, + "traj_8oh4r5km5eic": { + "title": "Implement GitHub primitive actions", + "status": "completed", + "startedAt": "2026-04-10T15:26:11.355Z", + "completedAt": "2026-04-10T15:33:35.150Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-04/traj_8oh4r5km5eic.json" + }, + "traj_9tt55is74dq5": { + "title": "Pin TypeScript build resolution for acp-bridge, memory, trajectory, and cloud", + "status": "completed", + "startedAt": "2026-04-11T13:34:46.304Z", + "completedAt": "2026-04-11T13:35:22.677Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-04/traj_9tt55is74dq5.json" + }, + "traj_abjovknvcijv": { + "title": "Scope CI so web-only changes do not run unrelated relay and SDK tests", + "status": "completed", + "startedAt": "2026-04-10T16:08:30.070Z", + "completedAt": "2026-04-10T16:11:08.673Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-04/traj_abjovknvcijv.json" + }, + "traj_avmkyoo2s3rt": { + "title": "Implement Browser primitive client", + "status": "completed", + "startedAt": "2026-04-10T14:42:17.242Z", + "completedAt": "2026-04-10T14:55:45.196Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-04/traj_avmkyoo2s3rt.json" + }, + "traj_d48czxmgx4ac": { + "title": "Shift dark-mode footer from black to Relay blue", + "status": "completed", + "startedAt": "2026-04-10T16:12:27.477Z", + "completedAt": "2026-04-10T16:13:14.348Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-04/traj_d48czxmgx4ac.json" + }, + "traj_dw8ihhdb8ip7": { + "title": "fix-dm-history-workflow", + "status": "abandoned", + "startedAt": "2026-04-13T19:51:57.984Z", + "completedAt": "2026-04-13T19:57:27.195Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-04/traj_dw8ihhdb8ip7.json" + }, + "traj_e5i62wdjx0jd": { + "title": "Plan autofix finding groups", + "status": "completed", + "startedAt": "2026-04-13T09:40:42.044Z", + "completedAt": "2026-04-13T09:41:07.789Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-04/traj_e5i62wdjx0jd.json" + }, + "traj_g3muawdq6bsb": { + "title": "Invert dark footer gradient so the lighter blue is at the top", + "status": "completed", + "startedAt": "2026-04-10T16:13:19.744Z", + "completedAt": "2026-04-10T16:13:43.289Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-04/traj_g3muawdq6bsb.json" + }, + "traj_mk0t0cgn4ytq": { + "title": "Merge origin/main into better-nav and resolve trajectory conflicts", + "status": "completed", + "startedAt": "2026-04-10T15:10:03.877Z", + "completedAt": "2026-04-10T15:10:29.410Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-04/traj_mk0t0cgn4ytq.json" + }, + "traj_o8kgzhfu6jth": { + "title": "Add /cloud link to footer", + "status": "completed", + "startedAt": "2026-04-10T16:07:15.131Z", + "completedAt": "2026-04-10T16:07:42.930Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-04/traj_o8kgzhfu6jth.json" + }, + "traj_qb54w47qwod6": { + "title": "fix-history-from-workflow", + "status": "completed", + "startedAt": "2026-04-13T20:16:10.459Z", + "completedAt": "2026-04-13T20:25:09.219Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-04/traj_qb54w47qwod6.json" + }, + "traj_rs2bt3x0fqba": { + "title": "Compare failed web deploy to prior deploys and identify no-downtime fix", + "status": "completed", + "startedAt": "2026-04-10T17:50:43.088Z", + "completedAt": "2026-04-10T18:00:44.095Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-04/traj_rs2bt3x0fqba.json" + }, + "traj_tjadoebpscps": { + "title": "fix-dm-history-workflow", + "status": "completed", + "startedAt": "2026-04-13T20:02:27.719Z", + "completedAt": "2026-04-13T20:02:35.662Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-04/traj_tjadoebpscps.json" + }, + "traj_tv1x9pamkqad": { + "title": "Add GitHub primitive workflow step integration", + "status": "completed", + "startedAt": "2026-04-10T15:34:36.611Z", + "completedAt": "2026-04-10T15:42:17.590Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-04/traj_tv1x9pamkqad.json" + }, + "traj_ui5omrgz819d": { + "title": "cloud-run-start-from-workflow", + "status": "completed", + "startedAt": "2026-04-27T20:00:33.269Z", + "completedAt": "2026-04-27T20:08:46.379Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-04/traj_ui5omrgz819d.json" + }, + "traj_w0xpsaoxuiyw": { + "title": "Pin TypeScript compiler version and build invocation in selected packages", + "status": "completed", + "startedAt": "2026-04-11T13:35:52.600Z", + "completedAt": "2026-04-11T13:36:48.341Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-04/traj_w0xpsaoxuiyw.json" + }, + "traj_0e8i20oitwvz": { + "title": "Final fresh-eyes review Codex GPT-5.5 fix", + "status": "completed", + "startedAt": "2026-05-15T12:46:11.342Z", + "completedAt": "2026-05-15T12:46:11.500Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_0e8i20oitwvz.json" + }, + "traj_0o6gb2wvk59t": { + "title": "Fresh end-to-end validation for headless readiness", + "status": "completed", + "startedAt": "2026-05-15T10:55:49.188Z", + "completedAt": "2026-05-15T11:11:52.324Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_0o6gb2wvk59t.json" + }, + "traj_0z98tkaigaxg": { + "title": "ricky-child-update-issue-860-transcript-test-workflow", + "status": "completed", + "startedAt": "2026-05-15T21:06:58.558Z", + "completedAt": "2026-05-15T21:35:56.724Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_0z98tkaigaxg.json" + }, + "traj_1775914133873_35667beb": { + "title": "fix-sdk-build-resolution-workflow", + "status": "completed", + "startedAt": "2026-04-11T13:28:53.873Z", + "completedAt": "2026-05-08T13:33:48.161Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_1775914133873_35667beb.json" + }, + "traj_1776073106646_1839be2d": { + "title": "autofix-swarm-Agentworkforce-relay-workflow", + "status": "completed", + "startedAt": "2026-04-13T09:38:26.646Z", + "completedAt": "2026-05-08T13:33:45.944Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_1776073106646_1839be2d.json" + }, + "traj_1776113772922_bc92f121": { + "title": "autofix-swarm-Agentworkforce-relay-workflow", + "status": "completed", + "startedAt": "2026-04-13T20:56:12.922Z", + "completedAt": "2026-05-08T13:33:43.489Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_1776113772922_bc92f121.json" + }, + "traj_1778873209642_c70e32ab": { + "title": "ricky-child-update-2-workflow", + "status": "completed", + "startedAt": "2026-05-15T19:26:49.642Z", + "completedAt": "2026-05-15T19:36:18.257Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_1778873209642_c70e32ab.json" + }, + "traj_1778873211616_6db3b2cd": { + "title": "ricky-child-update-docs-sync-workflow", + "status": "completed", + "startedAt": "2026-05-15T19:26:51.616Z", + "completedAt": "2026-05-15T19:35:07.059Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_1778873211616_6db3b2cd.json" + }, + "traj_1rrpe2r7fyem": { + "title": "Use streaming PTY input in CLI drive", + "status": "completed", + "startedAt": "2026-05-20T07:20:33.009Z", + "completedAt": "2026-05-20T07:26:17.567Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_1rrpe2r7fyem.json" + }, + "traj_2gpglosdsq7s": { + "title": "Fix broker session read paths and agent listing errors", + "status": "completed", + "startedAt": "2026-05-19T12:37:18.367Z", + "completedAt": "2026-05-19T12:48:50.116Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_2gpglosdsq7s.json" + }, + "traj_2tqxnib25omk": { + "title": "Add workflow reliability contract coverage", + "status": "completed", + "startedAt": "2026-05-08T15:27:50.875Z", + "completedAt": "2026-05-08T15:28:02.639Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_2tqxnib25omk.json" + }, + "traj_2yicjxgajt0a": { + "title": "Review GPT-5.5 hardening", + "status": "completed", + "startedAt": "2026-05-15T10:54:19.300Z", + "completedAt": "2026-05-15T10:54:19.476Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_2yicjxgajt0a.json" + }, + "traj_34b1u84b19gz": { + "title": "Address PR 827 review feedback", + "status": "completed", + "startedAt": "2026-05-08T18:29:34.717Z", + "completedAt": "2026-05-08T18:33:55.607Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_34b1u84b19gz.json" + }, + "traj_3gjtcykvybt5": { + "title": "Fix PR CI failures", + "status": "completed", + "startedAt": "2026-05-15T11:24:06.054Z", + "completedAt": "2026-05-15T11:25:49.087Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_3gjtcykvybt5.json" + }, + "traj_47akjihewlow": { + "title": "Further split broker runtime module for issue 875", + "status": "completed", + "startedAt": "2026-05-19T01:28:35.746Z", + "completedAt": "2026-05-19T01:38:29.105Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_47akjihewlow.json" + }, + "traj_4chzkm724ufo": { + "title": "Fix headless orchestrator worktree CLI E2E issues", + "status": "completed", + "startedAt": "2026-05-15T11:44:28.338Z", + "completedAt": "2026-05-15T11:51:05.319Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_4chzkm724ufo.json" + }, + "traj_4t07itef99ug": { + "title": "Implement relay CLI bootstrap commands for proactive runtime M1", + "status": "completed", + "startedAt": "2026-05-11T21:47:37.805Z", + "completedAt": "2026-05-11T21:49:49.859Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_4t07itef99ug.json" + }, + "traj_4vucir4qvqa2": { + "title": "Harden headless broker readiness semantics", + "status": "completed", + "startedAt": "2026-05-15T09:46:07.617Z", + "completedAt": "2026-05-15T09:59:00.460Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_4vucir4qvqa2.json" + }, + "traj_5k0jtc1g5l33": { + "title": "Resolve PR 932 conflicts and review comments", + "status": "completed", + "startedAt": "2026-05-22T19:13:09.359Z", + "completedAt": "2026-05-22T19:13:16.971Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_5k0jtc1g5l33.json" + }, + "traj_5nzj6v56id4z": { + "title": "Fix PR914 review comments", + "status": "completed", + "startedAt": "2026-05-19T13:20:42.407Z", + "completedAt": "2026-05-19T13:26:28.697Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_5nzj6v56id4z.json" + }, + "traj_5q8i0iz4klpo": { + "title": "ricky-child-update-2-workflow", + "status": "completed", + "startedAt": "2026-05-15T21:07:02.452Z", + "completedAt": "2026-05-15T21:36:03.688Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_5q8i0iz4klpo.json" + }, + "traj_5qbla7w4kzoi": { + "title": "Fix issue 877", + "status": "completed", + "startedAt": "2026-05-19T03:40:40.798Z", + "completedAt": "2026-05-19T03:54:06.889Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_5qbla7w4kzoi.json" + }, + "traj_60qc24ufr96g": { + "title": "Expand workflow reliability contract matrix", + "status": "completed", + "startedAt": "2026-05-08T15:40:11.699Z", + "completedAt": "2026-05-08T15:40:22.521Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_60qc24ufr96g.json" + }, + "traj_6sjeohtm3php": { + "title": "Address broker headless reliability review findings", + "status": "completed", + "startedAt": "2026-05-15T09:30:56.316Z", + "completedAt": "2026-05-15T09:32:47.870Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_6sjeohtm3php.json" + }, + "traj_6ujzpx82gqs9": { + "title": "ricky-slack-primitive-implementation-workflow-status-r-workflow", + "status": "completed", + "startedAt": "2026-05-08T16:06:54.844Z", + "completedAt": "2026-05-08T16:18:16.119Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_6ujzpx82gqs9.json" + }, + "traj_78ytpicts778": { + "title": "Address PR 932 result callback review findings", + "status": "completed", + "startedAt": "2026-05-22T15:59:25.187Z", + "completedAt": "2026-05-22T16:05:12.320Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_78ytpicts778.json" + }, + "traj_7uznwzoxbao6": { + "title": "Fix standalone detached headless startup", + "status": "completed", + "startedAt": "2026-05-15T10:18:46.273Z", + "completedAt": "2026-05-15T10:25:00.598Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_7uznwzoxbao6.json" + }, + "traj_7zu7et53ph3l": { + "title": "Harden Codex GPT-5.5 local CLI compatibility", + "status": "completed", + "startedAt": "2026-05-15T10:35:25.212Z", + "completedAt": "2026-05-15T10:40:53.355Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_7zu7et53ph3l.json" + }, + "traj_81kobstnzzwk": { + "title": "Orchestrate team review cycle for #892 #893 #894 #895", + "status": "completed", + "startedAt": "2026-05-19T08:16:32.762Z", + "completedAt": "2026-05-19T08:37:32.966Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_81kobstnzzwk.json" + }, + "traj_8ljgydz61do5": { + "title": "ricky-child-update-messaging-2-workflow", + "status": "completed", + "startedAt": "2026-05-15T21:06:54.217Z", + "completedAt": "2026-05-15T21:41:56.478Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_8ljgydz61do5.json" + }, + "traj_90jmd9z27oap": { + "title": "Resolve PR 948 merge conflicts", + "status": "completed", + "startedAt": "2026-05-22T19:49:08.797Z", + "completedAt": "2026-05-22T20:45:01.262Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_90jmd9z27oap.json" + }, + "traj_947wzpddsg9j": { + "title": "Implement relay CLI bootstrap commands for proactive runtime M1", + "status": "completed", + "startedAt": "2026-05-11T23:11:57.326Z", + "completedAt": "2026-05-11T23:14:23.136Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_947wzpddsg9j.json" + }, + "traj_9fdv7hxm0b60": { + "title": "Strict standalone smoke follow-up", + "status": "completed", + "startedAt": "2026-05-15T10:37:17.693Z", + "completedAt": "2026-05-15T10:43:11.587Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_9fdv7hxm0b60.json" + }, + "traj_9gq96irkj00s": { + "title": "Update relay to use published relaycast Rust reclaim fix", + "status": "completed", + "startedAt": "2026-05-10T18:45:02.118Z", + "completedAt": "2026-05-10T18:48:11.532Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_9gq96irkj00s.json" + }, + "traj_aw7stgf4qau0": { + "title": "Fix publish smoke cloud tarball dependency", + "status": "completed", + "startedAt": "2026-05-11T07:49:42.778Z", + "completedAt": "2026-05-11T07:50:37.848Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_aw7stgf4qau0.json" + }, + "traj_bdrlknyl8twj": { + "title": "Add workflow reliability defaults and E2E matrix", + "status": "completed", + "startedAt": "2026-05-08T17:54:45.069Z", + "completedAt": "2026-05-08T18:05:37.305Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_bdrlknyl8twj.json" + }, + "traj_bz1a1o15p7px": { + "title": "Fix PR 949 CI failure", + "status": "completed", + "startedAt": "2026-05-22T16:56:55.021Z", + "completedAt": "2026-05-22T16:57:55.372Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_bz1a1o15p7px.json" + }, + "traj_cbmwd07phhm2": { + "title": "Implement #869 snapshot module + dump-pty command", + "status": "completed", + "startedAt": "2026-05-17T14:19:10.603Z", + "completedAt": "2026-05-17T14:33:32.293Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_cbmwd07phhm2.json" + }, + "traj_ceo5q9bh2od3": { + "title": "Add structured spawned-agent results", + "status": "completed", + "startedAt": "2026-05-20T21:24:17.929Z", + "completedAt": "2026-05-20T21:43:51.936Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_ceo5q9bh2od3.json" + }, + "traj_d89s38ddu7cj": { + "title": "Review Codex GPT-5.5 spawn fix", + "status": "completed", + "startedAt": "2026-05-15T12:25:39.946Z", + "completedAt": "2026-05-15T12:25:40.708Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_d89s38ddu7cj.json" + }, + "traj_dbsnr453nxjw": { + "title": "Confirm and remove unused package dependencies", + "status": "completed", + "startedAt": "2026-05-22T16:01:11.967Z", + "completedAt": "2026-05-22T16:12:01.466Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_dbsnr453nxjw.json" + }, + "traj_dcl9hgoiuac5": { + "title": "Verify --broker-name override for agent-relay up", + "status": "completed", + "startedAt": "2026-05-21T18:56:55.532Z", + "completedAt": "2026-05-21T19:00:06.831Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_dcl9hgoiuac5.json" + }, + "traj_dpgn0am1jq1c": { + "title": "Implement M1 relay CLI bootstrap commands", + "status": "completed", + "startedAt": "2026-05-11T18:43:20.429Z", + "completedAt": "2026-05-11T18:43:20.733Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_dpgn0am1jq1c.json" + }, + "traj_e1b7ww3un1u3": { + "title": "Harden agents logs raw and follow output", + "status": "completed", + "startedAt": "2026-05-19T10:59:00.118Z", + "completedAt": "2026-05-19T11:04:44.466Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_e1b7ww3un1u3.json" + }, + "traj_elx0fcwgs37x": { + "title": "ricky-child-update-messaging-workflow", + "status": "completed", + "startedAt": "2026-05-15T21:06:50.250Z", + "completedAt": "2026-05-15T21:46:46.167Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_elx0fcwgs37x.json" + }, + "traj_erzd7j9nto9r": { + "title": "Strict review and PR prep for headless broker readiness", + "status": "completed", + "startedAt": "2026-05-15T10:02:10.164Z", + "completedAt": "2026-05-15T10:06:38.127Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_erzd7j9nto9r.json" + }, + "traj_f1iac9ngymlj": { + "title": "Fix reliability review findings 892-895", + "status": "completed", + "startedAt": "2026-05-19T09:52:54.932Z", + "completedAt": "2026-05-19T10:01:19.068Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_f1iac9ngymlj.json" + }, + "traj_f3arvbmmlomn": { + "title": "Address PR feedback for headless broker reliability", + "status": "completed", + "startedAt": "2026-05-15T12:09:02.122Z", + "completedAt": "2026-05-15T12:15:11.435Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_f3arvbmmlomn.json" + }, + "traj_f9wxa8ujeg78": { + "title": "Refactor broker main for issue 875", + "status": "completed", + "startedAt": "2026-05-19T00:54:40.328Z", + "completedAt": "2026-05-19T00:55:57.506Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_f9wxa8ujeg78.json" + }, + "traj_fh8oosbijpwc": { + "title": "Track A: relaycast subscribe + @self DM routing", + "status": "completed", + "startedAt": "2026-05-12T06:28:56.427Z", + "completedAt": "2026-05-12T11:21:33.352Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_fh8oosbijpwc.json" + }, + "traj_gh05rj5gwsap": { + "title": "Bump relaycast Rust SDK in relay", + "status": "completed", + "startedAt": "2026-05-14T16:41:17.430Z", + "completedAt": "2026-05-14T16:42:32.485Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_gh05rj5gwsap.json" + }, + "traj_gnqvtoxtc8dy": { + "title": "Fix broker half-start recovery", + "status": "completed", + "startedAt": "2026-05-19T12:34:36.057Z", + "completedAt": "2026-05-19T12:47:18.115Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_gnqvtoxtc8dy.json" + }, + "traj_hfkww5z7trxn": { + "title": "Fresh comprehensive review of PR 856", + "status": "completed", + "startedAt": "2026-05-15T12:56:14.439Z", + "completedAt": "2026-05-15T13:00:15.366Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_hfkww5z7trxn.json" + }, + "traj_hrsndfzk0qay": { + "title": "Tighten Codex 5.5 fallback coverage", + "status": "completed", + "startedAt": "2026-05-15T10:57:41.681Z", + "completedAt": "2026-05-15T10:57:41.827Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_hrsndfzk0qay.json" + }, + "traj_hysw5o7idqas": { + "title": "Fix issue 924", + "status": "completed", + "startedAt": "2026-05-20T05:35:07.262Z", + "completedAt": "2026-05-20T05:47:54.189Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_hysw5o7idqas.json" + }, + "traj_ij5b3kcatvwn": { + "title": "ricky-reading-worker-dm-replies-design-spec-status-draft-date-2026-05-15-issue-860-hea-workflow", + "status": "completed", + "startedAt": "2026-05-15T21:06:45.545Z", + "completedAt": "2026-05-15T21:50:07.842Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_ij5b3kcatvwn.json" + }, + "traj_iole5zdt9orr": { + "title": "Fix PR 831 CI conflicts", + "status": "completed", + "startedAt": "2026-05-10T15:18:12.326Z", + "completedAt": "2026-05-10T15:29:41.840Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_iole5zdt9orr.json" + }, + "traj_irafiyk6wpw0": { + "title": "Fix agents:logs near-unparseable TTY redraw garbage (codex implement, claude review)", + "status": "completed", + "startedAt": "2026-05-19T10:30:38.222Z", + "completedAt": "2026-05-19T10:44:24.757Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_irafiyk6wpw0.json" + }, + "traj_itgr2w8qs3xn": { + "title": "Make workflow deterministic failures repairable by agents", + "status": "completed", + "startedAt": "2026-05-08T14:44:45.732Z", + "completedAt": "2026-05-08T14:44:45.984Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_itgr2w8qs3xn.json" + }, + "traj_j9k10fez3e81": { + "title": "review-loop-mpb2bvnf-1-workflow", + "status": "completed", + "startedAt": "2026-05-18T10:30:09.927Z", + "completedAt": "2026-05-18T14:53:04.092Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_j9k10fez3e81.json" + }, + "traj_jbo2x14y7ovt": { + "title": "Fix issue 876", + "status": "completed", + "startedAt": "2026-05-19T02:48:10.768Z", + "completedAt": "2026-05-19T02:56:24.584Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_jbo2x14y7ovt.json" + }, + "traj_jmf9pyt3zikn": { + "title": "Fix issue 874", + "status": "completed", + "startedAt": "2026-05-19T00:07:13.993Z", + "completedAt": "2026-05-19T00:17:27.680Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_jmf9pyt3zikn.json" + }, + "traj_k7njijv51iq4": { + "title": "ricky-slack-primitive-implementation-workflow-status-r-workflow", + "status": "completed", + "startedAt": "2026-05-08T16:18:55.300Z", + "completedAt": "2026-05-08T16:26:03.266Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_k7njijv51iq4.json" + }, + "traj_lhyrcib40kao": { + "title": "Address PR #914 CodeRabbit reliability review findings", + "status": "completed", + "startedAt": "2026-05-19T11:52:46.110Z", + "completedAt": "2026-05-19T12:07:22.401Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_lhyrcib40kao.json" + }, + "traj_lieyyspidhfj": { + "title": "Fix PR 823 conflicts checks and comments", + "status": "completed", + "startedAt": "2026-05-09T08:37:17.563Z", + "completedAt": "2026-05-09T08:47:54.686Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_lieyyspidhfj.json" + }, + "traj_m7mpv7j8n78h": { + "title": "Address Relay PR 826 review feedback", + "status": "completed", + "startedAt": "2026-05-08T15:17:53.113Z", + "completedAt": "2026-05-08T15:24:32.409Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_m7mpv7j8n78h.json" + }, + "traj_mi9eqd4rjfea": { + "title": "Address stdio fresh review findings", + "status": "abandoned", + "startedAt": "2026-05-11T18:25:24.626Z", + "completedAt": "2026-05-11T18:37:05.318Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_mi9eqd4rjfea.json" + }, + "traj_mytnzgfayj3d": { + "title": "Fix PR 948 telemetry package validation failure", + "status": "completed", + "startedAt": "2026-05-22T23:34:27.422Z", + "completedAt": "2026-05-22T23:36:15.152Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_mytnzgfayj3d.json" + }, + "traj_mz5m5ysjj31e": { + "title": "Fix Relay SDK broker stdout drain", + "status": "completed", + "startedAt": "2026-05-10T20:24:43.831Z", + "completedAt": "2026-05-10T20:35:47.359Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_mz5m5ysjj31e.json" + }, + "traj_n8duofq5vq1a": { + "title": "Update Codex registry for GPT-5.5", + "status": "completed", + "startedAt": "2026-05-15T10:27:57.532Z", + "completedAt": "2026-05-15T10:33:19.705Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_n8duofq5vq1a.json" + }, + "traj_o251whkvy9rl": { + "title": "Fix Codex GPT-5.5 E2E rough edges", + "status": "completed", + "startedAt": "2026-05-15T11:59:26.764Z", + "completedAt": "2026-05-15T12:12:25.515Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_o251whkvy9rl.json" + }, + "traj_o9cx33xn5u39": { + "title": "add-mcp-args-register-flag-workflow", + "status": "completed", + "startedAt": "2026-04-20T15:06:23.387Z", + "completedAt": "2026-05-08T13:33:35.341Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_o9cx33xn5u39.json" + }, + "traj_ootb5rt3tozd": { + "title": "ricky-child-update-docs-sync-workflow", + "status": "completed", + "startedAt": "2026-05-15T21:07:04.494Z", + "completedAt": "2026-05-15T21:45:20.368Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_ootb5rt3tozd.json" + }, + "traj_oyc528j7suvo": { + "title": "Expose cloud workflow scheduling through Relay SDK", + "status": "completed", + "startedAt": "2026-05-09T19:43:34.805Z", + "completedAt": "2026-05-09T19:44:00.107Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_oyc528j7suvo.json" + }, + "traj_piik8r6zu3i7": { + "title": "Issue 867: RelayEventListener", + "status": "completed", + "startedAt": "2026-05-18T01:56:18.236Z", + "completedAt": "2026-05-18T02:01:49.991Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_piik8r6zu3i7.json" + }, + "traj_pmrcfj6or3pz": { + "title": "Address runtime split review comments", + "status": "completed", + "startedAt": "2026-05-19T02:03:43.962Z", + "completedAt": "2026-05-19T02:09:31.002Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_pmrcfj6or3pz.json" + }, + "traj_qtmid2nzz0kz": { + "title": "Address PR 929 review comments", + "status": "completed", + "startedAt": "2026-05-20T06:21:54.721Z", + "completedAt": "2026-05-20T06:26:56.700Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_qtmid2nzz0kz.json" + }, + "traj_ryf5sstno6p3": { + "title": "Telemetry key from env (P0.5 of #881)", + "status": "completed", + "startedAt": "2026-05-18T02:56:55.314Z", + "completedAt": "2026-05-18T03:02:35.202Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_ryf5sstno6p3.json" + }, + "traj_s5ojo1f4srz4": { + "title": "Remove unused user-directory package", + "status": "completed", + "startedAt": "2026-05-22T16:27:44.927Z", + "completedAt": "2026-05-22T16:36:20.545Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_s5ojo1f4srz4.json" + }, + "traj_sh2ahp9z2xg6": { + "title": "Fix uuid install deprecation warning", + "status": "completed", + "startedAt": "2026-05-19T17:21:40.756Z", + "completedAt": "2026-05-19T17:21:49.702Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_sh2ahp9z2xg6.json" + }, + "traj_sqerp89tc436": { + "title": "Remove legacy root bin fallback", + "status": "completed", + "startedAt": "2026-05-19T00:45:33.159Z", + "completedAt": "2026-05-19T00:50:03.857Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_sqerp89tc436.json" + }, + "traj_t5uknesn2fcw": { + "title": "ricky-child-update-skill-workflow", + "status": "completed", + "startedAt": "2026-05-15T21:06:52.453Z", + "completedAt": "2026-05-15T21:40:04.209Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_t5uknesn2fcw.json" + }, + "traj_tavtex0db4b0": { + "title": "Make workflow failures repairable by agents", + "status": "completed", + "startedAt": "2026-05-08T14:34:19.969Z", + "completedAt": "2026-05-08T14:44:45.719Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_tavtex0db4b0.json" + }, + "traj_tgism98me5na": { + "title": "Implement relay CLI proactive runtime bootstrap commands", + "status": "completed", + "startedAt": "2026-05-11T20:04:48.053Z", + "completedAt": "2026-05-11T20:05:54.956Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_tgism98me5na.json" + }, + "traj_u33qn99ijbh4": { + "title": "ricky-child-update-workflow", + "status": "completed", + "startedAt": "2026-05-15T21:07:00.444Z", + "completedAt": "2026-05-15T21:30:50.445Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_u33qn99ijbh4.json" + }, + "traj_u3loicehnwb4": { + "title": "Gate broker diagnostic logs behind env flag", + "status": "completed", + "startedAt": "2026-05-21T04:14:44.815Z", + "completedAt": "2026-05-21T04:14:45.063Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_u3loicehnwb4.json" + }, + "traj_u4ixmbqqm2y1": { + "title": "Add cloud workflow schedule CLI", + "status": "completed", + "startedAt": "2026-05-09T19:26:42.106Z", + "completedAt": "2026-05-09T19:29:18.024Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_u4ixmbqqm2y1.json" + }, + "traj_uf8y40ewrfh0": { + "title": "Address PR 831 review feedback and conflicts", + "status": "completed", + "startedAt": "2026-05-09T19:59:24.197Z", + "completedAt": "2026-05-09T19:59:24.403Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_uf8y40ewrfh0.json" + }, + "traj_v1wexlfur5zr": { + "title": "Fix broker headless reliability doc", + "status": "completed", + "startedAt": "2026-05-15T09:04:51.316Z", + "completedAt": "2026-05-15T09:13:50.970Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_v1wexlfur5zr.json" + }, + "traj_v87cyrs8dke9": { + "title": "Refactor runDriveSession below complexity 15 (#897)", + "status": "completed", + "startedAt": "2026-05-14T14:28:34.155Z", + "completedAt": "2026-05-18T18:06:04.950Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_v87cyrs8dke9.json" + }, + "traj_v9x3o92ag682": { + "title": "ricky-child-update-messaging-test-workflow", + "status": "completed", + "startedAt": "2026-05-15T21:06:56.418Z", + "completedAt": "2026-05-15T21:34:35.623Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_v9x3o92ag682.json" + }, + "traj_vfa1jr6otnjn": { + "title": "Refresh PR 948 after main advanced", + "status": "completed", + "startedAt": "2026-05-22T23:23:16.807Z", + "completedAt": "2026-05-22T23:23:26.380Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_vfa1jr6otnjn.json" + }, + "traj_vkozdglobkyg": { + "title": "Address Relay PR 826 review comments", + "status": "completed", + "startedAt": "2026-05-08T15:50:35.978Z", + "completedAt": "2026-05-08T15:51:38.854Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_vkozdglobkyg.json" + }, + "traj_wbn62q4cq16h": { + "title": "Update generated workflow to Codex agents only", + "status": "completed", + "startedAt": "2026-05-15T21:03:02.671Z", + "completedAt": "2026-05-15T21:06:00.384Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_wbn62q4cq16h.json" + }, + "traj_whd40oxptlhn": { + "title": "Review spawn persistence fix and open PR", + "status": "completed", + "startedAt": "2026-05-13T10:57:02.796Z", + "completedAt": "2026-05-13T11:00:43.100Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_whd40oxptlhn.json" + }, + "traj_wx00tjvpptvg": { + "title": "Investigate agent-relay spawn persistence", + "status": "completed", + "startedAt": "2026-05-13T10:49:12.464Z", + "completedAt": "2026-05-13T10:53:03.748Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_wx00tjvpptvg.json" + }, + "traj_wzzboitm85ee": { + "title": "Resolve PR conflicts around platform tradeoff copy", + "status": "completed", + "startedAt": "2026-05-15T12:47:36.508Z", + "completedAt": "2026-05-15T12:50:14.358Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_wzzboitm85ee.json" + }, + "traj_x37bhga2j5ph": { + "title": "Deepen broker runtime refactor for PR 906", + "status": "completed", + "startedAt": "2026-05-19T01:42:10.602Z", + "completedAt": "2026-05-19T01:50:40.359Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_x37bhga2j5ph.json" + }, + "traj_ybcrij9wg8m1": { + "title": "Implement agent-relay view read-only stream client (#864 sub-1)", + "status": "completed", + "startedAt": "2026-05-18T02:02:07.524Z", + "completedAt": "2026-05-18T02:05:41.120Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_ybcrij9wg8m1.json" + }, + "traj_z171lng2fbbi": { + "title": "Address PR 840 review feedback", + "status": "completed", + "startedAt": "2026-05-11T08:06:37.977Z", + "completedAt": "2026-05-11T08:07:48.097Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_z171lng2fbbi.json" + }, + "traj_zfa6skfr32vy": { + "title": "Implement relay CLI M1 bootstrap commands", + "status": "completed", + "startedAt": "2026-05-11T19:31:44.734Z", + "completedAt": "2026-05-11T19:34:54.971Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_zfa6skfr32vy.json" + }, + "traj_zqwco4gl76g3": { + "title": "Fix issue 878", + "status": "completed", + "startedAt": "2026-05-19T04:18:25.024Z", + "completedAt": "2026-05-19T04:27:18.903Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_zqwco4gl76g3.json" + }, + "traj_zu3252hxzoqh": { + "title": "Open PR for reading worker DM replies", + "status": "completed", + "startedAt": "2026-05-16T06:08:22.396Z", + "completedAt": "2026-05-16T06:09:24.599Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_zu3252hxzoqh.json" + }, + "traj_1775914296101_a4397efe": { + "title": "fix-sdk-build-resolution-workflow", + "status": "completed", + "startedAt": "2026-04-11T13:31:36.101Z", + "completedAt": "2026-04-11T13:39:53.105Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/traj_1775914296101_a4397efe.json" + }, + "traj_1776024661304_cfc829b9": { + "title": "fix-workflow-resume-elegant-workflow", + "status": "abandoned", + "startedAt": "2026-04-12T20:11:01.304Z", + "completedAt": "2026-04-12T20:11:16.381Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/traj_1776024661304_cfc829b9.json" + }, + "traj_1778873052429_03a4dacb": { + "title": "ricky-reading-worker-dm-replies-design-spec-status-draft-date-2026-05-15-issue-860-hea-workflow", + "status": "abandoned", + "startedAt": "2026-05-15T19:24:12.429Z", + "completedAt": "2026-05-15T20:01:57.036Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/traj_1778873052429_03a4dacb.json" + }, + "traj_1778873197540_01102ade": { + "title": "ricky-child-update-messaging-workflow", + "status": "abandoned", + "startedAt": "2026-05-15T19:26:37.540Z", + "completedAt": "2026-05-15T19:43:47.629Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/traj_1778873197540_01102ade.json" + }, + "traj_1778873199489_f2ce4060": { + "title": "ricky-child-update-skill-workflow", + "status": "abandoned", + "startedAt": "2026-05-15T19:26:39.489Z", + "completedAt": "2026-05-15T19:43:43.149Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/traj_1778873199489_f2ce4060.json" + }, + "traj_1778873201502_0dacf7c5": { + "title": "ricky-child-update-messaging-2-workflow", + "status": "abandoned", + "startedAt": "2026-05-15T19:26:41.502Z", + "completedAt": "2026-05-15T19:43:35.011Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/traj_1778873201502_0dacf7c5.json" + }, + "traj_1778873203502_4c225b7e": { + "title": "ricky-child-update-messaging-test-workflow", + "status": "abandoned", + "startedAt": "2026-05-15T19:26:43.502Z", + "completedAt": "2026-05-15T19:44:33.074Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/traj_1778873203502_4c225b7e.json" + }, + "traj_1778873205470_a4e5f0cb": { + "title": "ricky-child-update-issue-860-transcript-test-workflow", + "status": "abandoned", + "startedAt": "2026-05-15T19:26:45.470Z", + "completedAt": "2026-05-15T19:43:37.134Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/traj_1778873205470_a4e5f0cb.json" + }, + "traj_1778873207471_b7def991": { + "title": "ricky-child-update-workflow", + "status": "abandoned", + "startedAt": "2026-05-15T19:26:47.471Z", + "completedAt": "2026-05-15T19:43:24.329Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/traj_1778873207471_b7def991.json" + }, + "traj_1778874205797_81e92307": { + "title": "ricky-child-update-workflow", + "status": "abandoned", + "startedAt": "2026-05-15T19:43:25.797Z", + "completedAt": "2026-05-15T19:43:43.995Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/traj_1778874205797_81e92307.json" + }, + "traj_1778874216773_c6b12ab2": { + "title": "ricky-child-update-messaging-2-workflow", + "status": "abandoned", + "startedAt": "2026-05-15T19:43:36.773Z", + "completedAt": "2026-05-15T19:44:08.270Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/traj_1778874216773_c6b12ab2.json" + }, + "traj_1778874218579_a0225559": { + "title": "ricky-child-update-issue-860-transcript-test-workflow", + "status": "abandoned", + "startedAt": "2026-05-15T19:43:38.579Z", + "completedAt": "2026-05-15T19:43:58.721Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/traj_1778874218579_a0225559.json" + }, + "traj_1778874224855_9c722c4b": { + "title": "ricky-child-update-skill-workflow", + "status": "abandoned", + "startedAt": "2026-05-15T19:43:44.855Z", + "completedAt": "2026-05-15T19:44:16.528Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/traj_1778874224855_9c722c4b.json" + }, + "traj_1778874226983_3367d527": { + "title": "ricky-child-update-workflow", + "status": "abandoned", + "startedAt": "2026-05-15T19:43:46.983Z", + "completedAt": "2026-05-15T19:44:05.612Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/traj_1778874226983_3367d527.json" + }, + "traj_1778874229373_9cce9465": { + "title": "ricky-child-update-messaging-workflow", + "status": "abandoned", + "startedAt": "2026-05-15T19:43:49.374Z", + "completedAt": "2026-05-15T19:44:20.096Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/traj_1778874229373_9cce9465.json" + }, + "traj_1778874240339_51b823cd": { + "title": "ricky-child-update-issue-860-transcript-test-workflow", + "status": "abandoned", + "startedAt": "2026-05-15T19:44:00.339Z", + "completedAt": "2026-05-15T19:44:18.916Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/traj_1778874240339_51b823cd.json" + }, + "traj_1778874241076_caa675a9": { + "title": "ricky-child-update-2-workflow", + "status": "abandoned", + "startedAt": "2026-05-15T19:44:01.076Z", + "completedAt": "2026-05-15T19:44:32.521Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/traj_1778874241076_caa675a9.json" + }, + "traj_1778874248966_e29c4c54": { + "title": "ricky-child-update-workflow", + "status": "abandoned", + "startedAt": "2026-05-15T19:44:08.966Z", + "completedAt": "2026-05-15T19:44:27.330Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/traj_1778874248966_e29c4c54.json" + }, + "traj_1778874249983_12a98df3": { + "title": "ricky-child-update-messaging-2-workflow", + "status": "abandoned", + "startedAt": "2026-05-15T19:44:09.983Z", + "completedAt": "2026-05-15T19:44:41.100Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/traj_1778874249983_12a98df3.json" + }, + "traj_1778874258229_0bdc53d8": { + "title": "ricky-child-update-skill-workflow", + "status": "abandoned", + "startedAt": "2026-05-15T19:44:18.229Z", + "completedAt": "2026-05-15T19:44:49.274Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/traj_1778874258229_0bdc53d8.json" + }, + "traj_1778874261453_55f49624": { + "title": "ricky-child-update-messaging-workflow", + "status": "abandoned", + "startedAt": "2026-05-15T19:44:21.453Z", + "completedAt": "2026-05-15T19:44:53.643Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/traj_1778874261453_55f49624.json" + }, + "traj_1778874261608_48fb9bf5": { + "title": "ricky-child-update-issue-860-transcript-test-workflow", + "status": "abandoned", + "startedAt": "2026-05-15T19:44:21.608Z", + "completedAt": "2026-05-15T19:44:40.761Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/traj_1778874261608_48fb9bf5.json" + }, + "traj_1778874269139_d7d7485a": { + "title": "ricky-child-update-workflow", + "status": "abandoned", + "startedAt": "2026-05-15T19:44:29.139Z", + "completedAt": "2026-05-15T19:44:48.083Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/traj_1778874269139_d7d7485a.json" + }, + "traj_1778874274412_70843e0e": { + "title": "ricky-child-update-2-workflow", + "status": "abandoned", + "startedAt": "2026-05-15T19:44:34.412Z", + "completedAt": "2026-05-15T19:45:06.798Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/traj_1778874274412_70843e0e.json" + }, + "traj_1778874274581_71efa470": { + "title": "ricky-child-update-messaging-test-workflow", + "status": "abandoned", + "startedAt": "2026-05-15T19:44:34.581Z", + "completedAt": "2026-05-15T19:44:54.182Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/traj_1778874274581_71efa470.json" + }, + "traj_1778874282200_39ad11db": { + "title": "ricky-child-update-issue-860-transcript-test-workflow", + "status": "abandoned", + "startedAt": "2026-05-15T19:44:42.200Z", + "completedAt": "2026-05-15T19:45:02.477Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/traj_1778874282200_39ad11db.json" + }, + "traj_1778874283570_ce3585b8": { + "title": "ricky-child-update-messaging-2-workflow", + "status": "abandoned", + "startedAt": "2026-05-15T19:44:43.570Z", + "completedAt": "2026-05-15T19:45:14.888Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/traj_1778874283570_ce3585b8.json" + }, + "traj_1778874289674_e3f868c8": { + "title": "ricky-child-update-workflow", + "status": "abandoned", + "startedAt": "2026-05-15T19:44:49.674Z", + "completedAt": "2026-05-15T19:45:08.337Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/traj_1778874289674_e3f868c8.json" + }, + "traj_1778874291950_0b1b5c1f": { + "title": "ricky-child-update-skill-workflow", + "status": "abandoned", + "startedAt": "2026-05-15T19:44:51.950Z", + "completedAt": "2026-05-15T19:45:23.421Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/traj_1778874291950_0b1b5c1f.json" + }, + "traj_1778874295927_4083d181": { + "title": "ricky-child-update-messaging-test-workflow", + "status": "abandoned", + "startedAt": "2026-05-15T19:44:55.927Z", + "completedAt": "2026-05-15T19:45:15.333Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/traj_1778874295927_4083d181.json" + }, + "traj_1778874296362_bdf727ff": { + "title": "ricky-child-update-messaging-workflow", + "status": "abandoned", + "startedAt": "2026-05-15T19:44:56.362Z", + "completedAt": "2026-05-15T19:45:27.624Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/traj_1778874296362_bdf727ff.json" + }, + "traj_i2pjnx3dll5b": { + "title": "Fresh harness runtime plan and implementation", + "status": "completed", + "startedAt": "2026-05-25T15:49:27.102Z", + "completedAt": "2026-05-25T16:22:35.339Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_i2pjnx3dll5b.json" + } + } +} diff --git a/CHANGELOG.md b/CHANGELOG.md index d93eda36b..036f683ee 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - Broker and TypeScript SDK structured result contracts add the `submit_result` MCP tool, `agent.waitForResult()`, per-spawn `result.onResult`, and `relay.addListener('agentResult', ...)` for typed JSON worker outcomes. +- `@agent-relay/sdk` harness definitions resolve named agent runtimes into broker-executable `pty` or `app_server` plans, so custom CLIs like Qwen can be configured without Rust changes. +- `agent-relay-broker` accepts resolved harness plans on spawn and adds an `app_server` runtime path for delivering Relay messages to existing OpenCode server sessions. ### Changed diff --git a/crates/broker/src/cli/mod.rs b/crates/broker/src/cli/mod.rs index 5f90bf40a..eeb66e861 100644 --- a/crates/broker/src/cli/mod.rs +++ b/crates/broker/src/cli/mod.rs @@ -25,6 +25,7 @@ enum Commands { Init(InitCommand), Pty(PtyCommand), Headless(HeadlessCommand), + AppServer(AppServerCommand), /// Compute MCP injection args and side-effect config file paths for a CLI /// without spawning it. Outputs JSON to stdout. McpArgs(McpArgsCommand), @@ -52,6 +53,7 @@ impl Commands { Commands::Init(_) => "init", Commands::Pty(_) => "pty", Commands::Headless(_) => "headless", + Commands::AppServer(_) => "app_server", Commands::McpArgs(_) => "mcp_args", Commands::Swarm(_) => "swarm", Commands::DumpPty(_) => "dump_pty", @@ -86,6 +88,8 @@ impl Commands { } Commands::Headless(cmd) => non_empty_name(cmd.agent_name.as_deref()) .unwrap_or_else(|| format!("headless-{pid}")), + Commands::AppServer(cmd) => non_empty_name(cmd.agent_name.as_deref()) + .unwrap_or_else(|| format!("app_server-{pid}")), Commands::Wrap { cli, .. } => format!("wrap-{cli}-{pid}"), Commands::McpArgs(_) => format!("mcp_args-{pid}"), Commands::DumpPty(cmd) => format!("dump_pty-{}-{}", cmd.name, pid), @@ -114,6 +118,7 @@ pub(crate) async fn run() -> Result<()> { Commands::Init(cmd) => runtime::run_init(cmd, telemetry).await, Commands::Pty(cmd) => pty_worker::run_pty_worker(cmd).await, Commands::Headless(cmd) => runtime::run_headless_worker(cmd).await, + Commands::AppServer(cmd) => runtime::run_app_server_worker(cmd).await, Commands::McpArgs(cmd) => cli_mcp_args::run_mcp_args(cmd).await, Commands::Swarm(args) => swarm::run_swarm(args).await, Commands::DumpPty(cmd) => runtime::run_dump_pty(cmd).await, @@ -269,6 +274,24 @@ pub(crate) struct HeadlessCommand { pub(crate) agent_name: Option, } +#[derive(Debug, clap::Args, Clone)] +pub(crate) struct AppServerCommand { + #[arg(long)] + pub(crate) protocol: String, + + #[arg(long)] + pub(crate) endpoint: String, + + #[arg(long = "session-id")] + pub(crate) session_id: String, + + #[arg(long, default_value = "detach")] + pub(crate) release: String, + + #[arg(long)] + pub(crate) agent_name: Option, +} + #[derive(Debug, Clone, Copy, ValueEnum)] pub(crate) enum HeadlessCliProvider { Claude, diff --git a/crates/broker/src/listen_api.rs b/crates/broker/src/listen_api.rs index 69a65963b..5388d0b37 100644 --- a/crates/broker/src/listen_api.rs +++ b/crates/broker/src/listen_api.rs @@ -11,7 +11,7 @@ use std::{ }; use crate::{ - protocol::MessageInjectionMode, + protocol::{MessageInjectionMode, ResolvedHarnessPlan}, relaycast::WorkspaceMembershipSummary, replay_buffer::ReplayBuffer, types::{InboundDeliveryMode, PendingRelayMessage}, @@ -50,6 +50,7 @@ pub enum ListenApiRequest { idle_threshold_secs: Option, skip_relay_prompt: bool, restart_policy: Box>, + harness_plan: Option, agent_token: Option, agent_result_schema: Option, reply: tokio::sync::oneshot::Sender>, @@ -648,6 +649,25 @@ async fn listen_api_spawn( .or_else(|| body.get("restartPolicy")) .cloned(), ); + let harness_plan = match body + .get("harness_plan") + .or_else(|| body.get("harnessPlan")) + .cloned() + { + Some(value) => match serde_json::from_value::(value) { + Ok(plan) => Some(plan), + Err(error) => { + return ( + axum::http::StatusCode::BAD_REQUEST, + axum::Json(json!({ + "success": false, + "error": format!("Invalid harnessPlan: {error}") + })), + ); + } + }, + None => None, + }; let agent_token = body .get("agent_token") .or_else(|| body.get("agentToken")) @@ -685,6 +705,7 @@ async fn listen_api_spawn( idle_threshold_secs, skip_relay_prompt, restart_policy, + harness_plan, agent_token, agent_result_schema, reply: reply_tx, @@ -2421,13 +2442,14 @@ mod auth_tests { idle_threshold_secs, skip_relay_prompt: _, restart_policy: _, + harness_plan, agent_token: _, agent_result_schema, reply, }) => { assert_eq!(name, "worker-a"); assert_eq!(cli, "codex"); - assert_eq!(transport.as_deref(), Some("headless")); + assert_eq!(transport.as_deref(), Some("pty")); assert_eq!(model.as_deref(), Some("o3")); assert_eq!(args, vec!["--fast".to_string()]); assert_eq!(task.as_deref(), Some("Ship it")); @@ -2441,6 +2463,7 @@ mod auth_tests { assert_eq!(shadow_mode.as_deref(), Some("subagent")); assert_eq!(continue_from.as_deref(), Some("worker-prev")); assert_eq!(idle_threshold_secs, Some(30)); + assert!(harness_plan.is_some()); assert_eq!( agent_result_schema, Some(json!({"type": "object", "properties": {"ok": {"type": "boolean"}}})) @@ -2464,7 +2487,7 @@ mod auth_tests { json!({ "name": "worker-a", "cli": "codex", - "transport": "headless", + "transport": "pty", "model": "o3", "args": ["--fast"], "task": "Ship it", @@ -2475,6 +2498,11 @@ mod auth_tests { "shadowMode": "subagent", "continueFrom": "worker-prev", "idleThresholdSecs": 30, + "harnessPlan": { + "runtime": "pty", + "command": "codex", + "args": ["--fast"] + }, "resultSchema": {"type": "object", "properties": {"ok": {"type": "boolean"}}}, }) .to_string(), diff --git a/crates/broker/src/protocol.rs b/crates/broker/src/protocol.rs index 5e18f649d..ac6fedeb7 100644 --- a/crates/broker/src/protocol.rs +++ b/crates/broker/src/protocol.rs @@ -1,3 +1,5 @@ +use std::collections::HashMap; + use serde::{Deserialize, Serialize}; use serde_json::Value; @@ -10,6 +12,7 @@ pub const PROTOCOL_VERSION: u32 = 2; pub enum AgentRuntime { Pty, Headless, + AppServer, } #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] @@ -20,6 +23,130 @@ pub enum HeadlessProvider { } #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +#[serde(rename_all = "kebab-case")] +pub enum PtyHarnessDeliveryMode { + PtyInjection, +} + +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +#[serde(rename_all = "kebab-case")] +pub enum PtyHarnessDeliveryFormat { + RelayBlock, +} + +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct PtyHarnessDelivery { + #[serde(default, skip_serializing_if = "Option::is_none")] + pub mode: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub format: Option, +} + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct PtyHarnessPlan { + pub command: String, + #[serde(default)] + pub args: Vec, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub cwd: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub env: Option>, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub session_id: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub delivery: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub metadata: Option>, +} + +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +#[serde(rename_all = "lowercase")] +pub enum AppServerAuthType { + Bearer, + Basic, + None, +} + +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct AppServerHarnessAuth { + #[serde(rename = "type")] + pub auth_type: AppServerAuthType, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub token: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub username: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub password: Option, +} + +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +#[serde(rename_all = "kebab-case")] +pub enum AppServerHostOwnership { + BrokerOwned, + Attached, +} + +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct AppServerHarnessHost { + #[serde(default, skip_serializing_if = "Option::is_none")] + pub ownership: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub pid: Option, +} + +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Default)] +#[serde(rename_all = "snake_case")] +pub enum HarnessReleasePolicy { + Abort, + #[default] + Detach, + Delete, +} + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct AppServerHarnessPlan { + pub protocol: String, + pub endpoint: String, + pub session_id: String, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub auth: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub host: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub release: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub metadata: Option>, +} + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +#[serde(tag = "runtime", rename_all = "snake_case")] +pub enum ResolvedHarnessPlan { + Pty(PtyHarnessPlan), + AppServer(AppServerHarnessPlan), +} + +impl ResolvedHarnessPlan { + pub(crate) fn runtime(&self) -> AgentRuntime { + match self { + Self::Pty(_) => AgentRuntime::Pty, + Self::AppServer(_) => AgentRuntime::AppServer, + } + } + + pub(crate) fn session_id(&self) -> Option<&str> { + match self { + Self::Pty(plan) => plan.session_id.as_deref(), + Self::AppServer(plan) => Some(plan.session_id.as_str()), + } + } +} + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] pub struct AgentSpec { pub name: String, pub runtime: AgentRuntime, @@ -27,6 +154,14 @@ pub struct AgentSpec { pub provider: Option, #[serde(default)] pub cli: Option, + #[serde(default, alias = "sessionId", skip_serializing_if = "Option::is_none")] + pub session_id: Option, + #[serde( + default, + alias = "harnessPlan", + skip_serializing_if = "Option::is_none" + )] + pub harness_plan: Option, #[serde(skip_serializing_if = "Option::is_none")] pub model: Option, #[serde(skip_serializing_if = "Option::is_none")] @@ -158,6 +293,8 @@ pub enum BrokerEvent { cli: Option, model: Option, pid: Option, + #[serde(default)] + session_id: Option, source: Option, }, AgentReleased { @@ -369,7 +506,8 @@ mod tests { use super::{ AgentRuntime, AgentSpec, BrokerEvent, BrokerToSdk, BrokerToWorker, HeadlessProvider, - MessageInjectionMode, ProtocolEnvelope, RelayDelivery, WorkerToBroker, PROTOCOL_VERSION, + MessageInjectionMode, ProtocolEnvelope, RelayDelivery, ResolvedHarnessPlan, WorkerToBroker, + PROTOCOL_VERSION, }; #[test] @@ -455,6 +593,7 @@ mod tests { cli: None, model: None, pid: None, + session_id: None, source: None, }); let encoded = serde_json::to_string(&event).unwrap(); @@ -548,6 +687,8 @@ mod tests { assert_eq!(spec.runtime, AgentRuntime::Pty); assert_eq!(spec.provider, None); assert_eq!(spec.cli, None); + assert_eq!(spec.session_id, None); + assert_eq!(spec.harness_plan, None); assert_eq!(spec.model, None); assert_eq!(spec.cwd, None); assert_eq!(spec.team, None); @@ -569,6 +710,75 @@ mod tests { assert_eq!(decoded.provider, Some(HeadlessProvider::Opencode)); } + #[test] + fn agent_spec_accepts_camel_case_harness_plan() { + let raw = r#"{ + "name": "QwenWorker", + "runtime": "pty", + "cli": "qwen", + "sessionId": "native-session", + "harnessPlan": { + "runtime": "pty", + "command": "qwen", + "args": ["run", "-m", "qwen3-coder"], + "cwd": "/tmp/project", + "env": { "QWEN_MODE": "code" }, + "sessionId": "native-session" + } + }"#; + + let spec: AgentSpec = serde_json::from_str(raw).unwrap(); + assert_eq!(spec.runtime, AgentRuntime::Pty); + assert_eq!(spec.session_id.as_deref(), Some("native-session")); + let Some(ResolvedHarnessPlan::Pty(plan)) = spec.harness_plan else { + panic!("expected pty harness plan"); + }; + assert_eq!(plan.command, "qwen"); + assert_eq!( + plan.args, + vec![ + "run".to_string(), + "-m".to_string(), + "qwen3-coder".to_string() + ] + ); + assert_eq!(plan.cwd.as_deref(), Some("/tmp/project")); + assert_eq!( + plan.env + .as_ref() + .and_then(|env| env.get("QWEN_MODE")) + .map(String::as_str), + Some("code") + ); + assert_eq!(plan.session_id.as_deref(), Some("native-session")); + } + + #[test] + fn app_server_harness_plan_round_trips() { + let raw = json!({ + "runtime": "app_server", + "protocol": "opencode", + "endpoint": "http://127.0.0.1:4096", + "sessionId": "ses_123", + "auth": { + "type": "basic", + "username": "opencode", + "password": "secret" + }, + "release": "abort" + }); + + let plan: ResolvedHarnessPlan = serde_json::from_value(raw).unwrap(); + assert_eq!(plan.runtime(), AgentRuntime::AppServer); + assert_eq!(plan.session_id(), Some("ses_123")); + + let encoded = serde_json::to_string(&plan).unwrap(); + assert!(encoded.contains("\"runtime\":\"app_server\"")); + assert!(encoded.contains("\"sessionId\":\"ses_123\"")); + let decoded: ResolvedHarnessPlan = serde_json::from_str(&encoded).unwrap(); + assert_eq!(decoded.session_id(), Some("ses_123")); + } + #[test] fn broker_to_worker_resize_pty_round_trip() { let msg = BrokerToWorker::ResizePty { diff --git a/crates/broker/src/runtime/api.rs b/crates/broker/src/runtime/api.rs index 1f812d341..5eaa2df4b 100644 --- a/crates/broker/src/runtime/api.rs +++ b/crates/broker/src/runtime/api.rs @@ -45,6 +45,7 @@ impl BrokerRuntime { idle_threshold_secs, skip_relay_prompt, restart_policy, + harness_plan, agent_token, agent_result_schema, reply, @@ -66,6 +67,7 @@ impl BrokerRuntime { shadow_of, shadow_mode, *restart_policy, + harness_plan, ) { Ok(spec) => spec, Err(error) => { @@ -268,6 +270,7 @@ impl BrokerRuntime { "cli": effective_spec.cli.clone(), "model": effective_spec.model.clone(), "pid":pid, + "sessionId": effective_spec.session_id.clone(), "source":"http_api", "pre_registered": worker_relay_key.is_some(), "registration_warning": preregistration_warning.clone(), @@ -287,6 +290,7 @@ impl BrokerRuntime { "runtime": runtime_label(&effective_spec.runtime), "model": effective_spec.model.clone(), "pid": pid, + "sessionId": effective_spec.session_id.clone(), "pre_registered": worker_relay_key.is_some(), "warning": preregistration_warning, }))); @@ -940,21 +944,43 @@ impl BrokerRuntime { let _ = reply.send(Ok(json!({ "threads": threads }))); } ListenApiRequest::SendInput { name, data, reply } => { - if let Err(err) = workers - .send_to_worker( - &name, - "write_pty", - Some(format!("api_{}", Uuid::new_v4().simple())), - json!({ "data": data }), - ) - .await + match workers + .workers + .get(&name) + .map(|handle| handle.spec.runtime.clone()) { - let _ = reply.send(Err(format!("agent_not_found: {}", err))); - } else { - let _ = reply.send(Ok(json!({ - "name": name, - "bytes_written": data.len(), - }))); + None => { + let _ = + reply.send(Err(format!("agent_not_found: no worker named '{name}'"))); + } + Some(AgentRuntime::Headless) => { + let _ = reply.send(Err(format!( + "unsupported_runtime: worker '{name}' is headless; pty input is only supported on PTY workers" + ))); + } + Some(AgentRuntime::AppServer) => { + let _ = reply.send(Err(format!( + "unsupported_runtime: worker '{name}' is app_server; pty input is only supported on PTY workers" + ))); + } + Some(AgentRuntime::Pty) => { + if let Err(err) = workers + .send_to_worker( + &name, + "write_pty", + Some(format!("api_{}", Uuid::new_v4().simple())), + json!({ "data": data }), + ) + .await + { + let _ = reply.send(Err(format!("agent_not_found: {}", err))); + } else { + let _ = reply.send(Ok(json!({ + "name": name, + "bytes_written": data.len(), + }))); + } + } } } ListenApiRequest::CheckPtyInputTarget { name, reply } => { @@ -972,6 +998,11 @@ impl BrokerRuntime { "unsupported_runtime: worker '{name}' is headless; pty input streams are only supported on PTY workers" ))); } + Some(AgentRuntime::AppServer) => { + let _ = reply.send(Err(format!( + "unsupported_runtime: worker '{name}' is app_server; pty input streams are only supported on PTY workers" + ))); + } Some(AgentRuntime::Pty) => { let _ = reply.send(Ok(json!({ "name": name, @@ -989,22 +1020,46 @@ impl BrokerRuntime { if rows == 0 || cols == 0 { let _ = reply.send(Err("invalid_dimensions: rows and cols must be >= 1".into())); - } else if let Err(err) = workers - .send_to_worker( - &name, - "resize_pty", - Some(format!("api_{}", Uuid::new_v4().simple())), - json!({ "rows": rows, "cols": cols }), - ) - .await - { - let _ = reply.send(Err(format!("agent_not_found: {}", err))); } else { - let _ = reply.send(Ok(json!({ - "name": name, - "rows": rows, - "cols": cols, - }))); + match workers + .workers + .get(&name) + .map(|handle| handle.spec.runtime.clone()) + { + None => { + let _ = reply + .send(Err(format!("agent_not_found: no worker named '{name}'"))); + } + Some(AgentRuntime::Headless) => { + let _ = reply.send(Err(format!( + "unsupported_runtime: worker '{name}' is headless; resize_pty is only supported on PTY workers" + ))); + } + Some(AgentRuntime::AppServer) => { + let _ = reply.send(Err(format!( + "unsupported_runtime: worker '{name}' is app_server; resize_pty is only supported on PTY workers" + ))); + } + Some(AgentRuntime::Pty) => { + if let Err(err) = workers + .send_to_worker( + &name, + "resize_pty", + Some(format!("api_{}", Uuid::new_v4().simple())), + json!({ "rows": rows, "cols": cols }), + ) + .await + { + let _ = reply.send(Err(format!("agent_not_found: {}", err))); + } else { + let _ = reply.send(Ok(json!({ + "name": name, + "rows": rows, + "cols": cols, + }))); + } + } + } } } ListenApiRequest::WorkerRequest { @@ -1045,6 +1100,13 @@ impl BrokerRuntime { ), )); } + Some(AgentRuntime::AppServer) => { + let _ = reply.send(Err( + worker_request::RequestWorkerError::UnsupportedRuntime(format!( + "worker '{name}' is app_server; {kind} is only supported on PTY workers" + )), + )); + } Some(AgentRuntime::Pty) => { let request_id = format!("req_{}", Uuid::new_v4().simple()); if let Err(err) = workers diff --git a/crates/broker/src/runtime/app_server.rs b/crates/broker/src/runtime/app_server.rs new file mode 100644 index 000000000..caaf96e4c --- /dev/null +++ b/crates/broker/src/runtime/app_server.rs @@ -0,0 +1,411 @@ +use super::*; + +#[derive(Debug, Clone)] +struct AppServerAuthConfig { + auth_type: String, + token: Option, + username: Option, + password: Option, +} + +pub(crate) async fn run_app_server_worker(cmd: AppServerCommand) -> Result<()> { + let protocol = cmd.protocol.trim().to_ascii_lowercase(); + let endpoint = cmd.endpoint.trim().trim_end_matches('/').to_string(); + let session_id = cmd.session_id.clone(); + let release = cmd.release.trim().to_ascii_lowercase(); + let auth = app_server_auth_from_env(); + let http = reqwest::Client::new(); + + let (out_tx, mut out_rx) = mpsc::channel::>(512); + let writer_task = tokio::spawn(async move { + let mut stdout = tokio::io::stdout(); + while let Some(frame) = out_rx.recv().await { + if let Ok(mut line) = serde_json::to_string(&frame) { + line.push('\n'); + if stdout.write_all(line.as_bytes()).await.is_err() || stdout.flush().await.is_err() + { + break; + } + } + } + }); + + let mut lines = BufReader::new(tokio::io::stdin()).lines(); + let mut worker_name = cmd + .agent_name + .clone() + .unwrap_or_else(|| format!("app-server-{protocol}")); + let mut final_exit_code: Option = None; + let final_exit_signal: Option = None; + + while let Ok(Some(line)) = lines.next_line().await { + let frame: ProtocolEnvelope = match serde_json::from_str(&line) { + Ok(frame) => frame, + Err(error) => { + let _ = send_frame( + &out_tx, + "worker_error", + None, + json!({ + "code":"invalid_frame", + "message": error.to_string(), + "retryable": false, + }), + ) + .await; + continue; + } + }; + + match frame.msg_type.as_str() { + "init_worker" => { + worker_name = cmd + .agent_name + .clone() + .or_else(|| { + frame + .payload + .get("agent") + .and_then(|a| a.get("name")) + .and_then(Value::as_str) + .map(ToOwned::to_owned) + }) + .unwrap_or_else(|| format!("app-server-{protocol}")); + + let _ = send_frame( + &out_tx, + "worker_ready", + frame.request_id, + json!({ + "name": &worker_name, + "runtime": "app_server", + "sessionId": &session_id, + }), + ) + .await; + } + "deliver_relay" => { + let request_id = frame.request_id.clone(); + let delivery: RelayDelivery = match serde_json::from_value(frame.payload) { + Ok(d) => d, + Err(error) => { + let _ = send_frame( + &out_tx, + "worker_error", + request_id, + json!({ + "code":"invalid_delivery", + "message": error.to_string(), + "retryable": false, + }), + ) + .await; + continue; + } + }; + + let timestamp = chrono::Utc::now().timestamp_millis(); + let delivery_id = delivery.delivery_id.clone(); + let event_id = delivery.event_id.clone(); + let text = format_app_server_delivery(&delivery); + + let _ = send_frame( + &out_tx, + "delivery_queued", + None, + json!({ + "delivery_id": &delivery_id, + "event_id": &event_id, + "agent": &worker_name, + "timestamp": timestamp, + }), + ) + .await; + + let _ = send_frame( + &out_tx, + "delivery_injected", + None, + json!({ + "delivery_id": &delivery_id, + "event_id": &event_id, + "agent": &worker_name, + "timestamp": timestamp, + }), + ) + .await; + + let result = match protocol.as_str() { + "opencode" => { + send_opencode_prompt(&http, &endpoint, &session_id, &text, auth.as_ref()) + .await + } + other => Err(anyhow::anyhow!( + "unsupported app_server protocol '{other}' (supported: opencode)" + )), + }; + + match result { + Ok(()) => { + let _ = send_frame( + &out_tx, + "delivery_ack", + request_id.clone(), + json!({ + "delivery_id": &delivery_id, + "event_id": &event_id, + }), + ) + .await; + let _ = send_frame( + &out_tx, + "delivery_verified", + None, + json!({ + "delivery_id": &delivery_id, + "event_id": &event_id, + }), + ) + .await; + } + Err(error) => { + let reason = error.to_string(); + let _ = send_frame( + &out_tx, + "delivery_failed", + None, + json!({ + "delivery_id": &delivery_id, + "event_id": &event_id, + "reason": reason, + }), + ) + .await; + let _ = send_frame( + &out_tx, + "worker_error", + request_id, + json!({ + "code":"app_server_delivery_failed", + "message": error.to_string(), + "retryable": true, + }), + ) + .await; + } + } + } + "ping" => { + let ts = frame + .payload + .get("ts_ms") + .and_then(Value::as_u64) + .unwrap_or_default(); + let _ = send_frame(&out_tx, "pong", frame.request_id, json!({"ts_ms": ts})).await; + } + "shutdown_worker" => { + if let Err(error) = release_app_server( + &http, + &protocol, + &endpoint, + &session_id, + &release, + auth.as_ref(), + ) + .await + { + final_exit_code = Some(1); + let _ = send_frame( + &out_tx, + "worker_error", + frame.request_id, + json!({ + "code":"app_server_release_failed", + "message": error.to_string(), + "retryable": false, + }), + ) + .await; + } + break; + } + other => { + let _ = send_frame( + &out_tx, + "worker_error", + frame.request_id, + json!({ + "code":"unknown_type", + "message": format!("unsupported message type '{}'", other), + "retryable": false, + }), + ) + .await; + } + } + } + + let _ = send_frame( + &out_tx, + "worker_exited", + None, + json!({"code": final_exit_code, "signal": final_exit_signal}), + ) + .await; + drop(out_tx); + let _ = writer_task.await; + + Ok(()) +} + +fn app_server_auth_from_env() -> Option { + let auth_type = std::env::var("AGENT_RELAY_APP_SERVER_AUTH_TYPE").ok()?; + let normalized = auth_type.trim().to_ascii_lowercase(); + if normalized.is_empty() || normalized == "none" { + return None; + } + + Some(AppServerAuthConfig { + auth_type: normalized, + token: std::env::var("AGENT_RELAY_APP_SERVER_AUTH_TOKEN").ok(), + username: std::env::var("AGENT_RELAY_APP_SERVER_AUTH_USERNAME").ok(), + password: std::env::var("AGENT_RELAY_APP_SERVER_AUTH_PASSWORD").ok(), + }) +} + +fn format_app_server_delivery(delivery: &RelayDelivery) -> String { + let target = if delivery.target.trim().is_empty() { + "agent" + } else { + delivery.target.as_str() + }; + format!( + "Relay message from {} to {}:\n\n{}", + delivery.from, target, delivery.body + ) +} + +async fn send_opencode_prompt( + http: &reqwest::Client, + endpoint: &str, + session_id: &str, + text: &str, + auth: Option<&AppServerAuthConfig>, +) -> Result<()> { + let url = opencode_session_url(endpoint, session_id, "prompt_async"); + let request = http.post(&url).json(&json!({ + "parts": [ + { + "type": "text", + "text": text, + } + ] + })); + send_app_server_request(apply_app_server_auth(request, auth)).await +} + +async fn release_app_server( + http: &reqwest::Client, + protocol: &str, + endpoint: &str, + session_id: &str, + release: &str, + auth: Option<&AppServerAuthConfig>, +) -> Result<()> { + if release == "detach" || release.is_empty() { + return Ok(()); + } + if protocol != "opencode" { + anyhow::bail!("release is unsupported for app_server protocol '{protocol}'"); + } + + match release { + "abort" => { + let url = opencode_session_url(endpoint, session_id, "abort"); + send_app_server_request(apply_app_server_auth(http.post(url), auth)).await + } + "delete" => { + let url = opencode_session_url(endpoint, session_id, ""); + send_app_server_request(apply_app_server_auth(http.delete(url), auth)).await + } + other => anyhow::bail!( + "unsupported app_server release policy '{other}' (expected abort, detach, or delete)" + ), + } +} + +fn apply_app_server_auth( + request: reqwest::RequestBuilder, + auth: Option<&AppServerAuthConfig>, +) -> reqwest::RequestBuilder { + let Some(auth) = auth else { + return request; + }; + + match auth.auth_type.as_str() { + "bearer" => match auth.token.as_deref() { + Some(token) if !token.trim().is_empty() => request.bearer_auth(token), + _ => request, + }, + "basic" => match (auth.username.as_deref(), auth.password.as_deref()) { + (Some(username), Some(password)) => request.basic_auth(username, Some(password)), + _ => request, + }, + _ => request, + } +} + +async fn send_app_server_request(request: reqwest::RequestBuilder) -> Result<()> { + let response = request.send().await.context("app-server request failed")?; + if response.status().is_success() { + return Ok(()); + } + + let status = response.status(); + let body = response.text().await.unwrap_or_default(); + anyhow::bail!("app-server request failed with status {status}: {body}"); +} + +fn opencode_session_url(endpoint: &str, session_id: &str, action: &str) -> String { + let base = endpoint.trim_end_matches('/'); + let session = urlencoding::encode(session_id); + if action.is_empty() { + format!("{base}/session/{session}") + } else { + format!("{base}/session/{session}/{action}") + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn opencode_session_url_escapes_session_id() { + assert_eq!( + opencode_session_url("http://127.0.0.1:4096/", "ses/one", "prompt_async"), + "http://127.0.0.1:4096/session/ses%2Fone/prompt_async" + ); + } + + #[test] + fn format_app_server_delivery_includes_relay_context() { + let delivery = RelayDelivery { + delivery_id: "del_1".into(), + event_id: "evt_1".into(), + workspace_id: None, + workspace_alias: None, + from: "Lead".into(), + target: "Worker".into(), + body: "Do the thing".into(), + thread_id: None, + priority: None, + injection_mode: MessageInjectionMode::Wait, + }; + + assert_eq!( + format_app_server_delivery(&delivery), + "Relay message from Lead to Worker:\n\nDo the thing" + ); + } +} diff --git a/crates/broker/src/runtime/mod.rs b/crates/broker/src/runtime/mod.rs index 343e40c3c..4f23cd1f4 100644 --- a/crates/broker/src/runtime/mod.rs +++ b/crates/broker/src/runtime/mod.rs @@ -28,7 +28,8 @@ use crate::{ dedup::DedupCache, protocol::{ AgentRuntime, AgentSpec, BrokerEvent, HeadlessProvider as ProtocolHeadlessProvider, - MessageInjectionMode, ProtocolEnvelope, RelayDelivery, PROTOCOL_VERSION, + MessageInjectionMode, ProtocolEnvelope, RelayDelivery, ResolvedHarnessPlan, + PROTOCOL_VERSION, }, relaycast::{ agent_name_eq, ensure_relaycast_mcp_config, format_worker_preregistration_error, @@ -45,7 +46,7 @@ use crate::{ }, }; -use crate::cli::{DumpPtyCommand, DumpPtyFormat, HeadlessCommand, InitCommand}; +use crate::cli::{AppServerCommand, DumpPtyCommand, DumpPtyFormat, HeadlessCommand, InitCommand}; use crate::worker::{WorkerEvent, WorkerHandle, WorkerRegistry}; use crate::{broker, listen_api, routing, worker_request}; @@ -59,6 +60,7 @@ const DEFAULT_HTTP_API_EVENT_EMIT_TIMEOUT_MS: u64 = 200; static TRACING_GUARD: OnceLock = OnceLock::new(); mod api; +mod app_server; mod connection; mod delivery; mod event_loop; @@ -77,6 +79,7 @@ mod tests; mod util; mod worker_events; +pub(crate) use app_server::*; pub(crate) use connection::*; pub(crate) use delivery::*; pub(crate) use event_loop::*; diff --git a/crates/broker/src/runtime/relaycast_events.rs b/crates/broker/src/runtime/relaycast_events.rs index 9775fe0f1..d34bfc4c4 100644 --- a/crates/broker/src/runtime/relaycast_events.rs +++ b/crates/broker/src/runtime/relaycast_events.rs @@ -221,6 +221,8 @@ impl BrokerRuntime { runtime: AgentRuntime::Pty, provider: None, cli: Some(cli.clone()), + session_id: None, + harness_plan: None, model: None, cwd: None, team: None, @@ -431,6 +433,8 @@ impl BrokerRuntime { runtime: AgentRuntime::Pty, provider: None, cli: Some(cli.clone()), + session_id: None, + harness_plan: None, model: None, cwd: None, team: None, diff --git a/crates/broker/src/runtime/spawn_spec.rs b/crates/broker/src/runtime/spawn_spec.rs index 9781d84bb..1e8ed1eb9 100644 --- a/crates/broker/src/runtime/spawn_spec.rs +++ b/crates/broker/src/runtime/spawn_spec.rs @@ -4,6 +4,7 @@ pub(crate) fn runtime_label(runtime: &AgentRuntime) -> &'static str { match runtime { AgentRuntime::Pty => "pty", AgentRuntime::Headless => "headless", + AgentRuntime::AppServer => "app_server", } } @@ -20,8 +21,9 @@ pub(crate) fn build_http_api_spawn_spec( shadow_of: Option, shadow_mode: Option, restart_policy: Option, + harness_plan: Option, ) -> Result { - let runtime = match transport + let requested_runtime = match transport .as_deref() .map(str::trim) .filter(|value| !value.is_empty()) @@ -30,10 +32,35 @@ pub(crate) fn build_http_api_spawn_spec( None => AgentRuntime::Pty, Some(value) if value == "pty" => AgentRuntime::Pty, Some(value) if value == "headless" => AgentRuntime::Headless, + Some(value) if value == "app_server" || value == "app-server" => AgentRuntime::AppServer, Some(other) => { - anyhow::bail!("unsupported transport '{other}' (expected 'pty' or 'headless')") + anyhow::bail!( + "unsupported transport '{other}' (expected 'pty', 'headless', or 'app_server')" + ) } }; + let harness_runtime = harness_plan.as_ref().map(ResolvedHarnessPlan::runtime); + let runtime = match ( + transport + .as_deref() + .map(str::trim) + .filter(|value| !value.is_empty()), + harness_runtime, + ) { + (None, Some(harness_runtime)) => harness_runtime, + (_, Some(harness_runtime)) if harness_runtime == requested_runtime => requested_runtime, + (_, Some(harness_runtime)) => { + anyhow::bail!( + "harnessPlan runtime '{}' does not match requested transport '{}'", + runtime_label(&harness_runtime), + runtime_label(&requested_runtime) + ) + } + (_, None) => requested_runtime, + }; + if matches!(runtime, AgentRuntime::AppServer) && harness_plan.is_none() { + anyhow::bail!("app_server transport requires harnessPlan.runtime = 'app_server'"); + } let parsed_restart_policy = match restart_policy { Some(v) => Some(serde_json::from_value(v).context("invalid restart_policy")?), None => None, @@ -49,13 +76,20 @@ pub(crate) fn build_http_api_spawn_spec( })?; (Some(provider), None, model) } + AgentRuntime::AppServer => (None, Some(cli), model), }; + let session_id = harness_plan + .as_ref() + .and_then(ResolvedHarnessPlan::session_id) + .map(ToOwned::to_owned); Ok(AgentSpec { name, runtime, provider, cli: cli_command, + session_id, + harness_plan, model, cwd, team, diff --git a/crates/broker/src/runtime/tests.rs b/crates/broker/src/runtime/tests.rs index 001771807..cdb2a28d4 100644 --- a/crates/broker/src/runtime/tests.rs +++ b/crates/broker/src/runtime/tests.rs @@ -6,7 +6,10 @@ use std::{ time::{Duration, Instant}, }; -use crate::protocol::{AgentSpec, MessageInjectionMode, RelayDelivery}; +use crate::protocol::{ + AgentSpec, AppServerHarnessPlan, HarnessReleasePolicy, MessageInjectionMode, RelayDelivery, + ResolvedHarnessPlan, +}; use crate::worker::{AgentWorkState, WorkerEvent, WorkerHandle, WorkerRegistry}; use crate::{ broker::injection_format::format_injection, @@ -68,6 +71,8 @@ async fn make_worker_registry_with_worker(name: &str) -> WorkerRegistry { runtime: AgentRuntime::Pty, provider: None, cli: Some("cat".to_string()), + session_id: None, + harness_plan: None, model: None, cwd: None, team: None, @@ -1933,6 +1938,7 @@ fn http_api_spawn_spec_defaults_to_pty_runtime() { Some("Lead".to_string()), Some("subagent".to_string()), None, + None, ) .expect("spec should build"); @@ -1956,6 +1962,7 @@ fn http_api_spawn_spec_uses_headless_runtime_for_supported_providers() { None, None, None, + None, ) .expect("headless spec should build"); @@ -1968,6 +1975,67 @@ fn http_api_spawn_spec_uses_headless_runtime_for_supported_providers() { assert_eq!(spec.model.as_deref(), Some("ignored")); } +#[test] +fn http_api_spawn_spec_uses_app_server_runtime_from_harness_plan() { + let harness_plan = ResolvedHarnessPlan::AppServer(AppServerHarnessPlan { + protocol: "opencode".to_string(), + endpoint: "http://127.0.0.1:4096".to_string(), + session_id: "ses_123".to_string(), + auth: None, + host: None, + release: Some(HarnessReleasePolicy::Abort), + metadata: None, + }); + + let spec = build_http_api_spawn_spec( + "worker-a".to_string(), + "opencode-server".to_string(), + None, + None, + vec![], + vec!["general".to_string()], + None, + None, + None, + None, + None, + Some(harness_plan), + ) + .expect("app-server harness spec should build"); + + assert!(matches!(spec.runtime, AgentRuntime::AppServer)); + assert_eq!(spec.cli.as_deref(), Some("opencode-server")); + assert_eq!(spec.session_id.as_deref(), Some("ses_123")); + assert!(matches!( + spec.harness_plan, + Some(ResolvedHarnessPlan::AppServer(_)) + )); +} + +#[test] +fn http_api_spawn_spec_rejects_app_server_without_harness_plan() { + let error = build_http_api_spawn_spec( + "worker-a".to_string(), + "opencode-server".to_string(), + Some("app_server".to_string()), + None, + vec![], + vec!["general".to_string()], + None, + None, + None, + None, + None, + None, + ) + .expect_err("app-server spec without harness plan should fail"); + + assert!( + error.to_string().contains("requires harnessPlan"), + "unexpected error: {error}" + ); +} + #[test] fn headless_provider_command_claude_places_flags_before_task() { let (bin, args) = super::headless_provider_command( @@ -2016,6 +2084,7 @@ fn http_api_spawn_spec_rejects_unknown_headless_providers() { None, None, None, + None, ) .expect_err("unsupported headless provider should fail"); diff --git a/crates/broker/src/runtime/worker_events.rs b/crates/broker/src/runtime/worker_events.rs index abb5a16a4..c45ae580e 100644 --- a/crates/broker/src/runtime/worker_events.rs +++ b/crates/broker/src/runtime/worker_events.rs @@ -316,7 +316,7 @@ impl BrokerRuntime { .and_then(|p| p.get("runtime")) .and_then(Value::as_str) .unwrap_or("pty"); - let (provider_val, cli_val, model_val) = workers + let (provider_val, cli_val, model_val, session_id_val, pid_val) = workers .workers .get(&name) .map(|h| { @@ -324,9 +324,11 @@ impl BrokerRuntime { h.spec.provider.clone(), h.spec.cli.clone(), h.spec.model.clone(), + h.spec.session_id.clone(), + h.child.id(), ) }) - .unwrap_or((None, None, None)); + .unwrap_or((None, None, None, None, None)); let _ = send_event( sdk_out_tx, json!({ @@ -336,6 +338,8 @@ impl BrokerRuntime { "provider": provider_val, "cli": cli_val, "model": model_val, + "sessionId": session_id_val, + "pid": pid_val, }), ) .await; diff --git a/crates/broker/src/supervisor.rs b/crates/broker/src/supervisor.rs index d1c00f28e..cea6e1c38 100644 --- a/crates/broker/src/supervisor.rs +++ b/crates/broker/src/supervisor.rs @@ -230,6 +230,8 @@ mod tests { runtime: AgentRuntime::Pty, provider: None, cli: Some("claude".to_string()), + session_id: None, + harness_plan: None, model: None, cwd: None, team: None, diff --git a/crates/broker/src/worker.rs b/crates/broker/src/worker.rs index 2b952c17e..28235d05f 100644 --- a/crates/broker/src/worker.rs +++ b/crates/broker/src/worker.rs @@ -7,7 +7,10 @@ use std::{ use crate::{ metrics::MetricsCollector, - protocol::{AgentRuntime, AgentSpec, ProtocolEnvelope, RelayDelivery, PROTOCOL_VERSION}, + protocol::{ + AgentRuntime, AgentSpec, AppServerAuthType, HarnessReleasePolicy, ProtocolEnvelope, + RelayDelivery, ResolvedHarnessPlan, PROTOCOL_VERSION, + }, relaycast::configure_relaycast_mcp_with_result, supervisor::Supervisor, types::AgentResultMcpConfig, @@ -136,6 +139,7 @@ impl WorkerRegistry { "team": handle.spec.team, "channels": handle.spec.channels, "parent": handle.parent, + "sessionId": handle.spec.session_id, "pid": handle.child.id(), "last_activity_ms": handle.last_activity_at.elapsed().as_millis() as u64, "last_activity_at": chrono::Utc::now() @@ -224,15 +228,26 @@ impl WorkerRegistry { let mut command = Command::new(std::env::current_exe().context("failed to locate current executable")?); + let mut harness_env: Vec<(String, String)> = Vec::new(); - match spec.runtime { - AgentRuntime::Pty => { - let cli = spec.cli.as_deref().context("pty runtime requires `cli`")?; - let (resolved_cli, inline_cli_args) = parse_cli_command(cli) - .with_context(|| format!("invalid CLI command '{cli}'"))?; + match spec.harness_plan.clone() { + Some(ResolvedHarnessPlan::Pty(plan)) => { + spec.runtime = AgentRuntime::Pty; + if spec.session_id.is_none() { + spec.session_id = plan.session_id.clone(); + } + if spec.cwd.is_none() { + spec.cwd = plan.cwd.clone(); + } + if let Some(env) = plan.env { + harness_env.extend(env); + } + + let (resolved_cli, inline_cli_args) = parse_cli_command(&plan.command) + .with_context(|| format!("invalid harness command '{}'", plan.command))?; let normalized_cli = normalize_cli_name(&resolved_cli); let mut effective_args = inline_cli_args; - effective_args.extend(spec.args.clone()); + effective_args.extend(plan.args.clone()); command.arg("pty"); command.arg("--agent-name").arg(&spec.name); @@ -242,9 +257,6 @@ impl WorkerRegistry { command.arg(&resolved_cli); let cli_lower = normalized_cli.to_lowercase(); - let is_claude = cli_lower == "claude" || cli_lower.starts_with("claude:"); - let is_codex = cli_lower == "codex"; - let is_gemini = cli_lower == "gemini"; if let Some(model) = apply_codex_model_arg_fallback( &resolved_cli, &cli_lower, @@ -255,38 +267,10 @@ impl WorkerRegistry { { spec.model = Some(model); } - // NOTE: Permission-bypass flags are auto-injected for all spawned agents. - // This means any actor who can trigger agent.add gets agents with no permission - // guardrails. Future work should make this an explicit opt-in per step/agent. - let bypass_flag: Option<&str> = if is_claude - && !effective_args - .iter() - .any(|a| a.contains("dangerously-skip-permissions")) - { - Some("--dangerously-skip-permissions") - } else if is_codex - && !effective_args - .iter() - .any(|a| a.contains("dangerously-bypass") || a.contains("full-auto")) - { - Some("--dangerously-bypass-approvals-and-sandbox") - } else if is_gemini && !effective_args.iter().any(|a| a == "--yolo" || a == "-y") { - Some("--yolo") - } else { - None - }; - - if let Some(flag) = bypass_flag { - tracing::warn!( - worker = %spec.name, - flag = %flag, - "auto-injecting permission-bypass flag for spawned agent" - ); - } let mcp_args = self .build_mcp_args( - cli, + &resolved_cli, &spec.name, &effective_args, Path::new(spec.cwd.as_deref().unwrap_or(".")), @@ -308,15 +292,8 @@ impl WorkerRegistry { spec.model = Some(model.clone()); } - let has_extra = bypass_flag.is_some() - || model_flag.is_some() - || !effective_args.is_empty() - || !mcp_args.is_empty(); - if has_extra { + if model_flag.is_some() || !effective_args.is_empty() || !mcp_args.is_empty() { command.arg("--"); - if let Some(flag) = bypass_flag { - command.arg(flag); - } if let Some(ref model) = model_flag { command.arg("--model"); command.arg(model); @@ -329,64 +306,205 @@ impl WorkerRegistry { } } } - AgentRuntime::Headless => { - let provider = spec - .provider - .as_ref() - .context("headless runtime requires `provider`")?; - command.arg("headless"); + Some(ResolvedHarnessPlan::AppServer(plan)) => { + spec.runtime = AgentRuntime::AppServer; + spec.session_id = Some(plan.session_id.clone()); + + command.arg("app-server"); command.arg("--agent-name").arg(&spec.name); - let provider_cli = headless_provider_cli_name(provider); - command.arg(provider_cli); - if let Some(model) = apply_codex_model_arg_fallback( - provider_cli, - provider_cli, - &spec.name, - &mut spec.args, - ) - .await - { - spec.model = Some(model); + command.arg("--protocol").arg(&plan.protocol); + command.arg("--endpoint").arg(&plan.endpoint); + command.arg("--session-id").arg(&plan.session_id); + command + .arg("--release") + .arg(release_policy_arg(plan.release.as_ref())); + + if let Some(auth) = plan.auth { + harness_env.push(( + "AGENT_RELAY_APP_SERVER_AUTH_TYPE".to_string(), + app_server_auth_type_arg(&auth.auth_type).to_string(), + )); + if let Some(token) = auth.token { + harness_env.push(("AGENT_RELAY_APP_SERVER_AUTH_TOKEN".to_string(), token)); + } + if let Some(username) = auth.username { + harness_env + .push(("AGENT_RELAY_APP_SERVER_AUTH_USERNAME".to_string(), username)); + } + if let Some(password) = auth.password { + harness_env + .push(("AGENT_RELAY_APP_SERVER_AUTH_PASSWORD".to_string(), password)); + } } + } + None => match spec.runtime { + AgentRuntime::Pty => { + let cli = spec.cli.as_deref().context("pty runtime requires `cli`")?; + let (resolved_cli, inline_cli_args) = parse_cli_command(cli) + .with_context(|| format!("invalid CLI command '{cli}'"))?; + let normalized_cli = normalize_cli_name(&resolved_cli); + let mut effective_args = inline_cli_args; + effective_args.extend(spec.args.clone()); + + command.arg("pty"); + command.arg("--agent-name").arg(&spec.name); + if let Some(secs) = idle_threshold_secs { + command.arg("--idle-threshold-secs").arg(secs.to_string()); + } + command.arg(&resolved_cli); + + let cli_lower = normalized_cli.to_lowercase(); + let is_claude = cli_lower == "claude" || cli_lower.starts_with("claude:"); + let is_codex = cli_lower == "codex"; + let is_gemini = cli_lower == "gemini"; + if let Some(model) = apply_codex_model_arg_fallback( + &resolved_cli, + &cli_lower, + &spec.name, + &mut effective_args, + ) + .await + { + spec.model = Some(model); + } + // NOTE: Permission-bypass flags are auto-injected for all spawned agents. + // This means any actor who can trigger agent.add gets agents with no permission + // guardrails. Future work should make this an explicit opt-in per step/agent. + let bypass_flag: Option<&str> = if is_claude + && !effective_args + .iter() + .any(|a| a.contains("dangerously-skip-permissions")) + { + Some("--dangerously-skip-permissions") + } else if is_codex + && !effective_args + .iter() + .any(|a| a.contains("dangerously-bypass") || a.contains("full-auto")) + { + Some("--dangerously-bypass-approvals-and-sandbox") + } else if is_gemini + && !effective_args.iter().any(|a| a == "--yolo" || a == "-y") + { + Some("--yolo") + } else { + None + }; - let mcp_args = self - .build_mcp_args( - provider_cli, + if let Some(flag) = bypass_flag { + tracing::warn!( + worker = %spec.name, + flag = %flag, + "auto-injecting permission-bypass flag for spawned agent" + ); + } + + let mcp_args = self + .build_mcp_args( + cli, + &spec.name, + &effective_args, + Path::new(spec.cwd.as_deref().unwrap_or(".")), + worker_relay_api_key.as_deref(), + skip_relay_prompt, + agent_result.as_ref(), + ) + .await?; + + let model_flag = resolve_model_flag_for_cli( + &resolved_cli, + &cli_lower, &spec.name, - &spec.args, - Path::new(spec.cwd.as_deref().unwrap_or(".")), - worker_relay_api_key.as_deref(), - skip_relay_prompt, - agent_result.as_ref(), + spec.model.as_deref(), + &effective_args, ) - .await?; + .await; + if let Some(ref model) = model_flag { + spec.model = Some(model.clone()); + } - let model_arg = resolve_model_flag_for_cli( - provider_cli, - provider_cli, - &spec.name, - spec.model.as_deref(), - &spec.args, - ) - .await; - if let Some(ref model) = model_arg { - spec.model = Some(model.clone()); + let has_extra = bypass_flag.is_some() + || model_flag.is_some() + || !effective_args.is_empty() + || !mcp_args.is_empty(); + if has_extra { + command.arg("--"); + if let Some(flag) = bypass_flag { + command.arg(flag); + } + if let Some(ref model) = model_flag { + command.arg("--model"); + command.arg(model); + } + for arg in &mcp_args { + command.arg(arg); + } + for arg in &effective_args { + command.arg(arg); + } + } } - - if model_arg.is_some() || !spec.args.is_empty() || !mcp_args.is_empty() { - command.arg("--"); - if let Some(model) = model_arg { - command.arg("--model"); - command.arg(model); + AgentRuntime::Headless => { + let provider = spec + .provider + .as_ref() + .context("headless runtime requires `provider`")?; + command.arg("headless"); + command.arg("--agent-name").arg(&spec.name); + let provider_cli = headless_provider_cli_name(provider); + command.arg(provider_cli); + if let Some(model) = apply_codex_model_arg_fallback( + provider_cli, + provider_cli, + &spec.name, + &mut spec.args, + ) + .await + { + spec.model = Some(model); } - for arg in &mcp_args { - command.arg(arg); + + let mcp_args = self + .build_mcp_args( + provider_cli, + &spec.name, + &spec.args, + Path::new(spec.cwd.as_deref().unwrap_or(".")), + worker_relay_api_key.as_deref(), + skip_relay_prompt, + agent_result.as_ref(), + ) + .await?; + + let model_arg = resolve_model_flag_for_cli( + provider_cli, + provider_cli, + &spec.name, + spec.model.as_deref(), + &spec.args, + ) + .await; + if let Some(ref model) = model_arg { + spec.model = Some(model.clone()); } - for arg in &spec.args { - command.arg(arg); + + if model_arg.is_some() || !spec.args.is_empty() || !mcp_args.is_empty() { + command.arg("--"); + if let Some(model) = model_arg { + command.arg("--model"); + command.arg(model); + } + for arg in &mcp_args { + command.arg(arg); + } + for arg in &spec.args { + command.arg(arg); + } } } - } + AgentRuntime::AppServer => { + anyhow::bail!("app_server runtime requires a resolved harnessPlan"); + } + }, } command @@ -396,6 +514,9 @@ impl WorkerRegistry { for (key, value) in &self.worker_env { command.env(key, value); } + for (key, value) in &harness_env { + command.env(key, value); + } if let Some(config) = &agent_result { for (key, value) in config.env_pairs() { command.env(key, value); @@ -694,6 +815,22 @@ impl WorkerRegistry { } } +fn release_policy_arg(policy: Option<&HarnessReleasePolicy>) -> &'static str { + match policy { + Some(HarnessReleasePolicy::Abort) => "abort", + Some(HarnessReleasePolicy::Delete) => "delete", + Some(HarnessReleasePolicy::Detach) | None => "detach", + } +} + +fn app_server_auth_type_arg(auth_type: &AppServerAuthType) -> &'static str { + match auth_type { + AppServerAuthType::Bearer => "bearer", + AppServerAuthType::Basic => "basic", + AppServerAuthType::None => "none", + } +} + fn args_include_model_override(args: &[String]) -> bool { args.iter().any(|arg| { arg == "--model" || arg.starts_with("--model=") || arg == "-m" || arg.starts_with("-m=") diff --git a/packages/sdk/src/__tests__/harness.test.ts b/packages/sdk/src/__tests__/harness.test.ts new file mode 100644 index 000000000..f21e3c365 --- /dev/null +++ b/packages/sdk/src/__tests__/harness.test.ts @@ -0,0 +1,95 @@ +import { describe, expect, it, vi } from 'vitest'; + +import { AgentRelayClient } from '../client.js'; +import { harnessLookupKeys, resolveStaticHarnessPlan } from '../harness.js'; + +describe('harness plans', () => { + it('resolves static PTY harnesses to broker-executable plans', () => { + const plan = resolveStaticHarnessPlan({ + name: 'QwenReviewer', + cli: 'qwen', + definition: { + runtime: 'pty', + command: 'qwen', + args: ['run', '{modelArgs}', '{args}'], + modelArgs: ['-m', '{model}'], + env: { QWEN_MODE: 'code' }, + }, + args: ['--verbose'], + model: 'qwen3-coder', + cwd: '/workspace', + }); + + expect(plan).toEqual({ + runtime: 'pty', + command: 'qwen', + args: ['run', '-m', 'qwen3-coder', '--verbose'], + cwd: '/workspace', + env: { QWEN_MODE: 'code' }, + }); + }); + + it('resolves static app-server harnesses without process args', () => { + const plan = resolveStaticHarnessPlan({ + name: 'OpenCodeServerWorker', + cli: 'opencode-server', + definition: { + runtime: 'app_server', + protocol: 'opencode', + endpoint: 'http://127.0.0.1:4096', + sessionId: 'ses_123', + release: 'abort', + }, + }); + + expect(plan).toEqual({ + runtime: 'app_server', + protocol: 'opencode', + endpoint: 'http://127.0.0.1:4096', + sessionId: 'ses_123', + release: 'abort', + }); + }); + + it('looks up harnesses by full cli, executable token, and model suffix base', () => { + expect(harnessLookupKeys('qwen:coder --fast')).toEqual(['qwen:coder --fast', 'qwen:coder', 'qwen']); + }); + + it('serializes resolved harness plans on spawn requests', async () => { + const captures: unknown[] = []; + const fetchFn = vi.fn(async (_url: string | URL | Request, init?: RequestInit) => { + captures.push(JSON.parse(String(init?.body ?? '{}'))); + return new Response( + JSON.stringify({ name: 'QwenReviewer', runtime: 'pty', sessionId: 'ses_1', pid: 123 }), + { + status: 200, + headers: { 'Content-Type': 'application/json' }, + } + ); + }); + + const client = new AgentRelayClient({ baseUrl: 'http://broker.test', apiKey: 'k', fetch: fetchFn }); + const result = await client.spawnPty({ + name: 'QwenReviewer', + cli: 'qwen', + harnessPlan: { + runtime: 'pty', + command: 'qwen', + args: ['run'], + sessionId: 'ses_1', + }, + }); + + expect(result).toEqual({ name: 'QwenReviewer', runtime: 'pty', sessionId: 'ses_1', pid: 123 }); + expect(captures[0]).toMatchObject({ + name: 'QwenReviewer', + cli: 'qwen', + harnessPlan: { + runtime: 'pty', + command: 'qwen', + args: ['run'], + sessionId: 'ses_1', + }, + }); + }); +}); diff --git a/packages/sdk/src/client.ts b/packages/sdk/src/client.ts index 958be87b2..432089af5 100644 --- a/packages/sdk/src/client.ts +++ b/packages/sdk/src/client.ts @@ -35,6 +35,7 @@ import type { } from './protocol.js'; import type { AgentTransport, + SpawnAgentResult, SpawnHeadlessInput, SpawnPtyInput, SpawnProviderInput, @@ -152,7 +153,9 @@ function isHeadlessProvider(value: string): value is HeadlessProvider { } function resolveSpawnTransport(input: SpawnProviderInput): AgentTransport { - return input.transport ?? (input.provider === 'opencode' ? 'headless' : 'pty'); + if (input.transport) return input.transport; + if (input.harnessPlan) return input.harnessPlan.runtime; + return input.provider === 'opencode' ? 'headless' : 'pty'; } /** @@ -174,6 +177,7 @@ function buildSpawnPtyBody(input: SpawnPtyInput): Record { ...(input.shadowOf !== undefined ? { shadowOf: input.shadowOf } : {}), ...(input.shadowMode !== undefined ? { shadowMode: input.shadowMode } : {}), ...(input.continueFrom !== undefined ? { continueFrom: input.continueFrom } : {}), + ...(input.harnessPlan !== undefined ? { harnessPlan: input.harnessPlan } : {}), ...(input.idleThresholdSecs !== undefined ? { idleThresholdSecs: input.idleThresholdSecs } : {}), ...(input.restartPolicy !== undefined ? { restartPolicy: input.restartPolicy } : {}), ...(input.skipRelayPrompt !== undefined ? { skipRelayPrompt: input.skipRelayPrompt } : {}), @@ -198,6 +202,7 @@ function buildSpawnProviderBody( ...(input.shadowOf !== undefined ? { shadowOf: input.shadowOf } : {}), ...(input.shadowMode !== undefined ? { shadowMode: input.shadowMode } : {}), ...(input.continueFrom !== undefined ? { continueFrom: input.continueFrom } : {}), + ...(input.harnessPlan !== undefined ? { harnessPlan: input.harnessPlan } : {}), ...(input.idleThresholdSecs !== undefined ? { idleThresholdSecs: input.idleThresholdSecs } : {}), ...(input.restartPolicy !== undefined ? { restartPolicy: input.restartPolicy } : {}), ...(input.skipRelayPrompt !== undefined ? { skipRelayPrompt: input.skipRelayPrompt } : {}), @@ -584,7 +589,7 @@ export class AgentRelayClient { // ── Agent lifecycle ──────────────────────────────────────────────── - async spawnPty(input: SpawnPtyInput): Promise<{ name: string; runtime: AgentRuntime }> { + async spawnPty(input: SpawnPtyInput): Promise { const beforeCtx: BeforeAgentSpawnContext = { kind: 'pty', input, @@ -595,7 +600,7 @@ export class AgentRelayClient { const t0 = Date.now(); const resolvedInput = (await this.runBeforeSpawn(beforeCtx)) as SpawnPtyInput; try { - const result = await this.transport.request<{ name: string; runtime: AgentRuntime }>('/api/spawn', { + const result = await this.transport.request('/api/spawn', { method: 'POST', body: JSON.stringify(buildSpawnPtyBody(resolvedInput)), }); @@ -607,7 +612,7 @@ export class AgentRelayClient { } } - async spawnProvider(input: SpawnProviderInput): Promise<{ name: string; runtime: AgentRuntime }> { + async spawnProvider(input: SpawnProviderInput): Promise { const transport = resolveSpawnTransport(input); if (transport === 'headless' && !isHeadlessProvider(input.provider)) { throw new Error( @@ -625,7 +630,7 @@ export class AgentRelayClient { const t0 = Date.now(); const resolvedInput = (await this.runBeforeSpawn(beforeCtx)) as SpawnProviderInput; try { - const result = await this.transport.request<{ name: string; runtime: AgentRuntime }>('/api/spawn', { + const result = await this.transport.request('/api/spawn', { method: 'POST', body: JSON.stringify(buildSpawnProviderBody(resolvedInput, transport)), }); @@ -637,19 +642,15 @@ export class AgentRelayClient { } } - async spawnHeadless(input: SpawnHeadlessInput): Promise<{ name: string; runtime: AgentRuntime }> { + async spawnHeadless(input: SpawnHeadlessInput): Promise { return this.spawnProvider({ ...input, transport: 'headless' }); } - async spawnClaude( - input: Omit - ): Promise<{ name: string; runtime: AgentRuntime }> { + async spawnClaude(input: Omit): Promise { return this.spawnProvider({ ...input, provider: 'claude' }); } - async spawnOpencode( - input: Omit - ): Promise<{ name: string; runtime: AgentRuntime }> { + async spawnOpencode(input: Omit): Promise { return this.spawnProvider({ ...input, provider: 'opencode' }); } @@ -686,7 +687,7 @@ export class AgentRelayClient { beforeCtx: BeforeAgentSpawnContext, resolvedInput: SpawnPtyInput | SpawnProviderInput, startMs: number, - result: { name: string; runtime: AgentRuntime } | undefined, + result: SpawnAgentResult | undefined, error: unknown ): Promise { const afterCtx: AfterAgentSpawnContext = { diff --git a/packages/sdk/src/harness.ts b/packages/sdk/src/harness.ts new file mode 100644 index 000000000..c31a7543b --- /dev/null +++ b/packages/sdk/src/harness.ts @@ -0,0 +1,224 @@ +import { existsSync } from 'node:fs'; +import { homedir } from 'node:os'; +import path from 'node:path'; + +import type { AgentRuntime } from './protocol.js'; + +export type HarnessRuntime = Extract; +export type HarnessReleasePolicy = 'abort' | 'detach' | 'delete'; + +export interface PtyHarnessDelivery { + mode?: 'pty-injection'; + format?: 'relay-block'; +} + +export interface PtyHarnessPlan { + runtime: 'pty'; + command: string; + args: string[]; + cwd?: string; + env?: Record; + sessionId?: string; + delivery?: PtyHarnessDelivery; + metadata?: Record; +} + +export interface AppServerHarnessAuth { + type: 'bearer' | 'basic' | 'none'; + token?: string; + username?: string; + password?: string; +} + +export interface AppServerHarnessHost { + ownership?: 'broker-owned' | 'attached'; + pid?: number; +} + +export interface AppServerHarnessPlan { + runtime: 'app_server'; + protocol: 'opencode' | string; + endpoint: string; + sessionId: string; + auth?: AppServerHarnessAuth; + host?: AppServerHarnessHost; + release?: HarnessReleasePolicy; + metadata?: Record; +} + +export type ResolvedHarnessPlan = PtyHarnessPlan | AppServerHarnessPlan; + +export interface StaticPtyHarnessDefinition { + runtime: 'pty'; + command: string; + args?: string[]; + modelArgs?: string[]; + env?: Record; + cwd?: string; + sessionId?: string; + searchPaths?: string[]; + delivery?: PtyHarnessDelivery; + metadata?: Record; +} + +export interface StaticAppServerHarnessDefinition { + runtime: 'app_server'; + protocol: 'opencode' | string; + endpoint: string; + sessionId: string; + auth?: AppServerHarnessAuth; + host?: AppServerHarnessHost; + release?: HarnessReleasePolicy; + metadata?: Record; +} + +export type StaticHarnessDefinition = StaticPtyHarnessDefinition | StaticAppServerHarnessDefinition; + +export interface HarnessResolveContext { + name: string; + cli: string; + task?: string; + args: string[]; + model?: string; + cwd?: string; + env: Record; +} + +export type AttachedHarnessResolver = ( + context: HarnessResolveContext +) => ResolvedHarnessPlan | Promise; +export type HarnessDefinition = StaticHarnessDefinition | AttachedHarnessResolver; + +export interface ResolveStaticHarnessInput { + name: string; + cli: string; + definition: StaticHarnessDefinition; + args?: string[]; + task?: string; + model?: string; + cwd?: string; + env?: Record; +} + +const DEFAULT_PTY_ARGS = ['{args}'] as const; +const DEFAULT_MODEL_ARGS = ['--model', '{model}'] as const; + +export function isAttachedHarnessResolver(value: HarnessDefinition): value is AttachedHarnessResolver { + return typeof value === 'function'; +} + +export function resolveStaticHarnessPlan(input: ResolveStaticHarnessInput): ResolvedHarnessPlan { + const { definition } = input; + if (definition.runtime === 'app_server') { + return { + runtime: 'app_server', + protocol: definition.protocol, + endpoint: definition.endpoint, + sessionId: definition.sessionId, + ...(definition.auth ? { auth: { ...definition.auth } } : {}), + ...(definition.host ? { host: { ...definition.host } } : {}), + ...(definition.release ? { release: definition.release } : {}), + ...(definition.metadata ? { metadata: { ...definition.metadata } } : {}), + }; + } + + const context = { + args: input.args ?? [], + task: input.task, + model: input.model, + modelArgs: input.model + ? renderTemplate(definition.modelArgs ?? DEFAULT_MODEL_ARGS, { + args: [], + task: input.task, + model: input.model, + modelArgs: [], + }) + : [], + }; + + const planEnv = { + ...(definition.env ?? {}), + ...(input.env ?? {}), + }; + + return { + runtime: 'pty', + command: resolveCommand(definition.command, definition.searchPaths), + args: renderTemplate(definition.args ?? DEFAULT_PTY_ARGS, context), + ...((input.cwd ?? definition.cwd) ? { cwd: input.cwd ?? definition.cwd } : {}), + ...(Object.keys(planEnv).length > 0 ? { env: planEnv } : {}), + ...(definition.sessionId ? { sessionId: definition.sessionId } : {}), + ...(definition.delivery ? { delivery: { ...definition.delivery } } : {}), + ...(definition.metadata ? { metadata: { ...definition.metadata } } : {}), + }; +} + +export function harnessLookupKeys(cli: string): string[] { + const trimmed = cli.trim(); + if (!trimmed) return []; + const firstToken = trimmed.split(/\s+/)[0] ?? trimmed; + const withoutModel = firstToken.split(':')[0] ?? firstToken; + return Array.from(new Set([trimmed, firstToken, withoutModel].filter(Boolean))); +} + +function renderTemplate( + template: readonly string[], + context: { + args: string[]; + modelArgs: string[]; + task?: string; + model?: string; + } +): string[] { + const rendered: string[] = []; + for (const entry of template) { + if (isExactPlaceholder(entry, 'args')) { + rendered.push(...context.args); + continue; + } + if (isExactPlaceholder(entry, 'modelArgs')) { + rendered.push(...context.modelArgs); + continue; + } + if (isExactPlaceholder(entry, 'task')) { + if (context.task) rendered.push(context.task); + continue; + } + if (isExactPlaceholder(entry, 'model')) { + if (context.model) rendered.push(context.model); + continue; + } + + const value = entry + .replace(/\{\{\s*task\s*\}\}|\{task\}/g, context.task ?? '') + .replace(/\{\{\s*model\s*\}\}|\{model\}/g, context.model ?? ''); + if (value !== '') { + rendered.push(value); + } + } + return rendered; +} + +function isExactPlaceholder(value: string, name: string): boolean { + return value === `{${name}}` || value === `{{${name}}}`; +} + +function resolveCommand(command: string, searchPaths?: string[]): string { + if (!searchPaths?.length || command.includes('/') || command.includes('\\')) { + return command; + } + + for (const searchPath of searchPaths) { + const candidate = path.join(expandHome(searchPath), command); + if (existsSync(candidate)) { + return candidate; + } + } + return command; +} + +function expandHome(value: string): string { + if (value === '~') return homedir(); + if (value.startsWith('~/')) return path.join(homedir(), value.slice(2)); + return value; +} diff --git a/packages/sdk/src/index.ts b/packages/sdk/src/index.ts index 93c779d0e..ed3e1ac22 100644 --- a/packages/sdk/src/index.ts +++ b/packages/sdk/src/index.ts @@ -42,6 +42,7 @@ export * from './broker-logs.js'; export * from './consensus.js'; export * from './shadow.js'; export * from './relay-adapter.js'; +export * from './harness.js'; export * from './workflows/index.js'; export * from './spawn-from-env.js'; export * from './cli-registry.js'; diff --git a/packages/sdk/src/lifecycle-hooks.ts b/packages/sdk/src/lifecycle-hooks.ts index 6cb72df2a..dffe0db90 100644 --- a/packages/sdk/src/lifecycle-hooks.ts +++ b/packages/sdk/src/lifecycle-hooks.ts @@ -26,9 +26,9 @@ * (`relay.ts` → `event-bus.ts` → no further). */ -import type { AgentRuntime, BrokerEvent } from './protocol.js'; +import type { BrokerEvent } from './protocol.js'; import type { Agent, AgentActivityChange, AgentResult, Message } from './relay.js'; -import type { SpawnPtyInput, SpawnProviderInput } from './types.js'; +import type { SpawnAgentResult, SpawnPtyInput, SpawnProviderInput } from './types.js'; // ── SpawnPatch ───────────────────────────────────────────────────────────── @@ -52,7 +52,10 @@ import type { SpawnPtyInput, SpawnProviderInput } from './types.js'; * the same key. */ export type SpawnPatch = Partial< - Pick + Pick< + SpawnPtyInput & SpawnProviderInput, + 'args' | 'channels' | 'task' | 'model' | 'team' | 'agentToken' | 'harnessPlan' + > >; // ── Call-site contexts ───────────────────────────────────────────────────── @@ -78,7 +81,7 @@ export interface AfterAgentSpawnContext extends BeforeAgentSpawnContext { /** Final input that was sent to the broker — original input merged with every handler's patch. */ resolvedInput: SpawnPtyInput | SpawnProviderInput; /** Broker reply on success. */ - result?: { name: string; runtime: AgentRuntime }; + result?: SpawnAgentResult; /** Set when the broker call rejected. Mutually exclusive with `result`. */ error?: Error; /** Wall-clock duration from `beforeAgentSpawn` start to here. */ diff --git a/packages/sdk/src/protocol.ts b/packages/sdk/src/protocol.ts index 62cdc1e8a..061590790 100644 --- a/packages/sdk/src/protocol.ts +++ b/packages/sdk/src/protocol.ts @@ -1,6 +1,6 @@ export const PROTOCOL_VERSION = 2 as const; -export type AgentRuntime = 'pty' | 'headless'; +export type AgentRuntime = 'pty' | 'headless' | 'app_server'; export type HeadlessProvider = 'claude' | 'opencode'; export type InboundDeliveryMode = 'auto_inject' | 'manual_flush'; export type SnapshotFormat = 'plain' | 'ansi'; @@ -17,6 +17,8 @@ export interface AgentSpec { runtime: AgentRuntime; provider?: HeadlessProvider; cli?: string; + session_id?: string; + harness_plan?: import('./harness.js').ResolvedHarnessPlan; args?: string[]; channels?: string[]; model?: string; @@ -259,6 +261,7 @@ export type BrokerEvent = model?: string; parent?: string; pid?: number; + sessionId?: string; source?: string; } | { @@ -397,6 +400,8 @@ export type BrokerEvent = provider?: HeadlessProvider; cli?: string; model?: string; + sessionId?: string; + pid?: number; } | { kind: 'worker_error'; @@ -504,7 +509,7 @@ export type BrokerToWorker = export type WorkerToBroker = | { type: 'worker_ready'; - payload: { name: string; runtime: AgentRuntime; provider?: HeadlessProvider }; + payload: { name: string; runtime: AgentRuntime; provider?: HeadlessProvider; sessionId?: string }; } | { type: 'delivery_ack'; diff --git a/packages/sdk/src/relay.ts b/packages/sdk/src/relay.ts index f9fbf30b1..52196b919 100644 --- a/packages/sdk/src/relay.ts +++ b/packages/sdk/src/relay.ts @@ -33,6 +33,13 @@ import type { ZodTypeAny } from 'zod'; import { AgentRelayClient, type AgentRelayBrokerInitArgs, type AgentRelaySpawnOptions } from './client.js'; import { EventBus } from './event-bus.js'; +import { + harnessLookupKeys, + isAttachedHarnessResolver, + resolveStaticHarnessPlan, + type HarnessDefinition, + type ResolvedHarnessPlan, +} from './harness.js'; import type { AgentRelayEvents, BeforeAgentSpawnHandler } from './lifecycle-hooks.js'; import { buildPersonaSpawnSpec, @@ -45,7 +52,7 @@ import { type ResolvedPersona, } from './personas.js'; import { AgentRelayProtocolError } from './transport.js'; -import type { JsonSchema, SendMessageInput, SpawnPtyInput } from './types.js'; +import type { JsonSchema, SendMessageInput, SpawnAgentResult, SpawnPtyInput } from './types.js'; import type { AgentRuntime, BrokerEvent, @@ -282,6 +289,7 @@ export interface SpawnOptions extends SpawnLifecycleHook shadowMode?: string; idleThresholdSecs?: number; restartPolicy?: RestartPolicy; + harnessPlan?: ResolvedHarnessPlan; /** Optional pre-minted relaycast agent token (`at_live_`, from * `registerAgent(workspaceKey, name)` in `@agent-relay/sdk/http`). The * broker plumbs this as `RELAY_AGENT_TOKEN`, which the relaycast MCP @@ -340,6 +348,10 @@ export interface Agent { readonly name: string; readonly runtime: AgentRuntime; readonly channels: string[]; + /** Native harness session id, when the runtime exposes one. */ + readonly sessionId?: string; + /** Broker worker process id, when known. */ + readonly pid?: number; /** Current lifecycle status of the agent. */ readonly status: AgentStatus; /** Set when the agent exits. Available once the `agentExited` event fires. */ @@ -404,6 +416,7 @@ export interface SpawnerSpawnOptions extends SpawnLifecy model?: string; cwd?: string; idleThresholdSecs?: number; + harnessPlan?: ResolvedHarnessPlan; /** Optional pre-minted relaycast agent token (`at_live_`, from * `registerAgent(workspaceKey, name)` in `@agent-relay/sdk/http`). The * broker plumbs this as `RELAY_AGENT_TOKEN`, which the relaycast MCP @@ -457,6 +470,15 @@ export interface AgentRelayOptions { * `searchDirs` on `spawnPersona` still overrides this. */ personaDirs?: string[]; + /** + * Named harness definitions. Static definitions resolve to broker-executable + * JSON plans; function resolvers are only valid for attached brokers. + */ + harnesses?: Record; + /** Broker lifetime boundary for dynamic harness resolvers and hooks. */ + broker?: { + lifetime?: 'attached' | 'detached'; + }; } type OutputListener = { @@ -573,6 +595,8 @@ export class AgentRelay { private readonly workspaceName?: string; private readonly relaycastBaseUrl?: string; private readonly defaultPersonaDirs?: string[]; + private readonly harnesses: Record; + private readonly brokerLifetime: 'attached' | 'detached'; private relayApiKey?: string; private resolvedWorkspaceId?: string; private client?: AgentRelayClient; @@ -615,6 +639,8 @@ export class AgentRelay { } this.relaycastBaseUrl = options.relaycastBaseUrl; if (options.personaDirs) this.defaultPersonaDirs = [...options.personaDirs]; + this.harnesses = { ...(options.harnesses ?? {}) }; + this.brokerLifetime = options.broker?.lifetime ?? 'attached'; this.clientOptions = { binaryPath: options.binaryPath, binaryArgs: options.binaryArgs, @@ -714,6 +740,73 @@ export class AgentRelay { ); } + registerHarness(name: string, definition: HarnessDefinition): void { + const key = name.trim(); + if (!key) { + throw new Error('registerHarness() expects a non-empty harness name'); + } + this.harnesses[key] = definition; + } + + private findHarnessDefinition(cli: string): HarnessDefinition | undefined { + for (const key of harnessLookupKeys(cli)) { + const definition = this.harnesses[key]; + if (definition) return definition; + } + return undefined; + } + + private buildHarnessContext(input: SpawnPtyInput): { + name: string; + cli: string; + task?: string; + args: string[]; + model?: string; + cwd?: string; + env: Record; + } { + const envSource = this.clientOptions.env ?? process.env; + const env: Record = {}; + for (const [key, value] of Object.entries(envSource)) { + if (value !== undefined) env[key] = String(value); + } + return { + name: input.name, + cli: input.cli, + task: input.task, + args: input.args ?? [], + model: input.model, + cwd: input.cwd ?? this.clientOptions.cwd ?? process.cwd(), + env, + }; + } + + private async resolveHarnessPlan(input: SpawnPtyInput): Promise { + if (input.harnessPlan) return input.harnessPlan; + const definition = this.findHarnessDefinition(input.cli); + if (!definition) return undefined; + + const context = this.buildHarnessContext(input); + if (isAttachedHarnessResolver(definition)) { + if (this.brokerLifetime !== 'attached') { + throw new Error( + `Harness '${input.cli}' uses a dynamic resolver, which requires broker.lifetime = 'attached'` + ); + } + return definition(context); + } + + return resolveStaticHarnessPlan({ + name: context.name, + cli: context.cli, + definition, + args: context.args, + task: context.task, + model: context.model, + cwd: context.cwd, + }); + } + private applyWorkspaceEnv(workspaceId: string, apiKey: string): void { // `workspaceId` here is the **relaycast** workspace id resolved by this // SDK (auto-created or caller-supplied via `new AgentRelay({ workspaceId })`). @@ -780,12 +873,13 @@ export class AgentRelay { task: input.task, }; await this.invokeLifecycleHook(input.onStart, lifecycleContext, `spawnPty("${input.name}") onStart`); - let result: { name: string; runtime: AgentRuntime }; + let result: SpawnAgentResult; const resultContract = this.prepareAgentResultContract(input.result); if (resultContract) { this.resultContracts.set(input.name, resultContract as InternalAgentResultContract); } try { + const harnessPlan = await this.resolveHarnessPlan(input); result = await client.spawnPty({ name: input.name, cli: input.cli, @@ -800,6 +894,7 @@ export class AgentRelay { shadowMode: input.shadowMode, idleThresholdSecs: input.idleThresholdSecs, restartPolicy: input.restartPolicy, + harnessPlan, skipRelayPrompt: input.skipRelayPrompt, agentResultSchema: resultContract?.jsonSchema, }); @@ -822,7 +917,7 @@ export class AgentRelay { this.resultContracts.delete(input.name); this.resultContracts.set(result.name, resultContract as InternalAgentResultContract); } - const agent = this.makeAgent(result.name, result.runtime, channels) as Agent; + const agent = this.makeAgent(result.name, result.runtime, channels, result) as Agent; this.knownAgents.set(agent.name, agent); await this.invokeLifecycleHook( input.onSuccess, @@ -856,6 +951,7 @@ export class AgentRelay { shadowMode: options?.shadowMode, idleThresholdSecs: options?.idleThresholdSecs, restartPolicy: options?.restartPolicy, + harnessPlan: options?.harnessPlan, skipRelayPrompt: options?.skipRelayPrompt, result: options?.result, onStart: options?.onStart, @@ -940,6 +1036,7 @@ export class AgentRelay { shadowMode: options.shadowMode, idleThresholdSecs: options.idleThresholdSecs, restartPolicy: options.restartPolicy, + harnessPlan: options.harnessPlan, skipRelayPrompt: options.skipRelayPrompt, result: options.result, onStart: options.onStart, @@ -1090,7 +1187,7 @@ export class AgentRelay { return list.map((entry) => { const existing = this.knownAgents.get(entry.name); if (existing) return existing; - const agent = this.makeAgent(entry.name, entry.runtime, entry.channels); + const agent = this.makeAgent(entry.name, entry.runtime, entry.channels, entry); this.knownAgents.set(agent.name, agent); return agent; }); @@ -1246,7 +1343,10 @@ export class AgentRelay { if (event.kind !== 'worker_ready' || event.name !== name) { return; } - const agent = this.ensureAgentHandle(event.name, event.runtime); + const agent = this.ensureAgentHandle(event.name, event.runtime, [], { + sessionId: event.sessionId, + pid: event.pid, + }); this.readyAgents.add(event.name); this.exitedAgents.delete(event.name); resolveWith(agent); @@ -1376,12 +1476,17 @@ export class AgentRelay { // ── Private helpers ───────────────────────────────────────────────────── - private ensureAgentHandle(name: string, runtime: AgentRuntime = 'pty', channels: string[] = []): Agent { + private ensureAgentHandle( + name: string, + runtime: AgentRuntime = 'pty', + channels: string[] = [], + metadata?: { sessionId?: string; pid?: number } + ): Agent { const existing = this.knownAgents.get(name); if (existing) { return existing; } - const agent = this.makeAgent(name, runtime, channels); + const agent = this.makeAgent(name, runtime, channels, metadata); this.knownAgents.set(name, agent); return agent; } @@ -1664,7 +1769,10 @@ export class AgentRelay { break; } case 'agent_spawned': { - const agent = this.ensureAgentHandle(event.name, event.runtime); + const agent = this.ensureAgentHandle(event.name, event.runtime, [], { + sessionId: event.sessionId, + pid: event.pid, + }); this.readyAgents.delete(event.name); this.messageReadyAgents.delete(event.name); this.exitedAgents.delete(event.name); @@ -1725,7 +1833,10 @@ export class AgentRelay { break; } case 'worker_ready': { - const agent = this.ensureAgentHandle(event.name, event.runtime); + const agent = this.ensureAgentHandle(event.name, event.runtime, [], { + sessionId: event.sessionId, + pid: event.pid, + }); this.readyAgents.add(event.name); this.exitedAgents.delete(event.name); this.idleAgents.delete(event.name); @@ -1966,13 +2077,20 @@ export class AgentRelay { }); } - private makeAgent(name: string, runtime: AgentRuntime, channels: string[]): Agent { + private makeAgent( + name: string, + runtime: AgentRuntime, + channels: string[], + metadata?: { sessionId?: string; pid?: number } + ): Agent { // eslint-disable-next-line @typescript-eslint/no-this-alias const relay = this; let agentChannels = [...channels]; const agent: InternalAgent = { name, runtime, + sessionId: metadata?.sessionId, + pid: metadata?.pid, get channels() { return [...agentChannels]; }, @@ -2204,6 +2322,7 @@ export class AgentRelay { model: options?.model, cwd: options?.cwd, idleThresholdSecs: options?.idleThresholdSecs, + harnessPlan: options?.harnessPlan, agentToken: options?.agentToken, skipRelayPrompt: options?.skipRelayPrompt, result: options?.result, @@ -2221,22 +2340,34 @@ export class AgentRelay { task, }; await this.invokeLifecycleHook(options?.onStart, lifecycleContext, `spawn("${name}") onStart`); - let result: { name: string; runtime: AgentRuntime }; + let result: SpawnAgentResult; const resultContract = this.prepareAgentResultContract(options?.result); if (resultContract) { this.resultContracts.set(name, resultContract as InternalAgentResultContract); } try { + const harnessPlan = + options?.harnessPlan ?? + (await this.resolveHarnessPlan({ + name, + cli, + args, + channels, + task, + model: options?.model, + cwd: options?.cwd, + })); result = await client.spawnProvider({ name, provider: cli as HeadlessProvider, - transport: 'headless', + transport: harnessPlan?.runtime ?? 'headless', args, channels, task, model: options?.model, cwd: options?.cwd, idleThresholdSecs: options?.idleThresholdSecs, + harnessPlan, agentToken: options?.agentToken, skipRelayPrompt: options?.skipRelayPrompt, agentResultSchema: resultContract?.jsonSchema, @@ -2261,7 +2392,7 @@ export class AgentRelay { this.resultContracts.delete(name); this.resultContracts.set(result.name, resultContract as InternalAgentResultContract); } - const agent = this.makeAgent(result.name, result.runtime, channels) as Agent; + const agent = this.makeAgent(result.name, result.runtime, channels, result) as Agent; this.knownAgents.set(agent.name, agent); await this.invokeLifecycleHook( options?.onSuccess, diff --git a/packages/sdk/src/types.ts b/packages/sdk/src/types.ts index 232103bfe..0bcda148f 100644 --- a/packages/sdk/src/types.ts +++ b/packages/sdk/src/types.ts @@ -9,6 +9,7 @@ import type { MessageInjectionMode, RestartPolicy, } from './protocol.js'; +import type { ResolvedHarnessPlan } from './harness.js'; export type JsonSchema = Record | boolean; @@ -26,6 +27,7 @@ export interface SpawnPtyInput { idleThresholdSecs?: number; restartPolicy?: RestartPolicy; continueFrom?: string; + harnessPlan?: ResolvedHarnessPlan; skipRelayPrompt?: boolean; agentResultSchema?: JsonSchema; /** Optional pre-minted relaycast agent token (`at_live_`, from @@ -56,7 +58,14 @@ export interface SpawnHeadlessInput { agentToken?: string; } -export type AgentTransport = 'pty' | 'headless'; +export type AgentTransport = 'pty' | 'headless' | 'app_server'; + +export interface SpawnAgentResult { + name: string; + runtime: AgentRuntime; + sessionId?: string; + pid?: number; +} export interface SpawnProviderInput { name: string; @@ -73,6 +82,7 @@ export interface SpawnProviderInput { idleThresholdSecs?: number; restartPolicy?: RestartPolicy; continueFrom?: string; + harnessPlan?: ResolvedHarnessPlan; skipRelayPrompt?: boolean; agentResultSchema?: JsonSchema; /** Optional pre-minted relaycast agent token (`at_live_`, from @@ -106,6 +116,7 @@ export interface ListAgent { team?: string; channels: string[]; parent?: string; + sessionId?: string; pid?: number; last_activity_at?: string; last_activity_ms?: number; From 298ec2169dcc7827c076a37099824c62ad78d136 Mon Sep 17 00:00:00 2001 From: Will Washburn Date: Mon, 25 May 2026 12:35:10 -0400 Subject: [PATCH 03/19] Clarify headless app-server harnesses --- .../completed/2026-05/traj_7i9tigaejfje.json | 53 +++++++++++++++++++ .../completed/2026-05/traj_7i9tigaejfje.md | 33 ++++++++++++ .trajectories/index.json | 9 +++- CHANGELOG.md | 4 +- crates/broker/src/protocol.rs | 26 +++++---- crates/broker/src/runtime/api.rs | 22 -------- crates/broker/src/runtime/app_server.rs | 3 +- crates/broker/src/runtime/spawn_spec.rs | 29 +++++----- crates/broker/src/runtime/tests.rs | 26 +++++---- crates/broker/src/worker.rs | 16 +++--- docs/harness-runtime-plan.md | 41 +++++++++----- packages/sdk/src/__tests__/harness.test.ts | 8 +-- packages/sdk/src/client.ts | 2 +- packages/sdk/src/harness.ts | 22 ++++---- packages/sdk/src/protocol.ts | 2 +- packages/sdk/src/types.ts | 2 +- web/content/docs/harnesses.mdx | 31 ++++++----- 17 files changed, 216 insertions(+), 113 deletions(-) create mode 100644 .trajectories/completed/2026-05/traj_7i9tigaejfje.json create mode 100644 .trajectories/completed/2026-05/traj_7i9tigaejfje.md diff --git a/.trajectories/completed/2026-05/traj_7i9tigaejfje.json b/.trajectories/completed/2026-05/traj_7i9tigaejfje.json new file mode 100644 index 000000000..814f08bfa --- /dev/null +++ b/.trajectories/completed/2026-05/traj_7i9tigaejfje.json @@ -0,0 +1,53 @@ +{ + "id": "traj_7i9tigaejfje", + "version": 1, + "task": { + "title": "Clarify headless app-server harness terminology" + }, + "status": "completed", + "startedAt": "2026-05-25T16:34:21.397Z", + "completedAt": "2026-05-25T16:34:33.412Z", + "agents": [ + { + "name": "default", + "role": "lead", + "joinedAt": "2026-05-25T16:34:29.105Z" + } + ], + "chapters": [ + { + "id": "chap_vz66cc5xfiai", + "title": "Work", + "agentName": "default", + "startedAt": "2026-05-25T16:34:29.105Z", + "endedAt": "2026-05-25T16:34:33.412Z", + "events": [ + { + "ts": 1779726869106, + "type": "decision", + "content": "Collapsed app-server into headless runtime driver: Collapsed app-server into headless runtime driver", + "raw": { + "question": "Collapsed app-server into headless runtime driver", + "chosen": "Collapsed app-server into headless runtime driver", + "alternatives": [], + "reasoning": "App-server and provider command workers have the same non-PTY broker capability surface; keeping app_server as a separate public runtime made docs and API shape more confusing." + }, + "significance": "high" + } + ] + } + ], + "retrospective": { + "summary": "Clarified app-server as a headless harness driver instead of a separate public runtime.", + "approach": "Standard approach", + "confidence": 0.88 + }, + "commits": [], + "filesChanged": [], + "projectId": "/private/tmp/relay-harness-runtime-plans", + "tags": [], + "_trace": { + "startRef": "84d87355ef3a727947607690dd0df7bb0e158f5d", + "endRef": "84d87355ef3a727947607690dd0df7bb0e158f5d" + } +} diff --git a/.trajectories/completed/2026-05/traj_7i9tigaejfje.md b/.trajectories/completed/2026-05/traj_7i9tigaejfje.md new file mode 100644 index 000000000..17dd1bbfd --- /dev/null +++ b/.trajectories/completed/2026-05/traj_7i9tigaejfje.md @@ -0,0 +1,33 @@ +# Trajectory: Clarify headless app-server harness terminology + +> **Status:** ✅ Completed +> **Confidence:** 88% +> **Started:** May 25, 2026 at 12:34 PM +> **Completed:** May 25, 2026 at 12:34 PM + +--- + +## Summary + +Clarified app-server as a headless harness driver instead of a separate public runtime. + +**Approach:** Standard approach + +--- + +## Key Decisions + +### Collapsed app-server into headless runtime driver + +- **Chose:** Collapsed app-server into headless runtime driver +- **Reasoning:** App-server and provider command workers have the same non-PTY broker capability surface; keeping app_server as a separate public runtime made docs and API shape more confusing. + +--- + +## Chapters + +### 1. Work + +_Agent: default_ + +- Collapsed app-server into headless runtime driver: Collapsed app-server into headless runtime driver diff --git a/.trajectories/index.json b/.trajectories/index.json index d75b73b7e..7f6dea44e 100644 --- a/.trajectories/index.json +++ b/.trajectories/index.json @@ -1,6 +1,6 @@ { "version": 1, - "lastUpdated": "2026-05-25T16:22:35.521Z", + "lastUpdated": "2026-05-25T16:34:33.573Z", "trajectories": { "traj_05xg7j388bc4": { "title": "Add browser workflow step integration", @@ -1121,6 +1121,13 @@ "startedAt": "2026-05-25T15:49:27.102Z", "completedAt": "2026-05-25T16:22:35.339Z", "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_i2pjnx3dll5b.json" + }, + "traj_7i9tigaejfje": { + "title": "Clarify headless app-server harness terminology", + "status": "completed", + "startedAt": "2026-05-25T16:34:21.397Z", + "completedAt": "2026-05-25T16:34:33.412Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_7i9tigaejfje.json" } } } diff --git a/CHANGELOG.md b/CHANGELOG.md index 036f683ee..6a9a1c800 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,8 +10,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - Broker and TypeScript SDK structured result contracts add the `submit_result` MCP tool, `agent.waitForResult()`, per-spawn `result.onResult`, and `relay.addListener('agentResult', ...)` for typed JSON worker outcomes. -- `@agent-relay/sdk` harness definitions resolve named agent runtimes into broker-executable `pty` or `app_server` plans, so custom CLIs like Qwen can be configured without Rust changes. -- `agent-relay-broker` accepts resolved harness plans on spawn and adds an `app_server` runtime path for delivering Relay messages to existing OpenCode server sessions. +- `@agent-relay/sdk` harness definitions resolve named agent runtimes into broker-executable `pty` or `headless` plans, so custom CLIs like Qwen can be configured without Rust changes. +- `agent-relay-broker` accepts resolved harness plans on spawn and adds a headless app-server driver for delivering Relay messages to existing OpenCode server sessions. ### Changed diff --git a/crates/broker/src/protocol.rs b/crates/broker/src/protocol.rs index ac6fedeb7..559c467d3 100644 --- a/crates/broker/src/protocol.rs +++ b/crates/broker/src/protocol.rs @@ -12,7 +12,6 @@ pub const PROTOCOL_VERSION: u32 = 2; pub enum AgentRuntime { Pty, Headless, - AppServer, } #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] @@ -107,9 +106,16 @@ pub enum HarnessReleasePolicy { Delete, } +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +#[serde(rename_all = "snake_case")] +pub enum HeadlessHarnessDriver { + AppServer, +} + #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] -pub struct AppServerHarnessPlan { +pub struct HeadlessHarnessPlan { + pub driver: HeadlessHarnessDriver, pub protocol: String, pub endpoint: String, pub session_id: String, @@ -127,21 +133,21 @@ pub struct AppServerHarnessPlan { #[serde(tag = "runtime", rename_all = "snake_case")] pub enum ResolvedHarnessPlan { Pty(PtyHarnessPlan), - AppServer(AppServerHarnessPlan), + Headless(HeadlessHarnessPlan), } impl ResolvedHarnessPlan { pub(crate) fn runtime(&self) -> AgentRuntime { match self { Self::Pty(_) => AgentRuntime::Pty, - Self::AppServer(_) => AgentRuntime::AppServer, + Self::Headless(_) => AgentRuntime::Headless, } } pub(crate) fn session_id(&self) -> Option<&str> { match self { Self::Pty(plan) => plan.session_id.as_deref(), - Self::AppServer(plan) => Some(plan.session_id.as_str()), + Self::Headless(plan) => Some(plan.session_id.as_str()), } } } @@ -754,9 +760,10 @@ mod tests { } #[test] - fn app_server_harness_plan_round_trips() { + fn headless_app_server_harness_plan_round_trips() { let raw = json!({ - "runtime": "app_server", + "runtime": "headless", + "driver": "app_server", "protocol": "opencode", "endpoint": "http://127.0.0.1:4096", "sessionId": "ses_123", @@ -769,11 +776,12 @@ mod tests { }); let plan: ResolvedHarnessPlan = serde_json::from_value(raw).unwrap(); - assert_eq!(plan.runtime(), AgentRuntime::AppServer); + assert_eq!(plan.runtime(), AgentRuntime::Headless); assert_eq!(plan.session_id(), Some("ses_123")); let encoded = serde_json::to_string(&plan).unwrap(); - assert!(encoded.contains("\"runtime\":\"app_server\"")); + assert!(encoded.contains("\"runtime\":\"headless\"")); + assert!(encoded.contains("\"driver\":\"app_server\"")); assert!(encoded.contains("\"sessionId\":\"ses_123\"")); let decoded: ResolvedHarnessPlan = serde_json::from_str(&encoded).unwrap(); assert_eq!(decoded.session_id(), Some("ses_123")); diff --git a/crates/broker/src/runtime/api.rs b/crates/broker/src/runtime/api.rs index 5eaa2df4b..5e0136b43 100644 --- a/crates/broker/src/runtime/api.rs +++ b/crates/broker/src/runtime/api.rs @@ -958,11 +958,6 @@ impl BrokerRuntime { "unsupported_runtime: worker '{name}' is headless; pty input is only supported on PTY workers" ))); } - Some(AgentRuntime::AppServer) => { - let _ = reply.send(Err(format!( - "unsupported_runtime: worker '{name}' is app_server; pty input is only supported on PTY workers" - ))); - } Some(AgentRuntime::Pty) => { if let Err(err) = workers .send_to_worker( @@ -998,11 +993,6 @@ impl BrokerRuntime { "unsupported_runtime: worker '{name}' is headless; pty input streams are only supported on PTY workers" ))); } - Some(AgentRuntime::AppServer) => { - let _ = reply.send(Err(format!( - "unsupported_runtime: worker '{name}' is app_server; pty input streams are only supported on PTY workers" - ))); - } Some(AgentRuntime::Pty) => { let _ = reply.send(Ok(json!({ "name": name, @@ -1035,11 +1025,6 @@ impl BrokerRuntime { "unsupported_runtime: worker '{name}' is headless; resize_pty is only supported on PTY workers" ))); } - Some(AgentRuntime::AppServer) => { - let _ = reply.send(Err(format!( - "unsupported_runtime: worker '{name}' is app_server; resize_pty is only supported on PTY workers" - ))); - } Some(AgentRuntime::Pty) => { if let Err(err) = workers .send_to_worker( @@ -1100,13 +1085,6 @@ impl BrokerRuntime { ), )); } - Some(AgentRuntime::AppServer) => { - let _ = reply.send(Err( - worker_request::RequestWorkerError::UnsupportedRuntime(format!( - "worker '{name}' is app_server; {kind} is only supported on PTY workers" - )), - )); - } Some(AgentRuntime::Pty) => { let request_id = format!("req_{}", Uuid::new_v4().simple()); if let Err(err) = workers diff --git a/crates/broker/src/runtime/app_server.rs b/crates/broker/src/runtime/app_server.rs index caaf96e4c..4a030a5dd 100644 --- a/crates/broker/src/runtime/app_server.rs +++ b/crates/broker/src/runtime/app_server.rs @@ -78,7 +78,8 @@ pub(crate) async fn run_app_server_worker(cmd: AppServerCommand) -> Result<()> { frame.request_id, json!({ "name": &worker_name, - "runtime": "app_server", + "runtime": "headless", + "driver": "app_server", "sessionId": &session_id, }), ) diff --git a/crates/broker/src/runtime/spawn_spec.rs b/crates/broker/src/runtime/spawn_spec.rs index 1e8ed1eb9..8fa28444a 100644 --- a/crates/broker/src/runtime/spawn_spec.rs +++ b/crates/broker/src/runtime/spawn_spec.rs @@ -4,7 +4,6 @@ pub(crate) fn runtime_label(runtime: &AgentRuntime) -> &'static str { match runtime { AgentRuntime::Pty => "pty", AgentRuntime::Headless => "headless", - AgentRuntime::AppServer => "app_server", } } @@ -32,11 +31,8 @@ pub(crate) fn build_http_api_spawn_spec( None => AgentRuntime::Pty, Some(value) if value == "pty" => AgentRuntime::Pty, Some(value) if value == "headless" => AgentRuntime::Headless, - Some(value) if value == "app_server" || value == "app-server" => AgentRuntime::AppServer, Some(other) => { - anyhow::bail!( - "unsupported transport '{other}' (expected 'pty', 'headless', or 'app_server')" - ) + anyhow::bail!("unsupported transport '{other}' (expected 'pty' or 'headless')") } }; let harness_runtime = harness_plan.as_ref().map(ResolvedHarnessPlan::runtime); @@ -58,9 +54,6 @@ pub(crate) fn build_http_api_spawn_spec( } (_, None) => requested_runtime, }; - if matches!(runtime, AgentRuntime::AppServer) && harness_plan.is_none() { - anyhow::bail!("app_server transport requires harnessPlan.runtime = 'app_server'"); - } let parsed_restart_policy = match restart_policy { Some(v) => Some(serde_json::from_value(v).context("invalid restart_policy")?), None => None, @@ -68,15 +61,17 @@ pub(crate) fn build_http_api_spawn_spec( let (provider, cli_command, model) = match runtime { AgentRuntime::Pty => (None, Some(cli), model), - AgentRuntime::Headless => { - let provider = headless_provider_from_cli(&cli).with_context(|| { - format!( - "provider '{cli}' does not support headless transport (supported: claude, opencode)" - ) - })?; - (Some(provider), None, model) - } - AgentRuntime::AppServer => (None, Some(cli), model), + AgentRuntime::Headless => match harness_plan.as_ref() { + Some(ResolvedHarnessPlan::Headless(_)) => (None, Some(cli), model), + _ => { + let provider = headless_provider_from_cli(&cli).with_context(|| { + format!( + "provider '{cli}' does not support headless transport (supported: claude, opencode)" + ) + })?; + (Some(provider), None, model) + } + }, }; let session_id = harness_plan .as_ref() diff --git a/crates/broker/src/runtime/tests.rs b/crates/broker/src/runtime/tests.rs index cdb2a28d4..d51f382d6 100644 --- a/crates/broker/src/runtime/tests.rs +++ b/crates/broker/src/runtime/tests.rs @@ -7,8 +7,8 @@ use std::{ }; use crate::protocol::{ - AgentSpec, AppServerHarnessPlan, HarnessReleasePolicy, MessageInjectionMode, RelayDelivery, - ResolvedHarnessPlan, + AgentSpec, HarnessReleasePolicy, HeadlessHarnessDriver, HeadlessHarnessPlan, + MessageInjectionMode, RelayDelivery, ResolvedHarnessPlan, }; use crate::worker::{AgentWorkState, WorkerEvent, WorkerHandle, WorkerRegistry}; use crate::{ @@ -1976,8 +1976,9 @@ fn http_api_spawn_spec_uses_headless_runtime_for_supported_providers() { } #[test] -fn http_api_spawn_spec_uses_app_server_runtime_from_harness_plan() { - let harness_plan = ResolvedHarnessPlan::AppServer(AppServerHarnessPlan { +fn http_api_spawn_spec_uses_headless_runtime_for_app_server_harness_plan() { + let harness_plan = ResolvedHarnessPlan::Headless(HeadlessHarnessPlan { + driver: HeadlessHarnessDriver::AppServer, protocol: "opencode".to_string(), endpoint: "http://127.0.0.1:4096".to_string(), session_id: "ses_123".to_string(), @@ -2001,23 +2002,24 @@ fn http_api_spawn_spec_uses_app_server_runtime_from_harness_plan() { None, Some(harness_plan), ) - .expect("app-server harness spec should build"); + .expect("headless app-server harness spec should build"); - assert!(matches!(spec.runtime, AgentRuntime::AppServer)); + assert!(matches!(spec.runtime, AgentRuntime::Headless)); + assert!(spec.provider.is_none()); assert_eq!(spec.cli.as_deref(), Some("opencode-server")); assert_eq!(spec.session_id.as_deref(), Some("ses_123")); assert!(matches!( spec.harness_plan, - Some(ResolvedHarnessPlan::AppServer(_)) + Some(ResolvedHarnessPlan::Headless(_)) )); } #[test] -fn http_api_spawn_spec_rejects_app_server_without_harness_plan() { +fn http_api_spawn_spec_rejects_unknown_headless_provider_without_harness_plan() { let error = build_http_api_spawn_spec( "worker-a".to_string(), "opencode-server".to_string(), - Some("app_server".to_string()), + Some("headless".to_string()), None, vec![], vec!["general".to_string()], @@ -2028,10 +2030,12 @@ fn http_api_spawn_spec_rejects_app_server_without_harness_plan() { None, None, ) - .expect_err("app-server spec without harness plan should fail"); + .expect_err("custom headless provider without harness plan should fail"); assert!( - error.to_string().contains("requires harnessPlan"), + error + .to_string() + .contains("does not support headless transport"), "unexpected error: {error}" ); } diff --git a/crates/broker/src/worker.rs b/crates/broker/src/worker.rs index 28235d05f..abea642e2 100644 --- a/crates/broker/src/worker.rs +++ b/crates/broker/src/worker.rs @@ -8,8 +8,8 @@ use std::{ use crate::{ metrics::MetricsCollector, protocol::{ - AgentRuntime, AgentSpec, AppServerAuthType, HarnessReleasePolicy, ProtocolEnvelope, - RelayDelivery, ResolvedHarnessPlan, PROTOCOL_VERSION, + AgentRuntime, AgentSpec, AppServerAuthType, HarnessReleasePolicy, HeadlessHarnessDriver, + ProtocolEnvelope, RelayDelivery, ResolvedHarnessPlan, PROTOCOL_VERSION, }, relaycast::configure_relaycast_mcp_with_result, supervisor::Supervisor, @@ -306,9 +306,12 @@ impl WorkerRegistry { } } } - Some(ResolvedHarnessPlan::AppServer(plan)) => { - spec.runtime = AgentRuntime::AppServer; + Some(ResolvedHarnessPlan::Headless(plan)) => { + spec.runtime = AgentRuntime::Headless; spec.session_id = Some(plan.session_id.clone()); + match &plan.driver { + HeadlessHarnessDriver::AppServer => {} + } command.arg("app-server"); command.arg("--agent-name").arg(&spec.name); @@ -501,9 +504,6 @@ impl WorkerRegistry { } } } - AgentRuntime::AppServer => { - anyhow::bail!("app_server runtime requires a resolved harnessPlan"); - } }, } @@ -522,7 +522,7 @@ impl WorkerRegistry { command.env(key, value); } } - if !skip_relay_prompt && !matches!(spec.runtime, AgentRuntime::Headless) { + if !skip_relay_prompt && matches!(spec.runtime, AgentRuntime::Pty) { if let Some(relay_key) = worker_relay_api_key { command.env("RELAY_AGENT_TOKEN", relay_key); } diff --git a/docs/harness-runtime-plan.md b/docs/harness-runtime-plan.md index dc0caf875..4be799d0d 100644 --- a/docs/harness-runtime-plan.md +++ b/docs/harness-runtime-plan.md @@ -9,13 +9,20 @@ able to define named harnesses that resolve to broker-executable JSON plans. ## Core Model -The broker supports two runtime executors first: +The broker has two public runtime categories: - `pty`: runs a command inside a PTY and manages terminal-oriented delivery. -- `app_server`: talks to an existing or broker-owned app-server session. +- `headless`: controls a non-terminal agent through a driver. + +The first headless drivers are: + +- `provider_command`: the existing broker-owned one-shot headless path for + built-in providers such as Claude and OpenCode. +- `app_server`: a session-backed HTTP driver for existing or broker-owned agent + servers. Named harnesses such as `codex`, `qwen`, or `opencode-server` resolve to one of -those executable shapes. +those executable plans. ## Plan Shapes @@ -37,11 +44,13 @@ type PtyHarnessPlan = { }; ``` -App-server plans are session backed: +Headless app-server plans are session backed. They are still `headless` workers; +`driver: 'app_server'` explains how the broker talks to the worker: ```ts -type AppServerHarnessPlan = { - runtime: 'app_server'; +type HeadlessAppServerHarnessPlan = { + runtime: 'headless'; + driver: 'app_server'; protocol: 'opencode' | string; endpoint: string; sessionId: string; @@ -143,14 +152,18 @@ This lets users add a CLI like Qwen Code locally with config only. A Rust contribution is only needed when Relay wants a built-in with tested defaults or the CLI needs broker-side behavior. -## App-Server Runtime +## Headless Runtime + +The headless runtime covers non-PTY workers. Provider-command headless workers +run a command per delivery, for example `claude -p` or `opencode run`. +App-server headless workers attach to a session server instead. -The app-server executor consumes an app-server plan. For OpenCode, the adapter -can attach to a local or remote `opencode serve` endpoint, create or receive a -session id, deliver Relay messages through the session message API, and release -by aborting, detaching, or deleting the session. +For OpenCode app-server harnesses, the broker can attach to a local or remote +`opencode serve` endpoint, create or receive a session id, deliver Relay +messages through the session message API, and release by aborting, detaching, or +deleting the session. -App-server runtimes do not expose PTY input, resize, or snapshot capabilities. +Headless runtimes do not expose PTY input, resize, or snapshot capabilities. ## Hooks @@ -177,8 +190,8 @@ durable extension host for decision-making. 1. Add shared plan schema and SDK types. 2. Add static SDK harness resolution to PTY plans. 3. Teach the broker to accept and execute resolved PTY plans. -4. Add an app-server plan path with an OpenCode protocol driver. +4. Add a headless app-server plan path with an OpenCode protocol driver. 5. Add capability-aware runtime checks for PTY-only operations. 6. Add attached broker control RPCs for dynamic resolvers. 7. Add detached-mode validation for dynamic resolvers and in-process decision hooks. -8. Document static Qwen, dynamic Codex, and OpenCode app-server examples. +8. Document static Qwen, dynamic Codex, and OpenCode headless app-server examples. diff --git a/packages/sdk/src/__tests__/harness.test.ts b/packages/sdk/src/__tests__/harness.test.ts index f21e3c365..154233273 100644 --- a/packages/sdk/src/__tests__/harness.test.ts +++ b/packages/sdk/src/__tests__/harness.test.ts @@ -29,12 +29,13 @@ describe('harness plans', () => { }); }); - it('resolves static app-server harnesses without process args', () => { + it('resolves static headless app-server harnesses without process args', () => { const plan = resolveStaticHarnessPlan({ name: 'OpenCodeServerWorker', cli: 'opencode-server', definition: { - runtime: 'app_server', + runtime: 'headless', + driver: 'app_server', protocol: 'opencode', endpoint: 'http://127.0.0.1:4096', sessionId: 'ses_123', @@ -43,7 +44,8 @@ describe('harness plans', () => { }); expect(plan).toEqual({ - runtime: 'app_server', + runtime: 'headless', + driver: 'app_server', protocol: 'opencode', endpoint: 'http://127.0.0.1:4096', sessionId: 'ses_123', diff --git a/packages/sdk/src/client.ts b/packages/sdk/src/client.ts index 432089af5..b3e90a4bb 100644 --- a/packages/sdk/src/client.ts +++ b/packages/sdk/src/client.ts @@ -614,7 +614,7 @@ export class AgentRelayClient { async spawnProvider(input: SpawnProviderInput): Promise { const transport = resolveSpawnTransport(input); - if (transport === 'headless' && !isHeadlessProvider(input.provider)) { + if (transport === 'headless' && !isHeadlessProvider(input.provider) && !input.harnessPlan) { throw new Error( `provider '${input.provider}' does not support headless transport (supported: claude, opencode)` ); diff --git a/packages/sdk/src/harness.ts b/packages/sdk/src/harness.ts index c31a7543b..9c581d427 100644 --- a/packages/sdk/src/harness.ts +++ b/packages/sdk/src/harness.ts @@ -4,8 +4,9 @@ import path from 'node:path'; import type { AgentRuntime } from './protocol.js'; -export type HarnessRuntime = Extract; +export type HarnessRuntime = Extract; export type HarnessReleasePolicy = 'abort' | 'detach' | 'delete'; +export type HeadlessHarnessDriver = 'app_server'; export interface PtyHarnessDelivery { mode?: 'pty-injection'; @@ -35,8 +36,9 @@ export interface AppServerHarnessHost { pid?: number; } -export interface AppServerHarnessPlan { - runtime: 'app_server'; +export interface HeadlessAppServerHarnessPlan { + runtime: 'headless'; + driver: HeadlessHarnessDriver; protocol: 'opencode' | string; endpoint: string; sessionId: string; @@ -46,7 +48,7 @@ export interface AppServerHarnessPlan { metadata?: Record; } -export type ResolvedHarnessPlan = PtyHarnessPlan | AppServerHarnessPlan; +export type ResolvedHarnessPlan = PtyHarnessPlan | HeadlessAppServerHarnessPlan; export interface StaticPtyHarnessDefinition { runtime: 'pty'; @@ -61,8 +63,9 @@ export interface StaticPtyHarnessDefinition { metadata?: Record; } -export interface StaticAppServerHarnessDefinition { - runtime: 'app_server'; +export interface StaticHeadlessAppServerHarnessDefinition { + runtime: 'headless'; + driver: HeadlessHarnessDriver; protocol: 'opencode' | string; endpoint: string; sessionId: string; @@ -72,7 +75,7 @@ export interface StaticAppServerHarnessDefinition { metadata?: Record; } -export type StaticHarnessDefinition = StaticPtyHarnessDefinition | StaticAppServerHarnessDefinition; +export type StaticHarnessDefinition = StaticPtyHarnessDefinition | StaticHeadlessAppServerHarnessDefinition; export interface HarnessResolveContext { name: string; @@ -109,9 +112,10 @@ export function isAttachedHarnessResolver(value: HarnessDefinition): value is At export function resolveStaticHarnessPlan(input: ResolveStaticHarnessInput): ResolvedHarnessPlan { const { definition } = input; - if (definition.runtime === 'app_server') { + if (definition.runtime === 'headless') { return { - runtime: 'app_server', + runtime: 'headless', + driver: definition.driver, protocol: definition.protocol, endpoint: definition.endpoint, sessionId: definition.sessionId, diff --git a/packages/sdk/src/protocol.ts b/packages/sdk/src/protocol.ts index 061590790..6cfc55c82 100644 --- a/packages/sdk/src/protocol.ts +++ b/packages/sdk/src/protocol.ts @@ -1,6 +1,6 @@ export const PROTOCOL_VERSION = 2 as const; -export type AgentRuntime = 'pty' | 'headless' | 'app_server'; +export type AgentRuntime = 'pty' | 'headless'; export type HeadlessProvider = 'claude' | 'opencode'; export type InboundDeliveryMode = 'auto_inject' | 'manual_flush'; export type SnapshotFormat = 'plain' | 'ansi'; diff --git a/packages/sdk/src/types.ts b/packages/sdk/src/types.ts index 0bcda148f..90ec5de79 100644 --- a/packages/sdk/src/types.ts +++ b/packages/sdk/src/types.ts @@ -58,7 +58,7 @@ export interface SpawnHeadlessInput { agentToken?: string; } -export type AgentTransport = 'pty' | 'headless' | 'app_server'; +export type AgentTransport = 'pty' | 'headless'; export interface SpawnAgentResult { name: string; diff --git a/web/content/docs/harnesses.mdx b/web/content/docs/harnesses.mdx index e5efc3293..504d54f82 100644 --- a/web/content/docs/harnesses.mdx +++ b/web/content/docs/harnesses.mdx @@ -1,12 +1,16 @@ --- title: Harnesses -description: Define custom PTY and app-server harnesses for Agent Relay. +description: Define custom PTY and headless harnesses for Agent Relay. --- -A harness tells Relay how to control an agent runtime. The broker executes two -runtime shapes: `pty` for terminal-backed agents and `app_server` for -session-backed agent servers. Named harnesses such as `codex`, `qwen`, or -`opencode-server` resolve to one of those shapes. +A harness tells Relay how to control an agent runtime. The broker exposes two +runtime categories: `pty` for terminal-backed agents and `headless` for agents +without a terminal. Named harnesses such as `codex`, `qwen`, or +`opencode-server` resolve to one of those plans. + +Headless is the public runtime. App-server is only a headless driver: it says +the broker should deliver messages to a session server over HTTP instead of +typing into a PTY or spawning a one-shot provider command. The important boundary is that the Rust broker runs durable execution plans. SDKs can define names and resolve them into JSON, but the broker should not depend on @@ -53,10 +57,10 @@ The SDK resolves that definition to a broker-executable plan: The broker owns the PTY process, terminal stream, raw input, resize, snapshot, release, and Relay message injection. -## App-Server Harnesses +## Headless App-Server Harnesses -App-server harnesses control a session through HTTP instead of typing into a -terminal. OpenCode's `opencode serve` mode is the first target shape. +Headless app-server harnesses control a session through HTTP. OpenCode's +`opencode serve` mode is the first target driver. ```typescript file="opencode-server-harness.ts" import { AgentRelay } from '@agent-relay/sdk'; @@ -64,7 +68,8 @@ import { AgentRelay } from '@agent-relay/sdk'; const relay = new AgentRelay({ harnesses: { 'opencode-server': { - runtime: 'app_server', + runtime: 'headless', + driver: 'app_server', protocol: 'opencode', endpoint: 'http://127.0.0.1:4096', sessionId: 'ses_123', @@ -76,9 +81,9 @@ const relay = new AgentRelay({ await relay.spawn('OpenCodeServerWorker', 'opencode-server', 'Inspect the repo.'); ``` -For app-server plans, `sessionId` identifies the native runtime session. `pid` -only exists when the broker owns a local server process; remote or already -running servers may not have one. +For headless app-server plans, `sessionId` identifies the native runtime +session. `pid` only exists when the broker owns a local server process; remote +or already running servers may not have one. ## Dynamic Resolvers @@ -113,7 +118,7 @@ adapters, HTTP webhooks, or a durable extension host. Harness capabilities determine which broker routes are valid. -| Capability | PTY | App server | +| Capability | PTY | Headless app server | | --- | --- | --- | | Relay message delivery | Yes | Yes | | Release | Yes | Yes | From 6b4ee74f302b2b96fb678627d27b9f4dbb3a7327 Mon Sep 17 00:00:00 2001 From: Will Washburn Date: Mon, 25 May 2026 12:53:39 -0400 Subject: [PATCH 04/19] Refine harness adapter docs --- .../completed/2026-05/traj_1fjub7c9rlap.json | 25 +++ .../completed/2026-05/traj_1fjub7c9rlap.md | 14 ++ .trajectories/index.json | 9 +- docs/harness-runtime-plan.md | 15 +- web/content/docs/harnesses.mdx | 174 +++++++++--------- 5 files changed, 138 insertions(+), 99 deletions(-) create mode 100644 .trajectories/completed/2026-05/traj_1fjub7c9rlap.json create mode 100644 .trajectories/completed/2026-05/traj_1fjub7c9rlap.md diff --git a/.trajectories/completed/2026-05/traj_1fjub7c9rlap.json b/.trajectories/completed/2026-05/traj_1fjub7c9rlap.json new file mode 100644 index 000000000..124bdd9ff --- /dev/null +++ b/.trajectories/completed/2026-05/traj_1fjub7c9rlap.json @@ -0,0 +1,25 @@ +{ + "id": "traj_1fjub7c9rlap", + "version": 1, + "task": { + "title": "Rewrite harness docs around SDK adapters" + }, + "status": "completed", + "startedAt": "2026-05-25T16:53:04.706Z", + "completedAt": "2026-05-25T16:53:16.077Z", + "agents": [], + "chapters": [], + "retrospective": { + "summary": "Reworked harness docs to be concise and example-led around SDK adapter definitions for Claude, Codex, and OpenCode.", + "approach": "Standard approach", + "confidence": 0.9 + }, + "commits": [], + "filesChanged": [], + "projectId": "/private/tmp/relay-harness-runtime-plans", + "tags": [], + "_trace": { + "startRef": "298ec2169dcc7827c076a37099824c62ad78d136", + "endRef": "298ec2169dcc7827c076a37099824c62ad78d136" + } +} diff --git a/.trajectories/completed/2026-05/traj_1fjub7c9rlap.md b/.trajectories/completed/2026-05/traj_1fjub7c9rlap.md new file mode 100644 index 000000000..157d81464 --- /dev/null +++ b/.trajectories/completed/2026-05/traj_1fjub7c9rlap.md @@ -0,0 +1,14 @@ +# Trajectory: Rewrite harness docs around SDK adapters + +> **Status:** ✅ Completed +> **Confidence:** 90% +> **Started:** May 25, 2026 at 12:53 PM +> **Completed:** May 25, 2026 at 12:53 PM + +--- + +## Summary + +Reworked harness docs to be concise and example-led around SDK adapter definitions for Claude, Codex, and OpenCode. + +**Approach:** Standard approach diff --git a/.trajectories/index.json b/.trajectories/index.json index 7f6dea44e..fe10a6d31 100644 --- a/.trajectories/index.json +++ b/.trajectories/index.json @@ -1,6 +1,6 @@ { "version": 1, - "lastUpdated": "2026-05-25T16:34:33.573Z", + "lastUpdated": "2026-05-25T16:53:16.238Z", "trajectories": { "traj_05xg7j388bc4": { "title": "Add browser workflow step integration", @@ -1128,6 +1128,13 @@ "startedAt": "2026-05-25T16:34:21.397Z", "completedAt": "2026-05-25T16:34:33.412Z", "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_7i9tigaejfje.json" + }, + "traj_1fjub7c9rlap": { + "title": "Rewrite harness docs around SDK adapters", + "status": "completed", + "startedAt": "2026-05-25T16:53:04.706Z", + "completedAt": "2026-05-25T16:53:16.077Z", + "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_1fjub7c9rlap.json" } } } diff --git a/docs/harness-runtime-plan.md b/docs/harness-runtime-plan.md index 4be799d0d..606b7006a 100644 --- a/docs/harness-runtime-plan.md +++ b/docs/harness-runtime-plan.md @@ -21,7 +21,7 @@ The first headless drivers are: - `app_server`: a session-backed HTTP driver for existing or broker-owned agent servers. -Named harnesses such as `codex`, `qwen`, or `opencode-server` resolve to one of +Named harnesses such as `codex`, `claude`, or `opencode-server` resolve to one of those executable plans. ## Plan Shapes @@ -79,12 +79,11 @@ brokers: ```ts const harnesses = { - qwen: { + 'company-claude': { runtime: 'pty', - command: 'qwen', - args: ['run', '{modelArgs}', '{args}'], - modelArgs: ['-m', '{model}'], - searchPaths: ['~/.local/bin'], + command: 'claude', + args: ['--append-system-prompt', 'Follow the company review rubric.', '{modelArgs}', '{args}'], + modelArgs: ['--model', '{model}'], }, }; ``` @@ -148,7 +147,7 @@ The PTY executor consumes a concrete PTY plan. It handles process spawn, terminal streaming, raw input, resize, snapshot, release, and PTY message injection. -This lets users add a CLI like Qwen Code locally with config only. A Rust +This lets users add a CLI wrapper locally with config only. A Rust contribution is only needed when Relay wants a built-in with tested defaults or the CLI needs broker-side behavior. @@ -194,4 +193,4 @@ durable extension host for decision-making. 5. Add capability-aware runtime checks for PTY-only operations. 6. Add attached broker control RPCs for dynamic resolvers. 7. Add detached-mode validation for dynamic resolvers and in-process decision hooks. -8. Document static Qwen, dynamic Codex, and OpenCode headless app-server examples. +8. Document static Claude, dynamic Codex, and OpenCode headless app-server examples. diff --git a/web/content/docs/harnesses.mdx b/web/content/docs/harnesses.mdx index 504d54f82..bf2a17a9a 100644 --- a/web/content/docs/harnesses.mdx +++ b/web/content/docs/harnesses.mdx @@ -1,66 +1,100 @@ --- title: Harnesses -description: Define custom PTY and headless harnesses for Agent Relay. +description: Define custom PTY and headless harness adapters in the SDK. --- -A harness tells Relay how to control an agent runtime. The broker exposes two -runtime categories: `pty` for terminal-backed agents and `headless` for agents -without a terminal. Named harnesses such as `codex`, `qwen`, or -`opencode-server` resolve to one of those plans. +A harness adapter is a named SDK definition that turns `relay.spawn(...)` into a +broker-executable plan. The broker only runs durable plans; SDK code can prepare +those plans before spawn. -Headless is the public runtime. App-server is only a headless driver: it says -the broker should deliver messages to a session server over HTTP instead of -typing into a PTY or spawning a one-shot provider command. +Relay supports two public runtime categories: -The important boundary is that the Rust broker runs durable execution plans. SDKs -can define names and resolve them into JSON, but the broker should not depend on -an in-memory SDK callback unless the broker lifetime is explicitly attached to -that SDK process. +| Runtime | Use For | Broker Capabilities | +| --- | --- | --- | +| `pty` | Terminal-backed CLIs such as Codex or Claude Code | stream, input, resize, snapshot, delivery, release | +| `headless` | Non-terminal agents such as app-server sessions | delivery and release | + +`app_server` is not a third runtime. It is a `headless` driver for sessions +controlled over HTTP. -## Static PTY Harnesses +## Static PTY Adapter -Most CLI agents only need a PTY plan. Static harnesses are JSON-compatible and -work with attached or detached brokers. +Use a static adapter when a CLI only needs a command, args, env, and optional +model mapping. Static adapters are JSON-compatible and work with attached or +detached brokers. -```typescript file="qwen-harness.ts" +```typescript file="claude-harness.ts" import { AgentRelay } from '@agent-relay/sdk'; const relay = new AgentRelay({ harnesses: { - qwen: { + 'company-claude': { runtime: 'pty', - command: 'qwen', - args: ['run', '{modelArgs}', '{args}'], - modelArgs: ['-m', '{model}'], - searchPaths: ['~/.local/bin'], + command: 'claude', + args: ['--append-system-prompt', 'Follow the company review rubric.', '{modelArgs}', '{args}'], + modelArgs: ['--model', '{model}'], + env: { + CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC: '1', + }, }, }, }); -await relay.spawn('QwenReviewer', 'qwen', 'Review the current diff.', { - model: 'qwen3-coder', +await relay.spawn('ClaudeReviewer', 'company-claude', 'Review the current diff.', { + model: 'opus', args: ['--verbose'], - channels: ['dev'], }); ``` -The SDK resolves that definition to a broker-executable plan: +Supported placeholders: + +| Placeholder | Expands To | +| --- | --- | +| `{args}` | Spawn `args` | +| `{modelArgs}` | Rendered `modelArgs`, only when a model is set | +| `{model}` | Spawn `model` | +| `{task}` | Spawn task text | + +## Dynamic PTY Adapter + +Use a dynamic resolver when spawn needs SDK-side setup. This is attached-only: +the SDK process is part of the control path. + +```typescript file="codex-resume-harness.ts" +import { AgentRelay } from '@agent-relay/sdk'; + +const relay = new AgentRelay({ + broker: { lifetime: 'attached' }, + harnesses: { + 'codex-resume': async (ctx) => { + const sessionId = await createCodexSession({ + cwd: ctx.cwd, + task: ctx.task, + }); + + return { + runtime: 'pty', + command: 'codex', + args: ['resume', sessionId, ...ctx.args], + cwd: ctx.cwd, + env: ctx.env, + sessionId, + }; + }, + }, +}); -```json -{ - "runtime": "pty", - "command": "qwen", - "args": ["run", "-m", "qwen3-coder", "--verbose"] -} +await relay.spawn('CodexReviewer', 'codex-resume', 'Review the current diff.'); ``` -The broker owns the PTY process, terminal stream, raw input, resize, snapshot, -release, and Relay message injection. +Detached brokers should use static adapters, built-in broker behavior, HTTP +webhooks, or another durable extension host instead of in-process resolver +functions. -## Headless App-Server Harnesses +## Headless App-Server Adapter -Headless app-server harnesses control a session through HTTP. OpenCode's -`opencode serve` mode is the first target driver. +Use a headless app-server adapter when the agent already lives in a server +session. OpenCode `serve` is the first supported protocol driver. ```typescript file="opencode-server-harness.ts" import { AgentRelay } from '@agent-relay/sdk'; @@ -78,69 +112,29 @@ const relay = new AgentRelay({ }, }); -await relay.spawn('OpenCodeServerWorker', 'opencode-server', 'Inspect the repo.'); +await relay.spawn('OpenCodeWorker', 'opencode-server', 'Inspect the repo.'); ``` -For headless app-server plans, `sessionId` identifies the native runtime -session. `pid` only exists when the broker owns a local server process; remote -or already running servers may not have one. +For OpenCode, Relay delivers messages to `POST /session/:id/prompt_async`. +Release behavior is controlled by `release`: `abort`, `detach`, or `delete`. -## Dynamic Resolvers +## One-Off Plans -Some harnesses need pre-spawn work. Codex PTY spawning is the motivating -example: a resolver can call Codex app-server to create a resumable thread, then -return a PTY plan that resumes that thread. - -```typescript file="codex-resolver.ts" -const relay = new AgentRelay({ - broker: { lifetime: 'attached' }, - harnesses: { - codex: async (ctx) => { - const sessionId = await createCodexSession(ctx); +You can bypass named registration and pass a plan directly for a single spawn: - return { - runtime: 'pty', - command: 'codex', - args: ['resume', sessionId, ...ctx.args], - env: ctx.env, - sessionId, - }; - }, +```typescript file="one-off-codex.ts" +await relay.spawnPty({ + name: 'CodexOneOff', + cli: 'codex', + harnessPlan: { + runtime: 'pty', + command: 'codex', + args: ['--model', 'gpt-5.4'], }, }); ``` -Dynamic resolvers require an attached broker because the SDK process is part of -the control path. Detached brokers should use static plans, built-in Rust -adapters, HTTP webhooks, or a durable extension host. - -## Runtime Capabilities - -Harness capabilities determine which broker routes are valid. - -| Capability | PTY | Headless app server | -| --- | --- | --- | -| Relay message delivery | Yes | Yes | -| Release | Yes | Yes | -| Fork | No | Protocol-dependent | -| Terminal stream | Yes | No | -| Raw PTY input | Yes | No | -| PTY resize | Yes | No | -| PTY snapshot | Yes | No | -| Session messages | No | Protocol-dependent | - -PTY-only routes such as `sendInput`, `resizePty`, and `snapshotPty` fail when -the target harness does not expose PTY capabilities. - -## Broker Lifetime - -Attached brokers are owned by the SDK process. They can use in-process dynamic -resolvers and decision hooks because the broker exits when the SDK control -connection exits. - -Detached brokers survive SDK callers. They can be reached later by another SDK, -the CLI, the dashboard, or agent-triggered spawn requests, so they require -durable plans and durable hooks. +Use named adapters when more than one spawn should share the same behavior. ## See Also From 29c9e3af3bda02dd5e601dd1f648bab4cbf1384a Mon Sep 17 00:00:00 2001 From: Will Washburn Date: Mon, 25 May 2026 13:16:02 -0400 Subject: [PATCH 05/19] Address harness review feedback --- .../completed/2026-05/traj_0d1efjk6aeo2.json | 53 +++ .../completed/2026-05/traj_0d1efjk6aeo2.md | 33 ++ .trajectories/index.json | 333 +++++++++--------- crates/broker/src/protocol.rs | 66 +++- crates/broker/src/runtime/app_server.rs | 7 +- crates/broker/src/worker.rs | 19 + docs/harness-runtime-plan.md | 12 +- packages/sdk/src/__tests__/harness.test.ts | 16 + .../sdk/src/__tests__/lifecycle-hooks.test.ts | 32 ++ packages/sdk/src/client.ts | 18 +- packages/sdk/src/harness.ts | 9 +- packages/sdk/src/relay.ts | 64 +++- 12 files changed, 470 insertions(+), 192 deletions(-) create mode 100644 .trajectories/completed/2026-05/traj_0d1efjk6aeo2.json create mode 100644 .trajectories/completed/2026-05/traj_0d1efjk6aeo2.md diff --git a/.trajectories/completed/2026-05/traj_0d1efjk6aeo2.json b/.trajectories/completed/2026-05/traj_0d1efjk6aeo2.json new file mode 100644 index 000000000..5fc4b5b7d --- /dev/null +++ b/.trajectories/completed/2026-05/traj_0d1efjk6aeo2.json @@ -0,0 +1,53 @@ +{ + "id": "traj_0d1efjk6aeo2", + "version": 1, + "task": { + "title": "Respond to harness PR review comments" + }, + "status": "completed", + "startedAt": "2026-05-25T17:14:45.927Z", + "completedAt": "2026-05-25T17:14:53.457Z", + "agents": [ + { + "name": "default", + "role": "lead", + "joinedAt": "2026-05-25T17:14:49.998Z" + } + ], + "chapters": [ + { + "id": "chap_9esy8vjwbhf5", + "title": "Work", + "agentName": "default", + "startedAt": "2026-05-25T17:14:49.998Z", + "endedAt": "2026-05-25T17:14:53.457Z", + "events": [ + { + "ts": 1779729289999, + "type": "decision", + "content": "Fixed valid automated review findings: Fixed valid automated review findings", + "raw": { + "question": "Fixed valid automated review findings", + "chosen": "Fixed valid automated review findings", + "alternatives": [], + "reasoning": "Verified each PR comment against current code; patched runtime compatibility, hook ordering, app-server request boundedness, auth isolation, agent metadata updates, and docs mismatches." + }, + "significance": "high" + } + ] + } + ], + "retrospective": { + "summary": "Addressed PR review comments on harness runtime plans with compatibility, reliability, SDK metadata, and docs fixes.", + "approach": "Standard approach", + "confidence": 0.9 + }, + "commits": [], + "filesChanged": [], + "projectId": "/private/tmp/relay-harness-runtime-plans", + "tags": [], + "_trace": { + "startRef": "6b4ee74f302b2b96fb678627d27b9f4dbb3a7327", + "endRef": "6b4ee74f302b2b96fb678627d27b9f4dbb3a7327" + } +} diff --git a/.trajectories/completed/2026-05/traj_0d1efjk6aeo2.md b/.trajectories/completed/2026-05/traj_0d1efjk6aeo2.md new file mode 100644 index 000000000..04077f444 --- /dev/null +++ b/.trajectories/completed/2026-05/traj_0d1efjk6aeo2.md @@ -0,0 +1,33 @@ +# Trajectory: Respond to harness PR review comments + +> **Status:** ✅ Completed +> **Confidence:** 90% +> **Started:** May 25, 2026 at 01:14 PM +> **Completed:** May 25, 2026 at 01:14 PM + +--- + +## Summary + +Addressed PR review comments on harness runtime plans with compatibility, reliability, SDK metadata, and docs fixes. + +**Approach:** Standard approach + +--- + +## Key Decisions + +### Fixed valid automated review findings + +- **Chose:** Fixed valid automated review findings +- **Reasoning:** Verified each PR comment against current code; patched runtime compatibility, hook ordering, app-server request boundedness, auth isolation, agent metadata updates, and docs mismatches. + +--- + +## Chapters + +### 1. Work + +_Agent: default_ + +- Fixed valid automated review findings: Fixed valid automated review findings diff --git a/.trajectories/index.json b/.trajectories/index.json index fe10a6d31..187cebf75 100644 --- a/.trajectories/index.json +++ b/.trajectories/index.json @@ -1,1140 +1,1147 @@ { "version": 1, - "lastUpdated": "2026-05-25T16:53:16.238Z", + "lastUpdated": "2026-05-25T17:14:53.614Z", "trajectories": { "traj_05xg7j388bc4": { "title": "Add browser workflow step integration", "status": "completed", "startedAt": "2026-04-10T14:56:33.229Z", "completedAt": "2026-04-10T15:05:14.660Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-04/traj_05xg7j388bc4.json" + "path": ".trajectories/completed/2026-04/traj_05xg7j388bc4.json" }, "traj_0t92gxaz6igh": { "title": "Move docs sidebar into the mobile hamburger menu", "status": "completed", "startedAt": "2026-04-10T16:29:40.674Z", "completedAt": "2026-04-10T16:32:14.544Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-04/traj_0t92gxaz6igh.json" + "path": ".trajectories/completed/2026-04/traj_0t92gxaz6igh.json" }, "traj_1776105620545_9dcebb3d": { "title": "fix-inbox-agent-flag-workflow", "status": "completed", "startedAt": "2026-04-13T18:40:20.545Z", "completedAt": "2026-04-13T18:41:52.831Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-04/traj_1776105620545_9dcebb3d.json" + "path": ".trajectories/completed/2026-04/traj_1776105620545_9dcebb3d.json" }, "traj_1776105988184_29f1270c": { "title": "fix-inbox-agent-flag-workflow", "status": "completed", "startedAt": "2026-04-13T18:46:28.184Z", "completedAt": "2026-04-13T20:23:54.308Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-04/traj_1776105988184_29f1270c.json" + "path": ".trajectories/completed/2026-04/traj_1776105988184_29f1270c.json" }, "traj_222ha5671idc": { "title": "validate-cloud-connect-e2e-workflow", "status": "completed", "startedAt": "2026-04-15T21:32:51.980Z", "completedAt": "2026-04-15T21:45:41.024Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-04/traj_222ha5671idc.json" + "path": ".trajectories/completed/2026-04/traj_222ha5671idc.json" }, "traj_3b3p1z4y7qlo": { "title": "add-mcp-args-subcommand-workflow", "status": "completed", "startedAt": "2026-04-20T13:16:22.009Z", "completedAt": "2026-04-20T13:26:35.142Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-04/traj_3b3p1z4y7qlo.json" + "path": ".trajectories/completed/2026-04/traj_3b3p1z4y7qlo.json" }, "traj_4zqhfqw7g28l": { "title": "Investigate GitHub Actions failure for run 24255758219 job 70826792063", "status": "completed", "startedAt": "2026-04-10T17:48:33.502Z", "completedAt": "2026-04-10T17:49:14.485Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-04/traj_4zqhfqw7g28l.json" + "path": ".trajectories/completed/2026-04/traj_4zqhfqw7g28l.json" }, "traj_530xmbfeljyb": { "title": "Implement GitHub primitive adapter base layer", "status": "completed", "startedAt": "2026-04-10T15:16:25.682Z", "completedAt": "2026-04-10T15:25:16.937Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-04/traj_530xmbfeljyb.json" + "path": ".trajectories/completed/2026-04/traj_530xmbfeljyb.json" }, "traj_703m7sqyq89t": { "title": "Fix production docs loader using build-machine absolute MDX paths", "status": "completed", "startedAt": "2026-04-10T16:33:10.601Z", "completedAt": "2026-04-10T16:35:33.660Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-04/traj_703m7sqyq89t.json" + "path": ".trajectories/completed/2026-04/traj_703m7sqyq89t.json" }, "traj_8oh4r5km5eic": { "title": "Implement GitHub primitive actions", "status": "completed", "startedAt": "2026-04-10T15:26:11.355Z", "completedAt": "2026-04-10T15:33:35.150Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-04/traj_8oh4r5km5eic.json" + "path": ".trajectories/completed/2026-04/traj_8oh4r5km5eic.json" }, "traj_9tt55is74dq5": { "title": "Pin TypeScript build resolution for acp-bridge, memory, trajectory, and cloud", "status": "completed", "startedAt": "2026-04-11T13:34:46.304Z", "completedAt": "2026-04-11T13:35:22.677Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-04/traj_9tt55is74dq5.json" + "path": ".trajectories/completed/2026-04/traj_9tt55is74dq5.json" }, "traj_abjovknvcijv": { "title": "Scope CI so web-only changes do not run unrelated relay and SDK tests", "status": "completed", "startedAt": "2026-04-10T16:08:30.070Z", "completedAt": "2026-04-10T16:11:08.673Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-04/traj_abjovknvcijv.json" + "path": ".trajectories/completed/2026-04/traj_abjovknvcijv.json" }, "traj_avmkyoo2s3rt": { "title": "Implement Browser primitive client", "status": "completed", "startedAt": "2026-04-10T14:42:17.242Z", "completedAt": "2026-04-10T14:55:45.196Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-04/traj_avmkyoo2s3rt.json" + "path": ".trajectories/completed/2026-04/traj_avmkyoo2s3rt.json" }, "traj_d48czxmgx4ac": { "title": "Shift dark-mode footer from black to Relay blue", "status": "completed", "startedAt": "2026-04-10T16:12:27.477Z", "completedAt": "2026-04-10T16:13:14.348Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-04/traj_d48czxmgx4ac.json" + "path": ".trajectories/completed/2026-04/traj_d48czxmgx4ac.json" }, "traj_dw8ihhdb8ip7": { "title": "fix-dm-history-workflow", "status": "abandoned", "startedAt": "2026-04-13T19:51:57.984Z", "completedAt": "2026-04-13T19:57:27.195Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-04/traj_dw8ihhdb8ip7.json" + "path": ".trajectories/completed/2026-04/traj_dw8ihhdb8ip7.json" }, "traj_e5i62wdjx0jd": { "title": "Plan autofix finding groups", "status": "completed", "startedAt": "2026-04-13T09:40:42.044Z", "completedAt": "2026-04-13T09:41:07.789Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-04/traj_e5i62wdjx0jd.json" + "path": ".trajectories/completed/2026-04/traj_e5i62wdjx0jd.json" }, "traj_g3muawdq6bsb": { "title": "Invert dark footer gradient so the lighter blue is at the top", "status": "completed", "startedAt": "2026-04-10T16:13:19.744Z", "completedAt": "2026-04-10T16:13:43.289Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-04/traj_g3muawdq6bsb.json" + "path": ".trajectories/completed/2026-04/traj_g3muawdq6bsb.json" }, "traj_mk0t0cgn4ytq": { "title": "Merge origin/main into better-nav and resolve trajectory conflicts", "status": "completed", "startedAt": "2026-04-10T15:10:03.877Z", "completedAt": "2026-04-10T15:10:29.410Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-04/traj_mk0t0cgn4ytq.json" + "path": ".trajectories/completed/2026-04/traj_mk0t0cgn4ytq.json" }, "traj_o8kgzhfu6jth": { "title": "Add /cloud link to footer", "status": "completed", "startedAt": "2026-04-10T16:07:15.131Z", "completedAt": "2026-04-10T16:07:42.930Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-04/traj_o8kgzhfu6jth.json" + "path": ".trajectories/completed/2026-04/traj_o8kgzhfu6jth.json" }, "traj_qb54w47qwod6": { "title": "fix-history-from-workflow", "status": "completed", "startedAt": "2026-04-13T20:16:10.459Z", "completedAt": "2026-04-13T20:25:09.219Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-04/traj_qb54w47qwod6.json" + "path": ".trajectories/completed/2026-04/traj_qb54w47qwod6.json" }, "traj_rs2bt3x0fqba": { "title": "Compare failed web deploy to prior deploys and identify no-downtime fix", "status": "completed", "startedAt": "2026-04-10T17:50:43.088Z", "completedAt": "2026-04-10T18:00:44.095Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-04/traj_rs2bt3x0fqba.json" + "path": ".trajectories/completed/2026-04/traj_rs2bt3x0fqba.json" }, "traj_tjadoebpscps": { "title": "fix-dm-history-workflow", "status": "completed", "startedAt": "2026-04-13T20:02:27.719Z", "completedAt": "2026-04-13T20:02:35.662Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-04/traj_tjadoebpscps.json" + "path": ".trajectories/completed/2026-04/traj_tjadoebpscps.json" }, "traj_tv1x9pamkqad": { "title": "Add GitHub primitive workflow step integration", "status": "completed", "startedAt": "2026-04-10T15:34:36.611Z", "completedAt": "2026-04-10T15:42:17.590Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-04/traj_tv1x9pamkqad.json" + "path": ".trajectories/completed/2026-04/traj_tv1x9pamkqad.json" }, "traj_ui5omrgz819d": { "title": "cloud-run-start-from-workflow", "status": "completed", "startedAt": "2026-04-27T20:00:33.269Z", "completedAt": "2026-04-27T20:08:46.379Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-04/traj_ui5omrgz819d.json" + "path": ".trajectories/completed/2026-04/traj_ui5omrgz819d.json" }, "traj_w0xpsaoxuiyw": { "title": "Pin TypeScript compiler version and build invocation in selected packages", "status": "completed", "startedAt": "2026-04-11T13:35:52.600Z", "completedAt": "2026-04-11T13:36:48.341Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-04/traj_w0xpsaoxuiyw.json" + "path": ".trajectories/completed/2026-04/traj_w0xpsaoxuiyw.json" }, "traj_0e8i20oitwvz": { "title": "Final fresh-eyes review Codex GPT-5.5 fix", "status": "completed", "startedAt": "2026-05-15T12:46:11.342Z", "completedAt": "2026-05-15T12:46:11.500Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_0e8i20oitwvz.json" + "path": ".trajectories/completed/2026-05/traj_0e8i20oitwvz.json" }, "traj_0o6gb2wvk59t": { "title": "Fresh end-to-end validation for headless readiness", "status": "completed", "startedAt": "2026-05-15T10:55:49.188Z", "completedAt": "2026-05-15T11:11:52.324Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_0o6gb2wvk59t.json" + "path": ".trajectories/completed/2026-05/traj_0o6gb2wvk59t.json" }, "traj_0z98tkaigaxg": { "title": "ricky-child-update-issue-860-transcript-test-workflow", "status": "completed", "startedAt": "2026-05-15T21:06:58.558Z", "completedAt": "2026-05-15T21:35:56.724Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_0z98tkaigaxg.json" + "path": ".trajectories/completed/2026-05/traj_0z98tkaigaxg.json" }, "traj_1775914133873_35667beb": { "title": "fix-sdk-build-resolution-workflow", "status": "completed", "startedAt": "2026-04-11T13:28:53.873Z", "completedAt": "2026-05-08T13:33:48.161Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_1775914133873_35667beb.json" + "path": ".trajectories/completed/2026-05/traj_1775914133873_35667beb.json" }, "traj_1776073106646_1839be2d": { "title": "autofix-swarm-Agentworkforce-relay-workflow", "status": "completed", "startedAt": "2026-04-13T09:38:26.646Z", "completedAt": "2026-05-08T13:33:45.944Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_1776073106646_1839be2d.json" + "path": ".trajectories/completed/2026-05/traj_1776073106646_1839be2d.json" }, "traj_1776113772922_bc92f121": { "title": "autofix-swarm-Agentworkforce-relay-workflow", "status": "completed", "startedAt": "2026-04-13T20:56:12.922Z", "completedAt": "2026-05-08T13:33:43.489Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_1776113772922_bc92f121.json" + "path": ".trajectories/completed/2026-05/traj_1776113772922_bc92f121.json" }, "traj_1778873209642_c70e32ab": { "title": "ricky-child-update-2-workflow", "status": "completed", "startedAt": "2026-05-15T19:26:49.642Z", "completedAt": "2026-05-15T19:36:18.257Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_1778873209642_c70e32ab.json" + "path": ".trajectories/completed/2026-05/traj_1778873209642_c70e32ab.json" }, "traj_1778873211616_6db3b2cd": { "title": "ricky-child-update-docs-sync-workflow", "status": "completed", "startedAt": "2026-05-15T19:26:51.616Z", "completedAt": "2026-05-15T19:35:07.059Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_1778873211616_6db3b2cd.json" + "path": ".trajectories/completed/2026-05/traj_1778873211616_6db3b2cd.json" }, "traj_1rrpe2r7fyem": { "title": "Use streaming PTY input in CLI drive", "status": "completed", "startedAt": "2026-05-20T07:20:33.009Z", "completedAt": "2026-05-20T07:26:17.567Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_1rrpe2r7fyem.json" + "path": ".trajectories/completed/2026-05/traj_1rrpe2r7fyem.json" }, "traj_2gpglosdsq7s": { "title": "Fix broker session read paths and agent listing errors", "status": "completed", "startedAt": "2026-05-19T12:37:18.367Z", "completedAt": "2026-05-19T12:48:50.116Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_2gpglosdsq7s.json" + "path": ".trajectories/completed/2026-05/traj_2gpglosdsq7s.json" }, "traj_2tqxnib25omk": { "title": "Add workflow reliability contract coverage", "status": "completed", "startedAt": "2026-05-08T15:27:50.875Z", "completedAt": "2026-05-08T15:28:02.639Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_2tqxnib25omk.json" + "path": ".trajectories/completed/2026-05/traj_2tqxnib25omk.json" }, "traj_2yicjxgajt0a": { "title": "Review GPT-5.5 hardening", "status": "completed", "startedAt": "2026-05-15T10:54:19.300Z", "completedAt": "2026-05-15T10:54:19.476Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_2yicjxgajt0a.json" + "path": ".trajectories/completed/2026-05/traj_2yicjxgajt0a.json" }, "traj_34b1u84b19gz": { "title": "Address PR 827 review feedback", "status": "completed", "startedAt": "2026-05-08T18:29:34.717Z", "completedAt": "2026-05-08T18:33:55.607Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_34b1u84b19gz.json" + "path": ".trajectories/completed/2026-05/traj_34b1u84b19gz.json" }, "traj_3gjtcykvybt5": { "title": "Fix PR CI failures", "status": "completed", "startedAt": "2026-05-15T11:24:06.054Z", "completedAt": "2026-05-15T11:25:49.087Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_3gjtcykvybt5.json" + "path": ".trajectories/completed/2026-05/traj_3gjtcykvybt5.json" }, "traj_47akjihewlow": { "title": "Further split broker runtime module for issue 875", "status": "completed", "startedAt": "2026-05-19T01:28:35.746Z", "completedAt": "2026-05-19T01:38:29.105Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_47akjihewlow.json" + "path": ".trajectories/completed/2026-05/traj_47akjihewlow.json" }, "traj_4chzkm724ufo": { "title": "Fix headless orchestrator worktree CLI E2E issues", "status": "completed", "startedAt": "2026-05-15T11:44:28.338Z", "completedAt": "2026-05-15T11:51:05.319Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_4chzkm724ufo.json" + "path": ".trajectories/completed/2026-05/traj_4chzkm724ufo.json" }, "traj_4t07itef99ug": { "title": "Implement relay CLI bootstrap commands for proactive runtime M1", "status": "completed", "startedAt": "2026-05-11T21:47:37.805Z", "completedAt": "2026-05-11T21:49:49.859Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_4t07itef99ug.json" + "path": ".trajectories/completed/2026-05/traj_4t07itef99ug.json" }, "traj_4vucir4qvqa2": { "title": "Harden headless broker readiness semantics", "status": "completed", "startedAt": "2026-05-15T09:46:07.617Z", "completedAt": "2026-05-15T09:59:00.460Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_4vucir4qvqa2.json" + "path": ".trajectories/completed/2026-05/traj_4vucir4qvqa2.json" }, "traj_5k0jtc1g5l33": { "title": "Resolve PR 932 conflicts and review comments", "status": "completed", "startedAt": "2026-05-22T19:13:09.359Z", "completedAt": "2026-05-22T19:13:16.971Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_5k0jtc1g5l33.json" + "path": ".trajectories/completed/2026-05/traj_5k0jtc1g5l33.json" }, "traj_5nzj6v56id4z": { "title": "Fix PR914 review comments", "status": "completed", "startedAt": "2026-05-19T13:20:42.407Z", "completedAt": "2026-05-19T13:26:28.697Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_5nzj6v56id4z.json" + "path": ".trajectories/completed/2026-05/traj_5nzj6v56id4z.json" }, "traj_5q8i0iz4klpo": { "title": "ricky-child-update-2-workflow", "status": "completed", "startedAt": "2026-05-15T21:07:02.452Z", "completedAt": "2026-05-15T21:36:03.688Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_5q8i0iz4klpo.json" + "path": ".trajectories/completed/2026-05/traj_5q8i0iz4klpo.json" }, "traj_5qbla7w4kzoi": { "title": "Fix issue 877", "status": "completed", "startedAt": "2026-05-19T03:40:40.798Z", "completedAt": "2026-05-19T03:54:06.889Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_5qbla7w4kzoi.json" + "path": ".trajectories/completed/2026-05/traj_5qbla7w4kzoi.json" }, "traj_60qc24ufr96g": { "title": "Expand workflow reliability contract matrix", "status": "completed", "startedAt": "2026-05-08T15:40:11.699Z", "completedAt": "2026-05-08T15:40:22.521Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_60qc24ufr96g.json" + "path": ".trajectories/completed/2026-05/traj_60qc24ufr96g.json" }, "traj_6sjeohtm3php": { "title": "Address broker headless reliability review findings", "status": "completed", "startedAt": "2026-05-15T09:30:56.316Z", "completedAt": "2026-05-15T09:32:47.870Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_6sjeohtm3php.json" + "path": ".trajectories/completed/2026-05/traj_6sjeohtm3php.json" }, "traj_6ujzpx82gqs9": { "title": "ricky-slack-primitive-implementation-workflow-status-r-workflow", "status": "completed", "startedAt": "2026-05-08T16:06:54.844Z", "completedAt": "2026-05-08T16:18:16.119Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_6ujzpx82gqs9.json" + "path": ".trajectories/completed/2026-05/traj_6ujzpx82gqs9.json" }, "traj_78ytpicts778": { "title": "Address PR 932 result callback review findings", "status": "completed", "startedAt": "2026-05-22T15:59:25.187Z", "completedAt": "2026-05-22T16:05:12.320Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_78ytpicts778.json" + "path": ".trajectories/completed/2026-05/traj_78ytpicts778.json" }, "traj_7uznwzoxbao6": { "title": "Fix standalone detached headless startup", "status": "completed", "startedAt": "2026-05-15T10:18:46.273Z", "completedAt": "2026-05-15T10:25:00.598Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_7uznwzoxbao6.json" + "path": ".trajectories/completed/2026-05/traj_7uznwzoxbao6.json" }, "traj_7zu7et53ph3l": { "title": "Harden Codex GPT-5.5 local CLI compatibility", "status": "completed", "startedAt": "2026-05-15T10:35:25.212Z", "completedAt": "2026-05-15T10:40:53.355Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_7zu7et53ph3l.json" + "path": ".trajectories/completed/2026-05/traj_7zu7et53ph3l.json" }, "traj_81kobstnzzwk": { "title": "Orchestrate team review cycle for #892 #893 #894 #895", "status": "completed", "startedAt": "2026-05-19T08:16:32.762Z", "completedAt": "2026-05-19T08:37:32.966Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_81kobstnzzwk.json" + "path": ".trajectories/completed/2026-05/traj_81kobstnzzwk.json" }, "traj_8ljgydz61do5": { "title": "ricky-child-update-messaging-2-workflow", "status": "completed", "startedAt": "2026-05-15T21:06:54.217Z", "completedAt": "2026-05-15T21:41:56.478Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_8ljgydz61do5.json" + "path": ".trajectories/completed/2026-05/traj_8ljgydz61do5.json" }, "traj_90jmd9z27oap": { "title": "Resolve PR 948 merge conflicts", "status": "completed", "startedAt": "2026-05-22T19:49:08.797Z", "completedAt": "2026-05-22T20:45:01.262Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_90jmd9z27oap.json" + "path": ".trajectories/completed/2026-05/traj_90jmd9z27oap.json" }, "traj_947wzpddsg9j": { "title": "Implement relay CLI bootstrap commands for proactive runtime M1", "status": "completed", "startedAt": "2026-05-11T23:11:57.326Z", "completedAt": "2026-05-11T23:14:23.136Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_947wzpddsg9j.json" + "path": ".trajectories/completed/2026-05/traj_947wzpddsg9j.json" }, "traj_9fdv7hxm0b60": { "title": "Strict standalone smoke follow-up", "status": "completed", "startedAt": "2026-05-15T10:37:17.693Z", "completedAt": "2026-05-15T10:43:11.587Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_9fdv7hxm0b60.json" + "path": ".trajectories/completed/2026-05/traj_9fdv7hxm0b60.json" }, "traj_9gq96irkj00s": { "title": "Update relay to use published relaycast Rust reclaim fix", "status": "completed", "startedAt": "2026-05-10T18:45:02.118Z", "completedAt": "2026-05-10T18:48:11.532Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_9gq96irkj00s.json" + "path": ".trajectories/completed/2026-05/traj_9gq96irkj00s.json" }, "traj_aw7stgf4qau0": { "title": "Fix publish smoke cloud tarball dependency", "status": "completed", "startedAt": "2026-05-11T07:49:42.778Z", "completedAt": "2026-05-11T07:50:37.848Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_aw7stgf4qau0.json" + "path": ".trajectories/completed/2026-05/traj_aw7stgf4qau0.json" }, "traj_bdrlknyl8twj": { "title": "Add workflow reliability defaults and E2E matrix", "status": "completed", "startedAt": "2026-05-08T17:54:45.069Z", "completedAt": "2026-05-08T18:05:37.305Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_bdrlknyl8twj.json" + "path": ".trajectories/completed/2026-05/traj_bdrlknyl8twj.json" }, "traj_bz1a1o15p7px": { "title": "Fix PR 949 CI failure", "status": "completed", "startedAt": "2026-05-22T16:56:55.021Z", "completedAt": "2026-05-22T16:57:55.372Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_bz1a1o15p7px.json" + "path": ".trajectories/completed/2026-05/traj_bz1a1o15p7px.json" }, "traj_cbmwd07phhm2": { "title": "Implement #869 snapshot module + dump-pty command", "status": "completed", "startedAt": "2026-05-17T14:19:10.603Z", "completedAt": "2026-05-17T14:33:32.293Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_cbmwd07phhm2.json" + "path": ".trajectories/completed/2026-05/traj_cbmwd07phhm2.json" }, "traj_ceo5q9bh2od3": { "title": "Add structured spawned-agent results", "status": "completed", "startedAt": "2026-05-20T21:24:17.929Z", "completedAt": "2026-05-20T21:43:51.936Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_ceo5q9bh2od3.json" + "path": ".trajectories/completed/2026-05/traj_ceo5q9bh2od3.json" }, "traj_d89s38ddu7cj": { "title": "Review Codex GPT-5.5 spawn fix", "status": "completed", "startedAt": "2026-05-15T12:25:39.946Z", "completedAt": "2026-05-15T12:25:40.708Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_d89s38ddu7cj.json" + "path": ".trajectories/completed/2026-05/traj_d89s38ddu7cj.json" }, "traj_dbsnr453nxjw": { "title": "Confirm and remove unused package dependencies", "status": "completed", "startedAt": "2026-05-22T16:01:11.967Z", "completedAt": "2026-05-22T16:12:01.466Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_dbsnr453nxjw.json" + "path": ".trajectories/completed/2026-05/traj_dbsnr453nxjw.json" }, "traj_dcl9hgoiuac5": { "title": "Verify --broker-name override for agent-relay up", "status": "completed", "startedAt": "2026-05-21T18:56:55.532Z", "completedAt": "2026-05-21T19:00:06.831Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_dcl9hgoiuac5.json" + "path": ".trajectories/completed/2026-05/traj_dcl9hgoiuac5.json" }, "traj_dpgn0am1jq1c": { "title": "Implement M1 relay CLI bootstrap commands", "status": "completed", "startedAt": "2026-05-11T18:43:20.429Z", "completedAt": "2026-05-11T18:43:20.733Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_dpgn0am1jq1c.json" + "path": ".trajectories/completed/2026-05/traj_dpgn0am1jq1c.json" }, "traj_e1b7ww3un1u3": { "title": "Harden agents logs raw and follow output", "status": "completed", "startedAt": "2026-05-19T10:59:00.118Z", "completedAt": "2026-05-19T11:04:44.466Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_e1b7ww3un1u3.json" + "path": ".trajectories/completed/2026-05/traj_e1b7ww3un1u3.json" }, "traj_elx0fcwgs37x": { "title": "ricky-child-update-messaging-workflow", "status": "completed", "startedAt": "2026-05-15T21:06:50.250Z", "completedAt": "2026-05-15T21:46:46.167Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_elx0fcwgs37x.json" + "path": ".trajectories/completed/2026-05/traj_elx0fcwgs37x.json" }, "traj_erzd7j9nto9r": { "title": "Strict review and PR prep for headless broker readiness", "status": "completed", "startedAt": "2026-05-15T10:02:10.164Z", "completedAt": "2026-05-15T10:06:38.127Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_erzd7j9nto9r.json" + "path": ".trajectories/completed/2026-05/traj_erzd7j9nto9r.json" }, "traj_f1iac9ngymlj": { "title": "Fix reliability review findings 892-895", "status": "completed", "startedAt": "2026-05-19T09:52:54.932Z", "completedAt": "2026-05-19T10:01:19.068Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_f1iac9ngymlj.json" + "path": ".trajectories/completed/2026-05/traj_f1iac9ngymlj.json" }, "traj_f3arvbmmlomn": { "title": "Address PR feedback for headless broker reliability", "status": "completed", "startedAt": "2026-05-15T12:09:02.122Z", "completedAt": "2026-05-15T12:15:11.435Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_f3arvbmmlomn.json" + "path": ".trajectories/completed/2026-05/traj_f3arvbmmlomn.json" }, "traj_f9wxa8ujeg78": { "title": "Refactor broker main for issue 875", "status": "completed", "startedAt": "2026-05-19T00:54:40.328Z", "completedAt": "2026-05-19T00:55:57.506Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_f9wxa8ujeg78.json" + "path": ".trajectories/completed/2026-05/traj_f9wxa8ujeg78.json" }, "traj_fh8oosbijpwc": { "title": "Track A: relaycast subscribe + @self DM routing", "status": "completed", "startedAt": "2026-05-12T06:28:56.427Z", "completedAt": "2026-05-12T11:21:33.352Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_fh8oosbijpwc.json" + "path": ".trajectories/completed/2026-05/traj_fh8oosbijpwc.json" }, "traj_gh05rj5gwsap": { "title": "Bump relaycast Rust SDK in relay", "status": "completed", "startedAt": "2026-05-14T16:41:17.430Z", "completedAt": "2026-05-14T16:42:32.485Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_gh05rj5gwsap.json" + "path": ".trajectories/completed/2026-05/traj_gh05rj5gwsap.json" }, "traj_gnqvtoxtc8dy": { "title": "Fix broker half-start recovery", "status": "completed", "startedAt": "2026-05-19T12:34:36.057Z", "completedAt": "2026-05-19T12:47:18.115Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_gnqvtoxtc8dy.json" + "path": ".trajectories/completed/2026-05/traj_gnqvtoxtc8dy.json" }, "traj_hfkww5z7trxn": { "title": "Fresh comprehensive review of PR 856", "status": "completed", "startedAt": "2026-05-15T12:56:14.439Z", "completedAt": "2026-05-15T13:00:15.366Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_hfkww5z7trxn.json" + "path": ".trajectories/completed/2026-05/traj_hfkww5z7trxn.json" }, "traj_hrsndfzk0qay": { "title": "Tighten Codex 5.5 fallback coverage", "status": "completed", "startedAt": "2026-05-15T10:57:41.681Z", "completedAt": "2026-05-15T10:57:41.827Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_hrsndfzk0qay.json" + "path": ".trajectories/completed/2026-05/traj_hrsndfzk0qay.json" }, "traj_hysw5o7idqas": { "title": "Fix issue 924", "status": "completed", "startedAt": "2026-05-20T05:35:07.262Z", "completedAt": "2026-05-20T05:47:54.189Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_hysw5o7idqas.json" + "path": ".trajectories/completed/2026-05/traj_hysw5o7idqas.json" }, "traj_ij5b3kcatvwn": { "title": "ricky-reading-worker-dm-replies-design-spec-status-draft-date-2026-05-15-issue-860-hea-workflow", "status": "completed", "startedAt": "2026-05-15T21:06:45.545Z", "completedAt": "2026-05-15T21:50:07.842Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_ij5b3kcatvwn.json" + "path": ".trajectories/completed/2026-05/traj_ij5b3kcatvwn.json" }, "traj_iole5zdt9orr": { "title": "Fix PR 831 CI conflicts", "status": "completed", "startedAt": "2026-05-10T15:18:12.326Z", "completedAt": "2026-05-10T15:29:41.840Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_iole5zdt9orr.json" + "path": ".trajectories/completed/2026-05/traj_iole5zdt9orr.json" }, "traj_irafiyk6wpw0": { "title": "Fix agents:logs near-unparseable TTY redraw garbage (codex implement, claude review)", "status": "completed", "startedAt": "2026-05-19T10:30:38.222Z", "completedAt": "2026-05-19T10:44:24.757Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_irafiyk6wpw0.json" + "path": ".trajectories/completed/2026-05/traj_irafiyk6wpw0.json" }, "traj_itgr2w8qs3xn": { "title": "Make workflow deterministic failures repairable by agents", "status": "completed", "startedAt": "2026-05-08T14:44:45.732Z", "completedAt": "2026-05-08T14:44:45.984Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_itgr2w8qs3xn.json" + "path": ".trajectories/completed/2026-05/traj_itgr2w8qs3xn.json" }, "traj_j9k10fez3e81": { "title": "review-loop-mpb2bvnf-1-workflow", "status": "completed", "startedAt": "2026-05-18T10:30:09.927Z", "completedAt": "2026-05-18T14:53:04.092Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_j9k10fez3e81.json" + "path": ".trajectories/completed/2026-05/traj_j9k10fez3e81.json" }, "traj_jbo2x14y7ovt": { "title": "Fix issue 876", "status": "completed", "startedAt": "2026-05-19T02:48:10.768Z", "completedAt": "2026-05-19T02:56:24.584Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_jbo2x14y7ovt.json" + "path": ".trajectories/completed/2026-05/traj_jbo2x14y7ovt.json" }, "traj_jmf9pyt3zikn": { "title": "Fix issue 874", "status": "completed", "startedAt": "2026-05-19T00:07:13.993Z", "completedAt": "2026-05-19T00:17:27.680Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_jmf9pyt3zikn.json" + "path": ".trajectories/completed/2026-05/traj_jmf9pyt3zikn.json" }, "traj_k7njijv51iq4": { "title": "ricky-slack-primitive-implementation-workflow-status-r-workflow", "status": "completed", "startedAt": "2026-05-08T16:18:55.300Z", "completedAt": "2026-05-08T16:26:03.266Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_k7njijv51iq4.json" + "path": ".trajectories/completed/2026-05/traj_k7njijv51iq4.json" }, "traj_lhyrcib40kao": { "title": "Address PR #914 CodeRabbit reliability review findings", "status": "completed", "startedAt": "2026-05-19T11:52:46.110Z", "completedAt": "2026-05-19T12:07:22.401Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_lhyrcib40kao.json" + "path": ".trajectories/completed/2026-05/traj_lhyrcib40kao.json" }, "traj_lieyyspidhfj": { "title": "Fix PR 823 conflicts checks and comments", "status": "completed", "startedAt": "2026-05-09T08:37:17.563Z", "completedAt": "2026-05-09T08:47:54.686Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_lieyyspidhfj.json" + "path": ".trajectories/completed/2026-05/traj_lieyyspidhfj.json" }, "traj_m7mpv7j8n78h": { "title": "Address Relay PR 826 review feedback", "status": "completed", "startedAt": "2026-05-08T15:17:53.113Z", "completedAt": "2026-05-08T15:24:32.409Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_m7mpv7j8n78h.json" + "path": ".trajectories/completed/2026-05/traj_m7mpv7j8n78h.json" }, "traj_mi9eqd4rjfea": { "title": "Address stdio fresh review findings", "status": "abandoned", "startedAt": "2026-05-11T18:25:24.626Z", "completedAt": "2026-05-11T18:37:05.318Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_mi9eqd4rjfea.json" + "path": ".trajectories/completed/2026-05/traj_mi9eqd4rjfea.json" }, "traj_mytnzgfayj3d": { "title": "Fix PR 948 telemetry package validation failure", "status": "completed", "startedAt": "2026-05-22T23:34:27.422Z", "completedAt": "2026-05-22T23:36:15.152Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_mytnzgfayj3d.json" + "path": ".trajectories/completed/2026-05/traj_mytnzgfayj3d.json" }, "traj_mz5m5ysjj31e": { "title": "Fix Relay SDK broker stdout drain", "status": "completed", "startedAt": "2026-05-10T20:24:43.831Z", "completedAt": "2026-05-10T20:35:47.359Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_mz5m5ysjj31e.json" + "path": ".trajectories/completed/2026-05/traj_mz5m5ysjj31e.json" }, "traj_n8duofq5vq1a": { "title": "Update Codex registry for GPT-5.5", "status": "completed", "startedAt": "2026-05-15T10:27:57.532Z", "completedAt": "2026-05-15T10:33:19.705Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_n8duofq5vq1a.json" + "path": ".trajectories/completed/2026-05/traj_n8duofq5vq1a.json" }, "traj_o251whkvy9rl": { "title": "Fix Codex GPT-5.5 E2E rough edges", "status": "completed", "startedAt": "2026-05-15T11:59:26.764Z", "completedAt": "2026-05-15T12:12:25.515Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_o251whkvy9rl.json" + "path": ".trajectories/completed/2026-05/traj_o251whkvy9rl.json" }, "traj_o9cx33xn5u39": { "title": "add-mcp-args-register-flag-workflow", "status": "completed", "startedAt": "2026-04-20T15:06:23.387Z", "completedAt": "2026-05-08T13:33:35.341Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_o9cx33xn5u39.json" + "path": ".trajectories/completed/2026-05/traj_o9cx33xn5u39.json" }, "traj_ootb5rt3tozd": { "title": "ricky-child-update-docs-sync-workflow", "status": "completed", "startedAt": "2026-05-15T21:07:04.494Z", "completedAt": "2026-05-15T21:45:20.368Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_ootb5rt3tozd.json" + "path": ".trajectories/completed/2026-05/traj_ootb5rt3tozd.json" }, "traj_oyc528j7suvo": { "title": "Expose cloud workflow scheduling through Relay SDK", "status": "completed", "startedAt": "2026-05-09T19:43:34.805Z", "completedAt": "2026-05-09T19:44:00.107Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_oyc528j7suvo.json" + "path": ".trajectories/completed/2026-05/traj_oyc528j7suvo.json" }, "traj_piik8r6zu3i7": { "title": "Issue 867: RelayEventListener", "status": "completed", "startedAt": "2026-05-18T01:56:18.236Z", "completedAt": "2026-05-18T02:01:49.991Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_piik8r6zu3i7.json" + "path": ".trajectories/completed/2026-05/traj_piik8r6zu3i7.json" }, "traj_pmrcfj6or3pz": { "title": "Address runtime split review comments", "status": "completed", "startedAt": "2026-05-19T02:03:43.962Z", "completedAt": "2026-05-19T02:09:31.002Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_pmrcfj6or3pz.json" + "path": ".trajectories/completed/2026-05/traj_pmrcfj6or3pz.json" }, "traj_qtmid2nzz0kz": { "title": "Address PR 929 review comments", "status": "completed", "startedAt": "2026-05-20T06:21:54.721Z", "completedAt": "2026-05-20T06:26:56.700Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_qtmid2nzz0kz.json" + "path": ".trajectories/completed/2026-05/traj_qtmid2nzz0kz.json" }, "traj_ryf5sstno6p3": { "title": "Telemetry key from env (P0.5 of #881)", "status": "completed", "startedAt": "2026-05-18T02:56:55.314Z", "completedAt": "2026-05-18T03:02:35.202Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_ryf5sstno6p3.json" + "path": ".trajectories/completed/2026-05/traj_ryf5sstno6p3.json" }, "traj_s5ojo1f4srz4": { "title": "Remove unused user-directory package", "status": "completed", "startedAt": "2026-05-22T16:27:44.927Z", "completedAt": "2026-05-22T16:36:20.545Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_s5ojo1f4srz4.json" + "path": ".trajectories/completed/2026-05/traj_s5ojo1f4srz4.json" }, "traj_sh2ahp9z2xg6": { "title": "Fix uuid install deprecation warning", "status": "completed", "startedAt": "2026-05-19T17:21:40.756Z", "completedAt": "2026-05-19T17:21:49.702Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_sh2ahp9z2xg6.json" + "path": ".trajectories/completed/2026-05/traj_sh2ahp9z2xg6.json" }, "traj_sqerp89tc436": { "title": "Remove legacy root bin fallback", "status": "completed", "startedAt": "2026-05-19T00:45:33.159Z", "completedAt": "2026-05-19T00:50:03.857Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_sqerp89tc436.json" + "path": ".trajectories/completed/2026-05/traj_sqerp89tc436.json" }, "traj_t5uknesn2fcw": { "title": "ricky-child-update-skill-workflow", "status": "completed", "startedAt": "2026-05-15T21:06:52.453Z", "completedAt": "2026-05-15T21:40:04.209Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_t5uknesn2fcw.json" + "path": ".trajectories/completed/2026-05/traj_t5uknesn2fcw.json" }, "traj_tavtex0db4b0": { "title": "Make workflow failures repairable by agents", "status": "completed", "startedAt": "2026-05-08T14:34:19.969Z", "completedAt": "2026-05-08T14:44:45.719Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_tavtex0db4b0.json" + "path": ".trajectories/completed/2026-05/traj_tavtex0db4b0.json" }, "traj_tgism98me5na": { "title": "Implement relay CLI proactive runtime bootstrap commands", "status": "completed", "startedAt": "2026-05-11T20:04:48.053Z", "completedAt": "2026-05-11T20:05:54.956Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_tgism98me5na.json" + "path": ".trajectories/completed/2026-05/traj_tgism98me5na.json" }, "traj_u33qn99ijbh4": { "title": "ricky-child-update-workflow", "status": "completed", "startedAt": "2026-05-15T21:07:00.444Z", "completedAt": "2026-05-15T21:30:50.445Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_u33qn99ijbh4.json" + "path": ".trajectories/completed/2026-05/traj_u33qn99ijbh4.json" }, "traj_u3loicehnwb4": { "title": "Gate broker diagnostic logs behind env flag", "status": "completed", "startedAt": "2026-05-21T04:14:44.815Z", "completedAt": "2026-05-21T04:14:45.063Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_u3loicehnwb4.json" + "path": ".trajectories/completed/2026-05/traj_u3loicehnwb4.json" }, "traj_u4ixmbqqm2y1": { "title": "Add cloud workflow schedule CLI", "status": "completed", "startedAt": "2026-05-09T19:26:42.106Z", "completedAt": "2026-05-09T19:29:18.024Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_u4ixmbqqm2y1.json" + "path": ".trajectories/completed/2026-05/traj_u4ixmbqqm2y1.json" }, "traj_uf8y40ewrfh0": { "title": "Address PR 831 review feedback and conflicts", "status": "completed", "startedAt": "2026-05-09T19:59:24.197Z", "completedAt": "2026-05-09T19:59:24.403Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_uf8y40ewrfh0.json" + "path": ".trajectories/completed/2026-05/traj_uf8y40ewrfh0.json" }, "traj_v1wexlfur5zr": { "title": "Fix broker headless reliability doc", "status": "completed", "startedAt": "2026-05-15T09:04:51.316Z", "completedAt": "2026-05-15T09:13:50.970Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_v1wexlfur5zr.json" + "path": ".trajectories/completed/2026-05/traj_v1wexlfur5zr.json" }, "traj_v87cyrs8dke9": { "title": "Refactor runDriveSession below complexity 15 (#897)", "status": "completed", "startedAt": "2026-05-14T14:28:34.155Z", "completedAt": "2026-05-18T18:06:04.950Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_v87cyrs8dke9.json" + "path": ".trajectories/completed/2026-05/traj_v87cyrs8dke9.json" }, "traj_v9x3o92ag682": { "title": "ricky-child-update-messaging-test-workflow", "status": "completed", "startedAt": "2026-05-15T21:06:56.418Z", "completedAt": "2026-05-15T21:34:35.623Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_v9x3o92ag682.json" + "path": ".trajectories/completed/2026-05/traj_v9x3o92ag682.json" }, "traj_vfa1jr6otnjn": { "title": "Refresh PR 948 after main advanced", "status": "completed", "startedAt": "2026-05-22T23:23:16.807Z", "completedAt": "2026-05-22T23:23:26.380Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_vfa1jr6otnjn.json" + "path": ".trajectories/completed/2026-05/traj_vfa1jr6otnjn.json" }, "traj_vkozdglobkyg": { "title": "Address Relay PR 826 review comments", "status": "completed", "startedAt": "2026-05-08T15:50:35.978Z", "completedAt": "2026-05-08T15:51:38.854Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_vkozdglobkyg.json" + "path": ".trajectories/completed/2026-05/traj_vkozdglobkyg.json" }, "traj_wbn62q4cq16h": { "title": "Update generated workflow to Codex agents only", "status": "completed", "startedAt": "2026-05-15T21:03:02.671Z", "completedAt": "2026-05-15T21:06:00.384Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_wbn62q4cq16h.json" + "path": ".trajectories/completed/2026-05/traj_wbn62q4cq16h.json" }, "traj_whd40oxptlhn": { "title": "Review spawn persistence fix and open PR", "status": "completed", "startedAt": "2026-05-13T10:57:02.796Z", "completedAt": "2026-05-13T11:00:43.100Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_whd40oxptlhn.json" + "path": ".trajectories/completed/2026-05/traj_whd40oxptlhn.json" }, "traj_wx00tjvpptvg": { "title": "Investigate agent-relay spawn persistence", "status": "completed", "startedAt": "2026-05-13T10:49:12.464Z", "completedAt": "2026-05-13T10:53:03.748Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_wx00tjvpptvg.json" + "path": ".trajectories/completed/2026-05/traj_wx00tjvpptvg.json" }, "traj_wzzboitm85ee": { "title": "Resolve PR conflicts around platform tradeoff copy", "status": "completed", "startedAt": "2026-05-15T12:47:36.508Z", "completedAt": "2026-05-15T12:50:14.358Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_wzzboitm85ee.json" + "path": ".trajectories/completed/2026-05/traj_wzzboitm85ee.json" }, "traj_x37bhga2j5ph": { "title": "Deepen broker runtime refactor for PR 906", "status": "completed", "startedAt": "2026-05-19T01:42:10.602Z", "completedAt": "2026-05-19T01:50:40.359Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_x37bhga2j5ph.json" + "path": ".trajectories/completed/2026-05/traj_x37bhga2j5ph.json" }, "traj_ybcrij9wg8m1": { "title": "Implement agent-relay view read-only stream client (#864 sub-1)", "status": "completed", "startedAt": "2026-05-18T02:02:07.524Z", "completedAt": "2026-05-18T02:05:41.120Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_ybcrij9wg8m1.json" + "path": ".trajectories/completed/2026-05/traj_ybcrij9wg8m1.json" }, "traj_z171lng2fbbi": { "title": "Address PR 840 review feedback", "status": "completed", "startedAt": "2026-05-11T08:06:37.977Z", "completedAt": "2026-05-11T08:07:48.097Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_z171lng2fbbi.json" + "path": ".trajectories/completed/2026-05/traj_z171lng2fbbi.json" }, "traj_zfa6skfr32vy": { "title": "Implement relay CLI M1 bootstrap commands", "status": "completed", "startedAt": "2026-05-11T19:31:44.734Z", "completedAt": "2026-05-11T19:34:54.971Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_zfa6skfr32vy.json" + "path": ".trajectories/completed/2026-05/traj_zfa6skfr32vy.json" }, "traj_zqwco4gl76g3": { "title": "Fix issue 878", "status": "completed", "startedAt": "2026-05-19T04:18:25.024Z", "completedAt": "2026-05-19T04:27:18.903Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_zqwco4gl76g3.json" + "path": ".trajectories/completed/2026-05/traj_zqwco4gl76g3.json" }, "traj_zu3252hxzoqh": { "title": "Open PR for reading worker DM replies", "status": "completed", "startedAt": "2026-05-16T06:08:22.396Z", "completedAt": "2026-05-16T06:09:24.599Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_zu3252hxzoqh.json" + "path": ".trajectories/completed/2026-05/traj_zu3252hxzoqh.json" }, "traj_1775914296101_a4397efe": { "title": "fix-sdk-build-resolution-workflow", "status": "completed", "startedAt": "2026-04-11T13:31:36.101Z", "completedAt": "2026-04-11T13:39:53.105Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/traj_1775914296101_a4397efe.json" + "path": ".trajectories/completed/traj_1775914296101_a4397efe.json" }, "traj_1776024661304_cfc829b9": { "title": "fix-workflow-resume-elegant-workflow", "status": "abandoned", "startedAt": "2026-04-12T20:11:01.304Z", "completedAt": "2026-04-12T20:11:16.381Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/traj_1776024661304_cfc829b9.json" + "path": ".trajectories/completed/traj_1776024661304_cfc829b9.json" }, "traj_1778873052429_03a4dacb": { "title": "ricky-reading-worker-dm-replies-design-spec-status-draft-date-2026-05-15-issue-860-hea-workflow", "status": "abandoned", "startedAt": "2026-05-15T19:24:12.429Z", "completedAt": "2026-05-15T20:01:57.036Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/traj_1778873052429_03a4dacb.json" + "path": ".trajectories/completed/traj_1778873052429_03a4dacb.json" }, "traj_1778873197540_01102ade": { "title": "ricky-child-update-messaging-workflow", "status": "abandoned", "startedAt": "2026-05-15T19:26:37.540Z", "completedAt": "2026-05-15T19:43:47.629Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/traj_1778873197540_01102ade.json" + "path": ".trajectories/completed/traj_1778873197540_01102ade.json" }, "traj_1778873199489_f2ce4060": { "title": "ricky-child-update-skill-workflow", "status": "abandoned", "startedAt": "2026-05-15T19:26:39.489Z", "completedAt": "2026-05-15T19:43:43.149Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/traj_1778873199489_f2ce4060.json" + "path": ".trajectories/completed/traj_1778873199489_f2ce4060.json" }, "traj_1778873201502_0dacf7c5": { "title": "ricky-child-update-messaging-2-workflow", "status": "abandoned", "startedAt": "2026-05-15T19:26:41.502Z", "completedAt": "2026-05-15T19:43:35.011Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/traj_1778873201502_0dacf7c5.json" + "path": ".trajectories/completed/traj_1778873201502_0dacf7c5.json" }, "traj_1778873203502_4c225b7e": { "title": "ricky-child-update-messaging-test-workflow", "status": "abandoned", "startedAt": "2026-05-15T19:26:43.502Z", "completedAt": "2026-05-15T19:44:33.074Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/traj_1778873203502_4c225b7e.json" + "path": ".trajectories/completed/traj_1778873203502_4c225b7e.json" }, "traj_1778873205470_a4e5f0cb": { "title": "ricky-child-update-issue-860-transcript-test-workflow", "status": "abandoned", "startedAt": "2026-05-15T19:26:45.470Z", "completedAt": "2026-05-15T19:43:37.134Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/traj_1778873205470_a4e5f0cb.json" + "path": ".trajectories/completed/traj_1778873205470_a4e5f0cb.json" }, "traj_1778873207471_b7def991": { "title": "ricky-child-update-workflow", "status": "abandoned", "startedAt": "2026-05-15T19:26:47.471Z", "completedAt": "2026-05-15T19:43:24.329Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/traj_1778873207471_b7def991.json" + "path": ".trajectories/completed/traj_1778873207471_b7def991.json" }, "traj_1778874205797_81e92307": { "title": "ricky-child-update-workflow", "status": "abandoned", "startedAt": "2026-05-15T19:43:25.797Z", "completedAt": "2026-05-15T19:43:43.995Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/traj_1778874205797_81e92307.json" + "path": ".trajectories/completed/traj_1778874205797_81e92307.json" }, "traj_1778874216773_c6b12ab2": { "title": "ricky-child-update-messaging-2-workflow", "status": "abandoned", "startedAt": "2026-05-15T19:43:36.773Z", "completedAt": "2026-05-15T19:44:08.270Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/traj_1778874216773_c6b12ab2.json" + "path": ".trajectories/completed/traj_1778874216773_c6b12ab2.json" }, "traj_1778874218579_a0225559": { "title": "ricky-child-update-issue-860-transcript-test-workflow", "status": "abandoned", "startedAt": "2026-05-15T19:43:38.579Z", "completedAt": "2026-05-15T19:43:58.721Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/traj_1778874218579_a0225559.json" + "path": ".trajectories/completed/traj_1778874218579_a0225559.json" }, "traj_1778874224855_9c722c4b": { "title": "ricky-child-update-skill-workflow", "status": "abandoned", "startedAt": "2026-05-15T19:43:44.855Z", "completedAt": "2026-05-15T19:44:16.528Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/traj_1778874224855_9c722c4b.json" + "path": ".trajectories/completed/traj_1778874224855_9c722c4b.json" }, "traj_1778874226983_3367d527": { "title": "ricky-child-update-workflow", "status": "abandoned", "startedAt": "2026-05-15T19:43:46.983Z", "completedAt": "2026-05-15T19:44:05.612Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/traj_1778874226983_3367d527.json" + "path": ".trajectories/completed/traj_1778874226983_3367d527.json" }, "traj_1778874229373_9cce9465": { "title": "ricky-child-update-messaging-workflow", "status": "abandoned", "startedAt": "2026-05-15T19:43:49.374Z", "completedAt": "2026-05-15T19:44:20.096Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/traj_1778874229373_9cce9465.json" + "path": ".trajectories/completed/traj_1778874229373_9cce9465.json" }, "traj_1778874240339_51b823cd": { "title": "ricky-child-update-issue-860-transcript-test-workflow", "status": "abandoned", "startedAt": "2026-05-15T19:44:00.339Z", "completedAt": "2026-05-15T19:44:18.916Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/traj_1778874240339_51b823cd.json" + "path": ".trajectories/completed/traj_1778874240339_51b823cd.json" }, "traj_1778874241076_caa675a9": { "title": "ricky-child-update-2-workflow", "status": "abandoned", "startedAt": "2026-05-15T19:44:01.076Z", "completedAt": "2026-05-15T19:44:32.521Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/traj_1778874241076_caa675a9.json" + "path": ".trajectories/completed/traj_1778874241076_caa675a9.json" }, "traj_1778874248966_e29c4c54": { "title": "ricky-child-update-workflow", "status": "abandoned", "startedAt": "2026-05-15T19:44:08.966Z", "completedAt": "2026-05-15T19:44:27.330Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/traj_1778874248966_e29c4c54.json" + "path": ".trajectories/completed/traj_1778874248966_e29c4c54.json" }, "traj_1778874249983_12a98df3": { "title": "ricky-child-update-messaging-2-workflow", "status": "abandoned", "startedAt": "2026-05-15T19:44:09.983Z", "completedAt": "2026-05-15T19:44:41.100Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/traj_1778874249983_12a98df3.json" + "path": ".trajectories/completed/traj_1778874249983_12a98df3.json" }, "traj_1778874258229_0bdc53d8": { "title": "ricky-child-update-skill-workflow", "status": "abandoned", "startedAt": "2026-05-15T19:44:18.229Z", "completedAt": "2026-05-15T19:44:49.274Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/traj_1778874258229_0bdc53d8.json" + "path": ".trajectories/completed/traj_1778874258229_0bdc53d8.json" }, "traj_1778874261453_55f49624": { "title": "ricky-child-update-messaging-workflow", "status": "abandoned", "startedAt": "2026-05-15T19:44:21.453Z", "completedAt": "2026-05-15T19:44:53.643Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/traj_1778874261453_55f49624.json" + "path": ".trajectories/completed/traj_1778874261453_55f49624.json" }, "traj_1778874261608_48fb9bf5": { "title": "ricky-child-update-issue-860-transcript-test-workflow", "status": "abandoned", "startedAt": "2026-05-15T19:44:21.608Z", "completedAt": "2026-05-15T19:44:40.761Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/traj_1778874261608_48fb9bf5.json" + "path": ".trajectories/completed/traj_1778874261608_48fb9bf5.json" }, "traj_1778874269139_d7d7485a": { "title": "ricky-child-update-workflow", "status": "abandoned", "startedAt": "2026-05-15T19:44:29.139Z", "completedAt": "2026-05-15T19:44:48.083Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/traj_1778874269139_d7d7485a.json" + "path": ".trajectories/completed/traj_1778874269139_d7d7485a.json" }, "traj_1778874274412_70843e0e": { "title": "ricky-child-update-2-workflow", "status": "abandoned", "startedAt": "2026-05-15T19:44:34.412Z", "completedAt": "2026-05-15T19:45:06.798Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/traj_1778874274412_70843e0e.json" + "path": ".trajectories/completed/traj_1778874274412_70843e0e.json" }, "traj_1778874274581_71efa470": { "title": "ricky-child-update-messaging-test-workflow", "status": "abandoned", "startedAt": "2026-05-15T19:44:34.581Z", "completedAt": "2026-05-15T19:44:54.182Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/traj_1778874274581_71efa470.json" + "path": ".trajectories/completed/traj_1778874274581_71efa470.json" }, "traj_1778874282200_39ad11db": { "title": "ricky-child-update-issue-860-transcript-test-workflow", "status": "abandoned", "startedAt": "2026-05-15T19:44:42.200Z", "completedAt": "2026-05-15T19:45:02.477Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/traj_1778874282200_39ad11db.json" + "path": ".trajectories/completed/traj_1778874282200_39ad11db.json" }, "traj_1778874283570_ce3585b8": { "title": "ricky-child-update-messaging-2-workflow", "status": "abandoned", "startedAt": "2026-05-15T19:44:43.570Z", "completedAt": "2026-05-15T19:45:14.888Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/traj_1778874283570_ce3585b8.json" + "path": ".trajectories/completed/traj_1778874283570_ce3585b8.json" }, "traj_1778874289674_e3f868c8": { "title": "ricky-child-update-workflow", "status": "abandoned", "startedAt": "2026-05-15T19:44:49.674Z", "completedAt": "2026-05-15T19:45:08.337Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/traj_1778874289674_e3f868c8.json" + "path": ".trajectories/completed/traj_1778874289674_e3f868c8.json" }, "traj_1778874291950_0b1b5c1f": { "title": "ricky-child-update-skill-workflow", "status": "abandoned", "startedAt": "2026-05-15T19:44:51.950Z", "completedAt": "2026-05-15T19:45:23.421Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/traj_1778874291950_0b1b5c1f.json" + "path": ".trajectories/completed/traj_1778874291950_0b1b5c1f.json" }, "traj_1778874295927_4083d181": { "title": "ricky-child-update-messaging-test-workflow", "status": "abandoned", "startedAt": "2026-05-15T19:44:55.927Z", "completedAt": "2026-05-15T19:45:15.333Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/traj_1778874295927_4083d181.json" + "path": ".trajectories/completed/traj_1778874295927_4083d181.json" }, "traj_1778874296362_bdf727ff": { "title": "ricky-child-update-messaging-workflow", "status": "abandoned", "startedAt": "2026-05-15T19:44:56.362Z", "completedAt": "2026-05-15T19:45:27.624Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/traj_1778874296362_bdf727ff.json" + "path": ".trajectories/completed/traj_1778874296362_bdf727ff.json" }, "traj_i2pjnx3dll5b": { "title": "Fresh harness runtime plan and implementation", "status": "completed", "startedAt": "2026-05-25T15:49:27.102Z", "completedAt": "2026-05-25T16:22:35.339Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_i2pjnx3dll5b.json" + "path": ".trajectories/completed/2026-05/traj_i2pjnx3dll5b.json" }, "traj_7i9tigaejfje": { "title": "Clarify headless app-server harness terminology", "status": "completed", "startedAt": "2026-05-25T16:34:21.397Z", "completedAt": "2026-05-25T16:34:33.412Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_7i9tigaejfje.json" + "path": ".trajectories/completed/2026-05/traj_7i9tigaejfje.json" }, "traj_1fjub7c9rlap": { "title": "Rewrite harness docs around SDK adapters", "status": "completed", "startedAt": "2026-05-25T16:53:04.706Z", "completedAt": "2026-05-25T16:53:16.077Z", - "path": "/private/tmp/relay-harness-runtime-plans/.trajectories/completed/2026-05/traj_1fjub7c9rlap.json" + "path": ".trajectories/completed/2026-05/traj_1fjub7c9rlap.json" + }, + "traj_0d1efjk6aeo2": { + "title": "Respond to harness PR review comments", + "status": "completed", + "startedAt": "2026-05-25T17:14:45.927Z", + "completedAt": "2026-05-25T17:14:53.457Z", + "path": ".trajectories/completed/2026-05/traj_0d1efjk6aeo2.json" } } } diff --git a/crates/broker/src/protocol.rs b/crates/broker/src/protocol.rs index 559c467d3..ee740b416 100644 --- a/crates/broker/src/protocol.rs +++ b/crates/broker/src/protocol.rs @@ -1,6 +1,6 @@ use std::collections::HashMap; -use serde::{Deserialize, Serialize}; +use serde::{Deserialize, Deserializer, Serialize}; use serde_json::Value; use crate::supervisor::RestartPolicy; @@ -129,13 +129,51 @@ pub struct HeadlessHarnessPlan { pub metadata: Option>, } -#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +#[derive(Debug, Clone, PartialEq, Serialize)] #[serde(tag = "runtime", rename_all = "snake_case")] pub enum ResolvedHarnessPlan { Pty(PtyHarnessPlan), Headless(HeadlessHarnessPlan), } +impl<'de> Deserialize<'de> for ResolvedHarnessPlan { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + let mut value = Value::deserialize(deserializer)?; + let runtime = value + .get("runtime") + .and_then(Value::as_str) + .map(str::to_owned) + .ok_or_else(|| serde::de::Error::missing_field("runtime"))?; + + match runtime.as_str() { + "pty" => serde_json::from_value(value) + .map(Self::Pty) + .map_err(serde::de::Error::custom), + "headless" => serde_json::from_value(value) + .map(Self::Headless) + .map_err(serde::de::Error::custom), + "app_server" => { + if let Some(object) = value.as_object_mut() { + object.insert( + "driver".to_string(), + Value::String("app_server".to_string()), + ); + } + serde_json::from_value(value) + .map(Self::Headless) + .map_err(serde::de::Error::custom) + } + other => Err(serde::de::Error::unknown_variant( + other, + &["pty", "headless", "app_server"], + )), + } + } +} + impl ResolvedHarnessPlan { pub(crate) fn runtime(&self) -> AgentRuntime { match self { @@ -511,9 +549,9 @@ mod tests { use serde_json::{json, Value}; use super::{ - AgentRuntime, AgentSpec, BrokerEvent, BrokerToSdk, BrokerToWorker, HeadlessProvider, - MessageInjectionMode, ProtocolEnvelope, RelayDelivery, ResolvedHarnessPlan, WorkerToBroker, - PROTOCOL_VERSION, + AgentRuntime, AgentSpec, BrokerEvent, BrokerToSdk, BrokerToWorker, HeadlessHarnessDriver, + HeadlessProvider, MessageInjectionMode, ProtocolEnvelope, RelayDelivery, + ResolvedHarnessPlan, WorkerToBroker, PROTOCOL_VERSION, }; #[test] @@ -787,6 +825,24 @@ mod tests { assert_eq!(decoded.session_id(), Some("ses_123")); } + #[test] + fn legacy_app_server_harness_plan_deserializes_as_headless() { + let raw = json!({ + "runtime": "app_server", + "protocol": "opencode", + "endpoint": "http://127.0.0.1:4096", + "sessionId": "ses_legacy" + }); + + let plan: ResolvedHarnessPlan = serde_json::from_value(raw).unwrap(); + assert_eq!(plan.runtime(), AgentRuntime::Headless); + assert_eq!(plan.session_id(), Some("ses_legacy")); + let ResolvedHarnessPlan::Headless(plan) = plan else { + panic!("expected headless harness plan"); + }; + assert_eq!(plan.driver, HeadlessHarnessDriver::AppServer); + } + #[test] fn broker_to_worker_resize_pty_round_trip() { let msg = BrokerToWorker::ResizePty { diff --git a/crates/broker/src/runtime/app_server.rs b/crates/broker/src/runtime/app_server.rs index 4a030a5dd..dc1091037 100644 --- a/crates/broker/src/runtime/app_server.rs +++ b/crates/broker/src/runtime/app_server.rs @@ -8,13 +8,18 @@ struct AppServerAuthConfig { password: Option, } +const APP_SERVER_HTTP_TIMEOUT: Duration = Duration::from_secs(30); + pub(crate) async fn run_app_server_worker(cmd: AppServerCommand) -> Result<()> { let protocol = cmd.protocol.trim().to_ascii_lowercase(); let endpoint = cmd.endpoint.trim().trim_end_matches('/').to_string(); let session_id = cmd.session_id.clone(); let release = cmd.release.trim().to_ascii_lowercase(); let auth = app_server_auth_from_env(); - let http = reqwest::Client::new(); + let http = reqwest::Client::builder() + .timeout(APP_SERVER_HTTP_TIMEOUT) + .build() + .context("failed to build app-server HTTP client")?; let (out_tx, mut out_rx) = mpsc::channel::>(512); let writer_task = tokio::spawn(async move { diff --git a/crates/broker/src/worker.rs b/crates/broker/src/worker.rs index abea642e2..52411050c 100644 --- a/crates/broker/src/worker.rs +++ b/crates/broker/src/worker.rs @@ -32,6 +32,13 @@ use crate::{ spawner::terminate_child, }; +const APP_SERVER_AUTH_ENV_KEYS: [&str; 4] = [ + "AGENT_RELAY_APP_SERVER_AUTH_TYPE", + "AGENT_RELAY_APP_SERVER_AUTH_TOKEN", + "AGENT_RELAY_APP_SERVER_AUTH_USERNAME", + "AGENT_RELAY_APP_SERVER_AUTH_PASSWORD", +]; + pub(crate) mod detection; #[derive(Debug)] @@ -229,6 +236,7 @@ impl WorkerRegistry { let mut command = Command::new(std::env::current_exe().context("failed to locate current executable")?); let mut harness_env: Vec<(String, String)> = Vec::new(); + let mut suppress_worker_env: Vec<&'static str> = Vec::new(); match spec.harness_plan.clone() { Some(ResolvedHarnessPlan::Pty(plan)) => { @@ -322,6 +330,11 @@ impl WorkerRegistry { .arg("--release") .arg(release_policy_arg(plan.release.as_ref())); + suppress_worker_env.extend(APP_SERVER_AUTH_ENV_KEYS); + for key in APP_SERVER_AUTH_ENV_KEYS { + command.env_remove(key); + } + if let Some(auth) = plan.auth { harness_env.push(( "AGENT_RELAY_APP_SERVER_AUTH_TYPE".to_string(), @@ -512,6 +525,12 @@ impl WorkerRegistry { .stdout(Stdio::piped()) .stderr(Stdio::piped()); for (key, value) in &self.worker_env { + if suppress_worker_env + .iter() + .any(|blocked| key.as_str() == *blocked) + { + continue; + } command.env(key, value); } for (key, value) in &harness_env { diff --git a/docs/harness-runtime-plan.md b/docs/harness-runtime-plan.md index 606b7006a..89e325eef 100644 --- a/docs/harness-runtime-plan.md +++ b/docs/harness-runtime-plan.md @@ -37,7 +37,7 @@ type PtyHarnessPlan = { env?: Record; sessionId?: string; delivery?: { - mode: 'pty-injection'; + mode?: 'pty-injection'; format?: 'relay-block'; }; metadata?: Record; @@ -61,7 +61,7 @@ type HeadlessAppServerHarnessPlan = { password?: string; }; host?: { - ownership: 'broker-owned' | 'attached'; + ownership?: 'broker-owned' | 'attached'; pid?: number; }; release?: 'abort' | 'detach' | 'delete'; @@ -169,8 +169,12 @@ Headless runtimes do not expose PTY input, resize, or snapshot capabilities. Event hooks are non-blocking subscriptions: ```ts -relay.on('agent.spawned', async (event) => { - await posthog.capture(...); +relay.addListener('agentSpawned', async (agent) => { + await posthog.capture({ + distinctId: agent.name, + event: 'agent_spawned', + properties: { runtime: agent.runtime }, + }); }); ``` diff --git a/packages/sdk/src/__tests__/harness.test.ts b/packages/sdk/src/__tests__/harness.test.ts index 154233273..7939621de 100644 --- a/packages/sdk/src/__tests__/harness.test.ts +++ b/packages/sdk/src/__tests__/harness.test.ts @@ -1,3 +1,6 @@ +import { homedir } from 'node:os'; +import path from 'node:path'; + import { describe, expect, it, vi } from 'vitest'; import { AgentRelayClient } from '../client.js'; @@ -57,6 +60,19 @@ describe('harness plans', () => { expect(harnessLookupKeys('qwen:coder --fast')).toEqual(['qwen:coder --fast', 'qwen:coder', 'qwen']); }); + it('expands home directories in direct command paths', () => { + const plan = resolveStaticHarnessPlan({ + name: 'ClaudeReviewer', + cli: 'claude', + definition: { + runtime: 'pty', + command: '~/bin/claude', + }, + }); + + expect(plan.command).toBe(path.join(homedir(), 'bin/claude')); + }); + it('serializes resolved harness plans on spawn requests', async () => { const captures: unknown[] = []; const fetchFn = vi.fn(async (_url: string | URL | Request, init?: RequestInit) => { diff --git a/packages/sdk/src/__tests__/lifecycle-hooks.test.ts b/packages/sdk/src/__tests__/lifecycle-hooks.test.ts index 73de966e0..d0bd1228a 100644 --- a/packages/sdk/src/__tests__/lifecycle-hooks.test.ts +++ b/packages/sdk/src/__tests__/lifecycle-hooks.test.ts @@ -201,6 +201,38 @@ describe('AgentRelayClient lifecycle hooks', () => { expect((after.mock.calls[0][0] as AfterAgentSpawnContext).kind).toBe('provider'); }); + it('recomputes provider transport after beforeAgentSpawn patches add a harness plan', async () => { + const { fetchFn, captures } = makeMockFetch(); + const client = makeClient(fetchFn); + + client.addListener('beforeAgentSpawn', () => ({ + harnessPlan: { + runtime: 'headless', + driver: 'app_server', + protocol: 'opencode', + endpoint: 'http://127.0.0.1:4096', + sessionId: 'ses_hook', + }, + })); + + await client.spawnProvider({ + name: 'patched-headless', + provider: 'custom-provider', + transport: 'headless', + }); + + expect(captures[0].body).toMatchObject({ + name: 'patched-headless', + cli: 'custom-provider', + transport: 'headless', + harnessPlan: { + runtime: 'headless', + driver: 'app_server', + sessionId: 'ses_hook', + }, + }); + }); + it('release fires beforeAgentRelease then afterAgentRelease', async () => { const { fetchFn } = makeMockFetch(); const client = makeClient(fetchFn); diff --git a/packages/sdk/src/client.ts b/packages/sdk/src/client.ts index b3e90a4bb..26752d4f2 100644 --- a/packages/sdk/src/client.ts +++ b/packages/sdk/src/client.ts @@ -613,13 +613,6 @@ export class AgentRelayClient { } async spawnProvider(input: SpawnProviderInput): Promise { - const transport = resolveSpawnTransport(input); - if (transport === 'headless' && !isHeadlessProvider(input.provider) && !input.harnessPlan) { - throw new Error( - `provider '${input.provider}' does not support headless transport (supported: claude, opencode)` - ); - } - const beforeCtx: BeforeAgentSpawnContext = { kind: 'provider', input, @@ -629,6 +622,17 @@ export class AgentRelayClient { }; const t0 = Date.now(); const resolvedInput = (await this.runBeforeSpawn(beforeCtx)) as SpawnProviderInput; + const transport = resolveSpawnTransport(resolvedInput); + if ( + transport === 'headless' && + !isHeadlessProvider(resolvedInput.provider) && + !resolvedInput.harnessPlan + ) { + throw new Error( + `provider '${resolvedInput.provider}' does not support headless transport (supported: claude, opencode)` + ); + } + try { const result = await this.transport.request('/api/spawn', { method: 'POST', diff --git a/packages/sdk/src/harness.ts b/packages/sdk/src/harness.ts index 9c581d427..597e5d7fe 100644 --- a/packages/sdk/src/harness.ts +++ b/packages/sdk/src/harness.ts @@ -208,17 +208,18 @@ function isExactPlaceholder(value: string, name: string): boolean { } function resolveCommand(command: string, searchPaths?: string[]): string { - if (!searchPaths?.length || command.includes('/') || command.includes('\\')) { - return command; + const expandedCommand = expandHome(command); + if (!searchPaths?.length || expandedCommand.includes('/') || expandedCommand.includes('\\')) { + return expandedCommand; } for (const searchPath of searchPaths) { - const candidate = path.join(expandHome(searchPath), command); + const candidate = path.join(expandHome(searchPath), expandedCommand); if (existsSync(candidate)) { return candidate; } } - return command; + return expandedCommand; } function expandHome(value: string): string { diff --git a/packages/sdk/src/relay.ts b/packages/sdk/src/relay.ts index 52196b919..3f20c3e3a 100644 --- a/packages/sdk/src/relay.ts +++ b/packages/sdk/src/relay.ts @@ -489,6 +489,8 @@ type OutputListener = { type InternalAgent = Agent & { _setChannels: (channels: string[]) => void; + _setMetadata: (metadata?: { sessionId?: string; pid?: number }) => void; + _setRuntime: (runtime: AgentRuntime) => void; }; type InternalAgentResultContract = { @@ -917,8 +919,12 @@ export class AgentRelay { this.resultContracts.delete(input.name); this.resultContracts.set(result.name, resultContract as InternalAgentResultContract); } - const agent = this.makeAgent(result.name, result.runtime, channels, result) as Agent; - this.knownAgents.set(agent.name, agent); + const agent = this.ensureAgentHandle( + result.name, + result.runtime, + channels, + result + ) as Agent; await this.invokeLifecycleHook( input.onSuccess, { @@ -1186,7 +1192,10 @@ export class AgentRelay { const list = await client.listAgents(); return list.map((entry) => { const existing = this.knownAgents.get(entry.name); - if (existing) return existing; + if (existing) { + this.updateAgentHandle(existing, entry.runtime, entry.channels, entry); + return existing; + } const agent = this.makeAgent(entry.name, entry.runtime, entry.channels, entry); this.knownAgents.set(agent.name, agent); return agent; @@ -1484,6 +1493,7 @@ export class AgentRelay { ): Agent { const existing = this.knownAgents.get(name); if (existing) { + this.updateAgentHandle(existing, runtime, channels, metadata); return existing; } const agent = this.makeAgent(name, runtime, channels, metadata); @@ -1491,6 +1501,20 @@ export class AgentRelay { return agent; } + private updateAgentHandle( + agent: Agent, + runtime: AgentRuntime, + channels: string[], + metadata?: { sessionId?: string; pid?: number } + ): void { + const internal = agent as InternalAgent; + internal._setRuntime(runtime); + if (channels.length > 0) { + internal._setChannels([...new Set([...agent.channels, ...channels])]); + } + internal._setMetadata(metadata); + } + private updateDeliveryState( eventId: string, to: string, @@ -2086,11 +2110,20 @@ export class AgentRelay { // eslint-disable-next-line @typescript-eslint/no-this-alias const relay = this; let agentChannels = [...channels]; + let agentRuntime = runtime; + let sessionId = metadata?.sessionId; + let pid = metadata?.pid; const agent: InternalAgent = { name, - runtime, - sessionId: metadata?.sessionId, - pid: metadata?.pid, + get runtime() { + return agentRuntime; + }, + get sessionId() { + return sessionId; + }, + get pid() { + return pid; + }, get channels() { return [...agentChannels]; }, @@ -2300,6 +2333,17 @@ export class AgentRelay { _setChannels(nextChannels: string[]) { agentChannels = [...nextChannels]; }, + _setMetadata(nextMetadata) { + if (nextMetadata?.sessionId !== undefined) { + sessionId = nextMetadata.sessionId; + } + if (nextMetadata?.pid !== undefined) { + pid = nextMetadata.pid; + } + }, + _setRuntime(nextRuntime: AgentRuntime) { + agentRuntime = nextRuntime; + }, }; return agent; } @@ -2392,8 +2436,12 @@ export class AgentRelay { this.resultContracts.delete(name); this.resultContracts.set(result.name, resultContract as InternalAgentResultContract); } - const agent = this.makeAgent(result.name, result.runtime, channels, result) as Agent; - this.knownAgents.set(agent.name, agent); + const agent = this.ensureAgentHandle( + result.name, + result.runtime, + channels, + result + ) as Agent; await this.invokeLifecycleHook( options?.onSuccess, { From 8c429f257c346d3917c783b637d890eda045bbee Mon Sep 17 00:00:00 2001 From: Will Washburn Date: Mon, 25 May 2026 13:53:47 -0400 Subject: [PATCH 06/19] Fix harness runtime review issues --- .../completed/2026-05/traj_9dj3qiugt26j.json | 53 +++++ .../completed/2026-05/traj_9dj3qiugt26j.md | 33 +++ .trajectories/index.json | 9 +- CHANGELOG.md | 3 +- crates/broker/src/cli/mod.rs | 3 + crates/broker/src/pty.rs | 4 + crates/broker/src/pty_worker.rs | 6 +- crates/broker/src/runtime/api.rs | 4 +- crates/broker/src/runtime/app_server.rs | 25 +-- crates/broker/src/runtime/relaycast_events.rs | 6 +- crates/broker/src/runtime/tests.rs | 1 + crates/broker/src/runtime/worker_events.rs | 13 +- crates/broker/src/worker.rs | 196 +++++++++++++++++- docs/harness-runtime-plan.md | 35 +++- packages/sdk/src/harness.ts | 5 + web/content/docs/harnesses.mdx | 49 ++++- 16 files changed, 403 insertions(+), 42 deletions(-) create mode 100644 .trajectories/completed/2026-05/traj_9dj3qiugt26j.json create mode 100644 .trajectories/completed/2026-05/traj_9dj3qiugt26j.md diff --git a/.trajectories/completed/2026-05/traj_9dj3qiugt26j.json b/.trajectories/completed/2026-05/traj_9dj3qiugt26j.json new file mode 100644 index 000000000..5bcebc50f --- /dev/null +++ b/.trajectories/completed/2026-05/traj_9dj3qiugt26j.json @@ -0,0 +1,53 @@ +{ + "id": "traj_9dj3qiugt26j", + "version": 1, + "task": { + "title": "Fix harness runtime review issues" + }, + "status": "completed", + "startedAt": "2026-05-25T17:41:16.384Z", + "completedAt": "2026-05-25T17:53:06.394Z", + "agents": [ + { + "name": "default", + "role": "lead", + "joinedAt": "2026-05-25T17:52:56.230Z" + } + ], + "chapters": [ + { + "id": "chap_h9qfyvlzhsw1", + "title": "Work", + "agentName": "default", + "startedAt": "2026-05-25T17:52:56.230Z", + "endedAt": "2026-05-25T17:53:06.394Z", + "events": [ + { + "ts": 1779731576231, + "type": "decision", + "content": "Keep app-server plans attach-only for now: Keep app-server plans attach-only for now", + "raw": { + "question": "Keep app-server plans attach-only for now", + "chosen": "Keep app-server plans attach-only for now", + "alternatives": [], + "reasoning": "The Rust broker can execute durable JSON plans and report an attached host PID, but broker-owned app-server supervision would need explicit lifecycle ownership; rejecting broker-owned host plans avoids a half-supported mode." + }, + "significance": "high" + } + ] + } + ], + "retrospective": { + "summary": "Fixed harness runtime review issues: broker now tracks harness PID separately from worker wrapper PID, validates app-server plans at spawn, extends app-server release grace, avoids app-server delivery_verified overclaiming, and updates SDK/docs examples around env allowlists, permission flags, and attached app-server hosts.", + "approach": "Standard approach", + "confidence": 0.86 + }, + "commits": [], + "filesChanged": [], + "projectId": "/Users/will/Projects/AgentWorkforce/relay", + "tags": [], + "_trace": { + "startRef": "29c9e3af3bda02dd5e601dd1f648bab4cbf1384a", + "endRef": "29c9e3af3bda02dd5e601dd1f648bab4cbf1384a" + } +} diff --git a/.trajectories/completed/2026-05/traj_9dj3qiugt26j.md b/.trajectories/completed/2026-05/traj_9dj3qiugt26j.md new file mode 100644 index 000000000..dd90ae065 --- /dev/null +++ b/.trajectories/completed/2026-05/traj_9dj3qiugt26j.md @@ -0,0 +1,33 @@ +# Trajectory: Fix harness runtime review issues + +> **Status:** ✅ Completed +> **Confidence:** 86% +> **Started:** May 25, 2026 at 01:41 PM +> **Completed:** May 25, 2026 at 01:53 PM + +--- + +## Summary + +Fixed harness runtime review issues: broker now tracks harness PID separately from worker wrapper PID, validates app-server plans at spawn, extends app-server release grace, avoids app-server delivery_verified overclaiming, and updates SDK/docs examples around env allowlists, permission flags, and attached app-server hosts. + +**Approach:** Standard approach + +--- + +## Key Decisions + +### Keep app-server plans attach-only for now + +- **Chose:** Keep app-server plans attach-only for now +- **Reasoning:** The Rust broker can execute durable JSON plans and report an attached host PID, but broker-owned app-server supervision would need explicit lifecycle ownership; rejecting broker-owned host plans avoids a half-supported mode. + +--- + +## Chapters + +### 1. Work + +_Agent: default_ + +- Keep app-server plans attach-only for now: Keep app-server plans attach-only for now diff --git a/.trajectories/index.json b/.trajectories/index.json index 187cebf75..0a7eddc36 100644 --- a/.trajectories/index.json +++ b/.trajectories/index.json @@ -1,6 +1,6 @@ { "version": 1, - "lastUpdated": "2026-05-25T17:14:53.614Z", + "lastUpdated": "2026-05-25T17:53:06.564Z", "trajectories": { "traj_05xg7j388bc4": { "title": "Add browser workflow step integration", @@ -1142,6 +1142,13 @@ "startedAt": "2026-05-25T17:14:45.927Z", "completedAt": "2026-05-25T17:14:53.457Z", "path": ".trajectories/completed/2026-05/traj_0d1efjk6aeo2.json" + }, + "traj_9dj3qiugt26j": { + "title": "Fix harness runtime review issues", + "status": "completed", + "startedAt": "2026-05-25T17:41:16.384Z", + "completedAt": "2026-05-25T17:53:06.394Z", + "path": ".trajectories/completed/2026-05/traj_9dj3qiugt26j.json" } } } diff --git a/CHANGELOG.md b/CHANGELOG.md index 6a9a1c800..d00d967db 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,7 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - Broker and TypeScript SDK structured result contracts add the `submit_result` MCP tool, `agent.waitForResult()`, per-spawn `result.onResult`, and `relay.addListener('agentResult', ...)` for typed JSON worker outcomes. -- `@agent-relay/sdk` harness definitions resolve named agent runtimes into broker-executable `pty` or `headless` plans, so custom CLIs like Qwen can be configured without Rust changes. +- `@agent-relay/sdk` harness definitions resolve named agent runtimes into broker-executable `pty` or `headless` plans, so custom CLIs can be configured without Rust changes. - `agent-relay-broker` accepts resolved harness plans on spawn and adds a headless app-server driver for delivering Relay messages to existing OpenCode server sessions. ### Changed @@ -19,6 +19,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed +- `agent-relay-broker` harness plans now report harness PIDs instead of wrapper worker PIDs, validate app-server protocol/auth/host settings at spawn, and give app-server release requests time to finish. - `web`: PR preview SST deploys use and comment the generated CloudFront URL and AWS's managed disabled cache policy instead of creating per-preview Cloudflare DNS records, ACM certificates, and custom CloudFront cache policies. ### Security diff --git a/crates/broker/src/cli/mod.rs b/crates/broker/src/cli/mod.rs index eeb66e861..3d23e1a74 100644 --- a/crates/broker/src/cli/mod.rs +++ b/crates/broker/src/cli/mod.rs @@ -285,6 +285,9 @@ pub(crate) struct AppServerCommand { #[arg(long = "session-id")] pub(crate) session_id: String, + #[arg(long = "host-pid")] + pub(crate) host_pid: Option, + #[arg(long, default_value = "detach")] pub(crate) release: String, diff --git a/crates/broker/src/pty.rs b/crates/broker/src/pty.rs index 75530b4ce..0cc7965d1 100644 --- a/crates/broker/src/pty.rs +++ b/crates/broker/src/pty.rs @@ -461,6 +461,10 @@ impl PtySession { (grid.screen_lines() as u16, grid.columns() as u16) } + pub fn child_pid(&self) -> Option { + self.child_pid + } + /// Run a closure against the live `Term`, holding the term lock for the /// duration. Used by `snapshot::Snapshot::capture` to walk the grid /// (cells + colours + flags) without exposing the underlying `Term` type diff --git a/crates/broker/src/pty_worker.rs b/crates/broker/src/pty_worker.rs index 9f7e8061b..a37b8e262 100644 --- a/crates/broker/src/pty_worker.rs +++ b/crates/broker/src/pty_worker.rs @@ -193,6 +193,7 @@ fn should_block_pending_injection( async fn try_emit_worker_ready( out_tx: &mpsc::Sender>, worker_name: &str, + child_pid: Option, init_request_id: &mut Option, init_received_at: Option, worker_ready_sent: &mut bool, @@ -226,7 +227,7 @@ async fn try_emit_worker_ready( out_tx, "worker_ready", request_id, - json!({"name": worker_name, "runtime": "pty"}), + json!({"name": worker_name, "runtime": "pty", "pid": child_pid}), ) .await; *worker_ready_sent = true; @@ -422,6 +423,7 @@ pub(crate) async fn run_pty_worker(cmd: PtyCommand) -> Result<()> { try_emit_worker_ready( &out_tx, &worker_name, + pty.child_pid(), &mut init_request_id, init_received_at, &mut worker_ready_sent, @@ -666,6 +668,7 @@ pub(crate) async fn run_pty_worker(cmd: PtyCommand) -> Result<()> { try_emit_worker_ready( &out_tx, &worker_name, + pty.child_pid(), &mut init_request_id, init_received_at, &mut worker_ready_sent, @@ -1026,6 +1029,7 @@ pub(crate) async fn run_pty_worker(cmd: PtyCommand) -> Result<()> { try_emit_worker_ready( &out_tx, &worker_name, + pty.child_pid(), &mut init_request_id, init_received_at, &mut worker_ready_sent, diff --git a/crates/broker/src/runtime/api.rs b/crates/broker/src/runtime/api.rs index 5e0136b43..028d2e5c5 100644 --- a/crates/broker/src/runtime/api.rs +++ b/crates/broker/src/runtime/api.rs @@ -232,7 +232,7 @@ impl BrokerRuntime { is_shadow: effective_spec.shadow_of.is_some() || effective_spec.shadow_mode.is_some(), }); - let pid = workers.worker_pid(&name).unwrap_or(0); + let pid = workers.harness_pid(&name); state.agents.insert( name.clone(), broker::PersistedAgent { @@ -269,7 +269,7 @@ impl BrokerRuntime { "provider": effective_spec.provider.clone(), "cli": effective_spec.cli.clone(), "model": effective_spec.model.clone(), - "pid":pid, + "pid": pid, "sessionId": effective_spec.session_id.clone(), "source":"http_api", "pre_registered": worker_relay_key.is_some(), diff --git a/crates/broker/src/runtime/app_server.rs b/crates/broker/src/runtime/app_server.rs index dc1091037..29b59f25f 100644 --- a/crates/broker/src/runtime/app_server.rs +++ b/crates/broker/src/runtime/app_server.rs @@ -14,6 +14,7 @@ pub(crate) async fn run_app_server_worker(cmd: AppServerCommand) -> Result<()> { let protocol = cmd.protocol.trim().to_ascii_lowercase(); let endpoint = cmd.endpoint.trim().trim_end_matches('/').to_string(); let session_id = cmd.session_id.clone(); + let host_pid = cmd.host_pid; let release = cmd.release.trim().to_ascii_lowercase(); let auth = app_server_auth_from_env(); let http = reqwest::Client::builder() @@ -86,6 +87,7 @@ pub(crate) async fn run_app_server_worker(cmd: AppServerCommand) -> Result<()> { "runtime": "headless", "driver": "app_server", "sessionId": &session_id, + "pid": host_pid, }), ) .await; @@ -128,19 +130,6 @@ pub(crate) async fn run_app_server_worker(cmd: AppServerCommand) -> Result<()> { ) .await; - let _ = send_frame( - &out_tx, - "delivery_injected", - None, - json!({ - "delivery_id": &delivery_id, - "event_id": &event_id, - "agent": &worker_name, - "timestamp": timestamp, - }), - ) - .await; - let result = match protocol.as_str() { "opencode" => { send_opencode_prompt(&http, &endpoint, &session_id, &text, auth.as_ref()) @@ -155,18 +144,20 @@ pub(crate) async fn run_app_server_worker(cmd: AppServerCommand) -> Result<()> { Ok(()) => { let _ = send_frame( &out_tx, - "delivery_ack", - request_id.clone(), + "delivery_injected", + None, json!({ "delivery_id": &delivery_id, "event_id": &event_id, + "agent": &worker_name, + "timestamp": timestamp, }), ) .await; let _ = send_frame( &out_tx, - "delivery_verified", - None, + "delivery_ack", + request_id.clone(), json!({ "delivery_id": &delivery_id, "event_id": &event_id, diff --git a/crates/broker/src/runtime/relaycast_events.rs b/crates/broker/src/runtime/relaycast_events.rs index d34bfc4c4..a52cad0a8 100644 --- a/crates/broker/src/runtime/relaycast_events.rs +++ b/crates/broker/src/runtime/relaycast_events.rs @@ -307,7 +307,7 @@ impl BrokerRuntime { has_task: effective_task.is_some(), is_shadow: false, }); - let pid = workers.worker_pid(&name).unwrap_or(0); + let pid = workers.harness_pid(&name); state.agents.insert( name.clone(), broker::PersistedAgent { @@ -350,7 +350,7 @@ impl BrokerRuntime { Some("relaycast_spawn"), ) .await; - tracing::info!(child = %name, pid, "spawned worker via relaycast WS"); + tracing::info!(child = %name, pid = ?pid, "spawned worker via relaycast WS"); eprintln!("[agent-relay] spawned worker '{}' via relaycast", name); } Err(e) => { @@ -503,7 +503,7 @@ impl BrokerRuntime { has_task: effective_task.is_some(), is_shadow: false, }); - let pid = workers.worker_pid(&name).unwrap_or(0); + let pid = workers.harness_pid(&name); state.agents.insert( name.clone(), broker::PersistedAgent { diff --git a/crates/broker/src/runtime/tests.rs b/crates/broker/src/runtime/tests.rs index d51f382d6..f20d81535 100644 --- a/crates/broker/src/runtime/tests.rs +++ b/crates/broker/src/runtime/tests.rs @@ -86,6 +86,7 @@ async fn make_worker_registry_with_worker(name: &str) -> WorkerRegistry { workspace_id: Some("ws_demo".to_string()), child, stdin, + harness_pid: None, spawned_at: Instant::now(), last_activity_at: Instant::now(), context_budget_pct: None, diff --git a/crates/broker/src/runtime/worker_events.rs b/crates/broker/src/runtime/worker_events.rs index c45ae580e..61d3ab18c 100644 --- a/crates/broker/src/runtime/worker_events.rs +++ b/crates/broker/src/runtime/worker_events.rs @@ -316,16 +316,25 @@ impl BrokerRuntime { .and_then(|p| p.get("runtime")) .and_then(Value::as_str) .unwrap_or("pty"); + let payload_pid = value + .get("payload") + .and_then(|p| p.get("pid")) + .and_then(Value::as_u64) + .filter(|pid| *pid <= u32::MAX as u64) + .map(|pid| pid as u32); let (provider_val, cli_val, model_val, session_id_val, pid_val) = workers .workers - .get(&name) + .get_mut(&name) .map(|h| { + if let Some(pid) = payload_pid { + h.harness_pid = Some(pid); + } ( h.spec.provider.clone(), h.spec.cli.clone(), h.spec.model.clone(), h.spec.session_id.clone(), - h.child.id(), + h.harness_pid, ) }) .unwrap_or((None, None, None, None, None)); diff --git a/crates/broker/src/worker.rs b/crates/broker/src/worker.rs index 52411050c..d3c5fda07 100644 --- a/crates/broker/src/worker.rs +++ b/crates/broker/src/worker.rs @@ -8,8 +8,9 @@ use std::{ use crate::{ metrics::MetricsCollector, protocol::{ - AgentRuntime, AgentSpec, AppServerAuthType, HarnessReleasePolicy, HeadlessHarnessDriver, - ProtocolEnvelope, RelayDelivery, ResolvedHarnessPlan, PROTOCOL_VERSION, + AgentRuntime, AgentSpec, AppServerAuthType, AppServerHostOwnership, HarnessReleasePolicy, + HeadlessHarnessDriver, HeadlessHarnessPlan, ProtocolEnvelope, RelayDelivery, + ResolvedHarnessPlan, PROTOCOL_VERSION, }, relaycast::configure_relaycast_mcp_with_result, supervisor::Supervisor, @@ -38,6 +39,8 @@ const APP_SERVER_AUTH_ENV_KEYS: [&str; 4] = [ "AGENT_RELAY_APP_SERVER_AUTH_USERNAME", "AGENT_RELAY_APP_SERVER_AUTH_PASSWORD", ]; +const DEFAULT_RELEASE_GRACE: Duration = Duration::from_secs(2); +const APP_SERVER_RELEASE_GRACE: Duration = Duration::from_secs(35); pub(crate) mod detection; @@ -48,6 +51,7 @@ pub(crate) struct WorkerHandle { pub(crate) workspace_id: Option, pub(crate) child: Child, pub(crate) stdin: ChildStdin, + pub(crate) harness_pid: Option, pub(crate) spawned_at: Instant, pub(crate) last_activity_at: Instant, pub(crate) context_budget_pct: Option, @@ -147,7 +151,8 @@ impl WorkerRegistry { "channels": handle.spec.channels, "parent": handle.parent, "sessionId": handle.spec.session_id, - "pid": handle.child.id(), + "pid": handle.harness_pid, + "workerPid": handle.child.id(), "last_activity_ms": handle.last_activity_at.elapsed().as_millis() as u64, "last_activity_at": chrono::Utc::now() - chrono::Duration::from_std(handle.last_activity_at.elapsed()).unwrap_or_default(), @@ -207,6 +212,10 @@ impl WorkerRegistry { self.workers.get(name).and_then(|h| h.child.id()) } + pub(crate) fn harness_pid(&self, name: &str) -> Option { + self.workers.get(name).and_then(|h| h.harness_pid) + } + #[allow(clippy::too_many_arguments)] pub(crate) async fn spawn( &mut self, @@ -237,6 +246,7 @@ impl WorkerRegistry { Command::new(std::env::current_exe().context("failed to locate current executable")?); let mut harness_env: Vec<(String, String)> = Vec::new(); let mut suppress_worker_env: Vec<&'static str> = Vec::new(); + let mut initial_harness_pid: Option = None; match spec.harness_plan.clone() { Some(ResolvedHarnessPlan::Pty(plan)) => { @@ -315,8 +325,10 @@ impl WorkerRegistry { } } Some(ResolvedHarnessPlan::Headless(plan)) => { + validate_app_server_plan(&plan)?; spec.runtime = AgentRuntime::Headless; spec.session_id = Some(plan.session_id.clone()); + initial_harness_pid = plan.host.as_ref().and_then(|host| host.pid); match &plan.driver { HeadlessHarnessDriver::AppServer => {} } @@ -326,6 +338,9 @@ impl WorkerRegistry { command.arg("--protocol").arg(&plan.protocol); command.arg("--endpoint").arg(&plan.endpoint); command.arg("--session-id").arg(&plan.session_id); + if let Some(pid) = initial_harness_pid { + command.arg("--host-pid").arg(pid.to_string()); + } command .arg("--release") .arg(release_policy_arg(plan.release.as_ref())); @@ -585,6 +600,7 @@ impl WorkerRegistry { workspace_id, child, stdin, + harness_pid: initial_harness_pid, spawned_at: Instant::now(), last_activity_at: Instant::now(), context_budget_pct: None, @@ -671,19 +687,20 @@ impl WorkerRegistry { .workers .remove(name) .with_context(|| format!("unknown worker '{name}'"))?; + let release_grace = release_grace_for_spec(&handle.spec); let shutdown_frame = ProtocolEnvelope { v: PROTOCOL_VERSION, msg_type: "shutdown_worker".to_string(), request_id: None, - payload: json!({"reason":"release","grace_ms":2000}), + payload: json!({"reason":"release","grace_ms": release_grace.as_millis() as u64}), }; let encoded = serde_json::to_string(&shutdown_frame)?; let _ = handle.stdin.write_all(encoded.as_bytes()).await; let _ = handle.stdin.write_all(b"\n").await; let _ = handle.stdin.flush().await; - let result = terminate_child(&mut handle.child, Duration::from_secs(2)).await; + let result = terminate_child(&mut handle.child, release_grace).await; match &result { Ok(()) => tracing::info!(target = "broker::release", name = %name, "worker released"), Err(error) => { @@ -850,6 +867,91 @@ fn app_server_auth_type_arg(auth_type: &AppServerAuthType) -> &'static str { } } +fn release_grace_for_spec(spec: &AgentSpec) -> Duration { + match spec.harness_plan.as_ref() { + Some(ResolvedHarnessPlan::Headless(plan)) + if matches!(&plan.driver, HeadlessHarnessDriver::AppServer) => + { + APP_SERVER_RELEASE_GRACE + } + _ => DEFAULT_RELEASE_GRACE, + } +} + +fn validate_app_server_plan(plan: &HeadlessHarnessPlan) -> Result<()> { + if !matches!(&plan.driver, HeadlessHarnessDriver::AppServer) { + anyhow::bail!("unsupported headless harness driver"); + } + + let protocol = plan.protocol.trim().to_ascii_lowercase(); + if protocol != "opencode" { + anyhow::bail!( + "unsupported app_server protocol '{}' (supported: opencode)", + plan.protocol + ); + } + + let endpoint = plan.endpoint.trim(); + if endpoint.is_empty() { + anyhow::bail!("app_server endpoint is required"); + } + let parsed_endpoint = reqwest::Url::parse(endpoint) + .with_context(|| format!("invalid app_server endpoint '{}'", plan.endpoint))?; + match parsed_endpoint.scheme() { + "http" | "https" => {} + scheme => anyhow::bail!( + "invalid app_server endpoint scheme '{}' (expected http or https)", + scheme + ), + } + + if plan.session_id.trim().is_empty() { + anyhow::bail!("app_server sessionId is required"); + } + + if plan + .host + .as_ref() + .and_then(|host| host.ownership.as_ref()) + .is_some_and(|ownership| matches!(ownership, AppServerHostOwnership::BrokerOwned)) + { + anyhow::bail!("broker-owned app_server hosts are not supported yet"); + } + + if let Some(auth) = plan.auth.as_ref() { + match auth.auth_type { + AppServerAuthType::Bearer => { + if auth + .token + .as_deref() + .is_none_or(|value| value.trim().is_empty()) + { + anyhow::bail!("app_server bearer auth requires token"); + } + } + AppServerAuthType::Basic => { + if auth + .username + .as_deref() + .is_none_or(|value| value.trim().is_empty()) + { + anyhow::bail!("app_server basic auth requires username"); + } + if auth + .password + .as_deref() + .is_none_or(|value| value.trim().is_empty()) + { + anyhow::bail!("app_server basic auth requires password"); + } + } + AppServerAuthType::None => {} + } + } + + Ok(()) +} + fn args_include_model_override(args: &[String]) -> bool { args.iter().any(|arg| { arg == "--model" || arg.starts_with("--model=") || arg == "-m" || arg.starts_with("-m=") @@ -1168,6 +1270,7 @@ fn spawn_worker_reader( #[cfg(test)] mod tests { use super::*; + use crate::protocol::{AppServerHarnessAuth, AppServerHarnessHost}; fn make_registry(env: Vec<(String, String)>) -> WorkerRegistry { let (tx, _rx) = mpsc::channel::(16); @@ -1207,6 +1310,89 @@ mod tests { assert_eq!(reg.env_value("MISSING"), None); } + fn make_app_server_plan() -> HeadlessHarnessPlan { + HeadlessHarnessPlan { + driver: HeadlessHarnessDriver::AppServer, + protocol: "opencode".to_string(), + endpoint: "http://127.0.0.1:4096".to_string(), + session_id: "ses_123".to_string(), + auth: None, + host: Some(AppServerHarnessHost { + ownership: Some(AppServerHostOwnership::Attached), + pid: Some(12345), + }), + release: Some(HarnessReleasePolicy::Detach), + metadata: None, + } + } + + #[test] + fn app_server_plan_validation_accepts_attached_opencode_plan() { + let plan = make_app_server_plan(); + validate_app_server_plan(&plan).expect("valid app-server plan"); + } + + #[test] + fn app_server_plan_validation_rejects_missing_bearer_token() { + let mut plan = make_app_server_plan(); + plan.auth = Some(AppServerHarnessAuth { + auth_type: AppServerAuthType::Bearer, + token: None, + username: None, + password: None, + }); + + let error = validate_app_server_plan(&plan).expect_err("missing token rejected"); + assert!(error.to_string().contains("bearer auth requires token")); + } + + #[test] + fn app_server_plan_validation_rejects_broker_owned_host() { + let mut plan = make_app_server_plan(); + plan.host = Some(AppServerHarnessHost { + ownership: Some(AppServerHostOwnership::BrokerOwned), + pid: None, + }); + + let error = validate_app_server_plan(&plan).expect_err("broker-owned host rejected"); + assert!(error + .to_string() + .contains("broker-owned app_server hosts are not supported yet")); + } + + #[test] + fn app_server_plan_validation_rejects_unsupported_protocol() { + let mut plan = make_app_server_plan(); + plan.protocol = "custom".to_string(); + + let error = validate_app_server_plan(&plan).expect_err("unsupported protocol rejected"); + assert!(error + .to_string() + .contains("unsupported app_server protocol")); + } + + #[test] + fn app_server_release_uses_extended_grace() { + let spec = AgentSpec { + name: "opencode-app".to_string(), + runtime: AgentRuntime::Headless, + provider: None, + cli: None, + session_id: Some("ses_123".to_string()), + harness_plan: Some(ResolvedHarnessPlan::Headless(make_app_server_plan())), + model: None, + cwd: None, + team: None, + shadow_of: None, + shadow_mode: None, + args: Vec::new(), + channels: Vec::new(), + restart_policy: None, + }; + + assert_eq!(release_grace_for_spec(&spec), APP_SERVER_RELEASE_GRACE); + } + #[test] fn routing_workers_empty_when_no_workers() { let reg = make_registry(vec![]); diff --git a/docs/harness-runtime-plan.md b/docs/harness-runtime-plan.md index 89e325eef..33a508c7e 100644 --- a/docs/harness-runtime-plan.md +++ b/docs/harness-runtime-plan.md @@ -18,8 +18,7 @@ The first headless drivers are: - `provider_command`: the existing broker-owned one-shot headless path for built-in providers such as Claude and OpenCode. -- `app_server`: a session-backed HTTP driver for existing or broker-owned agent - servers. +- `app_server`: a session-backed HTTP driver for attached agent servers. Named harnesses such as `codex`, `claude`, or `opencode-server` resolve to one of those executable plans. @@ -72,6 +71,14 @@ type HeadlessAppServerHarnessPlan = { The broker runs the returned plan. It does not need to understand arbitrary TypeScript or Python logic. +For now, `app_server` plans are attach-only. `host.ownership: 'broker-owned'` +is reserved and rejected until the broker owns app-server lifecycle supervision. +When `host.pid` is provided, the broker reports that as the harness PID. + +Plan `env` and `auth` values are visible to the broker and may be included in +runtime state. SDK resolvers should return explicit allowlists and avoid copying +the whole process environment. + ## Harness Definition Classes Static harness definitions are JSON-compatible and work in attached or detached @@ -82,12 +89,21 @@ const harnesses = { 'company-claude': { runtime: 'pty', command: 'claude', - args: ['--append-system-prompt', 'Follow the company review rubric.', '{modelArgs}', '{args}'], + args: [ + '--dangerously-skip-permissions', + '--append-system-prompt', + 'Follow the company review rubric.', + '{modelArgs}', + '{args}', + ], modelArgs: ['--model', '{model}'], }, }; ``` +Custom PTY harnesses own their CLI flags. Broker built-in permission bypass +defaults are not injected into caller-provided harness plans. + Dynamic harness resolvers are SDK functions and are attached-only. They can run pre-spawn logic, such as creating a provider session, then return a concrete plan: @@ -100,7 +116,10 @@ const harnesses = { runtime: 'pty', command: 'codex', args: ['resume', sessionId, ...ctx.args], - env: ctx.env, + env: { + PATH: ctx.env.PATH ?? '', + CODEX_HOME: ctx.env.CODEX_HOME ?? '', + }, sessionId, }; }, @@ -157,10 +176,10 @@ The headless runtime covers non-PTY workers. Provider-command headless workers run a command per delivery, for example `claude -p` or `opencode run`. App-server headless workers attach to a session server instead. -For OpenCode app-server harnesses, the broker can attach to a local or remote -`opencode serve` endpoint, create or receive a session id, deliver Relay -messages through the session message API, and release by aborting, detaching, or -deleting the session. +For OpenCode app-server harnesses, the SDK creates or selects a session and +returns its endpoint and session id. The broker attaches to that local or remote +`opencode serve` endpoint, delivers Relay messages through the session message +API, and releases by aborting, detaching, or deleting the session. Headless runtimes do not expose PTY input, resize, or snapshot capabilities. diff --git a/packages/sdk/src/harness.ts b/packages/sdk/src/harness.ts index 597e5d7fe..5486a78f7 100644 --- a/packages/sdk/src/harness.ts +++ b/packages/sdk/src/harness.ts @@ -32,7 +32,12 @@ export interface AppServerHarnessAuth { } export interface AppServerHarnessHost { + /** + * `broker-owned` is reserved for a future broker-supervised app-server mode. + * Current broker releases accept attached hosts only. + */ ownership?: 'broker-owned' | 'attached'; + /** Local app-server host PID to report as the harness PID when known. */ pid?: number; } diff --git a/web/content/docs/harnesses.mdx b/web/content/docs/harnesses.mdx index bf2a17a9a..5d2202bda 100644 --- a/web/content/docs/harnesses.mdx +++ b/web/content/docs/harnesses.mdx @@ -31,7 +31,13 @@ const relay = new AgentRelay({ 'company-claude': { runtime: 'pty', command: 'claude', - args: ['--append-system-prompt', 'Follow the company review rubric.', '{modelArgs}', '{args}'], + args: [ + '--dangerously-skip-permissions', + '--append-system-prompt', + 'Follow the company review rubric.', + '{modelArgs}', + '{args}', + ], modelArgs: ['--model', '{model}'], env: { CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC: '1', @@ -46,6 +52,9 @@ await relay.spawn('ClaudeReviewer', 'company-claude', 'Review the current diff.' }); ``` +When you provide a PTY harness plan, Relay runs that plan as written. Built-in +CLI defaults such as Claude permission bypass flags are not auto-injected. + Supported placeholders: | Placeholder | Expands To | @@ -77,7 +86,10 @@ const relay = new AgentRelay({ command: 'codex', args: ['resume', sessionId, ...ctx.args], cwd: ctx.cwd, - env: ctx.env, + env: { + PATH: ctx.env.PATH ?? '', + CODEX_HOME: ctx.env.CODEX_HOME ?? '', + }, sessionId, }; }, @@ -87,6 +99,9 @@ const relay = new AgentRelay({ await relay.spawn('CodexReviewer', 'codex-resume', 'Review the current diff.'); ``` +Do not forward `ctx.env` wholesale. It is the SDK process environment and may +contain secrets. Pass only the keys the harness actually needs. + Detached brokers should use static adapters, built-in broker behavior, HTTP webhooks, or another durable extension host instead of in-process resolver functions. @@ -107,6 +122,7 @@ const relay = new AgentRelay({ protocol: 'opencode', endpoint: 'http://127.0.0.1:4096', sessionId: 'ses_123', + host: { ownership: 'attached', pid: 34567 }, release: 'abort', }, }, @@ -117,6 +133,35 @@ await relay.spawn('OpenCodeWorker', 'opencode-server', 'Inspect the repo.'); For OpenCode, Relay delivers messages to `POST /session/:id/prompt_async`. Release behavior is controlled by `release`: `abort`, `detach`, or `delete`. +`host.pid` is reported as the harness PID when the server is local and known. + +Static app-server adapters attach to a known session. For per-spawn sessions, +create the session in a dynamic resolver and return the concrete plan: + +```typescript file="opencode-dynamic-harness.ts" +const relay = new AgentRelay({ + broker: { lifetime: 'attached' }, + harnesses: { + 'opencode-new-session': async (ctx) => { + const session = await createOpenCodeSession({ cwd: ctx.cwd, task: ctx.task }); + + return { + runtime: 'headless', + driver: 'app_server', + protocol: 'opencode', + endpoint: session.endpoint, + sessionId: session.id, + host: { ownership: 'attached', pid: session.pid }, + release: 'detach', + }; + }, + }, +}); +``` + +For now, app-server plans must use `protocol: 'opencode'`, an `http` or `https` +endpoint, a non-empty `sessionId`, and attached host ownership. `broker-owned` +app-server hosts are reserved for a later broker-supervised mode. ## One-Off Plans From 21a480e19cb5ae58fdd0cd65c6a75f96e8a2ab81 Mon Sep 17 00:00:00 2001 From: Will Washburn Date: Mon, 25 May 2026 14:07:22 -0400 Subject: [PATCH 07/19] Rename harness plans to configs --- .../completed/2026-05/traj_q2r3c9dmdep7.json | 53 ++++++++++ .../completed/2026-05/traj_q2r3c9dmdep7.md | 33 ++++++ .trajectories/index.json | 9 +- CHANGELOG.md | 6 +- crates/broker/src/listen_api.rs | 24 +++-- crates/broker/src/protocol.rs | 92 ++++++++++------ crates/broker/src/runtime/api.rs | 4 +- crates/broker/src/runtime/mod.rs | 2 +- crates/broker/src/runtime/relaycast_events.rs | 4 +- crates/broker/src/runtime/spawn_spec.rs | 16 +-- crates/broker/src/runtime/tests.rs | 20 ++-- crates/broker/src/supervisor.rs | 2 +- crates/broker/src/worker.rs | 100 +++++++++--------- ...time-plan.md => harness-runtime-config.md} | 38 +++---- packages/sdk/src/__tests__/harness.test.ts | 24 ++--- .../sdk/src/__tests__/lifecycle-hooks.test.ts | 6 +- packages/sdk/src/client.ts | 8 +- packages/sdk/src/harness.ts | 14 +-- packages/sdk/src/lifecycle-hooks.ts | 2 +- packages/sdk/src/protocol.ts | 2 +- packages/sdk/src/relay.ts | 36 +++---- packages/sdk/src/types.ts | 6 +- web/content/docs/harnesses.mdx | 16 +-- 23 files changed, 318 insertions(+), 199 deletions(-) create mode 100644 .trajectories/completed/2026-05/traj_q2r3c9dmdep7.json create mode 100644 .trajectories/completed/2026-05/traj_q2r3c9dmdep7.md rename docs/{harness-runtime-plan.md => harness-runtime-config.md} (86%) diff --git a/.trajectories/completed/2026-05/traj_q2r3c9dmdep7.json b/.trajectories/completed/2026-05/traj_q2r3c9dmdep7.json new file mode 100644 index 000000000..295e8fa1e --- /dev/null +++ b/.trajectories/completed/2026-05/traj_q2r3c9dmdep7.json @@ -0,0 +1,53 @@ +{ + "id": "traj_q2r3c9dmdep7", + "version": 1, + "task": { + "title": "Rename harness plans to harness configs" + }, + "status": "completed", + "startedAt": "2026-05-25T18:00:40.591Z", + "completedAt": "2026-05-25T18:06:34.954Z", + "agents": [ + { + "name": "default", + "role": "lead", + "joinedAt": "2026-05-25T18:06:31.002Z" + } + ], + "chapters": [ + { + "id": "chap_fqok6eor5g3t", + "title": "Work", + "agentName": "default", + "startedAt": "2026-05-25T18:06:31.002Z", + "endedAt": "2026-05-25T18:06:34.954Z", + "events": [ + { + "ts": 1779732391003, + "type": "decision", + "content": "Rename harness plan API to harness config: Rename harness plan API to harness config", + "raw": { + "question": "Rename harness plan API to harness config", + "chosen": "Rename harness plan API to harness config", + "alternatives": [], + "reasoning": "The adapter output is declarative runtime configuration, not an execution plan; SDK and docs should expose harnessConfig/ResolvedHarnessConfig while the broker keeps legacy harnessPlan aliases for payload tolerance." + }, + "significance": "high" + } + ] + } + ], + "retrospective": { + "summary": "Renamed harness runtime terminology from plan to config across SDK, broker protocol, API payloads, tests, docs, and changelog. The broker now accepts harnessConfig as the primary field while retaining harnessPlan/harness_plan deserialization aliases for compatibility.", + "approach": "Standard approach", + "confidence": 0.88 + }, + "commits": [], + "filesChanged": [], + "projectId": "/Users/will/Projects/AgentWorkforce/relay", + "tags": [], + "_trace": { + "startRef": "8c429f257c346d3917c783b637d890eda045bbee", + "endRef": "8c429f257c346d3917c783b637d890eda045bbee" + } +} diff --git a/.trajectories/completed/2026-05/traj_q2r3c9dmdep7.md b/.trajectories/completed/2026-05/traj_q2r3c9dmdep7.md new file mode 100644 index 000000000..530785825 --- /dev/null +++ b/.trajectories/completed/2026-05/traj_q2r3c9dmdep7.md @@ -0,0 +1,33 @@ +# Trajectory: Rename harness plans to harness configs + +> **Status:** ✅ Completed +> **Confidence:** 88% +> **Started:** May 25, 2026 at 02:00 PM +> **Completed:** May 25, 2026 at 02:06 PM + +--- + +## Summary + +Renamed harness runtime terminology from plan to config across SDK, broker protocol, API payloads, tests, docs, and changelog. The broker now accepts harnessConfig as the primary field while retaining harnessPlan/harness_plan deserialization aliases for compatibility. + +**Approach:** Standard approach + +--- + +## Key Decisions + +### Rename harness plan API to harness config + +- **Chose:** Rename harness plan API to harness config +- **Reasoning:** The adapter output is declarative runtime configuration, not an execution plan; SDK and docs should expose harnessConfig/ResolvedHarnessConfig while the broker keeps legacy harnessPlan aliases for payload tolerance. + +--- + +## Chapters + +### 1. Work + +_Agent: default_ + +- Rename harness plan API to harness config: Rename harness plan API to harness config diff --git a/.trajectories/index.json b/.trajectories/index.json index 0a7eddc36..eb11b792b 100644 --- a/.trajectories/index.json +++ b/.trajectories/index.json @@ -1,6 +1,6 @@ { "version": 1, - "lastUpdated": "2026-05-25T17:53:06.564Z", + "lastUpdated": "2026-05-25T18:06:35.146Z", "trajectories": { "traj_05xg7j388bc4": { "title": "Add browser workflow step integration", @@ -1149,6 +1149,13 @@ "startedAt": "2026-05-25T17:41:16.384Z", "completedAt": "2026-05-25T17:53:06.394Z", "path": ".trajectories/completed/2026-05/traj_9dj3qiugt26j.json" + }, + "traj_q2r3c9dmdep7": { + "title": "Rename harness plans to harness configs", + "status": "completed", + "startedAt": "2026-05-25T18:00:40.591Z", + "completedAt": "2026-05-25T18:06:34.954Z", + "path": ".trajectories/completed/2026-05/traj_q2r3c9dmdep7.json" } } } diff --git a/CHANGELOG.md b/CHANGELOG.md index d00d967db..7a416d708 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,8 +10,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - Broker and TypeScript SDK structured result contracts add the `submit_result` MCP tool, `agent.waitForResult()`, per-spawn `result.onResult`, and `relay.addListener('agentResult', ...)` for typed JSON worker outcomes. -- `@agent-relay/sdk` harness definitions resolve named agent runtimes into broker-executable `pty` or `headless` plans, so custom CLIs can be configured without Rust changes. -- `agent-relay-broker` accepts resolved harness plans on spawn and adds a headless app-server driver for delivering Relay messages to existing OpenCode server sessions. +- `@agent-relay/sdk` harness definitions resolve named agent runtimes into broker-executable `pty` or `headless` configs, so custom CLIs can be configured without Rust changes. +- `agent-relay-broker` accepts resolved harness configs on spawn and adds a headless app-server driver for delivering Relay messages to existing OpenCode server sessions. ### Changed @@ -19,7 +19,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed -- `agent-relay-broker` harness plans now report harness PIDs instead of wrapper worker PIDs, validate app-server protocol/auth/host settings at spawn, and give app-server release requests time to finish. +- `agent-relay-broker` harness configs now report harness PIDs instead of wrapper worker PIDs, validate app-server protocol/auth/host settings at spawn, and give app-server release requests time to finish. - `web`: PR preview SST deploys use and comment the generated CloudFront URL and AWS's managed disabled cache policy instead of creating per-preview Cloudflare DNS records, ACM certificates, and custom CloudFront cache policies. ### Security diff --git a/crates/broker/src/listen_api.rs b/crates/broker/src/listen_api.rs index 5388d0b37..38af2b260 100644 --- a/crates/broker/src/listen_api.rs +++ b/crates/broker/src/listen_api.rs @@ -11,7 +11,7 @@ use std::{ }; use crate::{ - protocol::{MessageInjectionMode, ResolvedHarnessPlan}, + protocol::{MessageInjectionMode, ResolvedHarnessConfig}, relaycast::WorkspaceMembershipSummary, replay_buffer::ReplayBuffer, types::{InboundDeliveryMode, PendingRelayMessage}, @@ -50,7 +50,7 @@ pub enum ListenApiRequest { idle_threshold_secs: Option, skip_relay_prompt: bool, restart_policy: Box>, - harness_plan: Option, + harness_config: Option, agent_token: Option, agent_result_schema: Option, reply: tokio::sync::oneshot::Sender>, @@ -649,19 +649,21 @@ async fn listen_api_spawn( .or_else(|| body.get("restartPolicy")) .cloned(), ); - let harness_plan = match body - .get("harness_plan") + let harness_config = match body + .get("harness_config") + .or_else(|| body.get("harnessConfig")) + .or_else(|| body.get("harness_plan")) .or_else(|| body.get("harnessPlan")) .cloned() { - Some(value) => match serde_json::from_value::(value) { - Ok(plan) => Some(plan), + Some(value) => match serde_json::from_value::(value) { + Ok(config) => Some(config), Err(error) => { return ( axum::http::StatusCode::BAD_REQUEST, axum::Json(json!({ "success": false, - "error": format!("Invalid harnessPlan: {error}") + "error": format!("Invalid harnessConfig: {error}") })), ); } @@ -705,7 +707,7 @@ async fn listen_api_spawn( idle_threshold_secs, skip_relay_prompt, restart_policy, - harness_plan, + harness_config, agent_token, agent_result_schema, reply: reply_tx, @@ -2442,7 +2444,7 @@ mod auth_tests { idle_threshold_secs, skip_relay_prompt: _, restart_policy: _, - harness_plan, + harness_config, agent_token: _, agent_result_schema, reply, @@ -2463,7 +2465,7 @@ mod auth_tests { assert_eq!(shadow_mode.as_deref(), Some("subagent")); assert_eq!(continue_from.as_deref(), Some("worker-prev")); assert_eq!(idle_threshold_secs, Some(30)); - assert!(harness_plan.is_some()); + assert!(harness_config.is_some()); assert_eq!( agent_result_schema, Some(json!({"type": "object", "properties": {"ok": {"type": "boolean"}}})) @@ -2498,7 +2500,7 @@ mod auth_tests { "shadowMode": "subagent", "continueFrom": "worker-prev", "idleThresholdSecs": 30, - "harnessPlan": { + "harnessConfig": { "runtime": "pty", "command": "codex", "args": ["--fast"] diff --git a/crates/broker/src/protocol.rs b/crates/broker/src/protocol.rs index ee740b416..375d7a7ab 100644 --- a/crates/broker/src/protocol.rs +++ b/crates/broker/src/protocol.rs @@ -44,7 +44,7 @@ pub struct PtyHarnessDelivery { #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] -pub struct PtyHarnessPlan { +pub struct PtyHarnessConfig { pub command: String, #[serde(default)] pub args: Vec, @@ -114,7 +114,7 @@ pub enum HeadlessHarnessDriver { #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] -pub struct HeadlessHarnessPlan { +pub struct HeadlessHarnessConfig { pub driver: HeadlessHarnessDriver, pub protocol: String, pub endpoint: String, @@ -131,12 +131,12 @@ pub struct HeadlessHarnessPlan { #[derive(Debug, Clone, PartialEq, Serialize)] #[serde(tag = "runtime", rename_all = "snake_case")] -pub enum ResolvedHarnessPlan { - Pty(PtyHarnessPlan), - Headless(HeadlessHarnessPlan), +pub enum ResolvedHarnessConfig { + Pty(PtyHarnessConfig), + Headless(HeadlessHarnessConfig), } -impl<'de> Deserialize<'de> for ResolvedHarnessPlan { +impl<'de> Deserialize<'de> for ResolvedHarnessConfig { fn deserialize(deserializer: D) -> Result where D: Deserializer<'de>, @@ -174,7 +174,7 @@ impl<'de> Deserialize<'de> for ResolvedHarnessPlan { } } -impl ResolvedHarnessPlan { +impl ResolvedHarnessConfig { pub(crate) fn runtime(&self) -> AgentRuntime { match self { Self::Pty(_) => AgentRuntime::Pty, @@ -184,8 +184,8 @@ impl ResolvedHarnessPlan { pub(crate) fn session_id(&self) -> Option<&str> { match self { - Self::Pty(plan) => plan.session_id.as_deref(), - Self::Headless(plan) => Some(plan.session_id.as_str()), + Self::Pty(config) => config.session_id.as_deref(), + Self::Headless(config) => Some(config.session_id.as_str()), } } } @@ -202,10 +202,13 @@ pub struct AgentSpec { pub session_id: Option, #[serde( default, + rename = "harnessConfig", + alias = "harness_config", alias = "harnessPlan", + alias = "harness_plan", skip_serializing_if = "Option::is_none" )] - pub harness_plan: Option, + pub harness_config: Option, #[serde(skip_serializing_if = "Option::is_none")] pub model: Option, #[serde(skip_serializing_if = "Option::is_none")] @@ -551,7 +554,7 @@ mod tests { use super::{ AgentRuntime, AgentSpec, BrokerEvent, BrokerToSdk, BrokerToWorker, HeadlessHarnessDriver, HeadlessProvider, MessageInjectionMode, ProtocolEnvelope, RelayDelivery, - ResolvedHarnessPlan, WorkerToBroker, PROTOCOL_VERSION, + ResolvedHarnessConfig, WorkerToBroker, PROTOCOL_VERSION, }; #[test] @@ -732,7 +735,7 @@ mod tests { assert_eq!(spec.provider, None); assert_eq!(spec.cli, None); assert_eq!(spec.session_id, None); - assert_eq!(spec.harness_plan, None); + assert_eq!(spec.harness_config, None); assert_eq!(spec.model, None); assert_eq!(spec.cwd, None); assert_eq!(spec.team, None); @@ -755,13 +758,13 @@ mod tests { } #[test] - fn agent_spec_accepts_camel_case_harness_plan() { + fn agent_spec_accepts_camel_case_harness_config() { let raw = r#"{ "name": "QwenWorker", "runtime": "pty", "cli": "qwen", "sessionId": "native-session", - "harnessPlan": { + "harnessConfig": { "runtime": "pty", "command": "qwen", "args": ["run", "-m", "qwen3-coder"], @@ -774,31 +777,52 @@ mod tests { let spec: AgentSpec = serde_json::from_str(raw).unwrap(); assert_eq!(spec.runtime, AgentRuntime::Pty); assert_eq!(spec.session_id.as_deref(), Some("native-session")); - let Some(ResolvedHarnessPlan::Pty(plan)) = spec.harness_plan else { - panic!("expected pty harness plan"); + let Some(ResolvedHarnessConfig::Pty(config)) = spec.harness_config else { + panic!("expected pty harness config"); }; - assert_eq!(plan.command, "qwen"); + assert_eq!(config.command, "qwen"); assert_eq!( - plan.args, + config.args, vec![ "run".to_string(), "-m".to_string(), "qwen3-coder".to_string() ] ); - assert_eq!(plan.cwd.as_deref(), Some("/tmp/project")); + assert_eq!(config.cwd.as_deref(), Some("/tmp/project")); assert_eq!( - plan.env + config + .env .as_ref() .and_then(|env| env.get("QWEN_MODE")) .map(String::as_str), Some("code") ); - assert_eq!(plan.session_id.as_deref(), Some("native-session")); + assert_eq!(config.session_id.as_deref(), Some("native-session")); + } + + #[test] + fn agent_spec_accepts_legacy_camel_case_harness_plan() { + let raw = r#"{ + "name": "LegacyHarnessWorker", + "runtime": "pty", + "cli": "codex", + "harnessPlan": { + "runtime": "pty", + "command": "codex", + "args": ["--model", "gpt-5.4"] + } + }"#; + + let spec: AgentSpec = serde_json::from_str(raw).unwrap(); + assert!(matches!( + spec.harness_config, + Some(ResolvedHarnessConfig::Pty(_)) + )); } #[test] - fn headless_app_server_harness_plan_round_trips() { + fn headless_app_server_harness_config_round_trips() { let raw = json!({ "runtime": "headless", "driver": "app_server", @@ -813,20 +837,20 @@ mod tests { "release": "abort" }); - let plan: ResolvedHarnessPlan = serde_json::from_value(raw).unwrap(); - assert_eq!(plan.runtime(), AgentRuntime::Headless); - assert_eq!(plan.session_id(), Some("ses_123")); + let config: ResolvedHarnessConfig = serde_json::from_value(raw).unwrap(); + assert_eq!(config.runtime(), AgentRuntime::Headless); + assert_eq!(config.session_id(), Some("ses_123")); - let encoded = serde_json::to_string(&plan).unwrap(); + let encoded = serde_json::to_string(&config).unwrap(); assert!(encoded.contains("\"runtime\":\"headless\"")); assert!(encoded.contains("\"driver\":\"app_server\"")); assert!(encoded.contains("\"sessionId\":\"ses_123\"")); - let decoded: ResolvedHarnessPlan = serde_json::from_str(&encoded).unwrap(); + let decoded: ResolvedHarnessConfig = serde_json::from_str(&encoded).unwrap(); assert_eq!(decoded.session_id(), Some("ses_123")); } #[test] - fn legacy_app_server_harness_plan_deserializes_as_headless() { + fn legacy_app_server_harness_config_deserializes_as_headless() { let raw = json!({ "runtime": "app_server", "protocol": "opencode", @@ -834,13 +858,13 @@ mod tests { "sessionId": "ses_legacy" }); - let plan: ResolvedHarnessPlan = serde_json::from_value(raw).unwrap(); - assert_eq!(plan.runtime(), AgentRuntime::Headless); - assert_eq!(plan.session_id(), Some("ses_legacy")); - let ResolvedHarnessPlan::Headless(plan) = plan else { - panic!("expected headless harness plan"); + let config: ResolvedHarnessConfig = serde_json::from_value(raw).unwrap(); + assert_eq!(config.runtime(), AgentRuntime::Headless); + assert_eq!(config.session_id(), Some("ses_legacy")); + let ResolvedHarnessConfig::Headless(config) = config else { + panic!("expected headless harness config"); }; - assert_eq!(plan.driver, HeadlessHarnessDriver::AppServer); + assert_eq!(config.driver, HeadlessHarnessDriver::AppServer); } #[test] diff --git a/crates/broker/src/runtime/api.rs b/crates/broker/src/runtime/api.rs index 028d2e5c5..ed5c397a2 100644 --- a/crates/broker/src/runtime/api.rs +++ b/crates/broker/src/runtime/api.rs @@ -45,7 +45,7 @@ impl BrokerRuntime { idle_threshold_secs, skip_relay_prompt, restart_policy, - harness_plan, + harness_config, agent_token, agent_result_schema, reply, @@ -67,7 +67,7 @@ impl BrokerRuntime { shadow_of, shadow_mode, *restart_policy, - harness_plan, + harness_config, ) { Ok(spec) => spec, Err(error) => { diff --git a/crates/broker/src/runtime/mod.rs b/crates/broker/src/runtime/mod.rs index 4f23cd1f4..36a79d7a0 100644 --- a/crates/broker/src/runtime/mod.rs +++ b/crates/broker/src/runtime/mod.rs @@ -28,7 +28,7 @@ use crate::{ dedup::DedupCache, protocol::{ AgentRuntime, AgentSpec, BrokerEvent, HeadlessProvider as ProtocolHeadlessProvider, - MessageInjectionMode, ProtocolEnvelope, RelayDelivery, ResolvedHarnessPlan, + MessageInjectionMode, ProtocolEnvelope, RelayDelivery, ResolvedHarnessConfig, PROTOCOL_VERSION, }, relaycast::{ diff --git a/crates/broker/src/runtime/relaycast_events.rs b/crates/broker/src/runtime/relaycast_events.rs index a52cad0a8..482e085d8 100644 --- a/crates/broker/src/runtime/relaycast_events.rs +++ b/crates/broker/src/runtime/relaycast_events.rs @@ -222,7 +222,7 @@ impl BrokerRuntime { provider: None, cli: Some(cli.clone()), session_id: None, - harness_plan: None, + harness_config: None, model: None, cwd: None, team: None, @@ -434,7 +434,7 @@ impl BrokerRuntime { provider: None, cli: Some(cli.clone()), session_id: None, - harness_plan: None, + harness_config: None, model: None, cwd: None, team: None, diff --git a/crates/broker/src/runtime/spawn_spec.rs b/crates/broker/src/runtime/spawn_spec.rs index 8fa28444a..7afe8dc07 100644 --- a/crates/broker/src/runtime/spawn_spec.rs +++ b/crates/broker/src/runtime/spawn_spec.rs @@ -20,7 +20,7 @@ pub(crate) fn build_http_api_spawn_spec( shadow_of: Option, shadow_mode: Option, restart_policy: Option, - harness_plan: Option, + harness_config: Option, ) -> Result { let requested_runtime = match transport .as_deref() @@ -35,7 +35,7 @@ pub(crate) fn build_http_api_spawn_spec( anyhow::bail!("unsupported transport '{other}' (expected 'pty' or 'headless')") } }; - let harness_runtime = harness_plan.as_ref().map(ResolvedHarnessPlan::runtime); + let harness_runtime = harness_config.as_ref().map(ResolvedHarnessConfig::runtime); let runtime = match ( transport .as_deref() @@ -47,7 +47,7 @@ pub(crate) fn build_http_api_spawn_spec( (_, Some(harness_runtime)) if harness_runtime == requested_runtime => requested_runtime, (_, Some(harness_runtime)) => { anyhow::bail!( - "harnessPlan runtime '{}' does not match requested transport '{}'", + "harnessConfig runtime '{}' does not match requested transport '{}'", runtime_label(&harness_runtime), runtime_label(&requested_runtime) ) @@ -61,8 +61,8 @@ pub(crate) fn build_http_api_spawn_spec( let (provider, cli_command, model) = match runtime { AgentRuntime::Pty => (None, Some(cli), model), - AgentRuntime::Headless => match harness_plan.as_ref() { - Some(ResolvedHarnessPlan::Headless(_)) => (None, Some(cli), model), + AgentRuntime::Headless => match harness_config.as_ref() { + Some(ResolvedHarnessConfig::Headless(_)) => (None, Some(cli), model), _ => { let provider = headless_provider_from_cli(&cli).with_context(|| { format!( @@ -73,9 +73,9 @@ pub(crate) fn build_http_api_spawn_spec( } }, }; - let session_id = harness_plan + let session_id = harness_config .as_ref() - .and_then(ResolvedHarnessPlan::session_id) + .and_then(ResolvedHarnessConfig::session_id) .map(ToOwned::to_owned); Ok(AgentSpec { @@ -84,7 +84,7 @@ pub(crate) fn build_http_api_spawn_spec( provider, cli: cli_command, session_id, - harness_plan, + harness_config, model, cwd, team, diff --git a/crates/broker/src/runtime/tests.rs b/crates/broker/src/runtime/tests.rs index f20d81535..1d17331da 100644 --- a/crates/broker/src/runtime/tests.rs +++ b/crates/broker/src/runtime/tests.rs @@ -7,8 +7,8 @@ use std::{ }; use crate::protocol::{ - AgentSpec, HarnessReleasePolicy, HeadlessHarnessDriver, HeadlessHarnessPlan, - MessageInjectionMode, RelayDelivery, ResolvedHarnessPlan, + AgentSpec, HarnessReleasePolicy, HeadlessHarnessConfig, HeadlessHarnessDriver, + MessageInjectionMode, RelayDelivery, ResolvedHarnessConfig, }; use crate::worker::{AgentWorkState, WorkerEvent, WorkerHandle, WorkerRegistry}; use crate::{ @@ -72,7 +72,7 @@ async fn make_worker_registry_with_worker(name: &str) -> WorkerRegistry { provider: None, cli: Some("cat".to_string()), session_id: None, - harness_plan: None, + harness_config: None, model: None, cwd: None, team: None, @@ -1977,8 +1977,8 @@ fn http_api_spawn_spec_uses_headless_runtime_for_supported_providers() { } #[test] -fn http_api_spawn_spec_uses_headless_runtime_for_app_server_harness_plan() { - let harness_plan = ResolvedHarnessPlan::Headless(HeadlessHarnessPlan { +fn http_api_spawn_spec_uses_headless_runtime_for_app_server_harness_config() { + let harness_config = ResolvedHarnessConfig::Headless(HeadlessHarnessConfig { driver: HeadlessHarnessDriver::AppServer, protocol: "opencode".to_string(), endpoint: "http://127.0.0.1:4096".to_string(), @@ -2001,7 +2001,7 @@ fn http_api_spawn_spec_uses_headless_runtime_for_app_server_harness_plan() { None, None, None, - Some(harness_plan), + Some(harness_config), ) .expect("headless app-server harness spec should build"); @@ -2010,13 +2010,13 @@ fn http_api_spawn_spec_uses_headless_runtime_for_app_server_harness_plan() { assert_eq!(spec.cli.as_deref(), Some("opencode-server")); assert_eq!(spec.session_id.as_deref(), Some("ses_123")); assert!(matches!( - spec.harness_plan, - Some(ResolvedHarnessPlan::Headless(_)) + spec.harness_config, + Some(ResolvedHarnessConfig::Headless(_)) )); } #[test] -fn http_api_spawn_spec_rejects_unknown_headless_provider_without_harness_plan() { +fn http_api_spawn_spec_rejects_unknown_headless_provider_without_harness_config() { let error = build_http_api_spawn_spec( "worker-a".to_string(), "opencode-server".to_string(), @@ -2031,7 +2031,7 @@ fn http_api_spawn_spec_rejects_unknown_headless_provider_without_harness_plan() None, None, ) - .expect_err("custom headless provider without harness plan should fail"); + .expect_err("custom headless provider without harness config should fail"); assert!( error diff --git a/crates/broker/src/supervisor.rs b/crates/broker/src/supervisor.rs index cea6e1c38..f89b092fc 100644 --- a/crates/broker/src/supervisor.rs +++ b/crates/broker/src/supervisor.rs @@ -231,7 +231,7 @@ mod tests { provider: None, cli: Some("claude".to_string()), session_id: None, - harness_plan: None, + harness_config: None, model: None, cwd: None, team: None, diff --git a/crates/broker/src/worker.rs b/crates/broker/src/worker.rs index d3c5fda07..f9eb9a08e 100644 --- a/crates/broker/src/worker.rs +++ b/crates/broker/src/worker.rs @@ -9,8 +9,8 @@ use crate::{ metrics::MetricsCollector, protocol::{ AgentRuntime, AgentSpec, AppServerAuthType, AppServerHostOwnership, HarnessReleasePolicy, - HeadlessHarnessDriver, HeadlessHarnessPlan, ProtocolEnvelope, RelayDelivery, - ResolvedHarnessPlan, PROTOCOL_VERSION, + HeadlessHarnessConfig, HeadlessHarnessDriver, ProtocolEnvelope, RelayDelivery, + ResolvedHarnessConfig, PROTOCOL_VERSION, }, relaycast::configure_relaycast_mcp_with_result, supervisor::Supervisor, @@ -248,24 +248,24 @@ impl WorkerRegistry { let mut suppress_worker_env: Vec<&'static str> = Vec::new(); let mut initial_harness_pid: Option = None; - match spec.harness_plan.clone() { - Some(ResolvedHarnessPlan::Pty(plan)) => { + match spec.harness_config.clone() { + Some(ResolvedHarnessConfig::Pty(config)) => { spec.runtime = AgentRuntime::Pty; if spec.session_id.is_none() { - spec.session_id = plan.session_id.clone(); + spec.session_id = config.session_id.clone(); } if spec.cwd.is_none() { - spec.cwd = plan.cwd.clone(); + spec.cwd = config.cwd.clone(); } - if let Some(env) = plan.env { + if let Some(env) = config.env { harness_env.extend(env); } - let (resolved_cli, inline_cli_args) = parse_cli_command(&plan.command) - .with_context(|| format!("invalid harness command '{}'", plan.command))?; + let (resolved_cli, inline_cli_args) = parse_cli_command(&config.command) + .with_context(|| format!("invalid harness command '{}'", config.command))?; let normalized_cli = normalize_cli_name(&resolved_cli); let mut effective_args = inline_cli_args; - effective_args.extend(plan.args.clone()); + effective_args.extend(config.args.clone()); command.arg("pty"); command.arg("--agent-name").arg(&spec.name); @@ -324,33 +324,33 @@ impl WorkerRegistry { } } } - Some(ResolvedHarnessPlan::Headless(plan)) => { - validate_app_server_plan(&plan)?; + Some(ResolvedHarnessConfig::Headless(config)) => { + validate_app_server_config(&config)?; spec.runtime = AgentRuntime::Headless; - spec.session_id = Some(plan.session_id.clone()); - initial_harness_pid = plan.host.as_ref().and_then(|host| host.pid); - match &plan.driver { + spec.session_id = Some(config.session_id.clone()); + initial_harness_pid = config.host.as_ref().and_then(|host| host.pid); + match &config.driver { HeadlessHarnessDriver::AppServer => {} } command.arg("app-server"); command.arg("--agent-name").arg(&spec.name); - command.arg("--protocol").arg(&plan.protocol); - command.arg("--endpoint").arg(&plan.endpoint); - command.arg("--session-id").arg(&plan.session_id); + command.arg("--protocol").arg(&config.protocol); + command.arg("--endpoint").arg(&config.endpoint); + command.arg("--session-id").arg(&config.session_id); if let Some(pid) = initial_harness_pid { command.arg("--host-pid").arg(pid.to_string()); } command .arg("--release") - .arg(release_policy_arg(plan.release.as_ref())); + .arg(release_policy_arg(config.release.as_ref())); suppress_worker_env.extend(APP_SERVER_AUTH_ENV_KEYS); for key in APP_SERVER_AUTH_ENV_KEYS { command.env_remove(key); } - if let Some(auth) = plan.auth { + if let Some(auth) = config.auth { harness_env.push(( "AGENT_RELAY_APP_SERVER_AUTH_TYPE".to_string(), app_server_auth_type_arg(&auth.auth_type).to_string(), @@ -868,9 +868,9 @@ fn app_server_auth_type_arg(auth_type: &AppServerAuthType) -> &'static str { } fn release_grace_for_spec(spec: &AgentSpec) -> Duration { - match spec.harness_plan.as_ref() { - Some(ResolvedHarnessPlan::Headless(plan)) - if matches!(&plan.driver, HeadlessHarnessDriver::AppServer) => + match spec.harness_config.as_ref() { + Some(ResolvedHarnessConfig::Headless(config)) + if matches!(&config.driver, HeadlessHarnessDriver::AppServer) => { APP_SERVER_RELEASE_GRACE } @@ -878,25 +878,25 @@ fn release_grace_for_spec(spec: &AgentSpec) -> Duration { } } -fn validate_app_server_plan(plan: &HeadlessHarnessPlan) -> Result<()> { - if !matches!(&plan.driver, HeadlessHarnessDriver::AppServer) { +fn validate_app_server_config(config: &HeadlessHarnessConfig) -> Result<()> { + if !matches!(&config.driver, HeadlessHarnessDriver::AppServer) { anyhow::bail!("unsupported headless harness driver"); } - let protocol = plan.protocol.trim().to_ascii_lowercase(); + let protocol = config.protocol.trim().to_ascii_lowercase(); if protocol != "opencode" { anyhow::bail!( "unsupported app_server protocol '{}' (supported: opencode)", - plan.protocol + config.protocol ); } - let endpoint = plan.endpoint.trim(); + let endpoint = config.endpoint.trim(); if endpoint.is_empty() { anyhow::bail!("app_server endpoint is required"); } let parsed_endpoint = reqwest::Url::parse(endpoint) - .with_context(|| format!("invalid app_server endpoint '{}'", plan.endpoint))?; + .with_context(|| format!("invalid app_server endpoint '{}'", config.endpoint))?; match parsed_endpoint.scheme() { "http" | "https" => {} scheme => anyhow::bail!( @@ -905,11 +905,11 @@ fn validate_app_server_plan(plan: &HeadlessHarnessPlan) -> Result<()> { ), } - if plan.session_id.trim().is_empty() { + if config.session_id.trim().is_empty() { anyhow::bail!("app_server sessionId is required"); } - if plan + if config .host .as_ref() .and_then(|host| host.ownership.as_ref()) @@ -918,7 +918,7 @@ fn validate_app_server_plan(plan: &HeadlessHarnessPlan) -> Result<()> { anyhow::bail!("broker-owned app_server hosts are not supported yet"); } - if let Some(auth) = plan.auth.as_ref() { + if let Some(auth) = config.auth.as_ref() { match auth.auth_type { AppServerAuthType::Bearer => { if auth @@ -1310,8 +1310,8 @@ mod tests { assert_eq!(reg.env_value("MISSING"), None); } - fn make_app_server_plan() -> HeadlessHarnessPlan { - HeadlessHarnessPlan { + fn make_app_server_config() -> HeadlessHarnessConfig { + HeadlessHarnessConfig { driver: HeadlessHarnessDriver::AppServer, protocol: "opencode".to_string(), endpoint: "http://127.0.0.1:4096".to_string(), @@ -1327,45 +1327,45 @@ mod tests { } #[test] - fn app_server_plan_validation_accepts_attached_opencode_plan() { - let plan = make_app_server_plan(); - validate_app_server_plan(&plan).expect("valid app-server plan"); + fn app_server_config_validation_accepts_attached_opencode_config() { + let config = make_app_server_config(); + validate_app_server_config(&config).expect("valid app-server config"); } #[test] - fn app_server_plan_validation_rejects_missing_bearer_token() { - let mut plan = make_app_server_plan(); - plan.auth = Some(AppServerHarnessAuth { + fn app_server_config_validation_rejects_missing_bearer_token() { + let mut config = make_app_server_config(); + config.auth = Some(AppServerHarnessAuth { auth_type: AppServerAuthType::Bearer, token: None, username: None, password: None, }); - let error = validate_app_server_plan(&plan).expect_err("missing token rejected"); + let error = validate_app_server_config(&config).expect_err("missing token rejected"); assert!(error.to_string().contains("bearer auth requires token")); } #[test] - fn app_server_plan_validation_rejects_broker_owned_host() { - let mut plan = make_app_server_plan(); - plan.host = Some(AppServerHarnessHost { + fn app_server_config_validation_rejects_broker_owned_host() { + let mut config = make_app_server_config(); + config.host = Some(AppServerHarnessHost { ownership: Some(AppServerHostOwnership::BrokerOwned), pid: None, }); - let error = validate_app_server_plan(&plan).expect_err("broker-owned host rejected"); + let error = validate_app_server_config(&config).expect_err("broker-owned host rejected"); assert!(error .to_string() .contains("broker-owned app_server hosts are not supported yet")); } #[test] - fn app_server_plan_validation_rejects_unsupported_protocol() { - let mut plan = make_app_server_plan(); - plan.protocol = "custom".to_string(); + fn app_server_config_validation_rejects_unsupported_protocol() { + let mut config = make_app_server_config(); + config.protocol = "custom".to_string(); - let error = validate_app_server_plan(&plan).expect_err("unsupported protocol rejected"); + let error = validate_app_server_config(&config).expect_err("unsupported protocol rejected"); assert!(error .to_string() .contains("unsupported app_server protocol")); @@ -1379,7 +1379,7 @@ mod tests { provider: None, cli: None, session_id: Some("ses_123".to_string()), - harness_plan: Some(ResolvedHarnessPlan::Headless(make_app_server_plan())), + harness_config: Some(ResolvedHarnessConfig::Headless(make_app_server_config())), model: None, cwd: None, team: None, diff --git a/docs/harness-runtime-plan.md b/docs/harness-runtime-config.md similarity index 86% rename from docs/harness-runtime-plan.md rename to docs/harness-runtime-config.md index 33a508c7e..5eebcbb19 100644 --- a/docs/harness-runtime-plan.md +++ b/docs/harness-runtime-config.md @@ -1,11 +1,11 @@ -# Harness Runtime Plan +# Harness Runtime Config ## Goal Harnesses should be user-extensible without requiring Rust changes for normal agent CLIs. The Rust broker should own durable runtime execution, lifecycle tracking, routing, delivery queues, retries, and observability. SDKs should be -able to define named harnesses that resolve to broker-executable JSON plans. +able to define named harnesses that resolve to broker-executable JSON configs. ## Core Model @@ -21,14 +21,14 @@ The first headless drivers are: - `app_server`: a session-backed HTTP driver for attached agent servers. Named harnesses such as `codex`, `claude`, or `opencode-server` resolve to one of -those executable plans. +those executable configs. -## Plan Shapes +## Config Shapes -PTY plans are process and terminal backed: +PTY configs are process and terminal backed: ```ts -type PtyHarnessPlan = { +type PtyHarnessConfig = { runtime: 'pty'; command: string; args: string[]; @@ -43,11 +43,11 @@ type PtyHarnessPlan = { }; ``` -Headless app-server plans are session backed. They are still `headless` workers; +Headless app-server configs are session backed. They are still `headless` workers; `driver: 'app_server'` explains how the broker talks to the worker: ```ts -type HeadlessAppServerHarnessPlan = { +type HeadlessAppServerHarnessConfig = { runtime: 'headless'; driver: 'app_server'; protocol: 'opencode' | string; @@ -68,14 +68,14 @@ type HeadlessAppServerHarnessPlan = { }; ``` -The broker runs the returned plan. It does not need to understand arbitrary +The broker runs the returned config. It does not need to understand arbitrary TypeScript or Python logic. -For now, `app_server` plans are attach-only. `host.ownership: 'broker-owned'` +For now, `app_server` configs are attach-only. `host.ownership: 'broker-owned'` is reserved and rejected until the broker owns app-server lifecycle supervision. When `host.pid` is provided, the broker reports that as the harness PID. -Plan `env` and `auth` values are visible to the broker and may be included in +Config `env` and `auth` values are visible to the broker and may be included in runtime state. SDK resolvers should return explicit allowlists and avoid copying the whole process environment. @@ -102,11 +102,11 @@ const harnesses = { ``` Custom PTY harnesses own their CLI flags. Broker built-in permission bypass -defaults are not injected into caller-provided harness plans. +defaults are not injected into caller-provided harness configs. Dynamic harness resolvers are SDK functions and are attached-only. They can run pre-spawn logic, such as creating a provider session, then return a concrete -plan: +config: ```ts const harnesses = { @@ -143,7 +143,7 @@ Attached brokers are owned by the SDK process. Dynamic resolvers and in-process decision hooks are allowed because the broker exits if the SDK control connection exits. -Detached brokers survive SDK callers. They only accept static harness plans, +Detached brokers survive SDK callers. They only accept static harness configs, built-in Rust adapters, and durable extension hosts. ## Broker Responsibilities @@ -162,7 +162,7 @@ The broker does not own custom user logic unless that logic is built into Rust. ## PTY Runtime -The PTY executor consumes a concrete PTY plan. It handles process spawn, +The PTY executor consumes a concrete PTY config. It handles process spawn, terminal streaming, raw input, resize, snapshot, release, and PTY message injection. @@ -209,10 +209,10 @@ durable extension host for decision-making. ## Implementation Phases -1. Add shared plan schema and SDK types. -2. Add static SDK harness resolution to PTY plans. -3. Teach the broker to accept and execute resolved PTY plans. -4. Add a headless app-server plan path with an OpenCode protocol driver. +1. Add shared config schema and SDK types. +2. Add static SDK harness resolution to PTY configs. +3. Teach the broker to accept and execute resolved PTY configs. +4. Add a headless app-server config path with an OpenCode protocol driver. 5. Add capability-aware runtime checks for PTY-only operations. 6. Add attached broker control RPCs for dynamic resolvers. 7. Add detached-mode validation for dynamic resolvers and in-process decision hooks. diff --git a/packages/sdk/src/__tests__/harness.test.ts b/packages/sdk/src/__tests__/harness.test.ts index 7939621de..6b6fc261b 100644 --- a/packages/sdk/src/__tests__/harness.test.ts +++ b/packages/sdk/src/__tests__/harness.test.ts @@ -4,11 +4,11 @@ import path from 'node:path'; import { describe, expect, it, vi } from 'vitest'; import { AgentRelayClient } from '../client.js'; -import { harnessLookupKeys, resolveStaticHarnessPlan } from '../harness.js'; +import { harnessLookupKeys, resolveStaticHarnessConfig } from '../harness.js'; -describe('harness plans', () => { - it('resolves static PTY harnesses to broker-executable plans', () => { - const plan = resolveStaticHarnessPlan({ +describe('harness configs', () => { + it('resolves static PTY harnesses to broker-executable configs', () => { + const config = resolveStaticHarnessConfig({ name: 'QwenReviewer', cli: 'qwen', definition: { @@ -23,7 +23,7 @@ describe('harness plans', () => { cwd: '/workspace', }); - expect(plan).toEqual({ + expect(config).toEqual({ runtime: 'pty', command: 'qwen', args: ['run', '-m', 'qwen3-coder', '--verbose'], @@ -33,7 +33,7 @@ describe('harness plans', () => { }); it('resolves static headless app-server harnesses without process args', () => { - const plan = resolveStaticHarnessPlan({ + const config = resolveStaticHarnessConfig({ name: 'OpenCodeServerWorker', cli: 'opencode-server', definition: { @@ -46,7 +46,7 @@ describe('harness plans', () => { }, }); - expect(plan).toEqual({ + expect(config).toEqual({ runtime: 'headless', driver: 'app_server', protocol: 'opencode', @@ -61,7 +61,7 @@ describe('harness plans', () => { }); it('expands home directories in direct command paths', () => { - const plan = resolveStaticHarnessPlan({ + const config = resolveStaticHarnessConfig({ name: 'ClaudeReviewer', cli: 'claude', definition: { @@ -70,10 +70,10 @@ describe('harness plans', () => { }, }); - expect(plan.command).toBe(path.join(homedir(), 'bin/claude')); + expect(config.command).toBe(path.join(homedir(), 'bin/claude')); }); - it('serializes resolved harness plans on spawn requests', async () => { + it('serializes resolved harness configs on spawn requests', async () => { const captures: unknown[] = []; const fetchFn = vi.fn(async (_url: string | URL | Request, init?: RequestInit) => { captures.push(JSON.parse(String(init?.body ?? '{}'))); @@ -90,7 +90,7 @@ describe('harness plans', () => { const result = await client.spawnPty({ name: 'QwenReviewer', cli: 'qwen', - harnessPlan: { + harnessConfig: { runtime: 'pty', command: 'qwen', args: ['run'], @@ -102,7 +102,7 @@ describe('harness plans', () => { expect(captures[0]).toMatchObject({ name: 'QwenReviewer', cli: 'qwen', - harnessPlan: { + harnessConfig: { runtime: 'pty', command: 'qwen', args: ['run'], diff --git a/packages/sdk/src/__tests__/lifecycle-hooks.test.ts b/packages/sdk/src/__tests__/lifecycle-hooks.test.ts index d0bd1228a..712b2f655 100644 --- a/packages/sdk/src/__tests__/lifecycle-hooks.test.ts +++ b/packages/sdk/src/__tests__/lifecycle-hooks.test.ts @@ -201,12 +201,12 @@ describe('AgentRelayClient lifecycle hooks', () => { expect((after.mock.calls[0][0] as AfterAgentSpawnContext).kind).toBe('provider'); }); - it('recomputes provider transport after beforeAgentSpawn patches add a harness plan', async () => { + it('recomputes provider transport after beforeAgentSpawn patches add a harness config', async () => { const { fetchFn, captures } = makeMockFetch(); const client = makeClient(fetchFn); client.addListener('beforeAgentSpawn', () => ({ - harnessPlan: { + harnessConfig: { runtime: 'headless', driver: 'app_server', protocol: 'opencode', @@ -225,7 +225,7 @@ describe('AgentRelayClient lifecycle hooks', () => { name: 'patched-headless', cli: 'custom-provider', transport: 'headless', - harnessPlan: { + harnessConfig: { runtime: 'headless', driver: 'app_server', sessionId: 'ses_hook', diff --git a/packages/sdk/src/client.ts b/packages/sdk/src/client.ts index 26752d4f2..2cf89ebf4 100644 --- a/packages/sdk/src/client.ts +++ b/packages/sdk/src/client.ts @@ -154,7 +154,7 @@ function isHeadlessProvider(value: string): value is HeadlessProvider { function resolveSpawnTransport(input: SpawnProviderInput): AgentTransport { if (input.transport) return input.transport; - if (input.harnessPlan) return input.harnessPlan.runtime; + if (input.harnessConfig) return input.harnessConfig.runtime; return input.provider === 'opencode' ? 'headless' : 'pty'; } @@ -177,7 +177,7 @@ function buildSpawnPtyBody(input: SpawnPtyInput): Record { ...(input.shadowOf !== undefined ? { shadowOf: input.shadowOf } : {}), ...(input.shadowMode !== undefined ? { shadowMode: input.shadowMode } : {}), ...(input.continueFrom !== undefined ? { continueFrom: input.continueFrom } : {}), - ...(input.harnessPlan !== undefined ? { harnessPlan: input.harnessPlan } : {}), + ...(input.harnessConfig !== undefined ? { harnessConfig: input.harnessConfig } : {}), ...(input.idleThresholdSecs !== undefined ? { idleThresholdSecs: input.idleThresholdSecs } : {}), ...(input.restartPolicy !== undefined ? { restartPolicy: input.restartPolicy } : {}), ...(input.skipRelayPrompt !== undefined ? { skipRelayPrompt: input.skipRelayPrompt } : {}), @@ -202,7 +202,7 @@ function buildSpawnProviderBody( ...(input.shadowOf !== undefined ? { shadowOf: input.shadowOf } : {}), ...(input.shadowMode !== undefined ? { shadowMode: input.shadowMode } : {}), ...(input.continueFrom !== undefined ? { continueFrom: input.continueFrom } : {}), - ...(input.harnessPlan !== undefined ? { harnessPlan: input.harnessPlan } : {}), + ...(input.harnessConfig !== undefined ? { harnessConfig: input.harnessConfig } : {}), ...(input.idleThresholdSecs !== undefined ? { idleThresholdSecs: input.idleThresholdSecs } : {}), ...(input.restartPolicy !== undefined ? { restartPolicy: input.restartPolicy } : {}), ...(input.skipRelayPrompt !== undefined ? { skipRelayPrompt: input.skipRelayPrompt } : {}), @@ -626,7 +626,7 @@ export class AgentRelayClient { if ( transport === 'headless' && !isHeadlessProvider(resolvedInput.provider) && - !resolvedInput.harnessPlan + !resolvedInput.harnessConfig ) { throw new Error( `provider '${resolvedInput.provider}' does not support headless transport (supported: claude, opencode)` diff --git a/packages/sdk/src/harness.ts b/packages/sdk/src/harness.ts index 5486a78f7..af580a4c3 100644 --- a/packages/sdk/src/harness.ts +++ b/packages/sdk/src/harness.ts @@ -13,7 +13,7 @@ export interface PtyHarnessDelivery { format?: 'relay-block'; } -export interface PtyHarnessPlan { +export interface PtyHarnessConfig { runtime: 'pty'; command: string; args: string[]; @@ -41,7 +41,7 @@ export interface AppServerHarnessHost { pid?: number; } -export interface HeadlessAppServerHarnessPlan { +export interface HeadlessAppServerHarnessConfig { runtime: 'headless'; driver: HeadlessHarnessDriver; protocol: 'opencode' | string; @@ -53,7 +53,7 @@ export interface HeadlessAppServerHarnessPlan { metadata?: Record; } -export type ResolvedHarnessPlan = PtyHarnessPlan | HeadlessAppServerHarnessPlan; +export type ResolvedHarnessConfig = PtyHarnessConfig | HeadlessAppServerHarnessConfig; export interface StaticPtyHarnessDefinition { runtime: 'pty'; @@ -94,7 +94,7 @@ export interface HarnessResolveContext { export type AttachedHarnessResolver = ( context: HarnessResolveContext -) => ResolvedHarnessPlan | Promise; +) => ResolvedHarnessConfig | Promise; export type HarnessDefinition = StaticHarnessDefinition | AttachedHarnessResolver; export interface ResolveStaticHarnessInput { @@ -115,7 +115,7 @@ export function isAttachedHarnessResolver(value: HarnessDefinition): value is At return typeof value === 'function'; } -export function resolveStaticHarnessPlan(input: ResolveStaticHarnessInput): ResolvedHarnessPlan { +export function resolveStaticHarnessConfig(input: ResolveStaticHarnessInput): ResolvedHarnessConfig { const { definition } = input; if (definition.runtime === 'headless') { return { @@ -145,7 +145,7 @@ export function resolveStaticHarnessPlan(input: ResolveStaticHarnessInput): Reso : [], }; - const planEnv = { + const configEnv = { ...(definition.env ?? {}), ...(input.env ?? {}), }; @@ -155,7 +155,7 @@ export function resolveStaticHarnessPlan(input: ResolveStaticHarnessInput): Reso command: resolveCommand(definition.command, definition.searchPaths), args: renderTemplate(definition.args ?? DEFAULT_PTY_ARGS, context), ...((input.cwd ?? definition.cwd) ? { cwd: input.cwd ?? definition.cwd } : {}), - ...(Object.keys(planEnv).length > 0 ? { env: planEnv } : {}), + ...(Object.keys(configEnv).length > 0 ? { env: configEnv } : {}), ...(definition.sessionId ? { sessionId: definition.sessionId } : {}), ...(definition.delivery ? { delivery: { ...definition.delivery } } : {}), ...(definition.metadata ? { metadata: { ...definition.metadata } } : {}), diff --git a/packages/sdk/src/lifecycle-hooks.ts b/packages/sdk/src/lifecycle-hooks.ts index dffe0db90..b21e4fabc 100644 --- a/packages/sdk/src/lifecycle-hooks.ts +++ b/packages/sdk/src/lifecycle-hooks.ts @@ -54,7 +54,7 @@ import type { SpawnAgentResult, SpawnPtyInput, SpawnProviderInput } from './type export type SpawnPatch = Partial< Pick< SpawnPtyInput & SpawnProviderInput, - 'args' | 'channels' | 'task' | 'model' | 'team' | 'agentToken' | 'harnessPlan' + 'args' | 'channels' | 'task' | 'model' | 'team' | 'agentToken' | 'harnessConfig' > >; diff --git a/packages/sdk/src/protocol.ts b/packages/sdk/src/protocol.ts index 6cfc55c82..53e4fb756 100644 --- a/packages/sdk/src/protocol.ts +++ b/packages/sdk/src/protocol.ts @@ -18,7 +18,7 @@ export interface AgentSpec { provider?: HeadlessProvider; cli?: string; session_id?: string; - harness_plan?: import('./harness.js').ResolvedHarnessPlan; + harness_config?: import('./harness.js').ResolvedHarnessConfig; args?: string[]; channels?: string[]; model?: string; diff --git a/packages/sdk/src/relay.ts b/packages/sdk/src/relay.ts index 3f20c3e3a..93970f870 100644 --- a/packages/sdk/src/relay.ts +++ b/packages/sdk/src/relay.ts @@ -36,9 +36,9 @@ import { EventBus } from './event-bus.js'; import { harnessLookupKeys, isAttachedHarnessResolver, - resolveStaticHarnessPlan, + resolveStaticHarnessConfig, type HarnessDefinition, - type ResolvedHarnessPlan, + type ResolvedHarnessConfig, } from './harness.js'; import type { AgentRelayEvents, BeforeAgentSpawnHandler } from './lifecycle-hooks.js'; import { @@ -289,7 +289,7 @@ export interface SpawnOptions extends SpawnLifecycleHook shadowMode?: string; idleThresholdSecs?: number; restartPolicy?: RestartPolicy; - harnessPlan?: ResolvedHarnessPlan; + harnessConfig?: ResolvedHarnessConfig; /** Optional pre-minted relaycast agent token (`at_live_`, from * `registerAgent(workspaceKey, name)` in `@agent-relay/sdk/http`). The * broker plumbs this as `RELAY_AGENT_TOKEN`, which the relaycast MCP @@ -416,7 +416,7 @@ export interface SpawnerSpawnOptions extends SpawnLifecy model?: string; cwd?: string; idleThresholdSecs?: number; - harnessPlan?: ResolvedHarnessPlan; + harnessConfig?: ResolvedHarnessConfig; /** Optional pre-minted relaycast agent token (`at_live_`, from * `registerAgent(workspaceKey, name)` in `@agent-relay/sdk/http`). The * broker plumbs this as `RELAY_AGENT_TOKEN`, which the relaycast MCP @@ -472,7 +472,7 @@ export interface AgentRelayOptions { personaDirs?: string[]; /** * Named harness definitions. Static definitions resolve to broker-executable - * JSON plans; function resolvers are only valid for attached brokers. + * JSON configs; function resolvers are only valid for attached brokers. */ harnesses?: Record; /** Broker lifetime boundary for dynamic harness resolvers and hooks. */ @@ -783,8 +783,8 @@ export class AgentRelay { }; } - private async resolveHarnessPlan(input: SpawnPtyInput): Promise { - if (input.harnessPlan) return input.harnessPlan; + private async resolveHarnessConfig(input: SpawnPtyInput): Promise { + if (input.harnessConfig) return input.harnessConfig; const definition = this.findHarnessDefinition(input.cli); if (!definition) return undefined; @@ -798,7 +798,7 @@ export class AgentRelay { return definition(context); } - return resolveStaticHarnessPlan({ + return resolveStaticHarnessConfig({ name: context.name, cli: context.cli, definition, @@ -881,7 +881,7 @@ export class AgentRelay { this.resultContracts.set(input.name, resultContract as InternalAgentResultContract); } try { - const harnessPlan = await this.resolveHarnessPlan(input); + const harnessConfig = await this.resolveHarnessConfig(input); result = await client.spawnPty({ name: input.name, cli: input.cli, @@ -896,7 +896,7 @@ export class AgentRelay { shadowMode: input.shadowMode, idleThresholdSecs: input.idleThresholdSecs, restartPolicy: input.restartPolicy, - harnessPlan, + harnessConfig, skipRelayPrompt: input.skipRelayPrompt, agentResultSchema: resultContract?.jsonSchema, }); @@ -957,7 +957,7 @@ export class AgentRelay { shadowMode: options?.shadowMode, idleThresholdSecs: options?.idleThresholdSecs, restartPolicy: options?.restartPolicy, - harnessPlan: options?.harnessPlan, + harnessConfig: options?.harnessConfig, skipRelayPrompt: options?.skipRelayPrompt, result: options?.result, onStart: options?.onStart, @@ -1042,7 +1042,7 @@ export class AgentRelay { shadowMode: options.shadowMode, idleThresholdSecs: options.idleThresholdSecs, restartPolicy: options.restartPolicy, - harnessPlan: options.harnessPlan, + harnessConfig: options.harnessConfig, skipRelayPrompt: options.skipRelayPrompt, result: options.result, onStart: options.onStart, @@ -2366,7 +2366,7 @@ export class AgentRelay { model: options?.model, cwd: options?.cwd, idleThresholdSecs: options?.idleThresholdSecs, - harnessPlan: options?.harnessPlan, + harnessConfig: options?.harnessConfig, agentToken: options?.agentToken, skipRelayPrompt: options?.skipRelayPrompt, result: options?.result, @@ -2390,9 +2390,9 @@ export class AgentRelay { this.resultContracts.set(name, resultContract as InternalAgentResultContract); } try { - const harnessPlan = - options?.harnessPlan ?? - (await this.resolveHarnessPlan({ + const harnessConfig = + options?.harnessConfig ?? + (await this.resolveHarnessConfig({ name, cli, args, @@ -2404,14 +2404,14 @@ export class AgentRelay { result = await client.spawnProvider({ name, provider: cli as HeadlessProvider, - transport: harnessPlan?.runtime ?? 'headless', + transport: harnessConfig?.runtime ?? 'headless', args, channels, task, model: options?.model, cwd: options?.cwd, idleThresholdSecs: options?.idleThresholdSecs, - harnessPlan, + harnessConfig, agentToken: options?.agentToken, skipRelayPrompt: options?.skipRelayPrompt, agentResultSchema: resultContract?.jsonSchema, diff --git a/packages/sdk/src/types.ts b/packages/sdk/src/types.ts index 90ec5de79..983eaba76 100644 --- a/packages/sdk/src/types.ts +++ b/packages/sdk/src/types.ts @@ -9,7 +9,7 @@ import type { MessageInjectionMode, RestartPolicy, } from './protocol.js'; -import type { ResolvedHarnessPlan } from './harness.js'; +import type { ResolvedHarnessConfig } from './harness.js'; export type JsonSchema = Record | boolean; @@ -27,7 +27,7 @@ export interface SpawnPtyInput { idleThresholdSecs?: number; restartPolicy?: RestartPolicy; continueFrom?: string; - harnessPlan?: ResolvedHarnessPlan; + harnessConfig?: ResolvedHarnessConfig; skipRelayPrompt?: boolean; agentResultSchema?: JsonSchema; /** Optional pre-minted relaycast agent token (`at_live_`, from @@ -82,7 +82,7 @@ export interface SpawnProviderInput { idleThresholdSecs?: number; restartPolicy?: RestartPolicy; continueFrom?: string; - harnessPlan?: ResolvedHarnessPlan; + harnessConfig?: ResolvedHarnessConfig; skipRelayPrompt?: boolean; agentResultSchema?: JsonSchema; /** Optional pre-minted relaycast agent token (`at_live_`, from diff --git a/web/content/docs/harnesses.mdx b/web/content/docs/harnesses.mdx index 5d2202bda..bda4d340c 100644 --- a/web/content/docs/harnesses.mdx +++ b/web/content/docs/harnesses.mdx @@ -4,8 +4,8 @@ description: Define custom PTY and headless harness adapters in the SDK. --- A harness adapter is a named SDK definition that turns `relay.spawn(...)` into a -broker-executable plan. The broker only runs durable plans; SDK code can prepare -those plans before spawn. +broker-executable harness config. The broker only runs durable configs; SDK code +can prepare those configs before spawn. Relay supports two public runtime categories: @@ -52,7 +52,7 @@ await relay.spawn('ClaudeReviewer', 'company-claude', 'Review the current diff.' }); ``` -When you provide a PTY harness plan, Relay runs that plan as written. Built-in +When you provide a PTY harness config, Relay runs that config as written. Built-in CLI defaults such as Claude permission bypass flags are not auto-injected. Supported placeholders: @@ -136,7 +136,7 @@ Release behavior is controlled by `release`: `abort`, `detach`, or `delete`. `host.pid` is reported as the harness PID when the server is local and known. Static app-server adapters attach to a known session. For per-spawn sessions, -create the session in a dynamic resolver and return the concrete plan: +create the session in a dynamic resolver and return the concrete config: ```typescript file="opencode-dynamic-harness.ts" const relay = new AgentRelay({ @@ -159,19 +159,19 @@ const relay = new AgentRelay({ }); ``` -For now, app-server plans must use `protocol: 'opencode'`, an `http` or `https` +For now, app-server configs must use `protocol: 'opencode'`, an `http` or `https` endpoint, a non-empty `sessionId`, and attached host ownership. `broker-owned` app-server hosts are reserved for a later broker-supervised mode. -## One-Off Plans +## One-Off Configs -You can bypass named registration and pass a plan directly for a single spawn: +You can bypass named registration and pass a config directly for a single spawn: ```typescript file="one-off-codex.ts" await relay.spawnPty({ name: 'CodexOneOff', cli: 'codex', - harnessPlan: { + harnessConfig: { runtime: 'pty', command: 'codex', args: ['--model', 'gpt-5.4'], From c2629f897d674166d1614651c41003893b8c0eb8 Mon Sep 17 00:00:00 2001 From: Will Washburn Date: Mon, 25 May 2026 14:09:30 -0400 Subject: [PATCH 08/19] Clarify harness config naming docs --- docs/harness-runtime-config.md | 12 +++++++++++- web/content/docs/harnesses.mdx | 14 ++++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/docs/harness-runtime-config.md b/docs/harness-runtime-config.md index 5eebcbb19..d4b7965c2 100644 --- a/docs/harness-runtime-config.md +++ b/docs/harness-runtime-config.md @@ -23,6 +23,16 @@ The first headless drivers are: Named harnesses such as `codex`, `claude`, or `opencode-server` resolve to one of those executable configs. +## Naming + +- A harness definition is the static or dynamic value registered by the SDK. +- A harness resolver is a dynamic SDK function that receives spawn context. +- A harness config is the concrete `pty` or `headless` object the broker runs. +- `harnessConfig` is the spawn field for a one-off concrete config. + +This keeps ownership clear: SDKs resolve definitions into configs, and the +broker executes configs durably. + ## Config Shapes PTY configs are process and terminal backed: @@ -200,7 +210,7 @@ relay.addListener('agentSpawned', async (agent) => { Decision hooks are request-response calls over an attached SDK control connection: -- `resolveHarness` +- `resolveHarnessConfig` - `beforeSpawn` - `authorizeSpawn` diff --git a/web/content/docs/harnesses.mdx b/web/content/docs/harnesses.mdx index bda4d340c..981195d69 100644 --- a/web/content/docs/harnesses.mdx +++ b/web/content/docs/harnesses.mdx @@ -17,6 +17,20 @@ Relay supports two public runtime categories: `app_server` is not a third runtime. It is a `headless` driver for sessions controlled over HTTP. +## Naming + +Use these names when building or reading harness code: + +| Name | Meaning | +| --- | --- | +| Harness definition | The value registered in `new AgentRelay({ harnesses })` | +| Harness resolver | A dynamic function that receives spawn context | +| Harness config | The concrete `pty` or `headless` object returned by a definition or resolver | +| `harnessConfig` | The one-off spawn field for passing a concrete config directly | + +The broker runs harness configs. It does not run SDK resolver functions or +placeholder templates. + ## Static PTY Adapter Use a static adapter when a CLI only needs a command, args, env, and optional From e02a2952e146b882f9ae30223ab99b6b1f80f312 Mon Sep 17 00:00:00 2001 From: Will Washburn Date: Mon, 25 May 2026 14:34:40 -0400 Subject: [PATCH 09/19] Fix harness clippy warnings --- .../completed/2026-05/traj_fiygtgr3tfey.json | 25 ++ .../completed/2026-05/traj_fiygtgr3tfey.md | 14 ++ .trajectories/index.json | 9 +- crates/broker/src/protocol.rs | 4 +- crates/broker/src/runtime/util.rs | 226 +++++++++--------- crates/broker/src/worker.rs | 5 +- 6 files changed, 163 insertions(+), 120 deletions(-) create mode 100644 .trajectories/completed/2026-05/traj_fiygtgr3tfey.json create mode 100644 .trajectories/completed/2026-05/traj_fiygtgr3tfey.md diff --git a/.trajectories/completed/2026-05/traj_fiygtgr3tfey.json b/.trajectories/completed/2026-05/traj_fiygtgr3tfey.json new file mode 100644 index 000000000..601d27596 --- /dev/null +++ b/.trajectories/completed/2026-05/traj_fiygtgr3tfey.json @@ -0,0 +1,25 @@ +{ + "id": "traj_fiygtgr3tfey", + "version": 1, + "task": { + "title": "Fix harness config clippy issues" + }, + "status": "completed", + "startedAt": "2026-05-25T18:31:39.975Z", + "completedAt": "2026-05-25T18:34:10.562Z", + "agents": [], + "chapters": [], + "retrospective": { + "summary": "Fixed broker clippy failures by boxing AgentSpec in large protocol enum variants, replacing a manual iter-any check with contains, and moving runtime util tests after all non-test items.", + "approach": "Standard approach", + "confidence": 0.9 + }, + "commits": [], + "filesChanged": [], + "projectId": "/Users/will/Projects/AgentWorkforce/relay", + "tags": [], + "_trace": { + "startRef": "c2629f897d674166d1614651c41003893b8c0eb8", + "endRef": "c2629f897d674166d1614651c41003893b8c0eb8" + } +} diff --git a/.trajectories/completed/2026-05/traj_fiygtgr3tfey.md b/.trajectories/completed/2026-05/traj_fiygtgr3tfey.md new file mode 100644 index 000000000..12f1cfa63 --- /dev/null +++ b/.trajectories/completed/2026-05/traj_fiygtgr3tfey.md @@ -0,0 +1,14 @@ +# Trajectory: Fix harness config clippy issues + +> **Status:** ✅ Completed +> **Confidence:** 90% +> **Started:** May 25, 2026 at 02:31 PM +> **Completed:** May 25, 2026 at 02:34 PM + +--- + +## Summary + +Fixed broker clippy failures by boxing AgentSpec in large protocol enum variants, replacing a manual iter-any check with contains, and moving runtime util tests after all non-test items. + +**Approach:** Standard approach diff --git a/.trajectories/index.json b/.trajectories/index.json index eb11b792b..463c7c4f1 100644 --- a/.trajectories/index.json +++ b/.trajectories/index.json @@ -1,6 +1,6 @@ { "version": 1, - "lastUpdated": "2026-05-25T18:06:35.146Z", + "lastUpdated": "2026-05-25T18:34:10.725Z", "trajectories": { "traj_05xg7j388bc4": { "title": "Add browser workflow step integration", @@ -1156,6 +1156,13 @@ "startedAt": "2026-05-25T18:00:40.591Z", "completedAt": "2026-05-25T18:06:34.954Z", "path": ".trajectories/completed/2026-05/traj_q2r3c9dmdep7.json" + }, + "traj_fiygtgr3tfey": { + "title": "Fix harness config clippy issues", + "status": "completed", + "startedAt": "2026-05-25T18:31:39.975Z", + "completedAt": "2026-05-25T18:34:10.562Z", + "path": ".trajectories/completed/2026-05/traj_fiygtgr3tfey.json" } } } diff --git a/crates/broker/src/protocol.rs b/crates/broker/src/protocol.rs index 375d7a7ab..b31715f19 100644 --- a/crates/broker/src/protocol.rs +++ b/crates/broker/src/protocol.rs @@ -272,7 +272,7 @@ pub enum SdkToBroker { client_version: String, }, SpawnAgent { - agent: AgentSpec, + agent: Box, }, SendMessage { to: String, @@ -496,7 +496,7 @@ pub enum BrokerEvent { #[serde(tag = "type", content = "payload", rename_all = "snake_case")] pub enum BrokerToWorker { InitWorker { - agent: AgentSpec, + agent: Box, }, DeliverRelay(RelayDelivery), ShutdownWorker { diff --git a/crates/broker/src/runtime/util.rs b/crates/broker/src/runtime/util.rs index b54cdb658..136192eac 100644 --- a/crates/broker/src/runtime/util.rs +++ b/crates/broker/src/runtime/util.rs @@ -227,119 +227,6 @@ pub(crate) fn delivery_retry_interval() -> Duration { Duration::from_millis(ms.max(50)) } -#[cfg(test)] -mod tests { - use super::{ - broker_log_dir, broker_log_file_prefix, sanitize_filename_segment, tracing_destination, - tracing_filter_directive, TracingDestination, - }; - - #[test] - fn tracing_destination_defaults_to_file() { - assert_eq!(tracing_destination(None), TracingDestination::File); - assert_eq!(tracing_destination(Some("")), TracingDestination::File); - assert_eq!(tracing_destination(Some(" ")), TracingDestination::File); - } - - #[test] - fn tracing_destination_recognises_off_aliases() { - for value in ["off", "OFF", "none", "0", "false", "no"] { - assert_eq!( - tracing_destination(Some(value)), - TracingDestination::Off, - "value `{value}` should disable tracing" - ); - } - } - - #[test] - fn tracing_destination_recognises_stderr_aliases() { - for value in ["stderr", "STDERR", "print", "Print"] { - assert_eq!( - tracing_destination(Some(value)), - TracingDestination::Stderr, - "value `{value}` should route to stderr" - ); - } - } - - #[test] - fn tracing_destination_recognises_file_aliases() { - for value in ["file", "FILE", "1", "true", "yes", "on", "unknown-value"] { - assert_eq!( - tracing_destination(Some(value)), - TracingDestination::File, - "value `{value}` should route to file" - ); - } - } - - #[test] - fn tracing_filter_defaults_to_info_when_rust_log_unset() { - assert_eq!(tracing_filter_directive(None), "info"); - assert_eq!(tracing_filter_directive(Some("")), "info"); - assert_eq!(tracing_filter_directive(Some(" ")), "info"); - } - - #[test] - fn tracing_filter_prefers_rust_log_directive() { - assert_eq!( - tracing_filter_directive(Some("agent_relay::worker::pty=debug")), - "agent_relay::worker::pty=debug" - ); - } - - #[test] - fn sanitize_filename_segment_replaces_unsafe_chars() { - assert_eq!( - sanitize_filename_segment("agent name/with:weird*chars"), - "agent-name-with-weird-chars" - ); - } - - #[test] - fn sanitize_filename_segment_keeps_safe_chars() { - assert_eq!(sanitize_filename_segment("alpha-Beta_01"), "alpha-Beta_01"); - } - - #[test] - fn sanitize_filename_segment_falls_back_to_broker() { - assert_eq!(sanitize_filename_segment(""), "broker"); - assert_eq!(sanitize_filename_segment("///"), "---"); - } - - #[test] - fn broker_log_file_prefix_includes_log_suffix() { - assert_eq!(broker_log_file_prefix("my-broker"), "my-broker.log"); - assert_eq!(broker_log_file_prefix(""), "broker.log"); - } - - #[test] - fn broker_log_dir_uses_platform_standard_layout() { - let Some(dir) = broker_log_dir() else { - return; - }; - let path_str = dir.to_string_lossy().replace('\\', "/"); - - if cfg!(target_os = "macos") { - assert!( - path_str.contains("/Library/Logs/agent-relay"), - "expected macOS Library/Logs path, got: {path_str}" - ); - } else if cfg!(target_os = "windows") { - assert!( - path_str.to_ascii_lowercase().contains("agent-relay/logs"), - "expected Windows LocalAppData layout, got: {path_str}" - ); - } else { - assert!( - path_str.contains("agent-relay/logs"), - "expected Unix state path, got: {path_str}" - ); - } - } -} - pub(crate) fn http_api_local_delivery_timeout() -> Duration { let ms = std::env::var("AGENT_RELAY_HTTP_API_LOCAL_DELIVERY_TIMEOUT_MS") .ok() @@ -463,3 +350,116 @@ pub(crate) fn extract_mcp_message_ids(buffer: &str) -> Vec { } ids } + +#[cfg(test)] +mod tests { + use super::{ + broker_log_dir, broker_log_file_prefix, sanitize_filename_segment, tracing_destination, + tracing_filter_directive, TracingDestination, + }; + + #[test] + fn tracing_destination_defaults_to_file() { + assert_eq!(tracing_destination(None), TracingDestination::File); + assert_eq!(tracing_destination(Some("")), TracingDestination::File); + assert_eq!(tracing_destination(Some(" ")), TracingDestination::File); + } + + #[test] + fn tracing_destination_recognises_off_aliases() { + for value in ["off", "OFF", "none", "0", "false", "no"] { + assert_eq!( + tracing_destination(Some(value)), + TracingDestination::Off, + "value `{value}` should disable tracing" + ); + } + } + + #[test] + fn tracing_destination_recognises_stderr_aliases() { + for value in ["stderr", "STDERR", "print", "Print"] { + assert_eq!( + tracing_destination(Some(value)), + TracingDestination::Stderr, + "value `{value}` should route to stderr" + ); + } + } + + #[test] + fn tracing_destination_recognises_file_aliases() { + for value in ["file", "FILE", "1", "true", "yes", "on", "unknown-value"] { + assert_eq!( + tracing_destination(Some(value)), + TracingDestination::File, + "value `{value}` should route to file" + ); + } + } + + #[test] + fn tracing_filter_defaults_to_info_when_rust_log_unset() { + assert_eq!(tracing_filter_directive(None), "info"); + assert_eq!(tracing_filter_directive(Some("")), "info"); + assert_eq!(tracing_filter_directive(Some(" ")), "info"); + } + + #[test] + fn tracing_filter_prefers_rust_log_directive() { + assert_eq!( + tracing_filter_directive(Some("agent_relay::worker::pty=debug")), + "agent_relay::worker::pty=debug" + ); + } + + #[test] + fn sanitize_filename_segment_replaces_unsafe_chars() { + assert_eq!( + sanitize_filename_segment("agent name/with:weird*chars"), + "agent-name-with-weird-chars" + ); + } + + #[test] + fn sanitize_filename_segment_keeps_safe_chars() { + assert_eq!(sanitize_filename_segment("alpha-Beta_01"), "alpha-Beta_01"); + } + + #[test] + fn sanitize_filename_segment_falls_back_to_broker() { + assert_eq!(sanitize_filename_segment(""), "broker"); + assert_eq!(sanitize_filename_segment("///"), "---"); + } + + #[test] + fn broker_log_file_prefix_includes_log_suffix() { + assert_eq!(broker_log_file_prefix("my-broker"), "my-broker.log"); + assert_eq!(broker_log_file_prefix(""), "broker.log"); + } + + #[test] + fn broker_log_dir_uses_platform_standard_layout() { + let Some(dir) = broker_log_dir() else { + return; + }; + let path_str = dir.to_string_lossy().replace('\\', "/"); + + if cfg!(target_os = "macos") { + assert!( + path_str.contains("/Library/Logs/agent-relay"), + "expected macOS Library/Logs path, got: {path_str}" + ); + } else if cfg!(target_os = "windows") { + assert!( + path_str.to_ascii_lowercase().contains("agent-relay/logs"), + "expected Windows LocalAppData layout, got: {path_str}" + ); + } else { + assert!( + path_str.contains("agent-relay/logs"), + "expected Unix state path, got: {path_str}" + ); + } + } +} diff --git a/crates/broker/src/worker.rs b/crates/broker/src/worker.rs index f9eb9a08e..b4e415be5 100644 --- a/crates/broker/src/worker.rs +++ b/crates/broker/src/worker.rs @@ -540,10 +540,7 @@ impl WorkerRegistry { .stdout(Stdio::piped()) .stderr(Stdio::piped()); for (key, value) in &self.worker_env { - if suppress_worker_env - .iter() - .any(|blocked| key.as_str() == *blocked) - { + if suppress_worker_env.contains(&key.as_str()) { continue; } command.env(key, value); From 75f019cf5c2601ae195315ea43ae601eb39cfed7 Mon Sep 17 00:00:00 2001 From: Will Washburn Date: Mon, 25 May 2026 15:53:28 -0400 Subject: [PATCH 10/19] Default headless harness driver --- .../completed/2026-05/traj_n0qwpjvmdl2s.json | 25 +++++++++++++++++++ .../completed/2026-05/traj_n0qwpjvmdl2s.md | 14 +++++++++++ .trajectories/index.json | 9 ++++++- crates/broker/src/protocol.rs | 10 +++++++- docs/harness-runtime-config.md | 5 ++-- packages/sdk/src/__tests__/harness.test.ts | 1 - .../sdk/src/__tests__/lifecycle-hooks.test.ts | 2 -- packages/sdk/src/harness.ts | 6 ++--- web/content/docs/harnesses.mdx | 9 +++---- 9 files changed, 66 insertions(+), 15 deletions(-) create mode 100644 .trajectories/completed/2026-05/traj_n0qwpjvmdl2s.json create mode 100644 .trajectories/completed/2026-05/traj_n0qwpjvmdl2s.md diff --git a/.trajectories/completed/2026-05/traj_n0qwpjvmdl2s.json b/.trajectories/completed/2026-05/traj_n0qwpjvmdl2s.json new file mode 100644 index 000000000..7ee04b70c --- /dev/null +++ b/.trajectories/completed/2026-05/traj_n0qwpjvmdl2s.json @@ -0,0 +1,25 @@ +{ + "id": "traj_n0qwpjvmdl2s", + "version": 1, + "task": { + "title": "Default headless harness driver" + }, + "status": "completed", + "startedAt": "2026-05-25T19:50:47.661Z", + "completedAt": "2026-05-25T19:52:52.791Z", + "agents": [], + "chapters": [], + "retrospective": { + "summary": "Made headless harness driver optional by defaulting missing driver values to app_server in broker deserialization and SDK static resolution, then updated docs/examples and tests to use the simpler headless config shape.", + "approach": "Standard approach", + "confidence": 0.9 + }, + "commits": [], + "filesChanged": [], + "projectId": "/Users/will/Projects/AgentWorkforce/relay", + "tags": [], + "_trace": { + "startRef": "e02a2952e146b882f9ae30223ab99b6b1f80f312", + "endRef": "e02a2952e146b882f9ae30223ab99b6b1f80f312" + } +} diff --git a/.trajectories/completed/2026-05/traj_n0qwpjvmdl2s.md b/.trajectories/completed/2026-05/traj_n0qwpjvmdl2s.md new file mode 100644 index 000000000..2f3dc0e81 --- /dev/null +++ b/.trajectories/completed/2026-05/traj_n0qwpjvmdl2s.md @@ -0,0 +1,14 @@ +# Trajectory: Default headless harness driver + +> **Status:** ✅ Completed +> **Confidence:** 90% +> **Started:** May 25, 2026 at 03:50 PM +> **Completed:** May 25, 2026 at 03:52 PM + +--- + +## Summary + +Made headless harness driver optional by defaulting missing driver values to app_server in broker deserialization and SDK static resolution, then updated docs/examples and tests to use the simpler headless config shape. + +**Approach:** Standard approach diff --git a/.trajectories/index.json b/.trajectories/index.json index 463c7c4f1..311e035b3 100644 --- a/.trajectories/index.json +++ b/.trajectories/index.json @@ -1,6 +1,6 @@ { "version": 1, - "lastUpdated": "2026-05-25T18:34:10.725Z", + "lastUpdated": "2026-05-25T19:52:52.973Z", "trajectories": { "traj_05xg7j388bc4": { "title": "Add browser workflow step integration", @@ -1163,6 +1163,13 @@ "startedAt": "2026-05-25T18:31:39.975Z", "completedAt": "2026-05-25T18:34:10.562Z", "path": ".trajectories/completed/2026-05/traj_fiygtgr3tfey.json" + }, + "traj_n0qwpjvmdl2s": { + "title": "Default headless harness driver", + "status": "completed", + "startedAt": "2026-05-25T19:50:47.661Z", + "completedAt": "2026-05-25T19:52:52.791Z", + "path": ".trajectories/completed/2026-05/traj_n0qwpjvmdl2s.json" } } } diff --git a/crates/broker/src/protocol.rs b/crates/broker/src/protocol.rs index b31715f19..cb968780a 100644 --- a/crates/broker/src/protocol.rs +++ b/crates/broker/src/protocol.rs @@ -112,9 +112,14 @@ pub enum HeadlessHarnessDriver { AppServer, } +fn default_headless_harness_driver() -> HeadlessHarnessDriver { + HeadlessHarnessDriver::AppServer +} + #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct HeadlessHarnessConfig { + #[serde(default = "default_headless_harness_driver")] pub driver: HeadlessHarnessDriver, pub protocol: String, pub endpoint: String, @@ -825,7 +830,6 @@ mod tests { fn headless_app_server_harness_config_round_trips() { let raw = json!({ "runtime": "headless", - "driver": "app_server", "protocol": "opencode", "endpoint": "http://127.0.0.1:4096", "sessionId": "ses_123", @@ -840,6 +844,10 @@ mod tests { let config: ResolvedHarnessConfig = serde_json::from_value(raw).unwrap(); assert_eq!(config.runtime(), AgentRuntime::Headless); assert_eq!(config.session_id(), Some("ses_123")); + let ResolvedHarnessConfig::Headless(headless) = &config else { + panic!("expected headless harness config"); + }; + assert_eq!(headless.driver, HeadlessHarnessDriver::AppServer); let encoded = serde_json::to_string(&config).unwrap(); assert!(encoded.contains("\"runtime\":\"headless\"")); diff --git a/docs/harness-runtime-config.md b/docs/harness-runtime-config.md index d4b7965c2..880914261 100644 --- a/docs/harness-runtime-config.md +++ b/docs/harness-runtime-config.md @@ -21,7 +21,8 @@ The first headless drivers are: - `app_server`: a session-backed HTTP driver for attached agent servers. Named harnesses such as `codex`, `claude`, or `opencode-server` resolve to one of -those executable configs. +those executable configs. `driver` defaults to `app_server` when `runtime` is +`headless`. ## Naming @@ -59,7 +60,7 @@ Headless app-server configs are session backed. They are still `headless` worker ```ts type HeadlessAppServerHarnessConfig = { runtime: 'headless'; - driver: 'app_server'; + driver?: 'app_server'; protocol: 'opencode' | string; endpoint: string; sessionId: string; diff --git a/packages/sdk/src/__tests__/harness.test.ts b/packages/sdk/src/__tests__/harness.test.ts index 6b6fc261b..bf38fd3cc 100644 --- a/packages/sdk/src/__tests__/harness.test.ts +++ b/packages/sdk/src/__tests__/harness.test.ts @@ -38,7 +38,6 @@ describe('harness configs', () => { cli: 'opencode-server', definition: { runtime: 'headless', - driver: 'app_server', protocol: 'opencode', endpoint: 'http://127.0.0.1:4096', sessionId: 'ses_123', diff --git a/packages/sdk/src/__tests__/lifecycle-hooks.test.ts b/packages/sdk/src/__tests__/lifecycle-hooks.test.ts index 712b2f655..d388c35bc 100644 --- a/packages/sdk/src/__tests__/lifecycle-hooks.test.ts +++ b/packages/sdk/src/__tests__/lifecycle-hooks.test.ts @@ -208,7 +208,6 @@ describe('AgentRelayClient lifecycle hooks', () => { client.addListener('beforeAgentSpawn', () => ({ harnessConfig: { runtime: 'headless', - driver: 'app_server', protocol: 'opencode', endpoint: 'http://127.0.0.1:4096', sessionId: 'ses_hook', @@ -227,7 +226,6 @@ describe('AgentRelayClient lifecycle hooks', () => { transport: 'headless', harnessConfig: { runtime: 'headless', - driver: 'app_server', sessionId: 'ses_hook', }, }); diff --git a/packages/sdk/src/harness.ts b/packages/sdk/src/harness.ts index af580a4c3..18e5424ae 100644 --- a/packages/sdk/src/harness.ts +++ b/packages/sdk/src/harness.ts @@ -43,7 +43,7 @@ export interface AppServerHarnessHost { export interface HeadlessAppServerHarnessConfig { runtime: 'headless'; - driver: HeadlessHarnessDriver; + driver?: HeadlessHarnessDriver; protocol: 'opencode' | string; endpoint: string; sessionId: string; @@ -70,7 +70,7 @@ export interface StaticPtyHarnessDefinition { export interface StaticHeadlessAppServerHarnessDefinition { runtime: 'headless'; - driver: HeadlessHarnessDriver; + driver?: HeadlessHarnessDriver; protocol: 'opencode' | string; endpoint: string; sessionId: string; @@ -120,7 +120,7 @@ export function resolveStaticHarnessConfig(input: ResolveStaticHarnessInput): Re if (definition.runtime === 'headless') { return { runtime: 'headless', - driver: definition.driver, + driver: definition.driver ?? 'app_server', protocol: definition.protocol, endpoint: definition.endpoint, sessionId: definition.sessionId, diff --git a/web/content/docs/harnesses.mdx b/web/content/docs/harnesses.mdx index 981195d69..7a686702c 100644 --- a/web/content/docs/harnesses.mdx +++ b/web/content/docs/harnesses.mdx @@ -15,7 +15,8 @@ Relay supports two public runtime categories: | `headless` | Non-terminal agents such as app-server sessions | delivery and release | `app_server` is not a third runtime. It is a `headless` driver for sessions -controlled over HTTP. +controlled over HTTP. When `runtime` is `headless`, `driver` defaults to +`app_server`. ## Naming @@ -122,8 +123,8 @@ functions. ## Headless App-Server Adapter -Use a headless app-server adapter when the agent already lives in a server -session. OpenCode `serve` is the first supported protocol driver. +Use a headless adapter when the agent already lives in a server session. +OpenCode `serve` is the first supported protocol. ```typescript file="opencode-server-harness.ts" import { AgentRelay } from '@agent-relay/sdk'; @@ -132,7 +133,6 @@ const relay = new AgentRelay({ harnesses: { 'opencode-server': { runtime: 'headless', - driver: 'app_server', protocol: 'opencode', endpoint: 'http://127.0.0.1:4096', sessionId: 'ses_123', @@ -161,7 +161,6 @@ const relay = new AgentRelay({ return { runtime: 'headless', - driver: 'app_server', protocol: 'opencode', endpoint: session.endpoint, sessionId: session.id, From 4fdda79ad264412bfc725e4d22a611a78b50df21 Mon Sep 17 00:00:00 2001 From: Will Washburn Date: Mon, 25 May 2026 17:47:56 -0400 Subject: [PATCH 11/19] Add broker harness registry --- .../completed/2026-05/traj_kgl2opmmfvus.json | 25 ++ .../completed/2026-05/traj_kgl2opmmfvus.md | 14 + .trajectories/index.json | 9 +- CHANGELOG.md | 2 +- crates/broker/src/listen_api.rs | 212 ++++++++++++-- crates/broker/src/runtime/api.rs | 31 +++ crates/broker/src/runtime/event_loop.rs | 1 + crates/broker/src/runtime/init.rs | 1 + crates/broker/src/runtime/relaycast_events.rs | 185 ++++++++++++- crates/broker/src/runtime/spawn_spec.rs | 20 ++ docs/harness-runtime-config.md | 234 ++++++++-------- packages/sdk/src/__tests__/harness.test.ts | 56 ++++ packages/sdk/src/client.ts | 26 ++ packages/sdk/src/harness.ts | 20 +- packages/sdk/src/lifecycle-hooks.ts | 2 +- packages/sdk/src/relay.ts | 116 +++----- packages/sdk/src/types.ts | 2 + web/content/docs/harnesses.mdx | 261 ++++++++---------- web/content/docs/reference-broker-api.mdx | 11 +- web/content/docs/typescript-sdk.mdx | 3 + 20 files changed, 845 insertions(+), 386 deletions(-) create mode 100644 .trajectories/completed/2026-05/traj_kgl2opmmfvus.json create mode 100644 .trajectories/completed/2026-05/traj_kgl2opmmfvus.md diff --git a/.trajectories/completed/2026-05/traj_kgl2opmmfvus.json b/.trajectories/completed/2026-05/traj_kgl2opmmfvus.json new file mode 100644 index 000000000..0c83dd81d --- /dev/null +++ b/.trajectories/completed/2026-05/traj_kgl2opmmfvus.json @@ -0,0 +1,25 @@ +{ + "id": "traj_kgl2opmmfvus", + "version": 1, + "task": { + "title": "Simplify harness config PR around broker-owned configs" + }, + "status": "completed", + "startedAt": "2026-05-25T21:32:14.085Z", + "completedAt": "2026-05-25T21:47:15.455Z", + "agents": [], + "chapters": [], + "retrospective": { + "summary": "Simplified harness work around broker-executable configs: added broker harness registry APIs, SDK harnessId registration/selection, Relaycast harnessId/inline config handling, and concise docs that remove dynamic SDK resolvers.", + "approach": "Standard approach", + "confidence": 0.86 + }, + "commits": [], + "filesChanged": [], + "projectId": "/Users/will/Projects/AgentWorkforce/relay", + "tags": [], + "_trace": { + "startRef": "75f019cf5c2601ae195315ea43ae601eb39cfed7", + "endRef": "75f019cf5c2601ae195315ea43ae601eb39cfed7" + } +} diff --git a/.trajectories/completed/2026-05/traj_kgl2opmmfvus.md b/.trajectories/completed/2026-05/traj_kgl2opmmfvus.md new file mode 100644 index 000000000..ffc74890c --- /dev/null +++ b/.trajectories/completed/2026-05/traj_kgl2opmmfvus.md @@ -0,0 +1,14 @@ +# Trajectory: Simplify harness config PR around broker-owned configs + +> **Status:** ✅ Completed +> **Confidence:** 86% +> **Started:** May 25, 2026 at 05:32 PM +> **Completed:** May 25, 2026 at 05:47 PM + +--- + +## Summary + +Simplified harness work around broker-executable configs: added broker harness registry APIs, SDK harnessId registration/selection, Relaycast harnessId/inline config handling, and concise docs that remove dynamic SDK resolvers. + +**Approach:** Standard approach diff --git a/.trajectories/index.json b/.trajectories/index.json index 311e035b3..855838fe4 100644 --- a/.trajectories/index.json +++ b/.trajectories/index.json @@ -1,6 +1,6 @@ { "version": 1, - "lastUpdated": "2026-05-25T19:52:52.973Z", + "lastUpdated": "2026-05-25T21:47:15.621Z", "trajectories": { "traj_05xg7j388bc4": { "title": "Add browser workflow step integration", @@ -1170,6 +1170,13 @@ "startedAt": "2026-05-25T19:50:47.661Z", "completedAt": "2026-05-25T19:52:52.791Z", "path": ".trajectories/completed/2026-05/traj_n0qwpjvmdl2s.json" + }, + "traj_kgl2opmmfvus": { + "title": "Simplify harness config PR around broker-owned configs", + "status": "completed", + "startedAt": "2026-05-25T21:32:14.085Z", + "completedAt": "2026-05-25T21:47:15.455Z", + "path": ".trajectories/completed/2026-05/traj_kgl2opmmfvus.json" } } } diff --git a/CHANGELOG.md b/CHANGELOG.md index 9a21ecaee..2d2760cfc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,7 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - Broker and TypeScript SDK structured result contracts add the `submit_result` MCP tool, `agent.waitForResult()`, per-spawn `result.onResult`, and `relay.addListener('agentResult', ...)` for typed JSON worker outcomes. -- `@agent-relay/sdk` harness definitions resolve named agent runtimes into broker-executable `pty` or `headless` configs, so custom CLIs can be configured without Rust changes. +- `@agent-relay/sdk` and `agent-relay-broker` add broker-executable `pty` and `headless` harness configs, named in-memory harness registration, and `harnessId` spawn selection for custom CLIs without Rust changes. - `agent-relay-broker` accepts resolved harness configs on spawn and adds a headless app-server driver for delivering Relay messages to existing OpenCode server sessions. ### Changed diff --git a/crates/broker/src/listen_api.rs b/crates/broker/src/listen_api.rs index 38af2b260..5df02b821 100644 --- a/crates/broker/src/listen_api.rs +++ b/crates/broker/src/listen_api.rs @@ -50,11 +50,20 @@ pub enum ListenApiRequest { idle_threshold_secs: Option, skip_relay_prompt: bool, restart_policy: Box>, + harness_id: Option, harness_config: Option, agent_token: Option, agent_result_schema: Option, reply: tokio::sync::oneshot::Sender>, }, + RegisterHarness { + name: String, + config: ResolvedHarnessConfig, + reply: tokio::sync::oneshot::Sender>, + }, + ListHarnesses { + reply: tokio::sync::oneshot::Sender>, + }, SetModel { name: String, model: String, @@ -358,6 +367,11 @@ fn listen_api_router_with_auth( .route("/api/session", routing::get(listen_api_session)) .route("/api/session/renew", routing::post(listen_api_renew_lease)) .route("/api/spawn", routing::post(listen_api_spawn)) + .route("/api/harnesses", routing::get(listen_api_list_harnesses)) + .route( + "/api/harnesses/{name}", + routing::put(listen_api_register_harness).post(listen_api_register_harness), + ) .route("/api/spawned", routing::get(listen_api_list)) .route( "/api/spawned/{name}/model", @@ -577,6 +591,102 @@ async fn listen_api_auth_middleware( Ok(next.run(request).await) } +fn parse_harness_config_value(value: Value) -> Result { + serde_json::from_value::(value) + .map_err(|error| format!("Invalid harnessConfig: {error}")) +} + +fn extract_harness_config(body: &Value) -> Result, String> { + match body + .get("harness_config") + .or_else(|| body.get("harnessConfig")) + .or_else(|| body.get("harness_plan")) + .or_else(|| body.get("harnessPlan")) + .cloned() + { + Some(value) => parse_harness_config_value(value).map(Some), + None => Ok(None), + } +} + +async fn listen_api_register_harness( + axum::extract::State(state): axum::extract::State, + axum::extract::Path(name): axum::extract::Path, + axum::Json(body): axum::Json, +) -> (axum::http::StatusCode, axum::Json) { + let name = name.trim().to_string(); + if name.is_empty() { + return ( + axum::http::StatusCode::BAD_REQUEST, + axum::Json(json!({ "success": false, "error": "Missing required field: name" })), + ); + } + + let config_value = body + .get("config") + .or_else(|| body.get("harnessConfig")) + .or_else(|| body.get("harness_config")) + .cloned() + .unwrap_or(body); + let config = match parse_harness_config_value(config_value) { + Ok(config) => config, + Err(error) => { + return ( + axum::http::StatusCode::BAD_REQUEST, + axum::Json(json!({ "success": false, "error": error })), + ); + } + }; + + let (reply_tx, reply_rx) = tokio::sync::oneshot::channel(); + if state + .tx + .send(ListenApiRequest::RegisterHarness { + name: name.clone(), + config, + reply: reply_tx, + }) + .await + .is_err() + { + return ( + axum::http::StatusCode::INTERNAL_SERVER_ERROR, + axum::Json(json!({ "success": false, "error": "internal channel closed" })), + ); + } + + match reply_rx.await { + Ok(Ok(val)) => (axum::http::StatusCode::OK, axum::Json(val)), + Ok(Err(err)) => ( + axum::http::StatusCode::INTERNAL_SERVER_ERROR, + axum::Json(json!({ "success": false, "name": name, "error": err })), + ), + Err(_) => ( + axum::http::StatusCode::INTERNAL_SERVER_ERROR, + axum::Json(json!({ "success": false, "error": "internal reply dropped" })), + ), + } +} + +async fn listen_api_list_harnesses( + axum::extract::State(state): axum::extract::State, +) -> axum::Json { + let (reply_tx, reply_rx) = tokio::sync::oneshot::channel(); + if state + .tx + .send(ListenApiRequest::ListHarnesses { reply: reply_tx }) + .await + .is_err() + { + return axum::Json(json!({ "success": false, "harnesses": {} })); + } + + match reply_rx.await { + Ok(Ok(val)) => axum::Json(val), + _ => axum::Json(json!({ "success": false, "harnesses": {} })), + } +} + async fn listen_api_spawn( axum::extract::State(state): axum::extract::State, axum::Json(body): axum::Json, @@ -649,27 +759,34 @@ async fn listen_api_spawn( .or_else(|| body.get("restartPolicy")) .cloned(), ); - let harness_config = match body - .get("harness_config") - .or_else(|| body.get("harnessConfig")) - .or_else(|| body.get("harness_plan")) - .or_else(|| body.get("harnessPlan")) - .cloned() - { - Some(value) => match serde_json::from_value::(value) { - Ok(config) => Some(config), - Err(error) => { - return ( - axum::http::StatusCode::BAD_REQUEST, - axum::Json(json!({ - "success": false, - "error": format!("Invalid harnessConfig: {error}") - })), - ); - } - }, - None => None, + let harness_id = body + .get("harness_id") + .or_else(|| body.get("harnessId")) + .and_then(Value::as_str) + .map(str::trim) + .filter(|value| !value.is_empty()) + .map(String::from); + let harness_config = match extract_harness_config(&body) { + Ok(config) => config, + Err(error) => { + return ( + axum::http::StatusCode::BAD_REQUEST, + axum::Json(json!({ + "success": false, + "error": error + })), + ); + } }; + if harness_id.is_some() && harness_config.is_some() { + return ( + axum::http::StatusCode::BAD_REQUEST, + axum::Json(json!({ + "success": false, + "error": "provide either harnessId or harnessConfig, not both" + })), + ); + } let agent_token = body .get("agent_token") .or_else(|| body.get("agentToken")) @@ -707,6 +824,7 @@ async fn listen_api_spawn( idle_threshold_secs, skip_relay_prompt, restart_policy, + harness_id, harness_config, agent_token, agent_result_schema, @@ -2444,6 +2562,7 @@ mod auth_tests { idle_threshold_secs, skip_relay_prompt: _, restart_policy: _, + harness_id, harness_config, agent_token: _, agent_result_schema, @@ -2465,6 +2584,7 @@ mod auth_tests { assert_eq!(shadow_mode.as_deref(), Some("subagent")); assert_eq!(continue_from.as_deref(), Some("worker-prev")); assert_eq!(idle_threshold_secs, Some(30)); + assert_eq!(harness_id.as_deref(), None); assert!(harness_config.is_some()); assert_eq!( agent_result_schema, @@ -2521,6 +2641,58 @@ mod auth_tests { spawn_replier.await.expect("spawn replier should complete"); } + #[tokio::test] + async fn harness_register_route_forwards_named_config() { + let (router, mut rx) = test_router(Some("secret")); + let replier = tokio::spawn(async move { + match rx.recv().await { + Some(ListenApiRequest::RegisterHarness { + name, + config, + reply, + }) => { + assert_eq!(name, "company-claude"); + assert_eq!(config.runtime(), crate::protocol::AgentRuntime::Pty); + let _ = reply.send(Ok(json!({ + "success": true, + "name": name, + "harnessConfig": config, + }))); + } + other => panic!("unexpected request: {:?}", other.map(|_| "other")), + } + }); + + let response = router + .oneshot( + Request::builder() + .uri("/api/harnesses/company-claude") + .method("PUT") + .header("x-api-key", "secret") + .header("content-type", "application/json") + .body(Body::from( + json!({ + "harnessConfig": { + "runtime": "pty", + "command": "claude", + "args": ["--dangerously-skip-permissions"] + } + }) + .to_string(), + )) + .expect("request should build"), + ) + .await + .expect("request should succeed"); + + assert_eq!(response.status(), StatusCode::OK); + let body = response_json(response).await; + assert_eq!(body["success"], json!(true)); + assert_eq!(body["name"], json!("company-claude")); + + replier.await.expect("register replier should complete"); + } + #[tokio::test] async fn agent_result_route_accepts_callback_token_without_broker_auth() { let (router, mut rx) = test_router(Some("secret")); diff --git a/crates/broker/src/runtime/api.rs b/crates/broker/src/runtime/api.rs index ed5c397a2..32a97d7dd 100644 --- a/crates/broker/src/runtime/api.rs +++ b/crates/broker/src/runtime/api.rs @@ -19,6 +19,7 @@ impl BrokerRuntime { let pending_requests = &mut self.pending_requests; let delivery_states = &mut self.delivery_states; let agent_result_tokens = &mut self.agent_result_tokens; + let harness_configs = &mut self.harness_configs; let dedup = &mut self.dedup; let recent_thread_messages = &mut self.recent_thread_messages; let delivery_retry_interval = self.delivery_retry_interval; @@ -45,6 +46,7 @@ impl BrokerRuntime { idle_threshold_secs, skip_relay_prompt, restart_policy, + harness_id, harness_config, agent_token, agent_result_schema, @@ -55,6 +57,17 @@ impl BrokerRuntime { } else { channels.clone() }; + let harness_config = match resolve_harness_config_selection( + harness_id.as_deref(), + harness_config, + harness_configs, + ) { + Ok(config) => config, + Err(error) => { + let _ = reply.send(Err(error.to_string())); + return; + } + }; let spec = match build_http_api_spawn_spec( name.clone(), cli.clone(), @@ -388,6 +401,24 @@ impl BrokerRuntime { } } } + ListenApiRequest::RegisterHarness { + name, + config, + reply, + } => { + harness_configs.insert(name.clone(), config.clone()); + let _ = reply.send(Ok(json!({ + "success": true, + "name": name, + "harnessConfig": config, + }))); + } + ListenApiRequest::ListHarnesses { reply } => { + let _ = reply.send(Ok(json!({ + "success": true, + "harnesses": harness_configs.clone(), + }))); + } ListenApiRequest::Release { name, reason, diff --git a/crates/broker/src/runtime/event_loop.rs b/crates/broker/src/runtime/event_loop.rs index 568941bc1..8263d6d8b 100644 --- a/crates/broker/src/runtime/event_loop.rs +++ b/crates/broker/src/runtime/event_loop.rs @@ -21,6 +21,7 @@ pub(crate) struct BrokerRuntime { pub(super) worker_event_rx: mpsc::Receiver, pub(super) worker_events_open: bool, pub(super) workers: WorkerRegistry, + pub(super) harness_configs: HashMap, pub(super) crash_insights: crate::crash_insights::CrashInsights, pub(super) crash_insights_path: PathBuf, pub(super) sdk_lines: tokio::io::Lines>, diff --git a/crates/broker/src/runtime/init.rs b/crates/broker/src/runtime/init.rs index d96363e24..8f66029ca 100644 --- a/crates/broker/src/runtime/init.rs +++ b/crates/broker/src/runtime/init.rs @@ -477,6 +477,7 @@ pub(crate) async fn run_init(cmd: InitCommand, telemetry: TelemetryClient) -> Re worker_event_rx, worker_events_open: true, workers, + harness_configs: HashMap::new(), crash_insights, crash_insights_path, sdk_lines, diff --git a/crates/broker/src/runtime/relaycast_events.rs b/crates/broker/src/runtime/relaycast_events.rs index 482e085d8..cfd0295bd 100644 --- a/crates/broker/src/runtime/relaycast_events.rs +++ b/crates/broker/src/runtime/relaycast_events.rs @@ -15,6 +15,7 @@ impl BrokerRuntime { let pending_requests = &mut self.pending_requests; let delivery_states = &mut self.delivery_states; let agent_result_tokens = &mut self.agent_result_tokens; + let harness_configs = &self.harness_configs; let dm_participants_cache = &mut self.dm_participants_cache; let recent_thread_messages = &mut self.recent_thread_messages; let delivery_retry_interval = self.delivery_retry_interval; @@ -204,6 +205,30 @@ impl BrokerRuntime { let cli = event.agent.cli; let task = Some(event.agent.task).filter(|value| !value.trim().is_empty()); let channel = event.agent.channel; + let harness_config = + match relaycast_harness_config_selection(&ws_value, harness_configs) { + Ok(config) => config, + Err(error) => { + tracing::warn!( + worker = %name, + error = %error, + "rejecting relaycast spawn with invalid harness selection" + ); + eprintln!( + "[agent-relay] rejecting spawn request for '{}': {}", + name, error + ); + return; + } + }; + let runtime = harness_config + .as_ref() + .map(ResolvedHarnessConfig::runtime) + .unwrap_or(AgentRuntime::Pty); + let session_id = harness_config + .as_ref() + .and_then(ResolvedHarnessConfig::session_id) + .map(ToOwned::to_owned); tracing::info!(name = %name, cli = %cli, task = ?task, channel = ?channel, "handling spawn request from relaycast WS"); let channels = channel @@ -218,11 +243,11 @@ impl BrokerRuntime { .unwrap_or_else(default_spawn_channels); let spec = AgentSpec { name: name.clone(), - runtime: AgentRuntime::Pty, + runtime: runtime.clone(), provider: None, cli: Some(cli.clone()), - session_id: None, - harness_config: None, + session_id, + harness_config, model: None, cwd: None, team: None, @@ -311,7 +336,7 @@ impl BrokerRuntime { state.agents.insert( name.clone(), broker::PersistedAgent { - runtime: AgentRuntime::Pty, + runtime: effective_spec.runtime.clone(), parent: Some("Relaycast".to_string()), channels, pid: workers.worker_pid(&name), @@ -334,7 +359,7 @@ impl BrokerRuntime { json!({ "kind": "agent_spawned", "name": name, - "runtime": "pty", + "runtime": runtime_label(&effective_spec.runtime), "cli": cli, "model": effective_spec.model.clone(), "pid": pid, @@ -428,13 +453,39 @@ impl BrokerRuntime { chs }) .unwrap_or_else(default_spawn_channels); + let harness_config = match relaycast_harness_config_selection( + &ws_value, + harness_configs, + ) { + Ok(config) => config, + Err(error) => { + tracing::warn!( + worker = %name, + error = %error, + "rejecting relaycast fallback spawn with invalid harness selection" + ); + eprintln!( + "[agent-relay] rejecting spawn request for '{}': {}", + name, error + ); + return; + } + }; + let runtime = harness_config + .as_ref() + .map(ResolvedHarnessConfig::runtime) + .unwrap_or(AgentRuntime::Pty); + let session_id = harness_config + .as_ref() + .and_then(ResolvedHarnessConfig::session_id) + .map(ToOwned::to_owned); let spec = AgentSpec { name: name.clone(), - runtime: AgentRuntime::Pty, + runtime: runtime.clone(), provider: None, cli: Some(cli.clone()), - session_id: None, - harness_config: None, + session_id, + harness_config, model: None, cwd: None, team: None, @@ -507,7 +558,7 @@ impl BrokerRuntime { state.agents.insert( name.clone(), broker::PersistedAgent { - runtime: AgentRuntime::Pty, + runtime: effective_spec.runtime.clone(), parent: Some("Relaycast".to_string()), channels, pid: workers.worker_pid(&name), @@ -530,7 +581,7 @@ impl BrokerRuntime { json!({ "kind": "agent_spawned", "name": name, - "runtime": "pty", + "runtime": runtime_label(&effective_spec.runtime), "cli": cli, "model": effective_spec.model.clone(), "pid": pid, @@ -881,3 +932,117 @@ impl BrokerRuntime { } } } + +fn relaycast_harness_id(value: &Value) -> Option { + let agent = value.get("agent"); + agent + .and_then(|agent| { + agent + .get("harnessId") + .or_else(|| agent.get("harness_id")) + .and_then(Value::as_str) + }) + .or_else(|| { + value + .get("harnessId") + .or_else(|| value.get("harness_id")) + .and_then(Value::as_str) + }) + .map(str::trim) + .filter(|id| !id.is_empty()) + .map(ToOwned::to_owned) +} + +fn relaycast_harness_config(value: &Value) -> Result, String> { + let agent = value.get("agent"); + let raw = agent + .and_then(|agent| { + agent + .get("harnessConfig") + .or_else(|| agent.get("harness_config")) + }) + .or_else(|| { + value + .get("harnessConfig") + .or_else(|| value.get("harness_config")) + }); + + match raw { + Some(config) => serde_json::from_value::(config.clone()) + .map(Some) + .map_err(|error| format!("Invalid harnessConfig: {error}")), + None => Ok(None), + } +} + +fn relaycast_harness_config_selection( + value: &Value, + registry: &HashMap, +) -> Result, String> { + let harness_id = relaycast_harness_id(value); + let harness_config = relaycast_harness_config(value)?; + resolve_harness_config_selection(harness_id.as_deref(), harness_config, registry) + .map_err(|error| error.to_string()) +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::protocol::PtyHarnessConfig; + + fn pty_config(command: &str) -> ResolvedHarnessConfig { + ResolvedHarnessConfig::Pty(PtyHarnessConfig { + command: command.to_string(), + args: vec![], + cwd: None, + env: None, + session_id: None, + delivery: None, + metadata: None, + }) + } + + #[test] + fn relaycast_harness_selection_resolves_agent_harness_id() { + let mut registry = HashMap::new(); + registry.insert("company-claude".to_string(), pty_config("claude")); + let value = json!({ + "type": "agent.spawn_requested", + "agent": { + "name": "ClaudeReviewer", + "cli": "company-claude", + "harnessId": "company-claude" + } + }); + + let config = relaycast_harness_config_selection(&value, ®istry) + .expect("selection should resolve") + .expect("selection should return config"); + + assert_eq!(config.runtime(), AgentRuntime::Pty); + } + + #[test] + fn relaycast_harness_selection_rejects_both_id_and_inline_config() { + let mut registry = HashMap::new(); + registry.insert("company-claude".to_string(), pty_config("claude")); + let value = json!({ + "type": "agent.spawn_requested", + "agent": { + "name": "ClaudeReviewer", + "cli": "company-claude", + "harnessId": "company-claude", + "harnessConfig": { + "runtime": "pty", + "command": "claude", + "args": [] + } + } + }); + + let error = relaycast_harness_config_selection(&value, ®istry) + .expect_err("conflicting selection should fail"); + + assert!(error.contains("provide either harnessId or harnessConfig")); + } +} diff --git a/crates/broker/src/runtime/spawn_spec.rs b/crates/broker/src/runtime/spawn_spec.rs index 7afe8dc07..720de5e24 100644 --- a/crates/broker/src/runtime/spawn_spec.rs +++ b/crates/broker/src/runtime/spawn_spec.rs @@ -7,6 +7,26 @@ pub(crate) fn runtime_label(runtime: &AgentRuntime) -> &'static str { } } +pub(crate) fn resolve_harness_config_selection( + harness_id: Option<&str>, + harness_config: Option, + registry: &HashMap, +) -> Result> { + let harness_id = harness_id.map(str::trim).filter(|value| !value.is_empty()); + + match (harness_id, harness_config) { + (Some(_), Some(_)) => { + anyhow::bail!("provide either harnessId or harnessConfig, not both") + } + (Some(id), None) => registry + .get(id) + .cloned() + .map(Some) + .with_context(|| format!("unknown harnessId '{id}'")), + (None, config) => Ok(config), + } +} + #[allow(clippy::too_many_arguments)] pub(crate) fn build_http_api_spawn_spec( name: String, diff --git a/docs/harness-runtime-config.md b/docs/harness-runtime-config.md index 880914261..6f888eaa6 100644 --- a/docs/harness-runtime-config.md +++ b/docs/harness-runtime-config.md @@ -3,9 +3,9 @@ ## Goal Harnesses should be user-extensible without requiring Rust changes for normal -agent CLIs. The Rust broker should own durable runtime execution, lifecycle -tracking, routing, delivery queues, retries, and observability. SDKs should be -able to define named harnesses that resolve to broker-executable JSON configs. +agent CLIs. The durable boundary is data: the Rust broker validates and executes +`HarnessConfig` objects. SDKs may help users build those objects, but the broker +does not call back into SDK-defined functions after the SDK process exits. ## Core Model @@ -14,25 +14,16 @@ The broker has two public runtime categories: - `pty`: runs a command inside a PTY and manages terminal-oriented delivery. - `headless`: controls a non-terminal agent through a driver. -The first headless drivers are: - -- `provider_command`: the existing broker-owned one-shot headless path for - built-in providers such as Claude and OpenCode. -- `app_server`: a session-backed HTTP driver for attached agent servers. - -Named harnesses such as `codex`, `claude`, or `opencode-server` resolve to one of -those executable configs. `driver` defaults to `app_server` when `runtime` is +The first headless driver is `app_server`, used for session-backed HTTP agents +such as OpenCode. `driver` defaults to `app_server` when `runtime` is `headless`. -## Naming +Names in this design: -- A harness definition is the static or dynamic value registered by the SDK. -- A harness resolver is a dynamic SDK function that receives spawn context. - A harness config is the concrete `pty` or `headless` object the broker runs. -- `harnessConfig` is the spawn field for a one-off concrete config. - -This keeps ownership clear: SDKs resolve definitions into configs, and the -broker executes configs durably. +- A harness adapter is SDK/userland code that returns a harness config. +- `harnessId` references a config in the broker's in-memory registry. +- `harnessConfig` is the spawn field for sending a one-off concrete config. ## Config Shapes @@ -54,8 +45,7 @@ type PtyHarnessConfig = { }; ``` -Headless app-server configs are session backed. They are still `headless` workers; -`driver: 'app_server'` explains how the broker talks to the worker: +Headless app-server configs are session backed: ```ts type HeadlessAppServerHarnessConfig = { @@ -79,83 +69,121 @@ type HeadlessAppServerHarnessConfig = { }; ``` -The broker runs the returned config. It does not need to understand arbitrary -TypeScript or Python logic. +For now, `app_server` configs are attach-only. `host.ownership: +'broker-owned'` is reserved and rejected until the broker owns app-server +lifecycle supervision. When `host.pid` is provided, the broker reports that as +the harness PID. -For now, `app_server` configs are attach-only. `host.ownership: 'broker-owned'` -is reserved and rejected until the broker owns app-server lifecycle supervision. -When `host.pid` is provided, the broker reports that as the harness PID. +Config `env` and `auth` values are visible to the broker. Adapters should return +explicit allowlists instead of copying whole process environments. -Config `env` and `auth` values are visible to the broker and may be included in -runtime state. SDK resolvers should return explicit allowlists and avoid copying -the whole process environment. +## SDK Adapters -## Harness Definition Classes - -Static harness definitions are JSON-compatible and work in attached or detached -brokers: +An SDK adapter is a helper that returns data: ```ts -const harnesses = { - 'company-claude': { +function companyClaude(): ResolvedHarnessConfig { + return { runtime: 'pty', command: 'claude', - args: [ - '--dangerously-skip-permissions', - '--append-system-prompt', - 'Follow the company review rubric.', - '{modelArgs}', - '{args}', - ], - modelArgs: ['--model', '{model}'], + args: ['--dangerously-skip-permissions', '--append-system-prompt', 'Follow the company review rubric.'], + }; +} +``` + +Register stable configs by name: + +```ts +const relay = new AgentRelay({ + harnesses: { + 'company-claude': companyClaude(), }, -}; +}); ``` -Custom PTY harnesses own their CLI flags. Broker built-in permission bypass -defaults are not injected into caller-provided harness configs. +The SDK registers those configs with the broker's in-memory registry on start. +Future spawns can use `harnessId: 'company-claude'`. -Dynamic harness resolvers are SDK functions and are attached-only. They can run -pre-spawn logic, such as creating a provider session, then return a concrete -config: +Use inline configs for per-spawn setup: ```ts -const harnesses = { - codex: async (ctx) => { - const sessionId = await createCodexSession(ctx); - return { - runtime: 'pty', - command: 'codex', - args: ['resume', sessionId, ...ctx.args], - env: { - PATH: ctx.env.PATH ?? '', - CODEX_HOME: ctx.env.CODEX_HOME ?? '', - }, - sessionId, - }; +const sessionId = await createCodexSession({ cwd, task }); + +await relay.spawn('CodexReviewer', 'codex', task, { + harnessConfig: { + runtime: 'pty', + command: 'codex', + args: ['resume', sessionId], + cwd, + sessionId, }, -}; +}); ``` -Detached brokers must reject dynamic in-process resolvers because the SDK -process may exit while the broker and agents continue. +This avoids pretending that SDK callbacks are durable. If the SDK process exits, +the broker can still execute registered or inline configs because it already has +the data. -## Broker Lifetime +## Broker Registry -Broker lifetime should be explicit: +The broker keeps an in-memory map: ```ts -broker: { - lifetime: 'attached' | 'detached'; +Record; +``` + +HTTP/SDK API: + +- `PUT /api/harnesses/:name` registers or replaces a config. +- `GET /api/harnesses` lists registered configs. +- `POST /api/spawn` accepts either `harnessId` or `harnessConfig`. + +Resolution rules: + +- `harnessConfig` is already concrete and runs as supplied. +- `harnessId` resolves against the receiving broker's registry. +- Providing both is rejected. +- Unknown `harnessId` is rejected. + +Registry state is intentionally runtime-local for now. In multi-broker +environments, use inline `harnessConfig` or ensure every broker registers the +same named configs before agents send `harnessId` spawns. + +## Relaycast Spawns + +Agent-crafted Relaycast spawns can send a registry reference: + +```json +{ + "agent": { + "name": "ClaudeReviewer", + "cli": "company-claude", + "task": "Review the current diff.", + "harnessId": "company-claude" + } } ``` -Attached brokers are owned by the SDK process. Dynamic resolvers and in-process -decision hooks are allowed because the broker exits if the SDK control -connection exits. +Or a portable inline config: + +```json +{ + "agent": { + "name": "CodexReviewer", + "cli": "codex", + "task": "Review the current diff.", + "harnessConfig": { + "runtime": "pty", + "command": "codex", + "args": ["resume", "session_123"], + "sessionId": "session_123" + } + } +} +``` -Detached brokers survive SDK callers. They only accept static harness configs, -built-in Rust adapters, and durable extension hosts. +The broker validates the selected config and then uses the same spawn path as +SDK-submitted configs. ## Broker Responsibilities @@ -169,62 +197,26 @@ The broker owns: - Capability checks for PTY-only routes. - Event emission, metrics, logs, and replay buffers. -The broker does not own custom user logic unless that logic is built into Rust. +The broker does not own arbitrary user logic unless that logic is built into +Rust or represented as validated config data. -## PTY Runtime +## Runtime Notes The PTY executor consumes a concrete PTY config. It handles process spawn, terminal streaming, raw input, resize, snapshot, release, and PTY message injection. -This lets users add a CLI wrapper locally with config only. A Rust -contribution is only needed when Relay wants a built-in with tested defaults or -the CLI needs broker-side behavior. - -## Headless Runtime - The headless runtime covers non-PTY workers. Provider-command headless workers -run a command per delivery, for example `claude -p` or `opencode run`. -App-server headless workers attach to a session server instead. - -For OpenCode app-server harnesses, the SDK creates or selects a session and -returns its endpoint and session id. The broker attaches to that local or remote -`opencode serve` endpoint, delivers Relay messages through the session message -API, and releases by aborting, detaching, or deleting the session. - -Headless runtimes do not expose PTY input, resize, or snapshot capabilities. - -## Hooks - -Event hooks are non-blocking subscriptions: - -```ts -relay.addListener('agentSpawned', async (agent) => { - await posthog.capture({ - distinctId: agent.name, - event: 'agent_spawned', - properties: { runtime: agent.runtime }, - }); -}); -``` - -Decision hooks are request-response calls over an attached SDK control -connection: - -- `resolveHarnessConfig` -- `beforeSpawn` -- `authorizeSpawn` - -Detached brokers must use static config, built-in sinks, HTTP webhooks, or a -durable extension host for decision-making. +remain the built-in path for existing providers. App-server headless workers +attach to a session server instead. Headless runtimes do not expose PTY input, +resize, or snapshot capabilities. ## Implementation Phases 1. Add shared config schema and SDK types. -2. Add static SDK harness resolution to PTY configs. -3. Teach the broker to accept and execute resolved PTY configs. -4. Add a headless app-server config path with an OpenCode protocol driver. -5. Add capability-aware runtime checks for PTY-only operations. -6. Add attached broker control RPCs for dynamic resolvers. -7. Add detached-mode validation for dynamic resolvers and in-process decision hooks. -8. Document static Claude, dynamic Codex, and OpenCode headless app-server examples. +2. Teach the broker to accept and execute resolved PTY configs. +3. Add a headless app-server config path with an OpenCode protocol driver. +4. Add an in-memory broker harness registry and `harnessId` spawn selection. +5. Allow Relaycast spawn events to carry `harnessId` or inline `harnessConfig`. +6. Add capability-aware runtime checks for PTY-only operations. +7. Document Claude PTY, Codex inline PTY, and OpenCode headless examples. diff --git a/packages/sdk/src/__tests__/harness.test.ts b/packages/sdk/src/__tests__/harness.test.ts index bf38fd3cc..fe14d292a 100644 --- a/packages/sdk/src/__tests__/harness.test.ts +++ b/packages/sdk/src/__tests__/harness.test.ts @@ -109,4 +109,60 @@ describe('harness configs', () => { }, }); }); + + it('serializes harness ids on spawn requests', async () => { + const captures: unknown[] = []; + const fetchFn = vi.fn(async (_url: string | URL | Request, init?: RequestInit) => { + captures.push(JSON.parse(String(init?.body ?? '{}'))); + return new Response(JSON.stringify({ name: 'ClaudeReviewer', runtime: 'pty' }), { + status: 200, + headers: { 'Content-Type': 'application/json' }, + }); + }); + + const client = new AgentRelayClient({ baseUrl: 'http://broker.test', apiKey: 'k', fetch: fetchFn }); + await client.spawnPty({ + name: 'ClaudeReviewer', + cli: 'company-claude', + harnessId: 'company-claude', + }); + + expect(captures[0]).toMatchObject({ + name: 'ClaudeReviewer', + cli: 'company-claude', + harnessId: 'company-claude', + }); + }); + + it('registers named harness configs with the broker', async () => { + const calls: Array<{ url: string; body: unknown }> = []; + const fetchFn = vi.fn(async (url: string | URL | Request, init?: RequestInit) => { + calls.push({ + url: String(url), + body: JSON.parse(String(init?.body ?? '{}')), + }); + return new Response(JSON.stringify({ success: true, name: 'company-claude' }), { + status: 200, + headers: { 'Content-Type': 'application/json' }, + }); + }); + + const client = new AgentRelayClient({ baseUrl: 'http://broker.test', apiKey: 'k', fetch: fetchFn }); + await client.registerHarness('company-claude', { + runtime: 'pty', + command: 'claude', + args: ['--dangerously-skip-permissions'], + }); + + expect(calls[0]).toMatchObject({ + url: 'http://broker.test/api/harnesses/company-claude', + body: { + harnessConfig: { + runtime: 'pty', + command: 'claude', + args: ['--dangerously-skip-permissions'], + }, + }, + }); + }); }); diff --git a/packages/sdk/src/client.ts b/packages/sdk/src/client.ts index 2cf89ebf4..c58a94eee 100644 --- a/packages/sdk/src/client.ts +++ b/packages/sdk/src/client.ts @@ -52,6 +52,7 @@ import type { BeforeAgentSpawnHandler, SpawnPatch, } from './lifecycle-hooks.js'; +import type { ResolvedHarnessConfig } from './harness.js'; // ── Types ────────────────────────────────────────────────────────────── @@ -177,6 +178,7 @@ function buildSpawnPtyBody(input: SpawnPtyInput): Record { ...(input.shadowOf !== undefined ? { shadowOf: input.shadowOf } : {}), ...(input.shadowMode !== undefined ? { shadowMode: input.shadowMode } : {}), ...(input.continueFrom !== undefined ? { continueFrom: input.continueFrom } : {}), + ...(input.harnessId !== undefined ? { harnessId: input.harnessId } : {}), ...(input.harnessConfig !== undefined ? { harnessConfig: input.harnessConfig } : {}), ...(input.idleThresholdSecs !== undefined ? { idleThresholdSecs: input.idleThresholdSecs } : {}), ...(input.restartPolicy !== undefined ? { restartPolicy: input.restartPolicy } : {}), @@ -202,6 +204,7 @@ function buildSpawnProviderBody( ...(input.shadowOf !== undefined ? { shadowOf: input.shadowOf } : {}), ...(input.shadowMode !== undefined ? { shadowMode: input.shadowMode } : {}), ...(input.continueFrom !== undefined ? { continueFrom: input.continueFrom } : {}), + ...(input.harnessId !== undefined ? { harnessId: input.harnessId } : {}), ...(input.harnessConfig !== undefined ? { harnessConfig: input.harnessConfig } : {}), ...(input.idleThresholdSecs !== undefined ? { idleThresholdSecs: input.idleThresholdSecs } : {}), ...(input.restartPolicy !== undefined ? { restartPolicy: input.restartPolicy } : {}), @@ -587,6 +590,28 @@ export class AgentRelayClient { return this.transport.getLastEvent(kind, name); } + async registerHarness(name: string, harnessConfig: ResolvedHarnessConfig): Promise { + const key = name.trim(); + if (!key) { + throw new Error('registerHarness() expects a non-empty harness name'); + } + await this.transport.request<{ success: boolean; name: string }>( + `/api/harnesses/${encodeURIComponent(key)}`, + { + method: 'PUT', + body: JSON.stringify({ harnessConfig }), + } + ); + } + + async listHarnesses(): Promise> { + const result = await this.transport.request<{ + success: boolean; + harnesses?: Record; + }>('/api/harnesses', { method: 'GET' }); + return result.harnesses ?? {}; + } + // ── Agent lifecycle ──────────────────────────────────────────────── async spawnPty(input: SpawnPtyInput): Promise { @@ -626,6 +651,7 @@ export class AgentRelayClient { if ( transport === 'headless' && !isHeadlessProvider(resolvedInput.provider) && + !resolvedInput.harnessId && !resolvedInput.harnessConfig ) { throw new Error( diff --git a/packages/sdk/src/harness.ts b/packages/sdk/src/harness.ts index 18e5424ae..a94104ab4 100644 --- a/packages/sdk/src/harness.ts +++ b/packages/sdk/src/harness.ts @@ -81,21 +81,7 @@ export interface StaticHeadlessAppServerHarnessDefinition { } export type StaticHarnessDefinition = StaticPtyHarnessDefinition | StaticHeadlessAppServerHarnessDefinition; - -export interface HarnessResolveContext { - name: string; - cli: string; - task?: string; - args: string[]; - model?: string; - cwd?: string; - env: Record; -} - -export type AttachedHarnessResolver = ( - context: HarnessResolveContext -) => ResolvedHarnessConfig | Promise; -export type HarnessDefinition = StaticHarnessDefinition | AttachedHarnessResolver; +export type HarnessDefinition = StaticHarnessDefinition; export interface ResolveStaticHarnessInput { name: string; @@ -111,10 +97,6 @@ export interface ResolveStaticHarnessInput { const DEFAULT_PTY_ARGS = ['{args}'] as const; const DEFAULT_MODEL_ARGS = ['--model', '{model}'] as const; -export function isAttachedHarnessResolver(value: HarnessDefinition): value is AttachedHarnessResolver { - return typeof value === 'function'; -} - export function resolveStaticHarnessConfig(input: ResolveStaticHarnessInput): ResolvedHarnessConfig { const { definition } = input; if (definition.runtime === 'headless') { diff --git a/packages/sdk/src/lifecycle-hooks.ts b/packages/sdk/src/lifecycle-hooks.ts index b21e4fabc..8bae0a360 100644 --- a/packages/sdk/src/lifecycle-hooks.ts +++ b/packages/sdk/src/lifecycle-hooks.ts @@ -54,7 +54,7 @@ import type { SpawnAgentResult, SpawnPtyInput, SpawnProviderInput } from './type export type SpawnPatch = Partial< Pick< SpawnPtyInput & SpawnProviderInput, - 'args' | 'channels' | 'task' | 'model' | 'team' | 'agentToken' | 'harnessConfig' + 'args' | 'channels' | 'task' | 'model' | 'team' | 'agentToken' | 'harnessId' | 'harnessConfig' > >; diff --git a/packages/sdk/src/relay.ts b/packages/sdk/src/relay.ts index 93970f870..afd017653 100644 --- a/packages/sdk/src/relay.ts +++ b/packages/sdk/src/relay.ts @@ -35,7 +35,6 @@ import { AgentRelayClient, type AgentRelayBrokerInitArgs, type AgentRelaySpawnOp import { EventBus } from './event-bus.js'; import { harnessLookupKeys, - isAttachedHarnessResolver, resolveStaticHarnessConfig, type HarnessDefinition, type ResolvedHarnessConfig, @@ -289,6 +288,7 @@ export interface SpawnOptions extends SpawnLifecycleHook shadowMode?: string; idleThresholdSecs?: number; restartPolicy?: RestartPolicy; + harnessId?: string; harnessConfig?: ResolvedHarnessConfig; /** Optional pre-minted relaycast agent token (`at_live_`, from * `registerAgent(workspaceKey, name)` in `@agent-relay/sdk/http`). The @@ -416,6 +416,7 @@ export interface SpawnerSpawnOptions extends SpawnLifecy model?: string; cwd?: string; idleThresholdSecs?: number; + harnessId?: string; harnessConfig?: ResolvedHarnessConfig; /** Optional pre-minted relaycast agent token (`at_live_`, from * `registerAgent(workspaceKey, name)` in `@agent-relay/sdk/http`). The @@ -471,11 +472,11 @@ export interface AgentRelayOptions { */ personaDirs?: string[]; /** - * Named harness definitions. Static definitions resolve to broker-executable - * JSON configs; function resolvers are only valid for attached brokers. + * Named harness definitions. Definitions are rendered to broker-executable + * configs and stored in the broker's in-memory harness registry. */ harnesses?: Record; - /** Broker lifetime boundary for dynamic harness resolvers and hooks. */ + /** Broker lifetime. Ephemeral attached brokers shut down when the SDK lease expires. */ broker?: { lifetime?: 'attached' | 'detached'; }; @@ -598,7 +599,6 @@ export class AgentRelay { private readonly relaycastBaseUrl?: string; private readonly defaultPersonaDirs?: string[]; private readonly harnesses: Record; - private readonly brokerLifetime: 'attached' | 'detached'; private relayApiKey?: string; private resolvedWorkspaceId?: string; private client?: AgentRelayClient; @@ -642,7 +642,6 @@ export class AgentRelay { this.relaycastBaseUrl = options.relaycastBaseUrl; if (options.personaDirs) this.defaultPersonaDirs = [...options.personaDirs]; this.harnesses = { ...(options.harnesses ?? {}) }; - this.brokerLifetime = options.broker?.lifetime ?? 'attached'; this.clientOptions = { binaryPath: options.binaryPath, binaryArgs: options.binaryArgs, @@ -742,71 +741,47 @@ export class AgentRelay { ); } - registerHarness(name: string, definition: HarnessDefinition): void { + async registerHarness(name: string, definition: HarnessDefinition): Promise { const key = name.trim(); if (!key) { throw new Error('registerHarness() expects a non-empty harness name'); } this.harnesses[key] = definition; + if (this.client) { + await this.client.registerHarness(key, this.resolveRegisteredHarnessConfig(key, definition)); + } } - private findHarnessDefinition(cli: string): HarnessDefinition | undefined { + private findHarnessDefinition(cli: string): { id: string; definition: HarnessDefinition } | undefined { for (const key of harnessLookupKeys(cli)) { const definition = this.harnesses[key]; - if (definition) return definition; + if (definition) return { id: key, definition }; } return undefined; } - private buildHarnessContext(input: SpawnPtyInput): { - name: string; - cli: string; - task?: string; - args: string[]; - model?: string; - cwd?: string; - env: Record; - } { - const envSource = this.clientOptions.env ?? process.env; - const env: Record = {}; - for (const [key, value] of Object.entries(envSource)) { - if (value !== undefined) env[key] = String(value); - } - return { - name: input.name, - cli: input.cli, - task: input.task, - args: input.args ?? [], - model: input.model, - cwd: input.cwd ?? this.clientOptions.cwd ?? process.cwd(), - env, - }; + private resolveRegisteredHarnessConfig(name: string, definition: HarnessDefinition): ResolvedHarnessConfig { + return resolveStaticHarnessConfig({ + name, + cli: name, + definition, + }); } - private async resolveHarnessConfig(input: SpawnPtyInput): Promise { - if (input.harnessConfig) return input.harnessConfig; - const definition = this.findHarnessDefinition(input.cli); - if (!definition) return undefined; + private resolveHarnessId(input: { + cli: string; + harnessId?: string; + harnessConfig?: ResolvedHarnessConfig; + }): string | undefined { + if (input.harnessConfig) return undefined; + if (input.harnessId) return input.harnessId; + return this.findHarnessDefinition(input.cli)?.id; + } - const context = this.buildHarnessContext(input); - if (isAttachedHarnessResolver(definition)) { - if (this.brokerLifetime !== 'attached') { - throw new Error( - `Harness '${input.cli}' uses a dynamic resolver, which requires broker.lifetime = 'attached'` - ); - } - return definition(context); + private async syncHarnessRegistry(client: AgentRelayClient): Promise { + for (const [name, definition] of Object.entries(this.harnesses)) { + await client.registerHarness(name, this.resolveRegisteredHarnessConfig(name, definition)); } - - return resolveStaticHarnessConfig({ - name: context.name, - cli: context.cli, - definition, - args: context.args, - task: context.task, - model: context.model, - cwd: context.cwd, - }); } private applyWorkspaceEnv(workspaceId: string, apiKey: string): void { @@ -881,7 +856,7 @@ export class AgentRelay { this.resultContracts.set(input.name, resultContract as InternalAgentResultContract); } try { - const harnessConfig = await this.resolveHarnessConfig(input); + const harnessId = this.resolveHarnessId(input); result = await client.spawnPty({ name: input.name, cli: input.cli, @@ -896,7 +871,8 @@ export class AgentRelay { shadowMode: input.shadowMode, idleThresholdSecs: input.idleThresholdSecs, restartPolicy: input.restartPolicy, - harnessConfig, + harnessId, + harnessConfig: input.harnessConfig, skipRelayPrompt: input.skipRelayPrompt, agentResultSchema: resultContract?.jsonSchema, }); @@ -957,6 +933,7 @@ export class AgentRelay { shadowMode: options?.shadowMode, idleThresholdSecs: options?.idleThresholdSecs, restartPolicy: options?.restartPolicy, + harnessId: options?.harnessId, harnessConfig: options?.harnessConfig, skipRelayPrompt: options?.skipRelayPrompt, result: options?.result, @@ -1042,6 +1019,7 @@ export class AgentRelay { shadowMode: options.shadowMode, idleThresholdSecs: options.idleThresholdSecs, restartPolicy: options.restartPolicy, + harnessId: options.harnessId, harnessConfig: options.harnessConfig, skipRelayPrompt: options.skipRelayPrompt, result: options.result, @@ -1741,7 +1719,7 @@ export class AgentRelay { }, }) ) - .then((c) => { + .then(async (c) => { // Use the workspace key the broker actually connected with. // This ensures SDK and workers are always on the same workspace. if (c.workspaceKey) { @@ -1756,6 +1734,7 @@ export class AgentRelay { } } } + await this.syncHarnessRegistry(c); this.wireEvents(c); this.client = c; this.startPromise = undefined; @@ -2366,6 +2345,7 @@ export class AgentRelay { model: options?.model, cwd: options?.cwd, idleThresholdSecs: options?.idleThresholdSecs, + harnessId: options?.harnessId, harnessConfig: options?.harnessConfig, agentToken: options?.agentToken, skipRelayPrompt: options?.skipRelayPrompt, @@ -2390,28 +2370,24 @@ export class AgentRelay { this.resultContracts.set(name, resultContract as InternalAgentResultContract); } try { - const harnessConfig = - options?.harnessConfig ?? - (await this.resolveHarnessConfig({ - name, - cli, - args, - channels, - task, - model: options?.model, - cwd: options?.cwd, - })); + const harnessEntry = options?.harnessConfig ? undefined : this.findHarnessDefinition(cli); + const harnessId = options?.harnessId ?? harnessEntry?.id; + const registeredHarnessConfig = harnessEntry + ? this.resolveRegisteredHarnessConfig(harnessEntry.id, harnessEntry.definition) + : undefined; + const transport = options?.harnessConfig?.runtime ?? registeredHarnessConfig?.runtime ?? 'headless'; result = await client.spawnProvider({ name, provider: cli as HeadlessProvider, - transport: harnessConfig?.runtime ?? 'headless', + transport, args, channels, task, model: options?.model, cwd: options?.cwd, idleThresholdSecs: options?.idleThresholdSecs, - harnessConfig, + harnessId, + harnessConfig: options?.harnessConfig, agentToken: options?.agentToken, skipRelayPrompt: options?.skipRelayPrompt, agentResultSchema: resultContract?.jsonSchema, diff --git a/packages/sdk/src/types.ts b/packages/sdk/src/types.ts index 983eaba76..df9d78b07 100644 --- a/packages/sdk/src/types.ts +++ b/packages/sdk/src/types.ts @@ -26,6 +26,7 @@ export interface SpawnPtyInput { shadowMode?: string; idleThresholdSecs?: number; restartPolicy?: RestartPolicy; + harnessId?: string; continueFrom?: string; harnessConfig?: ResolvedHarnessConfig; skipRelayPrompt?: boolean; @@ -81,6 +82,7 @@ export interface SpawnProviderInput { shadowMode?: string; idleThresholdSecs?: number; restartPolicy?: RestartPolicy; + harnessId?: string; continueFrom?: string; harnessConfig?: ResolvedHarnessConfig; skipRelayPrompt?: boolean; diff --git a/web/content/docs/harnesses.mdx b/web/content/docs/harnesses.mdx index 7a686702c..852d72974 100644 --- a/web/content/docs/harnesses.mdx +++ b/web/content/docs/harnesses.mdx @@ -1,198 +1,179 @@ --- title: Harnesses -description: Define custom PTY and headless harness adapters in the SDK. +description: Define custom PTY and headless harness configs in the SDK. --- -A harness adapter is a named SDK definition that turns `relay.spawn(...)` into a -broker-executable harness config. The broker only runs durable configs; SDK code -can prepare those configs before spawn. +A harness is the thing Relay controls for an agent. The broker only executes +serializable `HarnessConfig` data. SDK "adapters" should be small helpers that +return configs; they are not durable callback code that the broker calls later. -Relay supports two public runtime categories: +Relay supports two runtime categories: -| Runtime | Use For | Broker Capabilities | +| Runtime | Use for | Broker capabilities | | --- | --- | --- | | `pty` | Terminal-backed CLIs such as Codex or Claude Code | stream, input, resize, snapshot, delivery, release | -| `headless` | Non-terminal agents such as app-server sessions | delivery and release | +| `headless` | Non-terminal sessions such as OpenCode app-server | delivery, release | -`app_server` is not a third runtime. It is a `headless` driver for sessions -controlled over HTTP. When `runtime` is `headless`, `driver` defaults to -`app_server`. +When `runtime` is `headless`, `driver` defaults to `app_server`. ## Naming -Use these names when building or reading harness code: - | Name | Meaning | | --- | --- | -| Harness definition | The value registered in `new AgentRelay({ harnesses })` | -| Harness resolver | A dynamic function that receives spawn context | -| Harness config | The concrete `pty` or `headless` object returned by a definition or resolver | -| `harnessConfig` | The one-off spawn field for passing a concrete config directly | +| Harness config | Concrete `pty` or `headless` JSON the broker can validate and run | +| Harness adapter | SDK helper that returns a harness config | +| `harnessId` | Name of a config stored in the broker's in-memory harness registry | +| `harnessConfig` | One-off config sent directly on a spawn | -The broker runs harness configs. It does not run SDK resolver functions or -placeholder templates. +Use `harnessId` when every relevant broker has the same named config registered. +Use inline `harnessConfig` when the spawn must be portable across brokers. -## Static PTY Adapter +## Claude PTY Config -Use a static adapter when a CLI only needs a command, args, env, and optional -model mapping. Static adapters are JSON-compatible and work with attached or -detached brokers. +Register a named config when the command is stable across spawns: ```typescript file="claude-harness.ts" -import { AgentRelay } from '@agent-relay/sdk'; +import { AgentRelay, type ResolvedHarnessConfig } from '@agent-relay/sdk'; + +function companyClaude(): ResolvedHarnessConfig { + return { + runtime: 'pty', + command: 'claude', + args: [ + '--dangerously-skip-permissions', + '--append-system-prompt', + 'Follow the company review rubric.', + ], + env: { + CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC: '1', + }, + }; +} const relay = new AgentRelay({ harnesses: { - 'company-claude': { - runtime: 'pty', - command: 'claude', - args: [ - '--dangerously-skip-permissions', - '--append-system-prompt', - 'Follow the company review rubric.', - '{modelArgs}', - '{args}', - ], - modelArgs: ['--model', '{model}'], - env: { - CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC: '1', - }, - }, + 'company-claude': companyClaude(), }, }); -await relay.spawn('ClaudeReviewer', 'company-claude', 'Review the current diff.', { - model: 'opus', - args: ['--verbose'], -}); +await relay.spawn('ClaudeReviewer', 'company-claude', 'Review the current diff.'); ``` -When you provide a PTY harness config, Relay runs that config as written. Built-in -CLI defaults such as Claude permission bypass flags are not auto-injected. +The SDK registers `company-claude` with the broker before spawning. Later +Relaycast spawns can send only `{ "harnessId": "company-claude" }`. -Supported placeholders: +## Codex Per-Spawn Config -| Placeholder | Expands To | -| --- | --- | -| `{args}` | Spawn `args` | -| `{modelArgs}` | Rendered `modelArgs`, only when a model is set | -| `{model}` | Spawn `model` | -| `{task}` | Spawn task text | +Use inline `harnessConfig` when setup produces a different config for each +spawn, such as creating or resuming a Codex session: -## Dynamic PTY Adapter +```typescript file="codex-harness.ts" +import { AgentRelay, type ResolvedHarnessConfig } from '@agent-relay/sdk'; -Use a dynamic resolver when spawn needs SDK-side setup. This is attached-only: -the SDK process is part of the control path. +function codexResume(sessionId: string, cwd: string): ResolvedHarnessConfig { + return { + runtime: 'pty', + command: 'codex', + args: ['resume', sessionId], + cwd, + env: { + PATH: process.env.PATH ?? '', + CODEX_HOME: process.env.CODEX_HOME ?? '', + }, + sessionId, + }; +} -```typescript file="codex-resume-harness.ts" -import { AgentRelay } from '@agent-relay/sdk'; +const relay = new AgentRelay(); +const cwd = process.cwd(); +const sessionId = await createCodexSession({ cwd, task: 'Review the current diff.' }); -const relay = new AgentRelay({ - broker: { lifetime: 'attached' }, - harnesses: { - 'codex-resume': async (ctx) => { - const sessionId = await createCodexSession({ - cwd: ctx.cwd, - task: ctx.task, - }); - - return { - runtime: 'pty', - command: 'codex', - args: ['resume', sessionId, ...ctx.args], - cwd: ctx.cwd, - env: { - PATH: ctx.env.PATH ?? '', - CODEX_HOME: ctx.env.CODEX_HOME ?? '', - }, - sessionId, - }; - }, - }, +await relay.spawn('CodexReviewer', 'codex', 'Review the current diff.', { + cwd, + harnessConfig: codexResume(sessionId, cwd), }); - -await relay.spawn('CodexReviewer', 'codex-resume', 'Review the current diff.'); ``` -Do not forward `ctx.env` wholesale. It is the SDK process environment and may -contain secrets. Pass only the keys the harness actually needs. +Do not copy the whole process environment into `env`. Pass only the keys the +harness needs. -Detached brokers should use static adapters, built-in broker behavior, HTTP -webhooks, or another durable extension host instead of in-process resolver -functions. +## OpenCode Headless Config -## Headless App-Server Adapter +Use `headless` for an agent that already exists inside an app-server session. +OpenCode `serve` is the first supported protocol: -Use a headless adapter when the agent already lives in a server session. -OpenCode `serve` is the first supported protocol. +```typescript file="opencode-harness.ts" +import { AgentRelay, type ResolvedHarnessConfig } from '@agent-relay/sdk'; -```typescript file="opencode-server-harness.ts" -import { AgentRelay } from '@agent-relay/sdk'; +function opencodeSession(input: { + endpoint: string; + sessionId: string; + pid?: number; +}): ResolvedHarnessConfig { + return { + runtime: 'headless', + protocol: 'opencode', + endpoint: input.endpoint, + sessionId: input.sessionId, + host: { ownership: 'attached', pid: input.pid }, + release: 'abort', + }; +} const relay = new AgentRelay({ harnesses: { - 'opencode-server': { - runtime: 'headless', - protocol: 'opencode', + 'opencode-current': opencodeSession({ endpoint: 'http://127.0.0.1:4096', sessionId: 'ses_123', - host: { ownership: 'attached', pid: 34567 }, - release: 'abort', - }, + pid: 34567, + }), }, }); -await relay.spawn('OpenCodeWorker', 'opencode-server', 'Inspect the repo.'); +await relay.spawn('OpenCodeWorker', 'opencode-current', 'Inspect the repo.'); ``` For OpenCode, Relay delivers messages to `POST /session/:id/prompt_async`. -Release behavior is controlled by `release`: `abort`, `detach`, or `delete`. -`host.pid` is reported as the harness PID when the server is local and known. - -Static app-server adapters attach to a known session. For per-spawn sessions, -create the session in a dynamic resolver and return the concrete config: - -```typescript file="opencode-dynamic-harness.ts" -const relay = new AgentRelay({ - broker: { lifetime: 'attached' }, - harnesses: { - 'opencode-new-session': async (ctx) => { - const session = await createOpenCodeSession({ cwd: ctx.cwd, task: ctx.task }); - - return { - runtime: 'headless', - protocol: 'opencode', - endpoint: session.endpoint, - sessionId: session.id, - host: { ownership: 'attached', pid: session.pid }, - release: 'detach', - }; - }, - }, -}); +For now, app-server configs must use `protocol: 'opencode'`, an `http` or +`https` endpoint, a non-empty `sessionId`, and attached host ownership. +`broker-owned` app-server hosts are reserved for later broker supervision. + +## Relaycast Spawns + +Agent-crafted spawns can reference a registered config: + +```json +{ + "agent": { + "name": "ClaudeReviewer", + "cli": "company-claude", + "task": "Review the current diff.", + "harnessId": "company-claude" + } +} ``` -For now, app-server configs must use `protocol: 'opencode'`, an `http` or `https` -endpoint, a non-empty `sessionId`, and attached host ownership. `broker-owned` -app-server hosts are reserved for a later broker-supervised mode. - -## One-Off Configs - -You can bypass named registration and pass a config directly for a single spawn: - -```typescript file="one-off-codex.ts" -await relay.spawnPty({ - name: 'CodexOneOff', - cli: 'codex', - harnessConfig: { - runtime: 'pty', - command: 'codex', - args: ['--model', 'gpt-5.4'], - }, -}); +Or they can send the whole config when the receiving broker may not have the +same registry: + +```json +{ + "agent": { + "name": "CodexReviewer", + "cli": "codex", + "task": "Review the current diff.", + "harnessConfig": { + "runtime": "pty", + "command": "codex", + "args": ["resume", "session_123"], + "sessionId": "session_123" + } + } +} ``` -Use named adapters when more than one spawn should share the same behavior. +The broker rejects spawn payloads that provide both `harnessId` and +`harnessConfig`. ## See Also diff --git a/web/content/docs/reference-broker-api.mdx b/web/content/docs/reference-broker-api.mdx index da1c69bff..8328365fe 100644 --- a/web/content/docs/reference-broker-api.mdx +++ b/web/content/docs/reference-broker-api.mdx @@ -58,6 +58,8 @@ The only route exempt from auth is `GET /health`. | `GET` | `/api/history/stats` | Stub message-history counters. | | `POST` | `/api/preflight` | Check that each `{ name, cli }` agent can be spawned. | | `POST` | `/api/shutdown` | Graceful broker shutdown. | +| `GET` | `/api/harnesses` | List named in-memory harness configs. | +| `PUT` | `/api/harnesses/{id}` | Register or replace a named harness config. | ### Agent lifecycle @@ -91,13 +93,16 @@ Body (fields accept both camelCase and snake_case): "idleThresholdSecs": 0, "skipRelayPrompt": false, "restartPolicy": null, + "harnessId": null, + "harnessConfig": null, "agentToken": null } ``` -`name` and `cli` are required. Returns `{ "success": true, ... }` on -success or `{ "success": false, "error": "..." }` with a non-2xx -status on failure. +`name` and `cli` are required. `harnessId` references a config registered with +`/api/harnesses/{id}`. `harnessConfig` sends a one-off concrete config. Provide +at most one of them. Returns `{ "success": true, ... }` on success or +`{ "success": false, "error": "..." }` with a non-2xx status on failure. ### PTY interaction diff --git a/web/content/docs/typescript-sdk.mdx b/web/content/docs/typescript-sdk.mdx index daacf6923..a08e286e0 100644 --- a/web/content/docs/typescript-sdk.mdx +++ b/web/content/docs/typescript-sdk.mdx @@ -29,6 +29,7 @@ const relay = new AgentRelay(options?: AgentRelayOptions); | `channels` | `string[]` | Default channels agents are joined to on spawn | `['general']` | | `cwd` | `string` | Working directory for the broker and spawned agents | `process.cwd()` | | `env` | `NodeJS.ProcessEnv` | Environment variables passed to the broker | Inherited | +| `harnesses` | `Record` | Named harness configs registered with the broker | `{}` | | `workspaceName` | `string` | Name for the auto-created Relaycast workspace | Random | | `relaycastBaseUrl` | `string` | Base URL for the Relaycast API | `https://api.relaycast.dev` | @@ -199,6 +200,8 @@ const client = await AgentRelayClient.spawn({ cwd: '/my/project' }); | `client.spawnProvider(input)` | `POST /api/spawn` | Spawn by provider and transport. | | `client.spawnClaude(input)` | `POST /api/spawn` | Spawn a Claude worker. | | `client.spawnOpencode(input)` | `POST /api/spawn` | Spawn an OpenCode worker. | +| `client.registerHarness(name, config)` | `PUT /api/harnesses/{name}` | Register a named harness config. | +| `client.listHarnesses()` | `GET /api/harnesses` | List named harness configs. | | `client.release(name, reason?)` | `DELETE /api/spawned/{name}` | Release a worker. | | `client.listAgents()` | `GET /api/spawned` | List running workers. | | `client.sendMessage(input)` | `POST /api/send` | Inject a relay message. | From e86f7d05f9fc6c8c4f044ac0a6c9b580a927cb07 Mon Sep 17 00:00:00 2001 From: Will Washburn Date: Mon, 25 May 2026 18:03:00 -0400 Subject: [PATCH 12/19] Remove harness registry state --- .../completed/2026-05/traj_bd431l65n9lg.json | 25 +++ .../completed/2026-05/traj_bd431l65n9lg.md | 14 ++ .trajectories/index.json | 9 +- CHANGELOG.md | 2 +- crates/broker/src/listen_api.rs | 165 +++--------------- crates/broker/src/runtime/api.rs | 31 ---- crates/broker/src/runtime/event_loop.rs | 1 - crates/broker/src/runtime/init.rs | 1 - crates/broker/src/runtime/relaycast_events.rs | 109 ++++-------- crates/broker/src/runtime/spawn_spec.rs | 20 --- docs/harness-runtime-config.md | 70 +++----- packages/sdk/src/__tests__/harness.test.ts | 56 ------ packages/sdk/src/client.ts | 26 --- packages/sdk/src/lifecycle-hooks.ts | 2 +- packages/sdk/src/relay.ts | 82 ++++----- packages/sdk/src/types.ts | 2 - web/content/docs/harnesses.mdx | 103 +++++------ web/content/docs/reference-broker-api.mdx | 11 +- web/content/docs/typescript-sdk.mdx | 2 - 19 files changed, 222 insertions(+), 509 deletions(-) create mode 100644 .trajectories/completed/2026-05/traj_bd431l65n9lg.json create mode 100644 .trajectories/completed/2026-05/traj_bd431l65n9lg.md diff --git a/.trajectories/completed/2026-05/traj_bd431l65n9lg.json b/.trajectories/completed/2026-05/traj_bd431l65n9lg.json new file mode 100644 index 000000000..aff85cb8a --- /dev/null +++ b/.trajectories/completed/2026-05/traj_bd431l65n9lg.json @@ -0,0 +1,25 @@ +{ + "id": "traj_bd431l65n9lg", + "version": 1, + "task": { + "title": "Remove broker harness registry footgun" + }, + "status": "completed", + "startedAt": "2026-05-25T21:55:14.197Z", + "completedAt": "2026-05-25T22:02:22.902Z", + "agents": [], + "chapters": [], + "retrospective": { + "summary": "Removed broker harness registry and harnessId from the PR. SDK named harnesses now resolve to inline harnessConfig before spawn; broker and Relaycast reject harnessId and require concrete configs for custom harness behavior.", + "approach": "Standard approach", + "confidence": 0.9 + }, + "commits": [], + "filesChanged": [], + "projectId": "/Users/will/Projects/AgentWorkforce/relay", + "tags": [], + "_trace": { + "startRef": "4fdda79ad264412bfc725e4d22a611a78b50df21", + "endRef": "4fdda79ad264412bfc725e4d22a611a78b50df21" + } +} diff --git a/.trajectories/completed/2026-05/traj_bd431l65n9lg.md b/.trajectories/completed/2026-05/traj_bd431l65n9lg.md new file mode 100644 index 000000000..362edd37b --- /dev/null +++ b/.trajectories/completed/2026-05/traj_bd431l65n9lg.md @@ -0,0 +1,14 @@ +# Trajectory: Remove broker harness registry footgun + +> **Status:** ✅ Completed +> **Confidence:** 90% +> **Started:** May 25, 2026 at 05:55 PM +> **Completed:** May 25, 2026 at 06:02 PM + +--- + +## Summary + +Removed broker harness registry and harnessId from the PR. SDK named harnesses now resolve to inline harnessConfig before spawn; broker and Relaycast reject harnessId and require concrete configs for custom harness behavior. + +**Approach:** Standard approach diff --git a/.trajectories/index.json b/.trajectories/index.json index 855838fe4..159cd43ce 100644 --- a/.trajectories/index.json +++ b/.trajectories/index.json @@ -1,6 +1,6 @@ { "version": 1, - "lastUpdated": "2026-05-25T21:47:15.621Z", + "lastUpdated": "2026-05-25T22:02:23.071Z", "trajectories": { "traj_05xg7j388bc4": { "title": "Add browser workflow step integration", @@ -1177,6 +1177,13 @@ "startedAt": "2026-05-25T21:32:14.085Z", "completedAt": "2026-05-25T21:47:15.455Z", "path": ".trajectories/completed/2026-05/traj_kgl2opmmfvus.json" + }, + "traj_bd431l65n9lg": { + "title": "Remove broker harness registry footgun", + "status": "completed", + "startedAt": "2026-05-25T21:55:14.197Z", + "completedAt": "2026-05-25T22:02:22.902Z", + "path": ".trajectories/completed/2026-05/traj_bd431l65n9lg.json" } } } diff --git a/CHANGELOG.md b/CHANGELOG.md index 2d2760cfc..aca62efa8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,7 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - Broker and TypeScript SDK structured result contracts add the `submit_result` MCP tool, `agent.waitForResult()`, per-spawn `result.onResult`, and `relay.addListener('agentResult', ...)` for typed JSON worker outcomes. -- `@agent-relay/sdk` and `agent-relay-broker` add broker-executable `pty` and `headless` harness configs, named in-memory harness registration, and `harnessId` spawn selection for custom CLIs without Rust changes. +- `@agent-relay/sdk` and `agent-relay-broker` add broker-executable `pty` and `headless` harness configs, so custom CLIs can be configured without Rust changes while spawn requests remain self-contained. - `agent-relay-broker` accepts resolved harness configs on spawn and adds a headless app-server driver for delivering Relay messages to existing OpenCode server sessions. ### Changed diff --git a/crates/broker/src/listen_api.rs b/crates/broker/src/listen_api.rs index 5df02b821..669de9192 100644 --- a/crates/broker/src/listen_api.rs +++ b/crates/broker/src/listen_api.rs @@ -50,20 +50,11 @@ pub enum ListenApiRequest { idle_threshold_secs: Option, skip_relay_prompt: bool, restart_policy: Box>, - harness_id: Option, harness_config: Option, agent_token: Option, agent_result_schema: Option, reply: tokio::sync::oneshot::Sender>, }, - RegisterHarness { - name: String, - config: ResolvedHarnessConfig, - reply: tokio::sync::oneshot::Sender>, - }, - ListHarnesses { - reply: tokio::sync::oneshot::Sender>, - }, SetModel { name: String, model: String, @@ -367,11 +358,6 @@ fn listen_api_router_with_auth( .route("/api/session", routing::get(listen_api_session)) .route("/api/session/renew", routing::post(listen_api_renew_lease)) .route("/api/spawn", routing::post(listen_api_spawn)) - .route("/api/harnesses", routing::get(listen_api_list_harnesses)) - .route( - "/api/harnesses/{name}", - routing::put(listen_api_register_harness).post(listen_api_register_harness), - ) .route("/api/spawned", routing::get(listen_api_list)) .route( "/api/spawned/{name}/model", @@ -609,84 +595,6 @@ fn extract_harness_config(body: &Value) -> Result, } } -async fn listen_api_register_harness( - axum::extract::State(state): axum::extract::State, - axum::extract::Path(name): axum::extract::Path, - axum::Json(body): axum::Json, -) -> (axum::http::StatusCode, axum::Json) { - let name = name.trim().to_string(); - if name.is_empty() { - return ( - axum::http::StatusCode::BAD_REQUEST, - axum::Json(json!({ "success": false, "error": "Missing required field: name" })), - ); - } - - let config_value = body - .get("config") - .or_else(|| body.get("harnessConfig")) - .or_else(|| body.get("harness_config")) - .cloned() - .unwrap_or(body); - let config = match parse_harness_config_value(config_value) { - Ok(config) => config, - Err(error) => { - return ( - axum::http::StatusCode::BAD_REQUEST, - axum::Json(json!({ "success": false, "error": error })), - ); - } - }; - - let (reply_tx, reply_rx) = tokio::sync::oneshot::channel(); - if state - .tx - .send(ListenApiRequest::RegisterHarness { - name: name.clone(), - config, - reply: reply_tx, - }) - .await - .is_err() - { - return ( - axum::http::StatusCode::INTERNAL_SERVER_ERROR, - axum::Json(json!({ "success": false, "error": "internal channel closed" })), - ); - } - - match reply_rx.await { - Ok(Ok(val)) => (axum::http::StatusCode::OK, axum::Json(val)), - Ok(Err(err)) => ( - axum::http::StatusCode::INTERNAL_SERVER_ERROR, - axum::Json(json!({ "success": false, "name": name, "error": err })), - ), - Err(_) => ( - axum::http::StatusCode::INTERNAL_SERVER_ERROR, - axum::Json(json!({ "success": false, "error": "internal reply dropped" })), - ), - } -} - -async fn listen_api_list_harnesses( - axum::extract::State(state): axum::extract::State, -) -> axum::Json { - let (reply_tx, reply_rx) = tokio::sync::oneshot::channel(); - if state - .tx - .send(ListenApiRequest::ListHarnesses { reply: reply_tx }) - .await - .is_err() - { - return axum::Json(json!({ "success": false, "harnesses": {} })); - } - - match reply_rx.await { - Ok(Ok(val)) => axum::Json(val), - _ => axum::Json(json!({ "success": false, "harnesses": {} })), - } -} - async fn listen_api_spawn( axum::extract::State(state): axum::extract::State, axum::Json(body): axum::Json, @@ -759,13 +667,19 @@ async fn listen_api_spawn( .or_else(|| body.get("restartPolicy")) .cloned(), ); - let harness_id = body + if body .get("harness_id") .or_else(|| body.get("harnessId")) - .and_then(Value::as_str) - .map(str::trim) - .filter(|value| !value.is_empty()) - .map(String::from); + .is_some() + { + return ( + axum::http::StatusCode::BAD_REQUEST, + axum::Json(json!({ + "success": false, + "error": "harnessId is not supported by the broker API; send harnessConfig" + })), + ); + } let harness_config = match extract_harness_config(&body) { Ok(config) => config, Err(error) => { @@ -778,15 +692,6 @@ async fn listen_api_spawn( ); } }; - if harness_id.is_some() && harness_config.is_some() { - return ( - axum::http::StatusCode::BAD_REQUEST, - axum::Json(json!({ - "success": false, - "error": "provide either harnessId or harnessConfig, not both" - })), - ); - } let agent_token = body .get("agent_token") .or_else(|| body.get("agentToken")) @@ -824,7 +729,6 @@ async fn listen_api_spawn( idle_threshold_secs, skip_relay_prompt, restart_policy, - harness_id, harness_config, agent_token, agent_result_schema, @@ -2562,7 +2466,6 @@ mod auth_tests { idle_threshold_secs, skip_relay_prompt: _, restart_policy: _, - harness_id, harness_config, agent_token: _, agent_result_schema, @@ -2584,7 +2487,6 @@ mod auth_tests { assert_eq!(shadow_mode.as_deref(), Some("subagent")); assert_eq!(continue_from.as_deref(), Some("worker-prev")); assert_eq!(idle_threshold_secs, Some(30)); - assert_eq!(harness_id.as_deref(), None); assert!(harness_config.is_some()); assert_eq!( agent_result_schema, @@ -2642,41 +2544,20 @@ mod auth_tests { } #[tokio::test] - async fn harness_register_route_forwards_named_config() { - let (router, mut rx) = test_router(Some("secret")); - let replier = tokio::spawn(async move { - match rx.recv().await { - Some(ListenApiRequest::RegisterHarness { - name, - config, - reply, - }) => { - assert_eq!(name, "company-claude"); - assert_eq!(config.runtime(), crate::protocol::AgentRuntime::Pty); - let _ = reply.send(Ok(json!({ - "success": true, - "name": name, - "harnessConfig": config, - }))); - } - other => panic!("unexpected request: {:?}", other.map(|_| "other")), - } - }); - + async fn spawn_route_rejects_harness_id() { + let (router, _rx) = test_router(Some("secret")); let response = router .oneshot( Request::builder() - .uri("/api/harnesses/company-claude") - .method("PUT") + .uri("/api/spawn") + .method("POST") .header("x-api-key", "secret") .header("content-type", "application/json") .body(Body::from( json!({ - "harnessConfig": { - "runtime": "pty", - "command": "claude", - "args": ["--dangerously-skip-permissions"] - } + "name": "worker-a", + "cli": "company-claude", + "harnessId": "company-claude" }) .to_string(), )) @@ -2685,12 +2566,12 @@ mod auth_tests { .await .expect("request should succeed"); - assert_eq!(response.status(), StatusCode::OK); + assert_eq!(response.status(), StatusCode::BAD_REQUEST); let body = response_json(response).await; - assert_eq!(body["success"], json!(true)); - assert_eq!(body["name"], json!("company-claude")); - - replier.await.expect("register replier should complete"); + assert!(body["error"] + .as_str() + .expect("error should be a string") + .contains("harnessId is not supported")); } #[tokio::test] diff --git a/crates/broker/src/runtime/api.rs b/crates/broker/src/runtime/api.rs index 32a97d7dd..ed5c397a2 100644 --- a/crates/broker/src/runtime/api.rs +++ b/crates/broker/src/runtime/api.rs @@ -19,7 +19,6 @@ impl BrokerRuntime { let pending_requests = &mut self.pending_requests; let delivery_states = &mut self.delivery_states; let agent_result_tokens = &mut self.agent_result_tokens; - let harness_configs = &mut self.harness_configs; let dedup = &mut self.dedup; let recent_thread_messages = &mut self.recent_thread_messages; let delivery_retry_interval = self.delivery_retry_interval; @@ -46,7 +45,6 @@ impl BrokerRuntime { idle_threshold_secs, skip_relay_prompt, restart_policy, - harness_id, harness_config, agent_token, agent_result_schema, @@ -57,17 +55,6 @@ impl BrokerRuntime { } else { channels.clone() }; - let harness_config = match resolve_harness_config_selection( - harness_id.as_deref(), - harness_config, - harness_configs, - ) { - Ok(config) => config, - Err(error) => { - let _ = reply.send(Err(error.to_string())); - return; - } - }; let spec = match build_http_api_spawn_spec( name.clone(), cli.clone(), @@ -401,24 +388,6 @@ impl BrokerRuntime { } } } - ListenApiRequest::RegisterHarness { - name, - config, - reply, - } => { - harness_configs.insert(name.clone(), config.clone()); - let _ = reply.send(Ok(json!({ - "success": true, - "name": name, - "harnessConfig": config, - }))); - } - ListenApiRequest::ListHarnesses { reply } => { - let _ = reply.send(Ok(json!({ - "success": true, - "harnesses": harness_configs.clone(), - }))); - } ListenApiRequest::Release { name, reason, diff --git a/crates/broker/src/runtime/event_loop.rs b/crates/broker/src/runtime/event_loop.rs index 8263d6d8b..568941bc1 100644 --- a/crates/broker/src/runtime/event_loop.rs +++ b/crates/broker/src/runtime/event_loop.rs @@ -21,7 +21,6 @@ pub(crate) struct BrokerRuntime { pub(super) worker_event_rx: mpsc::Receiver, pub(super) worker_events_open: bool, pub(super) workers: WorkerRegistry, - pub(super) harness_configs: HashMap, pub(super) crash_insights: crate::crash_insights::CrashInsights, pub(super) crash_insights_path: PathBuf, pub(super) sdk_lines: tokio::io::Lines>, diff --git a/crates/broker/src/runtime/init.rs b/crates/broker/src/runtime/init.rs index 8f66029ca..d96363e24 100644 --- a/crates/broker/src/runtime/init.rs +++ b/crates/broker/src/runtime/init.rs @@ -477,7 +477,6 @@ pub(crate) async fn run_init(cmd: InitCommand, telemetry: TelemetryClient) -> Re worker_event_rx, worker_events_open: true, workers, - harness_configs: HashMap::new(), crash_insights, crash_insights_path, sdk_lines, diff --git a/crates/broker/src/runtime/relaycast_events.rs b/crates/broker/src/runtime/relaycast_events.rs index cfd0295bd..546c4180a 100644 --- a/crates/broker/src/runtime/relaycast_events.rs +++ b/crates/broker/src/runtime/relaycast_events.rs @@ -15,7 +15,6 @@ impl BrokerRuntime { let pending_requests = &mut self.pending_requests; let delivery_states = &mut self.delivery_states; let agent_result_tokens = &mut self.agent_result_tokens; - let harness_configs = &self.harness_configs; let dm_participants_cache = &mut self.dm_participants_cache; let recent_thread_messages = &mut self.recent_thread_messages; let delivery_retry_interval = self.delivery_retry_interval; @@ -205,22 +204,21 @@ impl BrokerRuntime { let cli = event.agent.cli; let task = Some(event.agent.task).filter(|value| !value.trim().is_empty()); let channel = event.agent.channel; - let harness_config = - match relaycast_harness_config_selection(&ws_value, harness_configs) { - Ok(config) => config, - Err(error) => { - tracing::warn!( - worker = %name, - error = %error, - "rejecting relaycast spawn with invalid harness selection" - ); - eprintln!( - "[agent-relay] rejecting spawn request for '{}': {}", - name, error - ); - return; - } - }; + let harness_config = match relaycast_harness_config(&ws_value) { + Ok(config) => config, + Err(error) => { + tracing::warn!( + worker = %name, + error = %error, + "rejecting relaycast spawn with invalid harness config" + ); + eprintln!( + "[agent-relay] rejecting spawn request for '{}': {}", + name, error + ); + return; + } + }; let runtime = harness_config .as_ref() .map(ResolvedHarnessConfig::runtime) @@ -453,16 +451,13 @@ impl BrokerRuntime { chs }) .unwrap_or_else(default_spawn_channels); - let harness_config = match relaycast_harness_config_selection( - &ws_value, - harness_configs, - ) { + let harness_config = match relaycast_harness_config(&ws_value) { Ok(config) => config, Err(error) => { tracing::warn!( worker = %name, error = %error, - "rejecting relaycast fallback spawn with invalid harness selection" + "rejecting relaycast fallback spawn with invalid harness config" ); eprintln!( "[agent-relay] rejecting spawn request for '{}': {}", @@ -933,9 +928,9 @@ impl BrokerRuntime { } } -fn relaycast_harness_id(value: &Value) -> Option { +fn relaycast_harness_config(value: &Value) -> Result, String> { let agent = value.get("agent"); - agent + let harness_id = agent .and_then(|agent| { agent .get("harnessId") @@ -949,12 +944,13 @@ fn relaycast_harness_id(value: &Value) -> Option { .and_then(Value::as_str) }) .map(str::trim) - .filter(|id| !id.is_empty()) - .map(ToOwned::to_owned) -} + .filter(|id| !id.is_empty()); + if harness_id.is_some() { + return Err( + "harnessId is not supported by Relaycast spawns; send harnessConfig".to_string(), + ); + } -fn relaycast_harness_config(value: &Value) -> Result, String> { - let agent = value.get("agent"); let raw = agent .and_then(|agent| { agent @@ -975,74 +971,45 @@ fn relaycast_harness_config(value: &Value) -> Result, -) -> Result, String> { - let harness_id = relaycast_harness_id(value); - let harness_config = relaycast_harness_config(value)?; - resolve_harness_config_selection(harness_id.as_deref(), harness_config, registry) - .map_err(|error| error.to_string()) -} - #[cfg(test)] mod tests { use super::*; - use crate::protocol::PtyHarnessConfig; - - fn pty_config(command: &str) -> ResolvedHarnessConfig { - ResolvedHarnessConfig::Pty(PtyHarnessConfig { - command: command.to_string(), - args: vec![], - cwd: None, - env: None, - session_id: None, - delivery: None, - metadata: None, - }) - } #[test] - fn relaycast_harness_selection_resolves_agent_harness_id() { - let mut registry = HashMap::new(); - registry.insert("company-claude".to_string(), pty_config("claude")); + fn relaycast_harness_config_accepts_inline_config() { let value = json!({ "type": "agent.spawn_requested", "agent": { "name": "ClaudeReviewer", "cli": "company-claude", - "harnessId": "company-claude" + "harnessConfig": { + "runtime": "pty", + "command": "claude", + "args": [] + } } }); - let config = relaycast_harness_config_selection(&value, ®istry) - .expect("selection should resolve") - .expect("selection should return config"); + let config = relaycast_harness_config(&value) + .expect("inline config should parse") + .expect("inline config should return config"); assert_eq!(config.runtime(), AgentRuntime::Pty); } #[test] - fn relaycast_harness_selection_rejects_both_id_and_inline_config() { - let mut registry = HashMap::new(); - registry.insert("company-claude".to_string(), pty_config("claude")); + fn relaycast_harness_config_rejects_harness_id() { let value = json!({ "type": "agent.spawn_requested", "agent": { "name": "ClaudeReviewer", "cli": "company-claude", - "harnessId": "company-claude", - "harnessConfig": { - "runtime": "pty", - "command": "claude", - "args": [] - } + "harnessId": "company-claude" } }); - let error = relaycast_harness_config_selection(&value, ®istry) - .expect_err("conflicting selection should fail"); + let error = relaycast_harness_config(&value).expect_err("harnessId should fail"); - assert!(error.contains("provide either harnessId or harnessConfig")); + assert!(error.contains("harnessId is not supported")); } } diff --git a/crates/broker/src/runtime/spawn_spec.rs b/crates/broker/src/runtime/spawn_spec.rs index 720de5e24..7afe8dc07 100644 --- a/crates/broker/src/runtime/spawn_spec.rs +++ b/crates/broker/src/runtime/spawn_spec.rs @@ -7,26 +7,6 @@ pub(crate) fn runtime_label(runtime: &AgentRuntime) -> &'static str { } } -pub(crate) fn resolve_harness_config_selection( - harness_id: Option<&str>, - harness_config: Option, - registry: &HashMap, -) -> Result> { - let harness_id = harness_id.map(str::trim).filter(|value| !value.is_empty()); - - match (harness_id, harness_config) { - (Some(_), Some(_)) => { - anyhow::bail!("provide either harnessId or harnessConfig, not both") - } - (Some(id), None) => registry - .get(id) - .cloned() - .map(Some) - .with_context(|| format!("unknown harnessId '{id}'")), - (None, config) => Ok(config), - } -} - #[allow(clippy::too_many_arguments)] pub(crate) fn build_http_api_spawn_spec( name: String, diff --git a/docs/harness-runtime-config.md b/docs/harness-runtime-config.md index 6f888eaa6..369bf8787 100644 --- a/docs/harness-runtime-config.md +++ b/docs/harness-runtime-config.md @@ -5,7 +5,8 @@ Harnesses should be user-extensible without requiring Rust changes for normal agent CLIs. The durable boundary is data: the Rust broker validates and executes `HarnessConfig` objects. SDKs may help users build those objects, but the broker -does not call back into SDK-defined functions after the SDK process exits. +does not call back into SDK functions and does not depend on broker-local named +config state. ## Core Model @@ -22,8 +23,8 @@ Names in this design: - A harness config is the concrete `pty` or `headless` object the broker runs. - A harness adapter is SDK/userland code that returns a harness config. -- `harnessId` references a config in the broker's in-memory registry. -- `harnessConfig` is the spawn field for sending a one-off concrete config. +- A named harness is an SDK-side shortcut in `new AgentRelay({ harnesses })`. +- `harnessConfig` is the spawn field that carries concrete config to the broker. ## Config Shapes @@ -91,7 +92,7 @@ function companyClaude(): ResolvedHarnessConfig { } ``` -Register stable configs by name: +Register stable configs by name in the SDK: ```ts const relay = new AgentRelay({ @@ -101,8 +102,10 @@ const relay = new AgentRelay({ }); ``` -The SDK registers those configs with the broker's in-memory registry on start. -Future spawns can use `harnessId: 'company-claude'`. +This name is local SDK ergonomics. Before spawn, the SDK resolves it to a +concrete `harnessConfig` and sends that config to the broker. The broker does +not keep an in-memory harness registry, because broker-local names become a +multi-broker footgun. Use inline configs for per-spawn setup: @@ -120,51 +123,28 @@ await relay.spawn('CodexReviewer', 'codex', task, { }); ``` -This avoids pretending that SDK callbacks are durable. If the SDK process exits, -the broker can still execute registered or inline configs because it already has -the data. +This avoids pretending SDK callbacks are durable. If the SDK process exits, the +broker can still execute the agent because it already received the concrete +config. -## Broker Registry +## Broker API -The broker keeps an in-memory map: - -```ts -Record; -``` - -HTTP/SDK API: - -- `PUT /api/harnesses/:name` registers or replaces a config. -- `GET /api/harnesses` lists registered configs. -- `POST /api/spawn` accepts either `harnessId` or `harnessConfig`. +`POST /api/spawn` accepts optional `harnessConfig`. Resolution rules: -- `harnessConfig` is already concrete and runs as supplied. -- `harnessId` resolves against the receiving broker's registry. -- Providing both is rejected. -- Unknown `harnessId` is rejected. +- `harnessConfig` is concrete and runs as supplied after validation. +- SDK names are resolved before this API call. +- Relaycast spawns that need custom behavior send full `harnessConfig`. +- `harnessId` is not accepted in broker or Relaycast spawn payloads. -Registry state is intentionally runtime-local for now. In multi-broker -environments, use inline `harnessConfig` or ensure every broker registers the -same named configs before agents send `harnessId` spawns. +That keeps every spawn request self-contained. It avoids bugs where behavior +depends on registration order, stale broker process memory, or whether two +brokers agree on what a mutable name means. ## Relaycast Spawns -Agent-crafted Relaycast spawns can send a registry reference: - -```json -{ - "agent": { - "name": "ClaudeReviewer", - "cli": "company-claude", - "task": "Review the current diff.", - "harnessId": "company-claude" - } -} -``` - -Or a portable inline config: +Agent-crafted Relaycast spawns should send a portable inline config: ```json { @@ -182,7 +162,7 @@ Or a portable inline config: } ``` -The broker validates the selected config and then uses the same spawn path as +The broker validates the config and then uses the same spawn path as SDK-submitted configs. ## Broker Responsibilities @@ -216,7 +196,7 @@ resize, or snapshot capabilities. 1. Add shared config schema and SDK types. 2. Teach the broker to accept and execute resolved PTY configs. 3. Add a headless app-server config path with an OpenCode protocol driver. -4. Add an in-memory broker harness registry and `harnessId` spawn selection. -5. Allow Relaycast spawn events to carry `harnessId` or inline `harnessConfig`. +4. Resolve named SDK harnesses to inline `harnessConfig` before spawn. +5. Allow Relaycast spawn events to carry inline `harnessConfig`. 6. Add capability-aware runtime checks for PTY-only operations. 7. Document Claude PTY, Codex inline PTY, and OpenCode headless examples. diff --git a/packages/sdk/src/__tests__/harness.test.ts b/packages/sdk/src/__tests__/harness.test.ts index fe14d292a..bf38fd3cc 100644 --- a/packages/sdk/src/__tests__/harness.test.ts +++ b/packages/sdk/src/__tests__/harness.test.ts @@ -109,60 +109,4 @@ describe('harness configs', () => { }, }); }); - - it('serializes harness ids on spawn requests', async () => { - const captures: unknown[] = []; - const fetchFn = vi.fn(async (_url: string | URL | Request, init?: RequestInit) => { - captures.push(JSON.parse(String(init?.body ?? '{}'))); - return new Response(JSON.stringify({ name: 'ClaudeReviewer', runtime: 'pty' }), { - status: 200, - headers: { 'Content-Type': 'application/json' }, - }); - }); - - const client = new AgentRelayClient({ baseUrl: 'http://broker.test', apiKey: 'k', fetch: fetchFn }); - await client.spawnPty({ - name: 'ClaudeReviewer', - cli: 'company-claude', - harnessId: 'company-claude', - }); - - expect(captures[0]).toMatchObject({ - name: 'ClaudeReviewer', - cli: 'company-claude', - harnessId: 'company-claude', - }); - }); - - it('registers named harness configs with the broker', async () => { - const calls: Array<{ url: string; body: unknown }> = []; - const fetchFn = vi.fn(async (url: string | URL | Request, init?: RequestInit) => { - calls.push({ - url: String(url), - body: JSON.parse(String(init?.body ?? '{}')), - }); - return new Response(JSON.stringify({ success: true, name: 'company-claude' }), { - status: 200, - headers: { 'Content-Type': 'application/json' }, - }); - }); - - const client = new AgentRelayClient({ baseUrl: 'http://broker.test', apiKey: 'k', fetch: fetchFn }); - await client.registerHarness('company-claude', { - runtime: 'pty', - command: 'claude', - args: ['--dangerously-skip-permissions'], - }); - - expect(calls[0]).toMatchObject({ - url: 'http://broker.test/api/harnesses/company-claude', - body: { - harnessConfig: { - runtime: 'pty', - command: 'claude', - args: ['--dangerously-skip-permissions'], - }, - }, - }); - }); }); diff --git a/packages/sdk/src/client.ts b/packages/sdk/src/client.ts index c58a94eee..2cf89ebf4 100644 --- a/packages/sdk/src/client.ts +++ b/packages/sdk/src/client.ts @@ -52,7 +52,6 @@ import type { BeforeAgentSpawnHandler, SpawnPatch, } from './lifecycle-hooks.js'; -import type { ResolvedHarnessConfig } from './harness.js'; // ── Types ────────────────────────────────────────────────────────────── @@ -178,7 +177,6 @@ function buildSpawnPtyBody(input: SpawnPtyInput): Record { ...(input.shadowOf !== undefined ? { shadowOf: input.shadowOf } : {}), ...(input.shadowMode !== undefined ? { shadowMode: input.shadowMode } : {}), ...(input.continueFrom !== undefined ? { continueFrom: input.continueFrom } : {}), - ...(input.harnessId !== undefined ? { harnessId: input.harnessId } : {}), ...(input.harnessConfig !== undefined ? { harnessConfig: input.harnessConfig } : {}), ...(input.idleThresholdSecs !== undefined ? { idleThresholdSecs: input.idleThresholdSecs } : {}), ...(input.restartPolicy !== undefined ? { restartPolicy: input.restartPolicy } : {}), @@ -204,7 +202,6 @@ function buildSpawnProviderBody( ...(input.shadowOf !== undefined ? { shadowOf: input.shadowOf } : {}), ...(input.shadowMode !== undefined ? { shadowMode: input.shadowMode } : {}), ...(input.continueFrom !== undefined ? { continueFrom: input.continueFrom } : {}), - ...(input.harnessId !== undefined ? { harnessId: input.harnessId } : {}), ...(input.harnessConfig !== undefined ? { harnessConfig: input.harnessConfig } : {}), ...(input.idleThresholdSecs !== undefined ? { idleThresholdSecs: input.idleThresholdSecs } : {}), ...(input.restartPolicy !== undefined ? { restartPolicy: input.restartPolicy } : {}), @@ -590,28 +587,6 @@ export class AgentRelayClient { return this.transport.getLastEvent(kind, name); } - async registerHarness(name: string, harnessConfig: ResolvedHarnessConfig): Promise { - const key = name.trim(); - if (!key) { - throw new Error('registerHarness() expects a non-empty harness name'); - } - await this.transport.request<{ success: boolean; name: string }>( - `/api/harnesses/${encodeURIComponent(key)}`, - { - method: 'PUT', - body: JSON.stringify({ harnessConfig }), - } - ); - } - - async listHarnesses(): Promise> { - const result = await this.transport.request<{ - success: boolean; - harnesses?: Record; - }>('/api/harnesses', { method: 'GET' }); - return result.harnesses ?? {}; - } - // ── Agent lifecycle ──────────────────────────────────────────────── async spawnPty(input: SpawnPtyInput): Promise { @@ -651,7 +626,6 @@ export class AgentRelayClient { if ( transport === 'headless' && !isHeadlessProvider(resolvedInput.provider) && - !resolvedInput.harnessId && !resolvedInput.harnessConfig ) { throw new Error( diff --git a/packages/sdk/src/lifecycle-hooks.ts b/packages/sdk/src/lifecycle-hooks.ts index 8bae0a360..b21e4fabc 100644 --- a/packages/sdk/src/lifecycle-hooks.ts +++ b/packages/sdk/src/lifecycle-hooks.ts @@ -54,7 +54,7 @@ import type { SpawnAgentResult, SpawnPtyInput, SpawnProviderInput } from './type export type SpawnPatch = Partial< Pick< SpawnPtyInput & SpawnProviderInput, - 'args' | 'channels' | 'task' | 'model' | 'team' | 'agentToken' | 'harnessId' | 'harnessConfig' + 'args' | 'channels' | 'task' | 'model' | 'team' | 'agentToken' | 'harnessConfig' > >; diff --git a/packages/sdk/src/relay.ts b/packages/sdk/src/relay.ts index afd017653..2562a1678 100644 --- a/packages/sdk/src/relay.ts +++ b/packages/sdk/src/relay.ts @@ -288,7 +288,6 @@ export interface SpawnOptions extends SpawnLifecycleHook shadowMode?: string; idleThresholdSecs?: number; restartPolicy?: RestartPolicy; - harnessId?: string; harnessConfig?: ResolvedHarnessConfig; /** Optional pre-minted relaycast agent token (`at_live_`, from * `registerAgent(workspaceKey, name)` in `@agent-relay/sdk/http`). The @@ -416,7 +415,6 @@ export interface SpawnerSpawnOptions extends SpawnLifecy model?: string; cwd?: string; idleThresholdSecs?: number; - harnessId?: string; harnessConfig?: ResolvedHarnessConfig; /** Optional pre-minted relaycast agent token (`at_live_`, from * `registerAgent(workspaceKey, name)` in `@agent-relay/sdk/http`). The @@ -472,8 +470,8 @@ export interface AgentRelayOptions { */ personaDirs?: string[]; /** - * Named harness definitions. Definitions are rendered to broker-executable - * configs and stored in the broker's in-memory harness registry. + * Named harness definitions. Definitions are SDK-side shortcuts that render + * to broker-executable JSON configs before each spawn. */ harnesses?: Record; /** Broker lifetime. Ephemeral attached brokers shut down when the SDK lease expires. */ @@ -741,47 +739,44 @@ export class AgentRelay { ); } - async registerHarness(name: string, definition: HarnessDefinition): Promise { + registerHarness(name: string, definition: HarnessDefinition): void { const key = name.trim(); if (!key) { throw new Error('registerHarness() expects a non-empty harness name'); } this.harnesses[key] = definition; - if (this.client) { - await this.client.registerHarness(key, this.resolveRegisteredHarnessConfig(key, definition)); - } } - private findHarnessDefinition(cli: string): { id: string; definition: HarnessDefinition } | undefined { + private findHarnessDefinition(cli: string): HarnessDefinition | undefined { for (const key of harnessLookupKeys(cli)) { const definition = this.harnesses[key]; - if (definition) return { id: key, definition }; + if (definition) return definition; } return undefined; } - private resolveRegisteredHarnessConfig(name: string, definition: HarnessDefinition): ResolvedHarnessConfig { - return resolveStaticHarnessConfig({ - name, - cli: name, - definition, - }); - } - - private resolveHarnessId(input: { + private resolveHarnessConfig(input: { + name: string; cli: string; - harnessId?: string; + args?: string[]; + task?: string; + model?: string; + cwd?: string; harnessConfig?: ResolvedHarnessConfig; - }): string | undefined { - if (input.harnessConfig) return undefined; - if (input.harnessId) return input.harnessId; - return this.findHarnessDefinition(input.cli)?.id; - } + }): ResolvedHarnessConfig | undefined { + if (input.harnessConfig) return input.harnessConfig; + const definition = this.findHarnessDefinition(input.cli); + if (!definition) return undefined; - private async syncHarnessRegistry(client: AgentRelayClient): Promise { - for (const [name, definition] of Object.entries(this.harnesses)) { - await client.registerHarness(name, this.resolveRegisteredHarnessConfig(name, definition)); - } + return resolveStaticHarnessConfig({ + name: input.name, + cli: input.cli, + definition, + args: input.args ?? [], + task: input.task, + model: input.model, + cwd: input.cwd ?? this.clientOptions.cwd ?? process.cwd(), + }); } private applyWorkspaceEnv(workspaceId: string, apiKey: string): void { @@ -856,7 +851,7 @@ export class AgentRelay { this.resultContracts.set(input.name, resultContract as InternalAgentResultContract); } try { - const harnessId = this.resolveHarnessId(input); + const harnessConfig = this.resolveHarnessConfig(input); result = await client.spawnPty({ name: input.name, cli: input.cli, @@ -871,8 +866,7 @@ export class AgentRelay { shadowMode: input.shadowMode, idleThresholdSecs: input.idleThresholdSecs, restartPolicy: input.restartPolicy, - harnessId, - harnessConfig: input.harnessConfig, + harnessConfig, skipRelayPrompt: input.skipRelayPrompt, agentResultSchema: resultContract?.jsonSchema, }); @@ -933,7 +927,6 @@ export class AgentRelay { shadowMode: options?.shadowMode, idleThresholdSecs: options?.idleThresholdSecs, restartPolicy: options?.restartPolicy, - harnessId: options?.harnessId, harnessConfig: options?.harnessConfig, skipRelayPrompt: options?.skipRelayPrompt, result: options?.result, @@ -1019,7 +1012,6 @@ export class AgentRelay { shadowMode: options.shadowMode, idleThresholdSecs: options.idleThresholdSecs, restartPolicy: options.restartPolicy, - harnessId: options.harnessId, harnessConfig: options.harnessConfig, skipRelayPrompt: options.skipRelayPrompt, result: options.result, @@ -1734,7 +1726,6 @@ export class AgentRelay { } } } - await this.syncHarnessRegistry(c); this.wireEvents(c); this.client = c; this.startPromise = undefined; @@ -2345,7 +2336,6 @@ export class AgentRelay { model: options?.model, cwd: options?.cwd, idleThresholdSecs: options?.idleThresholdSecs, - harnessId: options?.harnessId, harnessConfig: options?.harnessConfig, agentToken: options?.agentToken, skipRelayPrompt: options?.skipRelayPrompt, @@ -2370,24 +2360,26 @@ export class AgentRelay { this.resultContracts.set(name, resultContract as InternalAgentResultContract); } try { - const harnessEntry = options?.harnessConfig ? undefined : this.findHarnessDefinition(cli); - const harnessId = options?.harnessId ?? harnessEntry?.id; - const registeredHarnessConfig = harnessEntry - ? this.resolveRegisteredHarnessConfig(harnessEntry.id, harnessEntry.definition) - : undefined; - const transport = options?.harnessConfig?.runtime ?? registeredHarnessConfig?.runtime ?? 'headless'; + const harnessConfig = this.resolveHarnessConfig({ + name, + cli, + args, + task, + model: options?.model, + cwd: options?.cwd, + harnessConfig: options?.harnessConfig, + }); result = await client.spawnProvider({ name, provider: cli as HeadlessProvider, - transport, + transport: harnessConfig?.runtime ?? 'headless', args, channels, task, model: options?.model, cwd: options?.cwd, idleThresholdSecs: options?.idleThresholdSecs, - harnessId, - harnessConfig: options?.harnessConfig, + harnessConfig, agentToken: options?.agentToken, skipRelayPrompt: options?.skipRelayPrompt, agentResultSchema: resultContract?.jsonSchema, diff --git a/packages/sdk/src/types.ts b/packages/sdk/src/types.ts index df9d78b07..983eaba76 100644 --- a/packages/sdk/src/types.ts +++ b/packages/sdk/src/types.ts @@ -26,7 +26,6 @@ export interface SpawnPtyInput { shadowMode?: string; idleThresholdSecs?: number; restartPolicy?: RestartPolicy; - harnessId?: string; continueFrom?: string; harnessConfig?: ResolvedHarnessConfig; skipRelayPrompt?: boolean; @@ -82,7 +81,6 @@ export interface SpawnProviderInput { shadowMode?: string; idleThresholdSecs?: number; restartPolicy?: RestartPolicy; - harnessId?: string; continueFrom?: string; harnessConfig?: ResolvedHarnessConfig; skipRelayPrompt?: boolean; diff --git a/web/content/docs/harnesses.mdx b/web/content/docs/harnesses.mdx index 852d72974..86bffdff8 100644 --- a/web/content/docs/harnesses.mdx +++ b/web/content/docs/harnesses.mdx @@ -4,8 +4,8 @@ description: Define custom PTY and headless harness configs in the SDK. --- A harness is the thing Relay controls for an agent. The broker only executes -serializable `HarnessConfig` data. SDK "adapters" should be small helpers that -return configs; they are not durable callback code that the broker calls later. +serializable `HarnessConfig` data. SDK "adapters" are helpers that return those +configs before a spawn request is sent. Relay supports two runtime categories: @@ -22,49 +22,52 @@ When `runtime` is `headless`, `driver` defaults to `app_server`. | --- | --- | | Harness config | Concrete `pty` or `headless` JSON the broker can validate and run | | Harness adapter | SDK helper that returns a harness config | -| `harnessId` | Name of a config stored in the broker's in-memory harness registry | -| `harnessConfig` | One-off config sent directly on a spawn | +| Named harness | SDK-side shortcut in `new AgentRelay({ harnesses })` | +| `harnessConfig` | Spawn field carrying the concrete config to the broker | -Use `harnessId` when every relevant broker has the same named config registered. -Use inline `harnessConfig` when the spawn must be portable across brokers. +The broker boundary is always explicit config data. Named harnesses are resolved +by the SDK before spawn; Relaycast and multi-broker spawns should send +`harnessConfig` directly. ## Claude PTY Config -Register a named config when the command is stable across spawns: +Use a named harness when the command is stable across spawns: ```typescript file="claude-harness.ts" -import { AgentRelay, type ResolvedHarnessConfig } from '@agent-relay/sdk'; - -function companyClaude(): ResolvedHarnessConfig { - return { - runtime: 'pty', - command: 'claude', - args: [ - '--dangerously-skip-permissions', - '--append-system-prompt', - 'Follow the company review rubric.', - ], - env: { - CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC: '1', - }, - }; -} +import { AgentRelay } from '@agent-relay/sdk'; const relay = new AgentRelay({ harnesses: { - 'company-claude': companyClaude(), + 'company-claude': { + runtime: 'pty', + command: 'claude', + args: [ + '--dangerously-skip-permissions', + '--append-system-prompt', + 'Follow the company review rubric.', + '{modelArgs}', + '{args}', + ], + modelArgs: ['--model', '{model}'], + env: { + CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC: '1', + }, + }, }, }); -await relay.spawn('ClaudeReviewer', 'company-claude', 'Review the current diff.'); +await relay.spawn('ClaudeReviewer', 'company-claude', 'Review the current diff.', { + model: 'opus', + args: ['--verbose'], +}); ``` -The SDK registers `company-claude` with the broker before spawning. Later -Relaycast spawns can send only `{ "harnessId": "company-claude" }`. +The SDK turns `company-claude` into an inline `harnessConfig` for that spawn. +The broker does not keep a named harness registry. ## Codex Per-Spawn Config -Use inline `harnessConfig` when setup produces a different config for each +Use direct `harnessConfig` when setup produces a different config for each spawn, such as creating or resuming a Codex session: ```typescript file="codex-harness.ts" @@ -86,9 +89,10 @@ function codexResume(sessionId: string, cwd: string): ResolvedHarnessConfig { const relay = new AgentRelay(); const cwd = process.cwd(); -const sessionId = await createCodexSession({ cwd, task: 'Review the current diff.' }); +const task = 'Review the current diff.'; +const sessionId = await createCodexSession({ cwd, task }); -await relay.spawn('CodexReviewer', 'codex', 'Review the current diff.', { +await relay.spawn('CodexReviewer', 'codex', task, { cwd, harnessConfig: codexResume(sessionId, cwd), }); @@ -120,17 +124,15 @@ function opencodeSession(input: { }; } -const relay = new AgentRelay({ - harnesses: { - 'opencode-current': opencodeSession({ - endpoint: 'http://127.0.0.1:4096', - sessionId: 'ses_123', - pid: 34567, - }), - }, -}); +const relay = new AgentRelay(); -await relay.spawn('OpenCodeWorker', 'opencode-current', 'Inspect the repo.'); +await relay.spawn('OpenCodeWorker', 'opencode', 'Inspect the repo.', { + harnessConfig: opencodeSession({ + endpoint: 'http://127.0.0.1:4096', + sessionId: 'ses_123', + pid: 34567, + }), +}); ``` For OpenCode, Relay delivers messages to `POST /session/:id/prompt_async`. @@ -140,21 +142,7 @@ For now, app-server configs must use `protocol: 'opencode'`, an `http` or ## Relaycast Spawns -Agent-crafted spawns can reference a registered config: - -```json -{ - "agent": { - "name": "ClaudeReviewer", - "cli": "company-claude", - "task": "Review the current diff.", - "harnessId": "company-claude" - } -} -``` - -Or they can send the whole config when the receiving broker may not have the -same registry: +Agent-crafted spawns should send the full config: ```json { @@ -172,8 +160,9 @@ same registry: } ``` -The broker rejects spawn payloads that provide both `harnessId` and -`harnessConfig`. +Relay intentionally avoids a broker-local harness registry for now. A spawn +request should be self-contained so behavior does not depend on hidden runtime +state or which broker receives it. ## See Also diff --git a/web/content/docs/reference-broker-api.mdx b/web/content/docs/reference-broker-api.mdx index 8328365fe..89cf18fde 100644 --- a/web/content/docs/reference-broker-api.mdx +++ b/web/content/docs/reference-broker-api.mdx @@ -58,8 +58,6 @@ The only route exempt from auth is `GET /health`. | `GET` | `/api/history/stats` | Stub message-history counters. | | `POST` | `/api/preflight` | Check that each `{ name, cli }` agent can be spawned. | | `POST` | `/api/shutdown` | Graceful broker shutdown. | -| `GET` | `/api/harnesses` | List named in-memory harness configs. | -| `PUT` | `/api/harnesses/{id}` | Register or replace a named harness config. | ### Agent lifecycle @@ -93,16 +91,15 @@ Body (fields accept both camelCase and snake_case): "idleThresholdSecs": 0, "skipRelayPrompt": false, "restartPolicy": null, - "harnessId": null, "harnessConfig": null, "agentToken": null } ``` -`name` and `cli` are required. `harnessId` references a config registered with -`/api/harnesses/{id}`. `harnessConfig` sends a one-off concrete config. Provide -at most one of them. Returns `{ "success": true, ... }` on success or -`{ "success": false, "error": "..." }` with a non-2xx status on failure. +`name` and `cli` are required. `harnessConfig` sends a concrete broker-executable +config for a custom PTY or headless harness. Returns `{ "success": true, ... }` +on success or `{ "success": false, "error": "..." }` with a non-2xx status on +failure. ### PTY interaction diff --git a/web/content/docs/typescript-sdk.mdx b/web/content/docs/typescript-sdk.mdx index a08e286e0..c4ce2808a 100644 --- a/web/content/docs/typescript-sdk.mdx +++ b/web/content/docs/typescript-sdk.mdx @@ -200,8 +200,6 @@ const client = await AgentRelayClient.spawn({ cwd: '/my/project' }); | `client.spawnProvider(input)` | `POST /api/spawn` | Spawn by provider and transport. | | `client.spawnClaude(input)` | `POST /api/spawn` | Spawn a Claude worker. | | `client.spawnOpencode(input)` | `POST /api/spawn` | Spawn an OpenCode worker. | -| `client.registerHarness(name, config)` | `PUT /api/harnesses/{name}` | Register a named harness config. | -| `client.listHarnesses()` | `GET /api/harnesses` | List named harness configs. | | `client.release(name, reason?)` | `DELETE /api/spawned/{name}` | Release a worker. | | `client.listAgents()` | `GET /api/spawned` | List running workers. | | `client.sendMessage(input)` | `POST /api/send` | Inject a relay message. | From 9061a034dca4763de6957ea4b74974fab99e63ce Mon Sep 17 00:00:00 2001 From: Will Washburn Date: Mon, 25 May 2026 19:32:55 -0400 Subject: [PATCH 13/19] Fix SDK spawn pid null handling --- .../completed/2026-05/traj_l67sex3nkzfq.json | 53 +++++++++++++++++++ .../completed/2026-05/traj_l67sex3nkzfq.md | 33 ++++++++++++ .trajectories/index.json | 9 +++- CHANGELOG.md | 1 + .../sdk/src/__tests__/lifecycle-hooks.test.ts | 9 ++++ packages/sdk/src/client.ts | 3 +- 6 files changed, 106 insertions(+), 2 deletions(-) create mode 100644 .trajectories/completed/2026-05/traj_l67sex3nkzfq.json create mode 100644 .trajectories/completed/2026-05/traj_l67sex3nkzfq.md diff --git a/.trajectories/completed/2026-05/traj_l67sex3nkzfq.json b/.trajectories/completed/2026-05/traj_l67sex3nkzfq.json new file mode 100644 index 000000000..8838acaaf --- /dev/null +++ b/.trajectories/completed/2026-05/traj_l67sex3nkzfq.json @@ -0,0 +1,53 @@ +{ + "id": "traj_l67sex3nkzfq", + "version": 1, + "task": { + "title": "Fix failing harness PR e2e tests" + }, + "status": "completed", + "startedAt": "2026-05-25T23:22:50.714Z", + "completedAt": "2026-05-25T23:32:19.352Z", + "agents": [ + { + "name": "default", + "role": "lead", + "joinedAt": "2026-05-25T23:32:15.085Z" + } + ], + "chapters": [ + { + "id": "chap_8194bsxpmfsk", + "title": "Work", + "agentName": "default", + "startedAt": "2026-05-25T23:32:15.085Z", + "endedAt": "2026-05-25T23:32:19.352Z", + "events": [ + { + "ts": 1779751935086, + "type": "decision", + "content": "Normalize null spawn pid in SDK schema: Normalize null spawn pid in SDK schema", + "raw": { + "question": "Normalize null spawn pid in SDK schema", + "chosen": "Normalize null spawn pid in SDK schema", + "alternatives": [], + "reasoning": "CI showed /api/spawn can return pid:null before the PTY worker emits worker_ready with the harness PID; the SDK public type already treats pid as optional, so null should parse as undefined like sessionId." + }, + "significance": "high" + } + ] + } + ], + "retrospective": { + "summary": "Fixed the SDK spawn result schema so broker pid:null responses parse as undefined, added a regression test, and validated SDK checks/build plus daemon-only E2E smoke.", + "approach": "Standard approach", + "confidence": 0.88 + }, + "commits": [], + "filesChanged": [], + "projectId": "/Users/will/Projects/AgentWorkforce/relay", + "tags": [], + "_trace": { + "startRef": "af884f5961dbc9a62b751e2d29994e5755cc3552", + "endRef": "af884f5961dbc9a62b751e2d29994e5755cc3552" + } +} diff --git a/.trajectories/completed/2026-05/traj_l67sex3nkzfq.md b/.trajectories/completed/2026-05/traj_l67sex3nkzfq.md new file mode 100644 index 000000000..7666c2a1d --- /dev/null +++ b/.trajectories/completed/2026-05/traj_l67sex3nkzfq.md @@ -0,0 +1,33 @@ +# Trajectory: Fix failing harness PR e2e tests + +> **Status:** ✅ Completed +> **Confidence:** 88% +> **Started:** May 25, 2026 at 07:22 PM +> **Completed:** May 25, 2026 at 07:32 PM + +--- + +## Summary + +Fixed the SDK spawn result schema so broker pid:null responses parse as undefined, added a regression test, and validated SDK checks/build plus daemon-only E2E smoke. + +**Approach:** Standard approach + +--- + +## Key Decisions + +### Normalize null spawn pid in SDK schema + +- **Chose:** Normalize null spawn pid in SDK schema +- **Reasoning:** CI showed /api/spawn can return pid:null before the PTY worker emits worker_ready with the harness PID; the SDK public type already treats pid as optional, so null should parse as undefined like sessionId. + +--- + +## Chapters + +### 1. Work + +_Agent: default_ + +- Normalize null spawn pid in SDK schema: Normalize null spawn pid in SDK schema diff --git a/.trajectories/index.json b/.trajectories/index.json index d54bc5d2d..90811de22 100644 --- a/.trajectories/index.json +++ b/.trajectories/index.json @@ -1,6 +1,6 @@ { "version": 1, - "lastUpdated": "2026-05-25T22:25:19.057Z", + "lastUpdated": "2026-05-25T23:32:19.526Z", "trajectories": { "traj_05xg7j388bc4": { "title": "Add browser workflow step integration", @@ -1191,6 +1191,13 @@ "startedAt": "2026-05-25T22:03:51.255Z", "completedAt": "2026-05-25T22:25:18.889Z", "path": ".trajectories/completed/2026-05/traj_qbq3laxbvhzf.json" + }, + "traj_l67sex3nkzfq": { + "title": "Fix failing harness PR e2e tests", + "status": "completed", + "startedAt": "2026-05-25T23:22:50.714Z", + "completedAt": "2026-05-25T23:32:19.352Z", + "path": ".trajectories/completed/2026-05/traj_l67sex3nkzfq.json" } } } diff --git a/CHANGELOG.md b/CHANGELOG.md index 963b18eb6..76b0bf2cd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -35,6 +35,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed - `agent-relay-broker` harness configs now report harness PIDs instead of wrapper worker PIDs, validate app-server protocol/auth/host settings at spawn, and give app-server release requests time to finish. +- `@agent-relay/sdk` normalizes broker `pid: null` spawn responses to `undefined` while PTY harness PIDs are reported asynchronously. - `web`: PR preview SST deploys use and comment the generated CloudFront URL and AWS's managed disabled cache policy instead of creating per-preview Cloudflare DNS records, ACM certificates, and custom CloudFront cache policies. ### Security diff --git a/packages/sdk/src/__tests__/lifecycle-hooks.test.ts b/packages/sdk/src/__tests__/lifecycle-hooks.test.ts index ca3cb93ea..7aaf4447a 100644 --- a/packages/sdk/src/__tests__/lifecycle-hooks.test.ts +++ b/packages/sdk/src/__tests__/lifecycle-hooks.test.ts @@ -87,6 +87,15 @@ describe('AgentRelayClient lifecycle hooks', () => { expect(result.sessionId).toBeUndefined(); }); + it('normalizes null spawn pid to undefined', async () => { + const { fetchFn } = makeMockFetch([() => ({ name: 'agent-null-pid', runtime: 'pty', pid: null })]); + const client = makeClient(fetchFn); + + const result = await client.spawnPty({ name: 'agent-null-pid', cli: 'claude' }); + + expect(result.pid).toBeUndefined(); + }); + it('folds beforeAgentSpawn patches into resolvedInput before POST', async () => { const { fetchFn, captures } = makeMockFetch(); const client = makeClient(fetchFn); diff --git a/packages/sdk/src/client.ts b/packages/sdk/src/client.ts index bf5958ae6..a1fea3766 100644 --- a/packages/sdk/src/client.ts +++ b/packages/sdk/src/client.ts @@ -118,6 +118,7 @@ export interface AgentRelaySpawnOptions { } const optionalString = z.preprocess((value) => (value === null ? undefined : value), z.string().optional()); +const optionalNumber = z.preprocess((value) => (value === null ? undefined : value), z.number().optional()); export const SpawnAgentResultSchema = z .object({ @@ -125,7 +126,7 @@ export const SpawnAgentResultSchema = z name: z.string(), runtime: z.enum(['pty', 'headless']), model: z.string().nullable().optional(), - pid: z.number().optional(), + pid: optionalNumber, pre_registered: z.boolean().optional(), warning: z.string().nullable().optional(), sessionId: optionalString, From 7dd7af66d2cb418345959e9de6dbae094cc7534c Mon Sep 17 00:00:00 2001 From: Will Washburn Date: Tue, 26 May 2026 08:31:49 -0400 Subject: [PATCH 14/19] Move trajectories into .agentworkforce Rename/move trajectory files from the top-level .trajectories tree into the .agentworkforce/trajectories directory, preserving compacted and completed subdirectories and filenames. This reorganizes storage of JSON/MD/trace files and includes the addition of traj_9d5mdl0oj0ao.{json,md} in completed/2026-05. --- .../compact_gqmrna24cmm4_2026-05-19.json | 0 .../compact_gqmrna24cmm4_2026-05-19.md | 0 .../compact_j5u7qhaw4q6a_2026-05-08.json | 0 .../compact_j5u7qhaw4q6a_2026-05-08.md | 0 .../compacted/release-6.0.13.json | 0 .../trajectories}/compacted/release-6.0.13.md | 0 .../compacted/release-6.2.3.json | 0 .../trajectories}/compacted/release-6.2.3.md | 0 .../completed/2026-04/traj_05xg7j388bc4.json | 0 .../completed/2026-04/traj_05xg7j388bc4.md | 0 .../completed/2026-04/traj_0t92gxaz6igh.json | 0 .../completed/2026-04/traj_0t92gxaz6igh.md | 0 .../2026-04/traj_1776105620545_9dcebb3d.json | 0 .../2026-04/traj_1776105620545_9dcebb3d.md | 0 .../2026-04/traj_1776105988184_29f1270c.json | 0 .../2026-04/traj_1776105988184_29f1270c.md | 0 .../completed/2026-04/traj_222ha5671idc.json | 0 .../completed/2026-04/traj_222ha5671idc.md | 0 .../completed/2026-04/traj_3b3p1z4y7qlo.json | 0 .../completed/2026-04/traj_3b3p1z4y7qlo.md | 0 .../completed/2026-04/traj_4zqhfqw7g28l.json | 0 .../completed/2026-04/traj_4zqhfqw7g28l.md | 0 .../completed/2026-04/traj_530xmbfeljyb.json | 0 .../completed/2026-04/traj_530xmbfeljyb.md | 0 .../completed/2026-04/traj_703m7sqyq89t.json | 0 .../completed/2026-04/traj_703m7sqyq89t.md | 0 .../completed/2026-04/traj_8oh4r5km5eic.json | 0 .../completed/2026-04/traj_8oh4r5km5eic.md | 0 .../completed/2026-04/traj_9tt55is74dq5.json | 0 .../completed/2026-04/traj_9tt55is74dq5.md | 0 .../completed/2026-04/traj_abjovknvcijv.json | 0 .../completed/2026-04/traj_abjovknvcijv.md | 0 .../completed/2026-04/traj_avmkyoo2s3rt.json | 0 .../completed/2026-04/traj_avmkyoo2s3rt.md | 0 .../completed/2026-04/traj_d48czxmgx4ac.json | 0 .../completed/2026-04/traj_d48czxmgx4ac.md | 0 .../completed/2026-04/traj_dw8ihhdb8ip7.json | 0 .../completed/2026-04/traj_dw8ihhdb8ip7.md | 0 .../completed/2026-04/traj_e5i62wdjx0jd.json | 0 .../completed/2026-04/traj_e5i62wdjx0jd.md | 0 .../completed/2026-04/traj_g3muawdq6bsb.json | 0 .../completed/2026-04/traj_g3muawdq6bsb.md | 0 .../completed/2026-04/traj_mk0t0cgn4ytq.json | 0 .../completed/2026-04/traj_mk0t0cgn4ytq.md | 0 .../completed/2026-04/traj_o8kgzhfu6jth.json | 0 .../completed/2026-04/traj_o8kgzhfu6jth.md | 0 .../completed/2026-04/traj_qb54w47qwod6.json | 0 .../completed/2026-04/traj_qb54w47qwod6.md | 0 .../completed/2026-04/traj_rs2bt3x0fqba.json | 0 .../completed/2026-04/traj_rs2bt3x0fqba.md | 0 .../completed/2026-04/traj_tjadoebpscps.json | 0 .../completed/2026-04/traj_tjadoebpscps.md | 0 .../completed/2026-04/traj_tv1x9pamkqad.json | 0 .../completed/2026-04/traj_tv1x9pamkqad.md | 0 .../completed/2026-04/traj_ui5omrgz819d.json | 0 .../completed/2026-04/traj_ui5omrgz819d.md | 0 .../completed/2026-04/traj_w0xpsaoxuiyw.json | 0 .../completed/2026-04/traj_w0xpsaoxuiyw.md | 0 .../completed/2026-05/traj_0d1efjk6aeo2.json | 0 .../completed/2026-05/traj_0d1efjk6aeo2.md | 0 .../completed/2026-05/traj_0e8i20oitwvz.json | 0 .../completed/2026-05/traj_0e8i20oitwvz.md | 0 .../completed/2026-05/traj_0o6gb2wvk59t.json | 0 .../completed/2026-05/traj_0o6gb2wvk59t.md | 0 .../completed/2026-05/traj_0z98tkaigaxg.json | 0 .../completed/2026-05/traj_0z98tkaigaxg.md | 0 .../2026-05/traj_1775914133873_35667beb.json | 0 .../2026-05/traj_1775914133873_35667beb.md | 0 .../2026-05/traj_1776073106646_1839be2d.json | 0 .../2026-05/traj_1776073106646_1839be2d.md | 0 .../2026-05/traj_1776113772922_bc92f121.json | 0 .../2026-05/traj_1776113772922_bc92f121.md | 0 .../2026-05/traj_1778873209642_c70e32ab.json | 0 .../2026-05/traj_1778873209642_c70e32ab.md | 0 .../2026-05/traj_1778873211616_6db3b2cd.json | 0 .../2026-05/traj_1778873211616_6db3b2cd.md | 0 .../completed/2026-05/traj_1fjub7c9rlap.json | 0 .../completed/2026-05/traj_1fjub7c9rlap.md | 0 .../completed/2026-05/traj_1rrpe2r7fyem.json | 0 .../completed/2026-05/traj_1rrpe2r7fyem.md | 0 .../completed/2026-05/traj_2gpglosdsq7s.json | 0 .../completed/2026-05/traj_2gpglosdsq7s.md | 0 .../completed/2026-05/traj_2tqxnib25omk.json | 0 .../completed/2026-05/traj_2tqxnib25omk.md | 0 .../completed/2026-05/traj_2yicjxgajt0a.json | 0 .../completed/2026-05/traj_2yicjxgajt0a.md | 0 .../completed/2026-05/traj_34b1u84b19gz.json | 0 .../completed/2026-05/traj_34b1u84b19gz.md | 0 .../completed/2026-05/traj_3b3p1z4y7qlo.json | 0 .../completed/2026-05/traj_3b3p1z4y7qlo.md | 0 .../completed/2026-05/traj_3gjtcykvybt5.json | 0 .../completed/2026-05/traj_3gjtcykvybt5.md | 0 .../completed/2026-05/traj_47akjihewlow.json | 0 .../completed/2026-05/traj_47akjihewlow.md | 0 .../2026-05/traj_47akjihewlow.trace.json | 0 .../completed/2026-05/traj_4chzkm724ufo.json | 0 .../completed/2026-05/traj_4chzkm724ufo.md | 0 .../completed/2026-05/traj_4t07itef99ug.json | 0 .../completed/2026-05/traj_4t07itef99ug.md | 0 .../completed/2026-05/traj_4vucir4qvqa2.json | 0 .../completed/2026-05/traj_4vucir4qvqa2.md | 0 .../completed/2026-05/traj_5k0jtc1g5l33.json | 0 .../completed/2026-05/traj_5k0jtc1g5l33.md | 0 .../completed/2026-05/traj_5nzj6v56id4z.json | 0 .../completed/2026-05/traj_5q8i0iz4klpo.json | 0 .../completed/2026-05/traj_5q8i0iz4klpo.md | 0 .../completed/2026-05/traj_5qbla7w4kzoi.json | 0 .../completed/2026-05/traj_5qbla7w4kzoi.md | 0 .../completed/2026-05/traj_60qc24ufr96g.json | 0 .../completed/2026-05/traj_60qc24ufr96g.md | 0 .../completed/2026-05/traj_6sjeohtm3php.json | 0 .../completed/2026-05/traj_6sjeohtm3php.md | 0 .../completed/2026-05/traj_6ujzpx82gqs9.json | 0 .../completed/2026-05/traj_6ujzpx82gqs9.md | 0 .../completed/2026-05/traj_78ytpicts778.json | 0 .../completed/2026-05/traj_78ytpicts778.md | 0 .../completed/2026-05/traj_7i9tigaejfje.json | 0 .../completed/2026-05/traj_7i9tigaejfje.md | 0 .../completed/2026-05/traj_7uznwzoxbao6.json | 0 .../completed/2026-05/traj_7uznwzoxbao6.md | 0 .../completed/2026-05/traj_7zu7et53ph3l.json | 0 .../completed/2026-05/traj_7zu7et53ph3l.md | 0 .../completed/2026-05/traj_81kobstnzzwk.json | 0 .../completed/2026-05/traj_8ljgydz61do5.json | 0 .../completed/2026-05/traj_8ljgydz61do5.md | 0 .../completed/2026-05/traj_8nhd9lljhbsw.json | 0 .../completed/2026-05/traj_8nhd9lljhbsw.md | 0 .../completed/2026-05/traj_90jmd9z27oap.json | 0 .../completed/2026-05/traj_90jmd9z27oap.md | 0 .../completed/2026-05/traj_947wzpddsg9j.json | 0 .../completed/2026-05/traj_947wzpddsg9j.md | 0 .../completed/2026-05/traj_9d5mdl0oj0ao.json | 25 + .../completed/2026-05/traj_9d5mdl0oj0ao.md | 14 + .../completed/2026-05/traj_9dj3qiugt26j.json | 0 .../completed/2026-05/traj_9dj3qiugt26j.md | 0 .../completed/2026-05/traj_9fdv7hxm0b60.json | 0 .../completed/2026-05/traj_9fdv7hxm0b60.md | 0 .../completed/2026-05/traj_9gq96irkj00s.json | 0 .../completed/2026-05/traj_9gq96irkj00s.md | 0 .../completed/2026-05/traj_aw7stgf4qau0.json | 0 .../completed/2026-05/traj_aw7stgf4qau0.md | 0 .../completed/2026-05/traj_bd431l65n9lg.json | 0 .../completed/2026-05/traj_bd431l65n9lg.md | 0 .../completed/2026-05/traj_bdrlknyl8twj.json | 0 .../completed/2026-05/traj_bdrlknyl8twj.md | 0 .../completed/2026-05/traj_bz1a1o15p7px.json | 0 .../completed/2026-05/traj_bz1a1o15p7px.md | 0 .../completed/2026-05/traj_cbmwd07phhm2.json | 0 .../completed/2026-05/traj_cbmwd07phhm2.md | 0 .../completed/2026-05/traj_ceo5q9bh2od3.json | 0 .../completed/2026-05/traj_ceo5q9bh2od3.md | 0 .../completed/2026-05/traj_cszfl2icaj2t.json | 0 .../completed/2026-05/traj_cszfl2icaj2t.md | 0 .../completed/2026-05/traj_d89s38ddu7cj.json | 0 .../completed/2026-05/traj_d89s38ddu7cj.md | 0 .../completed/2026-05/traj_dbsnr453nxjw.json | 0 .../completed/2026-05/traj_dbsnr453nxjw.md | 0 .../completed/2026-05/traj_dcl9hgoiuac5.json | 0 .../completed/2026-05/traj_dcl9hgoiuac5.md | 0 .../completed/2026-05/traj_dpgn0am1jq1c.json | 0 .../completed/2026-05/traj_dpgn0am1jq1c.md | 0 .../completed/2026-05/traj_e1b7ww3un1u3.json | 0 .../completed/2026-05/traj_e1b7ww3un1u3.md | 0 .../completed/2026-05/traj_elx0fcwgs37x.json | 0 .../completed/2026-05/traj_elx0fcwgs37x.md | 0 .../completed/2026-05/traj_erzd7j9nto9r.json | 0 .../completed/2026-05/traj_erzd7j9nto9r.md | 0 .../completed/2026-05/traj_f1iac9ngymlj.json | 0 .../completed/2026-05/traj_f1iac9ngymlj.md | 0 .../completed/2026-05/traj_f3arvbmmlomn.json | 0 .../completed/2026-05/traj_f3arvbmmlomn.md | 0 .../completed/2026-05/traj_f9wxa8ujeg78.json | 0 .../completed/2026-05/traj_f9wxa8ujeg78.md | 0 .../completed/2026-05/traj_fh8oosbijpwc.json | 0 .../completed/2026-05/traj_fh8oosbijpwc.md | 0 .../2026-05/traj_fh8oosbijpwc.trace.json | 0 .../completed/2026-05/traj_fiygtgr3tfey.json | 0 .../completed/2026-05/traj_fiygtgr3tfey.md | 0 .../completed/2026-05/traj_gh05rj5gwsap.json | 0 .../completed/2026-05/traj_gh05rj5gwsap.md | 0 .../2026-05/traj_gh05rj5gwsap.trace.json | 0 .../completed/2026-05/traj_gkxajksmwoea.json | 0 .../completed/2026-05/traj_gkxajksmwoea.md | 0 .../completed/2026-05/traj_gnqvtoxtc8dy.json | 0 .../completed/2026-05/traj_gnqvtoxtc8dy.md | 0 .../completed/2026-05/traj_hfkww5z7trxn.json | 0 .../completed/2026-05/traj_hfkww5z7trxn.md | 0 .../completed/2026-05/traj_hrsndfzk0qay.json | 0 .../completed/2026-05/traj_hrsndfzk0qay.md | 0 .../completed/2026-05/traj_hysw5o7idqas.json | 0 .../completed/2026-05/traj_hysw5o7idqas.md | 0 .../completed/2026-05/traj_i2pjnx3dll5b.json | 0 .../completed/2026-05/traj_i2pjnx3dll5b.md | 0 .../2026-05/traj_i2pjnx3dll5b.trace.json | 0 .../completed/2026-05/traj_ij5b3kcatvwn.json | 0 .../completed/2026-05/traj_ij5b3kcatvwn.md | 0 .../completed/2026-05/traj_iole5zdt9orr.json | 0 .../completed/2026-05/traj_iole5zdt9orr.md | 0 .../completed/2026-05/traj_irafiyk6wpw0.json | 0 .../completed/2026-05/traj_itgr2w8qs3xn.json | 0 .../completed/2026-05/traj_itgr2w8qs3xn.md | 0 .../completed/2026-05/traj_j9k10fez3e81.json | 0 .../completed/2026-05/traj_j9k10fez3e81.md | 0 .../completed/2026-05/traj_jbo2x14y7ovt.json | 0 .../completed/2026-05/traj_jbo2x14y7ovt.md | 0 .../completed/2026-05/traj_jmf9pyt3zikn.json | 0 .../completed/2026-05/traj_jmf9pyt3zikn.md | 0 .../completed/2026-05/traj_k7njijv51iq4.json | 0 .../completed/2026-05/traj_k7njijv51iq4.md | 0 .../completed/2026-05/traj_kgl2opmmfvus.json | 0 .../completed/2026-05/traj_kgl2opmmfvus.md | 0 .../completed/2026-05/traj_l1349adi1g0o.json | 0 .../completed/2026-05/traj_l1349adi1g0o.md | 0 .../completed/2026-05/traj_l67sex3nkzfq.json | 0 .../completed/2026-05/traj_l67sex3nkzfq.md | 0 .../completed/2026-05/traj_lhyrcib40kao.json | 0 .../completed/2026-05/traj_lhyrcib40kao.md | 0 .../completed/2026-05/traj_lieyyspidhfj.json | 0 .../completed/2026-05/traj_lieyyspidhfj.md | 0 .../2026-05/traj_lieyyspidhfj.trace.json | 0 .../completed/2026-05/traj_m7mpv7j8n78h.json | 0 .../completed/2026-05/traj_m7mpv7j8n78h.md | 0 .../completed/2026-05/traj_mi9eqd4rjfea.json | 0 .../completed/2026-05/traj_mi9eqd4rjfea.md | 0 .../completed/2026-05/traj_mytnzgfayj3d.json | 0 .../completed/2026-05/traj_mytnzgfayj3d.md | 0 .../completed/2026-05/traj_mz5m5ysjj31e.json | 0 .../completed/2026-05/traj_mz5m5ysjj31e.md | 0 .../completed/2026-05/traj_n0qwpjvmdl2s.json | 0 .../completed/2026-05/traj_n0qwpjvmdl2s.md | 0 .../completed/2026-05/traj_n8duofq5vq1a.json | 0 .../completed/2026-05/traj_n8duofq5vq1a.md | 0 .../completed/2026-05/traj_o251whkvy9rl.json | 0 .../completed/2026-05/traj_o251whkvy9rl.md | 0 .../completed/2026-05/traj_o9cx33xn5u39.json | 0 .../completed/2026-05/traj_o9cx33xn5u39.md | 0 .../completed/2026-05/traj_ootb5rt3tozd.json | 0 .../completed/2026-05/traj_ootb5rt3tozd.md | 0 .../completed/2026-05/traj_oyc528j7suvo.json | 0 .../completed/2026-05/traj_oyc528j7suvo.md | 0 .../completed/2026-05/traj_piik8r6zu3i7.json | 0 .../completed/2026-05/traj_piik8r6zu3i7.md | 0 .../completed/2026-05/traj_pmrcfj6or3pz.json | 0 .../completed/2026-05/traj_pmrcfj6or3pz.md | 0 .../completed/2026-05/traj_q2r3c9dmdep7.json | 0 .../completed/2026-05/traj_q2r3c9dmdep7.md | 0 .../completed/2026-05/traj_qbq3laxbvhzf.json | 0 .../completed/2026-05/traj_qbq3laxbvhzf.md | 0 .../completed/2026-05/traj_qtmid2nzz0kz.json | 0 .../completed/2026-05/traj_qtmid2nzz0kz.md | 0 .../completed/2026-05/traj_ryf5sstno6p3.json | 0 .../completed/2026-05/traj_ryf5sstno6p3.md | 0 .../completed/2026-05/traj_s5ojo1f4srz4.json | 0 .../completed/2026-05/traj_s5ojo1f4srz4.md | 0 .../completed/2026-05/traj_sh2ahp9z2xg6.json | 0 .../completed/2026-05/traj_sh2ahp9z2xg6.md | 0 .../completed/2026-05/traj_sqerp89tc436.json | 0 .../completed/2026-05/traj_sqerp89tc436.md | 0 .../completed/2026-05/traj_t5uknesn2fcw.json | 0 .../completed/2026-05/traj_t5uknesn2fcw.md | 0 .../completed/2026-05/traj_t6h534vn0bpg.json | 0 .../completed/2026-05/traj_t6h534vn0bpg.md | 0 .../completed/2026-05/traj_tavtex0db4b0.json | 0 .../completed/2026-05/traj_tavtex0db4b0.md | 0 .../completed/2026-05/traj_tgism98me5na.json | 0 .../completed/2026-05/traj_tgism98me5na.md | 0 .../completed/2026-05/traj_u33qn99ijbh4.json | 0 .../completed/2026-05/traj_u33qn99ijbh4.md | 0 .../completed/2026-05/traj_u3loicehnwb4.json | 0 .../completed/2026-05/traj_u3loicehnwb4.md | 0 .../completed/2026-05/traj_u4ixmbqqm2y1.json | 0 .../completed/2026-05/traj_u4ixmbqqm2y1.md | 0 .../completed/2026-05/traj_uf8y40ewrfh0.json | 0 .../completed/2026-05/traj_uf8y40ewrfh0.md | 0 .../completed/2026-05/traj_v1wexlfur5zr.json | 0 .../completed/2026-05/traj_v1wexlfur5zr.md | 0 .../completed/2026-05/traj_v87cyrs8dke9.json | 0 .../completed/2026-05/traj_v87cyrs8dke9.md | 0 .../2026-05/traj_v87cyrs8dke9.trace.json | 0 .../completed/2026-05/traj_v9x3o92ag682.json | 0 .../completed/2026-05/traj_v9x3o92ag682.md | 0 .../completed/2026-05/traj_vfa1jr6otnjn.json | 0 .../completed/2026-05/traj_vfa1jr6otnjn.md | 0 .../completed/2026-05/traj_vkozdglobkyg.json | 0 .../completed/2026-05/traj_vkozdglobkyg.md | 0 .../completed/2026-05/traj_wbn62q4cq16h.json | 0 .../completed/2026-05/traj_wbn62q4cq16h.md | 0 .../completed/2026-05/traj_whd40oxptlhn.json | 0 .../completed/2026-05/traj_whd40oxptlhn.md | 0 .../2026-05/traj_whd40oxptlhn.trace.json | 0 .../completed/2026-05/traj_wx00tjvpptvg.json | 0 .../completed/2026-05/traj_wx00tjvpptvg.md | 0 .../completed/2026-05/traj_wzzboitm85ee.json | 0 .../completed/2026-05/traj_wzzboitm85ee.md | 0 .../completed/2026-05/traj_x37bhga2j5ph.json | 0 .../completed/2026-05/traj_x37bhga2j5ph.md | 0 .../completed/2026-05/traj_ybcrij9wg8m1.json | 0 .../completed/2026-05/traj_ybcrij9wg8m1.md | 0 .../completed/2026-05/traj_z171lng2fbbi.json | 0 .../completed/2026-05/traj_z171lng2fbbi.md | 0 .../completed/2026-05/traj_zfa6skfr32vy.json | 0 .../completed/2026-05/traj_zfa6skfr32vy.md | 0 .../completed/2026-05/traj_zqwco4gl76g3.json | 0 .../completed/2026-05/traj_zqwco4gl76g3.md | 0 .../completed/2026-05/traj_zu3252hxzoqh.json | 0 .../completed/2026-05/traj_zu3252hxzoqh.md | 0 .../completed/2026-05/traj_zyluvmlqo5j7.json | 0 .../completed/2026-05/traj_zyluvmlqo5j7.md | 0 .../traj_1775914296101_a4397efe.json | 0 .../traj_1776024661304_cfc829b9.json | 0 .../traj_1776105620545_9dcebb3d.json | 0 .../traj_1778873052429_03a4dacb.json | 0 .../traj_1778873197540_01102ade.json | 0 .../traj_1778873199489_f2ce4060.json | 0 .../traj_1778873201502_0dacf7c5.json | 0 .../traj_1778873203502_4c225b7e.json | 0 .../traj_1778873205470_a4e5f0cb.json | 0 .../traj_1778873207471_b7def991.json | 0 .../traj_1778873209642_c70e32ab.json | 0 .../traj_1778873211616_6db3b2cd.json | 0 .../traj_1778874205797_81e92307.json | 0 .../traj_1778874216773_c6b12ab2.json | 0 .../traj_1778874218579_a0225559.json | 0 .../traj_1778874224855_9c722c4b.json | 0 .../traj_1778874226983_3367d527.json | 0 .../traj_1778874229373_9cce9465.json | 0 .../traj_1778874240339_51b823cd.json | 0 .../traj_1778874241076_caa675a9.json | 0 .../traj_1778874248966_e29c4c54.json | 0 .../traj_1778874249983_12a98df3.json | 0 .../traj_1778874258229_0bdc53d8.json | 0 .../traj_1778874261453_55f49624.json | 0 .../traj_1778874261608_48fb9bf5.json | 0 .../traj_1778874269139_d7d7485a.json | 0 .../traj_1778874274412_70843e0e.json | 0 .../traj_1778874274581_71efa470.json | 0 .../traj_1778874282200_39ad11db.json | 0 .../traj_1778874283570_ce3585b8.json | 0 .../traj_1778874289674_e3f868c8.json | 0 .../traj_1778874291950_0b1b5c1f.json | 0 .../traj_1778874295927_4083d181.json | 0 .../traj_1778874296362_bdf727ff.json | 0 .trajectories/index.json | 1245 ----------------- example.ts | 38 + package-lock.json | 11 +- packages/cli/package.json | 2 +- packages/sdk/package.json | 2 +- 347 files changed, 85 insertions(+), 1252 deletions(-) rename {.trajectories => .agentworkforce/trajectories}/compacted/compact_gqmrna24cmm4_2026-05-19.json (100%) rename {.trajectories => .agentworkforce/trajectories}/compacted/compact_gqmrna24cmm4_2026-05-19.md (100%) rename {.trajectories => .agentworkforce/trajectories}/compacted/compact_j5u7qhaw4q6a_2026-05-08.json (100%) rename {.trajectories => .agentworkforce/trajectories}/compacted/compact_j5u7qhaw4q6a_2026-05-08.md (100%) rename {.trajectories => .agentworkforce/trajectories}/compacted/release-6.0.13.json (100%) rename {.trajectories => .agentworkforce/trajectories}/compacted/release-6.0.13.md (100%) rename {.trajectories => .agentworkforce/trajectories}/compacted/release-6.2.3.json (100%) rename {.trajectories => .agentworkforce/trajectories}/compacted/release-6.2.3.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-04/traj_05xg7j388bc4.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-04/traj_05xg7j388bc4.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-04/traj_0t92gxaz6igh.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-04/traj_0t92gxaz6igh.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-04/traj_1776105620545_9dcebb3d.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-04/traj_1776105620545_9dcebb3d.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-04/traj_1776105988184_29f1270c.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-04/traj_1776105988184_29f1270c.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-04/traj_222ha5671idc.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-04/traj_222ha5671idc.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-04/traj_3b3p1z4y7qlo.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-04/traj_3b3p1z4y7qlo.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-04/traj_4zqhfqw7g28l.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-04/traj_4zqhfqw7g28l.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-04/traj_530xmbfeljyb.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-04/traj_530xmbfeljyb.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-04/traj_703m7sqyq89t.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-04/traj_703m7sqyq89t.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-04/traj_8oh4r5km5eic.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-04/traj_8oh4r5km5eic.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-04/traj_9tt55is74dq5.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-04/traj_9tt55is74dq5.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-04/traj_abjovknvcijv.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-04/traj_abjovknvcijv.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-04/traj_avmkyoo2s3rt.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-04/traj_avmkyoo2s3rt.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-04/traj_d48czxmgx4ac.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-04/traj_d48czxmgx4ac.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-04/traj_dw8ihhdb8ip7.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-04/traj_dw8ihhdb8ip7.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-04/traj_e5i62wdjx0jd.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-04/traj_e5i62wdjx0jd.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-04/traj_g3muawdq6bsb.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-04/traj_g3muawdq6bsb.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-04/traj_mk0t0cgn4ytq.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-04/traj_mk0t0cgn4ytq.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-04/traj_o8kgzhfu6jth.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-04/traj_o8kgzhfu6jth.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-04/traj_qb54w47qwod6.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-04/traj_qb54w47qwod6.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-04/traj_rs2bt3x0fqba.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-04/traj_rs2bt3x0fqba.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-04/traj_tjadoebpscps.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-04/traj_tjadoebpscps.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-04/traj_tv1x9pamkqad.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-04/traj_tv1x9pamkqad.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-04/traj_ui5omrgz819d.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-04/traj_ui5omrgz819d.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-04/traj_w0xpsaoxuiyw.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-04/traj_w0xpsaoxuiyw.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_0d1efjk6aeo2.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_0d1efjk6aeo2.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_0e8i20oitwvz.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_0e8i20oitwvz.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_0o6gb2wvk59t.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_0o6gb2wvk59t.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_0z98tkaigaxg.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_0z98tkaigaxg.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_1775914133873_35667beb.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_1775914133873_35667beb.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_1776073106646_1839be2d.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_1776073106646_1839be2d.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_1776113772922_bc92f121.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_1776113772922_bc92f121.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_1778873209642_c70e32ab.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_1778873209642_c70e32ab.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_1778873211616_6db3b2cd.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_1778873211616_6db3b2cd.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_1fjub7c9rlap.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_1fjub7c9rlap.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_1rrpe2r7fyem.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_1rrpe2r7fyem.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_2gpglosdsq7s.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_2gpglosdsq7s.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_2tqxnib25omk.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_2tqxnib25omk.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_2yicjxgajt0a.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_2yicjxgajt0a.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_34b1u84b19gz.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_34b1u84b19gz.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_3b3p1z4y7qlo.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_3b3p1z4y7qlo.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_3gjtcykvybt5.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_3gjtcykvybt5.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_47akjihewlow.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_47akjihewlow.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_47akjihewlow.trace.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_4chzkm724ufo.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_4chzkm724ufo.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_4t07itef99ug.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_4t07itef99ug.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_4vucir4qvqa2.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_4vucir4qvqa2.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_5k0jtc1g5l33.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_5k0jtc1g5l33.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_5nzj6v56id4z.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_5q8i0iz4klpo.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_5q8i0iz4klpo.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_5qbla7w4kzoi.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_5qbla7w4kzoi.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_60qc24ufr96g.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_60qc24ufr96g.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_6sjeohtm3php.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_6sjeohtm3php.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_6ujzpx82gqs9.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_6ujzpx82gqs9.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_78ytpicts778.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_78ytpicts778.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_7i9tigaejfje.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_7i9tigaejfje.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_7uznwzoxbao6.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_7uznwzoxbao6.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_7zu7et53ph3l.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_7zu7et53ph3l.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_81kobstnzzwk.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_8ljgydz61do5.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_8ljgydz61do5.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_8nhd9lljhbsw.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_8nhd9lljhbsw.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_90jmd9z27oap.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_90jmd9z27oap.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_947wzpddsg9j.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_947wzpddsg9j.md (100%) create mode 100644 .agentworkforce/trajectories/completed/2026-05/traj_9d5mdl0oj0ao.json create mode 100644 .agentworkforce/trajectories/completed/2026-05/traj_9d5mdl0oj0ao.md rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_9dj3qiugt26j.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_9dj3qiugt26j.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_9fdv7hxm0b60.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_9fdv7hxm0b60.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_9gq96irkj00s.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_9gq96irkj00s.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_aw7stgf4qau0.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_aw7stgf4qau0.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_bd431l65n9lg.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_bd431l65n9lg.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_bdrlknyl8twj.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_bdrlknyl8twj.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_bz1a1o15p7px.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_bz1a1o15p7px.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_cbmwd07phhm2.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_cbmwd07phhm2.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_ceo5q9bh2od3.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_ceo5q9bh2od3.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_cszfl2icaj2t.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_cszfl2icaj2t.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_d89s38ddu7cj.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_d89s38ddu7cj.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_dbsnr453nxjw.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_dbsnr453nxjw.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_dcl9hgoiuac5.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_dcl9hgoiuac5.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_dpgn0am1jq1c.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_dpgn0am1jq1c.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_e1b7ww3un1u3.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_e1b7ww3un1u3.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_elx0fcwgs37x.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_elx0fcwgs37x.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_erzd7j9nto9r.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_erzd7j9nto9r.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_f1iac9ngymlj.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_f1iac9ngymlj.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_f3arvbmmlomn.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_f3arvbmmlomn.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_f9wxa8ujeg78.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_f9wxa8ujeg78.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_fh8oosbijpwc.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_fh8oosbijpwc.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_fh8oosbijpwc.trace.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_fiygtgr3tfey.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_fiygtgr3tfey.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_gh05rj5gwsap.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_gh05rj5gwsap.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_gh05rj5gwsap.trace.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_gkxajksmwoea.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_gkxajksmwoea.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_gnqvtoxtc8dy.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_gnqvtoxtc8dy.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_hfkww5z7trxn.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_hfkww5z7trxn.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_hrsndfzk0qay.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_hrsndfzk0qay.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_hysw5o7idqas.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_hysw5o7idqas.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_i2pjnx3dll5b.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_i2pjnx3dll5b.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_i2pjnx3dll5b.trace.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_ij5b3kcatvwn.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_ij5b3kcatvwn.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_iole5zdt9orr.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_iole5zdt9orr.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_irafiyk6wpw0.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_itgr2w8qs3xn.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_itgr2w8qs3xn.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_j9k10fez3e81.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_j9k10fez3e81.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_jbo2x14y7ovt.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_jbo2x14y7ovt.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_jmf9pyt3zikn.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_jmf9pyt3zikn.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_k7njijv51iq4.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_k7njijv51iq4.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_kgl2opmmfvus.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_kgl2opmmfvus.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_l1349adi1g0o.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_l1349adi1g0o.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_l67sex3nkzfq.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_l67sex3nkzfq.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_lhyrcib40kao.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_lhyrcib40kao.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_lieyyspidhfj.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_lieyyspidhfj.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_lieyyspidhfj.trace.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_m7mpv7j8n78h.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_m7mpv7j8n78h.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_mi9eqd4rjfea.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_mi9eqd4rjfea.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_mytnzgfayj3d.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_mytnzgfayj3d.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_mz5m5ysjj31e.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_mz5m5ysjj31e.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_n0qwpjvmdl2s.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_n0qwpjvmdl2s.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_n8duofq5vq1a.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_n8duofq5vq1a.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_o251whkvy9rl.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_o251whkvy9rl.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_o9cx33xn5u39.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_o9cx33xn5u39.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_ootb5rt3tozd.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_ootb5rt3tozd.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_oyc528j7suvo.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_oyc528j7suvo.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_piik8r6zu3i7.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_piik8r6zu3i7.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_pmrcfj6or3pz.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_pmrcfj6or3pz.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_q2r3c9dmdep7.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_q2r3c9dmdep7.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_qbq3laxbvhzf.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_qbq3laxbvhzf.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_qtmid2nzz0kz.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_qtmid2nzz0kz.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_ryf5sstno6p3.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_ryf5sstno6p3.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_s5ojo1f4srz4.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_s5ojo1f4srz4.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_sh2ahp9z2xg6.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_sh2ahp9z2xg6.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_sqerp89tc436.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_sqerp89tc436.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_t5uknesn2fcw.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_t5uknesn2fcw.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_t6h534vn0bpg.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_t6h534vn0bpg.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_tavtex0db4b0.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_tavtex0db4b0.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_tgism98me5na.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_tgism98me5na.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_u33qn99ijbh4.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_u33qn99ijbh4.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_u3loicehnwb4.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_u3loicehnwb4.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_u4ixmbqqm2y1.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_u4ixmbqqm2y1.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_uf8y40ewrfh0.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_uf8y40ewrfh0.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_v1wexlfur5zr.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_v1wexlfur5zr.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_v87cyrs8dke9.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_v87cyrs8dke9.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_v87cyrs8dke9.trace.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_v9x3o92ag682.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_v9x3o92ag682.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_vfa1jr6otnjn.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_vfa1jr6otnjn.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_vkozdglobkyg.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_vkozdglobkyg.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_wbn62q4cq16h.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_wbn62q4cq16h.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_whd40oxptlhn.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_whd40oxptlhn.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_whd40oxptlhn.trace.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_wx00tjvpptvg.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_wx00tjvpptvg.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_wzzboitm85ee.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_wzzboitm85ee.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_x37bhga2j5ph.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_x37bhga2j5ph.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_ybcrij9wg8m1.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_ybcrij9wg8m1.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_z171lng2fbbi.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_z171lng2fbbi.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_zfa6skfr32vy.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_zfa6skfr32vy.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_zqwco4gl76g3.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_zqwco4gl76g3.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_zu3252hxzoqh.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_zu3252hxzoqh.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_zyluvmlqo5j7.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_zyluvmlqo5j7.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/traj_1775914296101_a4397efe.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/traj_1776024661304_cfc829b9.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/traj_1776105620545_9dcebb3d.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/traj_1778873052429_03a4dacb.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/traj_1778873197540_01102ade.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/traj_1778873199489_f2ce4060.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/traj_1778873201502_0dacf7c5.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/traj_1778873203502_4c225b7e.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/traj_1778873205470_a4e5f0cb.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/traj_1778873207471_b7def991.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/traj_1778873209642_c70e32ab.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/traj_1778873211616_6db3b2cd.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/traj_1778874205797_81e92307.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/traj_1778874216773_c6b12ab2.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/traj_1778874218579_a0225559.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/traj_1778874224855_9c722c4b.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/traj_1778874226983_3367d527.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/traj_1778874229373_9cce9465.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/traj_1778874240339_51b823cd.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/traj_1778874241076_caa675a9.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/traj_1778874248966_e29c4c54.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/traj_1778874249983_12a98df3.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/traj_1778874258229_0bdc53d8.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/traj_1778874261453_55f49624.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/traj_1778874261608_48fb9bf5.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/traj_1778874269139_d7d7485a.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/traj_1778874274412_70843e0e.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/traj_1778874274581_71efa470.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/traj_1778874282200_39ad11db.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/traj_1778874283570_ce3585b8.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/traj_1778874289674_e3f868c8.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/traj_1778874291950_0b1b5c1f.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/traj_1778874295927_4083d181.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/traj_1778874296362_bdf727ff.json (100%) delete mode 100644 .trajectories/index.json create mode 100644 example.ts diff --git a/.trajectories/compacted/compact_gqmrna24cmm4_2026-05-19.json b/.agentworkforce/trajectories/compacted/compact_gqmrna24cmm4_2026-05-19.json similarity index 100% rename from .trajectories/compacted/compact_gqmrna24cmm4_2026-05-19.json rename to .agentworkforce/trajectories/compacted/compact_gqmrna24cmm4_2026-05-19.json diff --git a/.trajectories/compacted/compact_gqmrna24cmm4_2026-05-19.md b/.agentworkforce/trajectories/compacted/compact_gqmrna24cmm4_2026-05-19.md similarity index 100% rename from .trajectories/compacted/compact_gqmrna24cmm4_2026-05-19.md rename to .agentworkforce/trajectories/compacted/compact_gqmrna24cmm4_2026-05-19.md diff --git a/.trajectories/compacted/compact_j5u7qhaw4q6a_2026-05-08.json b/.agentworkforce/trajectories/compacted/compact_j5u7qhaw4q6a_2026-05-08.json similarity index 100% rename from .trajectories/compacted/compact_j5u7qhaw4q6a_2026-05-08.json rename to .agentworkforce/trajectories/compacted/compact_j5u7qhaw4q6a_2026-05-08.json diff --git a/.trajectories/compacted/compact_j5u7qhaw4q6a_2026-05-08.md b/.agentworkforce/trajectories/compacted/compact_j5u7qhaw4q6a_2026-05-08.md similarity index 100% rename from .trajectories/compacted/compact_j5u7qhaw4q6a_2026-05-08.md rename to .agentworkforce/trajectories/compacted/compact_j5u7qhaw4q6a_2026-05-08.md diff --git a/.trajectories/compacted/release-6.0.13.json b/.agentworkforce/trajectories/compacted/release-6.0.13.json similarity index 100% rename from .trajectories/compacted/release-6.0.13.json rename to .agentworkforce/trajectories/compacted/release-6.0.13.json diff --git a/.trajectories/compacted/release-6.0.13.md b/.agentworkforce/trajectories/compacted/release-6.0.13.md similarity index 100% rename from .trajectories/compacted/release-6.0.13.md rename to .agentworkforce/trajectories/compacted/release-6.0.13.md diff --git a/.trajectories/compacted/release-6.2.3.json b/.agentworkforce/trajectories/compacted/release-6.2.3.json similarity index 100% rename from .trajectories/compacted/release-6.2.3.json rename to .agentworkforce/trajectories/compacted/release-6.2.3.json diff --git a/.trajectories/compacted/release-6.2.3.md b/.agentworkforce/trajectories/compacted/release-6.2.3.md similarity index 100% rename from .trajectories/compacted/release-6.2.3.md rename to .agentworkforce/trajectories/compacted/release-6.2.3.md diff --git a/.trajectories/completed/2026-04/traj_05xg7j388bc4.json b/.agentworkforce/trajectories/completed/2026-04/traj_05xg7j388bc4.json similarity index 100% rename from .trajectories/completed/2026-04/traj_05xg7j388bc4.json rename to .agentworkforce/trajectories/completed/2026-04/traj_05xg7j388bc4.json diff --git a/.trajectories/completed/2026-04/traj_05xg7j388bc4.md b/.agentworkforce/trajectories/completed/2026-04/traj_05xg7j388bc4.md similarity index 100% rename from .trajectories/completed/2026-04/traj_05xg7j388bc4.md rename to .agentworkforce/trajectories/completed/2026-04/traj_05xg7j388bc4.md diff --git a/.trajectories/completed/2026-04/traj_0t92gxaz6igh.json b/.agentworkforce/trajectories/completed/2026-04/traj_0t92gxaz6igh.json similarity index 100% rename from .trajectories/completed/2026-04/traj_0t92gxaz6igh.json rename to .agentworkforce/trajectories/completed/2026-04/traj_0t92gxaz6igh.json diff --git a/.trajectories/completed/2026-04/traj_0t92gxaz6igh.md b/.agentworkforce/trajectories/completed/2026-04/traj_0t92gxaz6igh.md similarity index 100% rename from .trajectories/completed/2026-04/traj_0t92gxaz6igh.md rename to .agentworkforce/trajectories/completed/2026-04/traj_0t92gxaz6igh.md diff --git a/.trajectories/completed/2026-04/traj_1776105620545_9dcebb3d.json b/.agentworkforce/trajectories/completed/2026-04/traj_1776105620545_9dcebb3d.json similarity index 100% rename from .trajectories/completed/2026-04/traj_1776105620545_9dcebb3d.json rename to .agentworkforce/trajectories/completed/2026-04/traj_1776105620545_9dcebb3d.json diff --git a/.trajectories/completed/2026-04/traj_1776105620545_9dcebb3d.md b/.agentworkforce/trajectories/completed/2026-04/traj_1776105620545_9dcebb3d.md similarity index 100% rename from .trajectories/completed/2026-04/traj_1776105620545_9dcebb3d.md rename to .agentworkforce/trajectories/completed/2026-04/traj_1776105620545_9dcebb3d.md diff --git a/.trajectories/completed/2026-04/traj_1776105988184_29f1270c.json b/.agentworkforce/trajectories/completed/2026-04/traj_1776105988184_29f1270c.json similarity index 100% rename from .trajectories/completed/2026-04/traj_1776105988184_29f1270c.json rename to .agentworkforce/trajectories/completed/2026-04/traj_1776105988184_29f1270c.json diff --git a/.trajectories/completed/2026-04/traj_1776105988184_29f1270c.md b/.agentworkforce/trajectories/completed/2026-04/traj_1776105988184_29f1270c.md similarity index 100% rename from .trajectories/completed/2026-04/traj_1776105988184_29f1270c.md rename to .agentworkforce/trajectories/completed/2026-04/traj_1776105988184_29f1270c.md diff --git a/.trajectories/completed/2026-04/traj_222ha5671idc.json b/.agentworkforce/trajectories/completed/2026-04/traj_222ha5671idc.json similarity index 100% rename from .trajectories/completed/2026-04/traj_222ha5671idc.json rename to .agentworkforce/trajectories/completed/2026-04/traj_222ha5671idc.json diff --git a/.trajectories/completed/2026-04/traj_222ha5671idc.md b/.agentworkforce/trajectories/completed/2026-04/traj_222ha5671idc.md similarity index 100% rename from .trajectories/completed/2026-04/traj_222ha5671idc.md rename to .agentworkforce/trajectories/completed/2026-04/traj_222ha5671idc.md diff --git a/.trajectories/completed/2026-04/traj_3b3p1z4y7qlo.json b/.agentworkforce/trajectories/completed/2026-04/traj_3b3p1z4y7qlo.json similarity index 100% rename from .trajectories/completed/2026-04/traj_3b3p1z4y7qlo.json rename to .agentworkforce/trajectories/completed/2026-04/traj_3b3p1z4y7qlo.json diff --git a/.trajectories/completed/2026-04/traj_3b3p1z4y7qlo.md b/.agentworkforce/trajectories/completed/2026-04/traj_3b3p1z4y7qlo.md similarity index 100% rename from .trajectories/completed/2026-04/traj_3b3p1z4y7qlo.md rename to .agentworkforce/trajectories/completed/2026-04/traj_3b3p1z4y7qlo.md diff --git a/.trajectories/completed/2026-04/traj_4zqhfqw7g28l.json b/.agentworkforce/trajectories/completed/2026-04/traj_4zqhfqw7g28l.json similarity index 100% rename from .trajectories/completed/2026-04/traj_4zqhfqw7g28l.json rename to .agentworkforce/trajectories/completed/2026-04/traj_4zqhfqw7g28l.json diff --git a/.trajectories/completed/2026-04/traj_4zqhfqw7g28l.md b/.agentworkforce/trajectories/completed/2026-04/traj_4zqhfqw7g28l.md similarity index 100% rename from .trajectories/completed/2026-04/traj_4zqhfqw7g28l.md rename to .agentworkforce/trajectories/completed/2026-04/traj_4zqhfqw7g28l.md diff --git a/.trajectories/completed/2026-04/traj_530xmbfeljyb.json b/.agentworkforce/trajectories/completed/2026-04/traj_530xmbfeljyb.json similarity index 100% rename from .trajectories/completed/2026-04/traj_530xmbfeljyb.json rename to .agentworkforce/trajectories/completed/2026-04/traj_530xmbfeljyb.json diff --git a/.trajectories/completed/2026-04/traj_530xmbfeljyb.md b/.agentworkforce/trajectories/completed/2026-04/traj_530xmbfeljyb.md similarity index 100% rename from .trajectories/completed/2026-04/traj_530xmbfeljyb.md rename to .agentworkforce/trajectories/completed/2026-04/traj_530xmbfeljyb.md diff --git a/.trajectories/completed/2026-04/traj_703m7sqyq89t.json b/.agentworkforce/trajectories/completed/2026-04/traj_703m7sqyq89t.json similarity index 100% rename from .trajectories/completed/2026-04/traj_703m7sqyq89t.json rename to .agentworkforce/trajectories/completed/2026-04/traj_703m7sqyq89t.json diff --git a/.trajectories/completed/2026-04/traj_703m7sqyq89t.md b/.agentworkforce/trajectories/completed/2026-04/traj_703m7sqyq89t.md similarity index 100% rename from .trajectories/completed/2026-04/traj_703m7sqyq89t.md rename to .agentworkforce/trajectories/completed/2026-04/traj_703m7sqyq89t.md diff --git a/.trajectories/completed/2026-04/traj_8oh4r5km5eic.json b/.agentworkforce/trajectories/completed/2026-04/traj_8oh4r5km5eic.json similarity index 100% rename from .trajectories/completed/2026-04/traj_8oh4r5km5eic.json rename to .agentworkforce/trajectories/completed/2026-04/traj_8oh4r5km5eic.json diff --git a/.trajectories/completed/2026-04/traj_8oh4r5km5eic.md b/.agentworkforce/trajectories/completed/2026-04/traj_8oh4r5km5eic.md similarity index 100% rename from .trajectories/completed/2026-04/traj_8oh4r5km5eic.md rename to .agentworkforce/trajectories/completed/2026-04/traj_8oh4r5km5eic.md diff --git a/.trajectories/completed/2026-04/traj_9tt55is74dq5.json b/.agentworkforce/trajectories/completed/2026-04/traj_9tt55is74dq5.json similarity index 100% rename from .trajectories/completed/2026-04/traj_9tt55is74dq5.json rename to .agentworkforce/trajectories/completed/2026-04/traj_9tt55is74dq5.json diff --git a/.trajectories/completed/2026-04/traj_9tt55is74dq5.md b/.agentworkforce/trajectories/completed/2026-04/traj_9tt55is74dq5.md similarity index 100% rename from .trajectories/completed/2026-04/traj_9tt55is74dq5.md rename to .agentworkforce/trajectories/completed/2026-04/traj_9tt55is74dq5.md diff --git a/.trajectories/completed/2026-04/traj_abjovknvcijv.json b/.agentworkforce/trajectories/completed/2026-04/traj_abjovknvcijv.json similarity index 100% rename from .trajectories/completed/2026-04/traj_abjovknvcijv.json rename to .agentworkforce/trajectories/completed/2026-04/traj_abjovknvcijv.json diff --git a/.trajectories/completed/2026-04/traj_abjovknvcijv.md b/.agentworkforce/trajectories/completed/2026-04/traj_abjovknvcijv.md similarity index 100% rename from .trajectories/completed/2026-04/traj_abjovknvcijv.md rename to .agentworkforce/trajectories/completed/2026-04/traj_abjovknvcijv.md diff --git a/.trajectories/completed/2026-04/traj_avmkyoo2s3rt.json b/.agentworkforce/trajectories/completed/2026-04/traj_avmkyoo2s3rt.json similarity index 100% rename from .trajectories/completed/2026-04/traj_avmkyoo2s3rt.json rename to .agentworkforce/trajectories/completed/2026-04/traj_avmkyoo2s3rt.json diff --git a/.trajectories/completed/2026-04/traj_avmkyoo2s3rt.md b/.agentworkforce/trajectories/completed/2026-04/traj_avmkyoo2s3rt.md similarity index 100% rename from .trajectories/completed/2026-04/traj_avmkyoo2s3rt.md rename to .agentworkforce/trajectories/completed/2026-04/traj_avmkyoo2s3rt.md diff --git a/.trajectories/completed/2026-04/traj_d48czxmgx4ac.json b/.agentworkforce/trajectories/completed/2026-04/traj_d48czxmgx4ac.json similarity index 100% rename from .trajectories/completed/2026-04/traj_d48czxmgx4ac.json rename to .agentworkforce/trajectories/completed/2026-04/traj_d48czxmgx4ac.json diff --git a/.trajectories/completed/2026-04/traj_d48czxmgx4ac.md b/.agentworkforce/trajectories/completed/2026-04/traj_d48czxmgx4ac.md similarity index 100% rename from .trajectories/completed/2026-04/traj_d48czxmgx4ac.md rename to .agentworkforce/trajectories/completed/2026-04/traj_d48czxmgx4ac.md diff --git a/.trajectories/completed/2026-04/traj_dw8ihhdb8ip7.json b/.agentworkforce/trajectories/completed/2026-04/traj_dw8ihhdb8ip7.json similarity index 100% rename from .trajectories/completed/2026-04/traj_dw8ihhdb8ip7.json rename to .agentworkforce/trajectories/completed/2026-04/traj_dw8ihhdb8ip7.json diff --git a/.trajectories/completed/2026-04/traj_dw8ihhdb8ip7.md b/.agentworkforce/trajectories/completed/2026-04/traj_dw8ihhdb8ip7.md similarity index 100% rename from .trajectories/completed/2026-04/traj_dw8ihhdb8ip7.md rename to .agentworkforce/trajectories/completed/2026-04/traj_dw8ihhdb8ip7.md diff --git a/.trajectories/completed/2026-04/traj_e5i62wdjx0jd.json b/.agentworkforce/trajectories/completed/2026-04/traj_e5i62wdjx0jd.json similarity index 100% rename from .trajectories/completed/2026-04/traj_e5i62wdjx0jd.json rename to .agentworkforce/trajectories/completed/2026-04/traj_e5i62wdjx0jd.json diff --git a/.trajectories/completed/2026-04/traj_e5i62wdjx0jd.md b/.agentworkforce/trajectories/completed/2026-04/traj_e5i62wdjx0jd.md similarity index 100% rename from .trajectories/completed/2026-04/traj_e5i62wdjx0jd.md rename to .agentworkforce/trajectories/completed/2026-04/traj_e5i62wdjx0jd.md diff --git a/.trajectories/completed/2026-04/traj_g3muawdq6bsb.json b/.agentworkforce/trajectories/completed/2026-04/traj_g3muawdq6bsb.json similarity index 100% rename from .trajectories/completed/2026-04/traj_g3muawdq6bsb.json rename to .agentworkforce/trajectories/completed/2026-04/traj_g3muawdq6bsb.json diff --git a/.trajectories/completed/2026-04/traj_g3muawdq6bsb.md b/.agentworkforce/trajectories/completed/2026-04/traj_g3muawdq6bsb.md similarity index 100% rename from .trajectories/completed/2026-04/traj_g3muawdq6bsb.md rename to .agentworkforce/trajectories/completed/2026-04/traj_g3muawdq6bsb.md diff --git a/.trajectories/completed/2026-04/traj_mk0t0cgn4ytq.json b/.agentworkforce/trajectories/completed/2026-04/traj_mk0t0cgn4ytq.json similarity index 100% rename from .trajectories/completed/2026-04/traj_mk0t0cgn4ytq.json rename to .agentworkforce/trajectories/completed/2026-04/traj_mk0t0cgn4ytq.json diff --git a/.trajectories/completed/2026-04/traj_mk0t0cgn4ytq.md b/.agentworkforce/trajectories/completed/2026-04/traj_mk0t0cgn4ytq.md similarity index 100% rename from .trajectories/completed/2026-04/traj_mk0t0cgn4ytq.md rename to .agentworkforce/trajectories/completed/2026-04/traj_mk0t0cgn4ytq.md diff --git a/.trajectories/completed/2026-04/traj_o8kgzhfu6jth.json b/.agentworkforce/trajectories/completed/2026-04/traj_o8kgzhfu6jth.json similarity index 100% rename from .trajectories/completed/2026-04/traj_o8kgzhfu6jth.json rename to .agentworkforce/trajectories/completed/2026-04/traj_o8kgzhfu6jth.json diff --git a/.trajectories/completed/2026-04/traj_o8kgzhfu6jth.md b/.agentworkforce/trajectories/completed/2026-04/traj_o8kgzhfu6jth.md similarity index 100% rename from .trajectories/completed/2026-04/traj_o8kgzhfu6jth.md rename to .agentworkforce/trajectories/completed/2026-04/traj_o8kgzhfu6jth.md diff --git a/.trajectories/completed/2026-04/traj_qb54w47qwod6.json b/.agentworkforce/trajectories/completed/2026-04/traj_qb54w47qwod6.json similarity index 100% rename from .trajectories/completed/2026-04/traj_qb54w47qwod6.json rename to .agentworkforce/trajectories/completed/2026-04/traj_qb54w47qwod6.json diff --git a/.trajectories/completed/2026-04/traj_qb54w47qwod6.md b/.agentworkforce/trajectories/completed/2026-04/traj_qb54w47qwod6.md similarity index 100% rename from .trajectories/completed/2026-04/traj_qb54w47qwod6.md rename to .agentworkforce/trajectories/completed/2026-04/traj_qb54w47qwod6.md diff --git a/.trajectories/completed/2026-04/traj_rs2bt3x0fqba.json b/.agentworkforce/trajectories/completed/2026-04/traj_rs2bt3x0fqba.json similarity index 100% rename from .trajectories/completed/2026-04/traj_rs2bt3x0fqba.json rename to .agentworkforce/trajectories/completed/2026-04/traj_rs2bt3x0fqba.json diff --git a/.trajectories/completed/2026-04/traj_rs2bt3x0fqba.md b/.agentworkforce/trajectories/completed/2026-04/traj_rs2bt3x0fqba.md similarity index 100% rename from .trajectories/completed/2026-04/traj_rs2bt3x0fqba.md rename to .agentworkforce/trajectories/completed/2026-04/traj_rs2bt3x0fqba.md diff --git a/.trajectories/completed/2026-04/traj_tjadoebpscps.json b/.agentworkforce/trajectories/completed/2026-04/traj_tjadoebpscps.json similarity index 100% rename from .trajectories/completed/2026-04/traj_tjadoebpscps.json rename to .agentworkforce/trajectories/completed/2026-04/traj_tjadoebpscps.json diff --git a/.trajectories/completed/2026-04/traj_tjadoebpscps.md b/.agentworkforce/trajectories/completed/2026-04/traj_tjadoebpscps.md similarity index 100% rename from .trajectories/completed/2026-04/traj_tjadoebpscps.md rename to .agentworkforce/trajectories/completed/2026-04/traj_tjadoebpscps.md diff --git a/.trajectories/completed/2026-04/traj_tv1x9pamkqad.json b/.agentworkforce/trajectories/completed/2026-04/traj_tv1x9pamkqad.json similarity index 100% rename from .trajectories/completed/2026-04/traj_tv1x9pamkqad.json rename to .agentworkforce/trajectories/completed/2026-04/traj_tv1x9pamkqad.json diff --git a/.trajectories/completed/2026-04/traj_tv1x9pamkqad.md b/.agentworkforce/trajectories/completed/2026-04/traj_tv1x9pamkqad.md similarity index 100% rename from .trajectories/completed/2026-04/traj_tv1x9pamkqad.md rename to .agentworkforce/trajectories/completed/2026-04/traj_tv1x9pamkqad.md diff --git a/.trajectories/completed/2026-04/traj_ui5omrgz819d.json b/.agentworkforce/trajectories/completed/2026-04/traj_ui5omrgz819d.json similarity index 100% rename from .trajectories/completed/2026-04/traj_ui5omrgz819d.json rename to .agentworkforce/trajectories/completed/2026-04/traj_ui5omrgz819d.json diff --git a/.trajectories/completed/2026-04/traj_ui5omrgz819d.md b/.agentworkforce/trajectories/completed/2026-04/traj_ui5omrgz819d.md similarity index 100% rename from .trajectories/completed/2026-04/traj_ui5omrgz819d.md rename to .agentworkforce/trajectories/completed/2026-04/traj_ui5omrgz819d.md diff --git a/.trajectories/completed/2026-04/traj_w0xpsaoxuiyw.json b/.agentworkforce/trajectories/completed/2026-04/traj_w0xpsaoxuiyw.json similarity index 100% rename from .trajectories/completed/2026-04/traj_w0xpsaoxuiyw.json rename to .agentworkforce/trajectories/completed/2026-04/traj_w0xpsaoxuiyw.json diff --git a/.trajectories/completed/2026-04/traj_w0xpsaoxuiyw.md b/.agentworkforce/trajectories/completed/2026-04/traj_w0xpsaoxuiyw.md similarity index 100% rename from .trajectories/completed/2026-04/traj_w0xpsaoxuiyw.md rename to .agentworkforce/trajectories/completed/2026-04/traj_w0xpsaoxuiyw.md diff --git a/.trajectories/completed/2026-05/traj_0d1efjk6aeo2.json b/.agentworkforce/trajectories/completed/2026-05/traj_0d1efjk6aeo2.json similarity index 100% rename from .trajectories/completed/2026-05/traj_0d1efjk6aeo2.json rename to .agentworkforce/trajectories/completed/2026-05/traj_0d1efjk6aeo2.json diff --git a/.trajectories/completed/2026-05/traj_0d1efjk6aeo2.md b/.agentworkforce/trajectories/completed/2026-05/traj_0d1efjk6aeo2.md similarity index 100% rename from .trajectories/completed/2026-05/traj_0d1efjk6aeo2.md rename to .agentworkforce/trajectories/completed/2026-05/traj_0d1efjk6aeo2.md diff --git a/.trajectories/completed/2026-05/traj_0e8i20oitwvz.json b/.agentworkforce/trajectories/completed/2026-05/traj_0e8i20oitwvz.json similarity index 100% rename from .trajectories/completed/2026-05/traj_0e8i20oitwvz.json rename to .agentworkforce/trajectories/completed/2026-05/traj_0e8i20oitwvz.json diff --git a/.trajectories/completed/2026-05/traj_0e8i20oitwvz.md b/.agentworkforce/trajectories/completed/2026-05/traj_0e8i20oitwvz.md similarity index 100% rename from .trajectories/completed/2026-05/traj_0e8i20oitwvz.md rename to .agentworkforce/trajectories/completed/2026-05/traj_0e8i20oitwvz.md diff --git a/.trajectories/completed/2026-05/traj_0o6gb2wvk59t.json b/.agentworkforce/trajectories/completed/2026-05/traj_0o6gb2wvk59t.json similarity index 100% rename from .trajectories/completed/2026-05/traj_0o6gb2wvk59t.json rename to .agentworkforce/trajectories/completed/2026-05/traj_0o6gb2wvk59t.json diff --git a/.trajectories/completed/2026-05/traj_0o6gb2wvk59t.md b/.agentworkforce/trajectories/completed/2026-05/traj_0o6gb2wvk59t.md similarity index 100% rename from .trajectories/completed/2026-05/traj_0o6gb2wvk59t.md rename to .agentworkforce/trajectories/completed/2026-05/traj_0o6gb2wvk59t.md diff --git a/.trajectories/completed/2026-05/traj_0z98tkaigaxg.json b/.agentworkforce/trajectories/completed/2026-05/traj_0z98tkaigaxg.json similarity index 100% rename from .trajectories/completed/2026-05/traj_0z98tkaigaxg.json rename to .agentworkforce/trajectories/completed/2026-05/traj_0z98tkaigaxg.json diff --git a/.trajectories/completed/2026-05/traj_0z98tkaigaxg.md b/.agentworkforce/trajectories/completed/2026-05/traj_0z98tkaigaxg.md similarity index 100% rename from .trajectories/completed/2026-05/traj_0z98tkaigaxg.md rename to .agentworkforce/trajectories/completed/2026-05/traj_0z98tkaigaxg.md diff --git a/.trajectories/completed/2026-05/traj_1775914133873_35667beb.json b/.agentworkforce/trajectories/completed/2026-05/traj_1775914133873_35667beb.json similarity index 100% rename from .trajectories/completed/2026-05/traj_1775914133873_35667beb.json rename to .agentworkforce/trajectories/completed/2026-05/traj_1775914133873_35667beb.json diff --git a/.trajectories/completed/2026-05/traj_1775914133873_35667beb.md b/.agentworkforce/trajectories/completed/2026-05/traj_1775914133873_35667beb.md similarity index 100% rename from .trajectories/completed/2026-05/traj_1775914133873_35667beb.md rename to .agentworkforce/trajectories/completed/2026-05/traj_1775914133873_35667beb.md diff --git a/.trajectories/completed/2026-05/traj_1776073106646_1839be2d.json b/.agentworkforce/trajectories/completed/2026-05/traj_1776073106646_1839be2d.json similarity index 100% rename from .trajectories/completed/2026-05/traj_1776073106646_1839be2d.json rename to .agentworkforce/trajectories/completed/2026-05/traj_1776073106646_1839be2d.json diff --git a/.trajectories/completed/2026-05/traj_1776073106646_1839be2d.md b/.agentworkforce/trajectories/completed/2026-05/traj_1776073106646_1839be2d.md similarity index 100% rename from .trajectories/completed/2026-05/traj_1776073106646_1839be2d.md rename to .agentworkforce/trajectories/completed/2026-05/traj_1776073106646_1839be2d.md diff --git a/.trajectories/completed/2026-05/traj_1776113772922_bc92f121.json b/.agentworkforce/trajectories/completed/2026-05/traj_1776113772922_bc92f121.json similarity index 100% rename from .trajectories/completed/2026-05/traj_1776113772922_bc92f121.json rename to .agentworkforce/trajectories/completed/2026-05/traj_1776113772922_bc92f121.json diff --git a/.trajectories/completed/2026-05/traj_1776113772922_bc92f121.md b/.agentworkforce/trajectories/completed/2026-05/traj_1776113772922_bc92f121.md similarity index 100% rename from .trajectories/completed/2026-05/traj_1776113772922_bc92f121.md rename to .agentworkforce/trajectories/completed/2026-05/traj_1776113772922_bc92f121.md diff --git a/.trajectories/completed/2026-05/traj_1778873209642_c70e32ab.json b/.agentworkforce/trajectories/completed/2026-05/traj_1778873209642_c70e32ab.json similarity index 100% rename from .trajectories/completed/2026-05/traj_1778873209642_c70e32ab.json rename to .agentworkforce/trajectories/completed/2026-05/traj_1778873209642_c70e32ab.json diff --git a/.trajectories/completed/2026-05/traj_1778873209642_c70e32ab.md b/.agentworkforce/trajectories/completed/2026-05/traj_1778873209642_c70e32ab.md similarity index 100% rename from .trajectories/completed/2026-05/traj_1778873209642_c70e32ab.md rename to .agentworkforce/trajectories/completed/2026-05/traj_1778873209642_c70e32ab.md diff --git a/.trajectories/completed/2026-05/traj_1778873211616_6db3b2cd.json b/.agentworkforce/trajectories/completed/2026-05/traj_1778873211616_6db3b2cd.json similarity index 100% rename from .trajectories/completed/2026-05/traj_1778873211616_6db3b2cd.json rename to .agentworkforce/trajectories/completed/2026-05/traj_1778873211616_6db3b2cd.json diff --git a/.trajectories/completed/2026-05/traj_1778873211616_6db3b2cd.md b/.agentworkforce/trajectories/completed/2026-05/traj_1778873211616_6db3b2cd.md similarity index 100% rename from .trajectories/completed/2026-05/traj_1778873211616_6db3b2cd.md rename to .agentworkforce/trajectories/completed/2026-05/traj_1778873211616_6db3b2cd.md diff --git a/.trajectories/completed/2026-05/traj_1fjub7c9rlap.json b/.agentworkforce/trajectories/completed/2026-05/traj_1fjub7c9rlap.json similarity index 100% rename from .trajectories/completed/2026-05/traj_1fjub7c9rlap.json rename to .agentworkforce/trajectories/completed/2026-05/traj_1fjub7c9rlap.json diff --git a/.trajectories/completed/2026-05/traj_1fjub7c9rlap.md b/.agentworkforce/trajectories/completed/2026-05/traj_1fjub7c9rlap.md similarity index 100% rename from .trajectories/completed/2026-05/traj_1fjub7c9rlap.md rename to .agentworkforce/trajectories/completed/2026-05/traj_1fjub7c9rlap.md diff --git a/.trajectories/completed/2026-05/traj_1rrpe2r7fyem.json b/.agentworkforce/trajectories/completed/2026-05/traj_1rrpe2r7fyem.json similarity index 100% rename from .trajectories/completed/2026-05/traj_1rrpe2r7fyem.json rename to .agentworkforce/trajectories/completed/2026-05/traj_1rrpe2r7fyem.json diff --git a/.trajectories/completed/2026-05/traj_1rrpe2r7fyem.md b/.agentworkforce/trajectories/completed/2026-05/traj_1rrpe2r7fyem.md similarity index 100% rename from .trajectories/completed/2026-05/traj_1rrpe2r7fyem.md rename to .agentworkforce/trajectories/completed/2026-05/traj_1rrpe2r7fyem.md diff --git a/.trajectories/completed/2026-05/traj_2gpglosdsq7s.json b/.agentworkforce/trajectories/completed/2026-05/traj_2gpglosdsq7s.json similarity index 100% rename from .trajectories/completed/2026-05/traj_2gpglosdsq7s.json rename to .agentworkforce/trajectories/completed/2026-05/traj_2gpglosdsq7s.json diff --git a/.trajectories/completed/2026-05/traj_2gpglosdsq7s.md b/.agentworkforce/trajectories/completed/2026-05/traj_2gpglosdsq7s.md similarity index 100% rename from .trajectories/completed/2026-05/traj_2gpglosdsq7s.md rename to .agentworkforce/trajectories/completed/2026-05/traj_2gpglosdsq7s.md diff --git a/.trajectories/completed/2026-05/traj_2tqxnib25omk.json b/.agentworkforce/trajectories/completed/2026-05/traj_2tqxnib25omk.json similarity index 100% rename from .trajectories/completed/2026-05/traj_2tqxnib25omk.json rename to .agentworkforce/trajectories/completed/2026-05/traj_2tqxnib25omk.json diff --git a/.trajectories/completed/2026-05/traj_2tqxnib25omk.md b/.agentworkforce/trajectories/completed/2026-05/traj_2tqxnib25omk.md similarity index 100% rename from .trajectories/completed/2026-05/traj_2tqxnib25omk.md rename to .agentworkforce/trajectories/completed/2026-05/traj_2tqxnib25omk.md diff --git a/.trajectories/completed/2026-05/traj_2yicjxgajt0a.json b/.agentworkforce/trajectories/completed/2026-05/traj_2yicjxgajt0a.json similarity index 100% rename from .trajectories/completed/2026-05/traj_2yicjxgajt0a.json rename to .agentworkforce/trajectories/completed/2026-05/traj_2yicjxgajt0a.json diff --git a/.trajectories/completed/2026-05/traj_2yicjxgajt0a.md b/.agentworkforce/trajectories/completed/2026-05/traj_2yicjxgajt0a.md similarity index 100% rename from .trajectories/completed/2026-05/traj_2yicjxgajt0a.md rename to .agentworkforce/trajectories/completed/2026-05/traj_2yicjxgajt0a.md diff --git a/.trajectories/completed/2026-05/traj_34b1u84b19gz.json b/.agentworkforce/trajectories/completed/2026-05/traj_34b1u84b19gz.json similarity index 100% rename from .trajectories/completed/2026-05/traj_34b1u84b19gz.json rename to .agentworkforce/trajectories/completed/2026-05/traj_34b1u84b19gz.json diff --git a/.trajectories/completed/2026-05/traj_34b1u84b19gz.md b/.agentworkforce/trajectories/completed/2026-05/traj_34b1u84b19gz.md similarity index 100% rename from .trajectories/completed/2026-05/traj_34b1u84b19gz.md rename to .agentworkforce/trajectories/completed/2026-05/traj_34b1u84b19gz.md diff --git a/.trajectories/completed/2026-05/traj_3b3p1z4y7qlo.json b/.agentworkforce/trajectories/completed/2026-05/traj_3b3p1z4y7qlo.json similarity index 100% rename from .trajectories/completed/2026-05/traj_3b3p1z4y7qlo.json rename to .agentworkforce/trajectories/completed/2026-05/traj_3b3p1z4y7qlo.json diff --git a/.trajectories/completed/2026-05/traj_3b3p1z4y7qlo.md b/.agentworkforce/trajectories/completed/2026-05/traj_3b3p1z4y7qlo.md similarity index 100% rename from .trajectories/completed/2026-05/traj_3b3p1z4y7qlo.md rename to .agentworkforce/trajectories/completed/2026-05/traj_3b3p1z4y7qlo.md diff --git a/.trajectories/completed/2026-05/traj_3gjtcykvybt5.json b/.agentworkforce/trajectories/completed/2026-05/traj_3gjtcykvybt5.json similarity index 100% rename from .trajectories/completed/2026-05/traj_3gjtcykvybt5.json rename to .agentworkforce/trajectories/completed/2026-05/traj_3gjtcykvybt5.json diff --git a/.trajectories/completed/2026-05/traj_3gjtcykvybt5.md b/.agentworkforce/trajectories/completed/2026-05/traj_3gjtcykvybt5.md similarity index 100% rename from .trajectories/completed/2026-05/traj_3gjtcykvybt5.md rename to .agentworkforce/trajectories/completed/2026-05/traj_3gjtcykvybt5.md diff --git a/.trajectories/completed/2026-05/traj_47akjihewlow.json b/.agentworkforce/trajectories/completed/2026-05/traj_47akjihewlow.json similarity index 100% rename from .trajectories/completed/2026-05/traj_47akjihewlow.json rename to .agentworkforce/trajectories/completed/2026-05/traj_47akjihewlow.json diff --git a/.trajectories/completed/2026-05/traj_47akjihewlow.md b/.agentworkforce/trajectories/completed/2026-05/traj_47akjihewlow.md similarity index 100% rename from .trajectories/completed/2026-05/traj_47akjihewlow.md rename to .agentworkforce/trajectories/completed/2026-05/traj_47akjihewlow.md diff --git a/.trajectories/completed/2026-05/traj_47akjihewlow.trace.json b/.agentworkforce/trajectories/completed/2026-05/traj_47akjihewlow.trace.json similarity index 100% rename from .trajectories/completed/2026-05/traj_47akjihewlow.trace.json rename to .agentworkforce/trajectories/completed/2026-05/traj_47akjihewlow.trace.json diff --git a/.trajectories/completed/2026-05/traj_4chzkm724ufo.json b/.agentworkforce/trajectories/completed/2026-05/traj_4chzkm724ufo.json similarity index 100% rename from .trajectories/completed/2026-05/traj_4chzkm724ufo.json rename to .agentworkforce/trajectories/completed/2026-05/traj_4chzkm724ufo.json diff --git a/.trajectories/completed/2026-05/traj_4chzkm724ufo.md b/.agentworkforce/trajectories/completed/2026-05/traj_4chzkm724ufo.md similarity index 100% rename from .trajectories/completed/2026-05/traj_4chzkm724ufo.md rename to .agentworkforce/trajectories/completed/2026-05/traj_4chzkm724ufo.md diff --git a/.trajectories/completed/2026-05/traj_4t07itef99ug.json b/.agentworkforce/trajectories/completed/2026-05/traj_4t07itef99ug.json similarity index 100% rename from .trajectories/completed/2026-05/traj_4t07itef99ug.json rename to .agentworkforce/trajectories/completed/2026-05/traj_4t07itef99ug.json diff --git a/.trajectories/completed/2026-05/traj_4t07itef99ug.md b/.agentworkforce/trajectories/completed/2026-05/traj_4t07itef99ug.md similarity index 100% rename from .trajectories/completed/2026-05/traj_4t07itef99ug.md rename to .agentworkforce/trajectories/completed/2026-05/traj_4t07itef99ug.md diff --git a/.trajectories/completed/2026-05/traj_4vucir4qvqa2.json b/.agentworkforce/trajectories/completed/2026-05/traj_4vucir4qvqa2.json similarity index 100% rename from .trajectories/completed/2026-05/traj_4vucir4qvqa2.json rename to .agentworkforce/trajectories/completed/2026-05/traj_4vucir4qvqa2.json diff --git a/.trajectories/completed/2026-05/traj_4vucir4qvqa2.md b/.agentworkforce/trajectories/completed/2026-05/traj_4vucir4qvqa2.md similarity index 100% rename from .trajectories/completed/2026-05/traj_4vucir4qvqa2.md rename to .agentworkforce/trajectories/completed/2026-05/traj_4vucir4qvqa2.md diff --git a/.trajectories/completed/2026-05/traj_5k0jtc1g5l33.json b/.agentworkforce/trajectories/completed/2026-05/traj_5k0jtc1g5l33.json similarity index 100% rename from .trajectories/completed/2026-05/traj_5k0jtc1g5l33.json rename to .agentworkforce/trajectories/completed/2026-05/traj_5k0jtc1g5l33.json diff --git a/.trajectories/completed/2026-05/traj_5k0jtc1g5l33.md b/.agentworkforce/trajectories/completed/2026-05/traj_5k0jtc1g5l33.md similarity index 100% rename from .trajectories/completed/2026-05/traj_5k0jtc1g5l33.md rename to .agentworkforce/trajectories/completed/2026-05/traj_5k0jtc1g5l33.md diff --git a/.trajectories/completed/2026-05/traj_5nzj6v56id4z.json b/.agentworkforce/trajectories/completed/2026-05/traj_5nzj6v56id4z.json similarity index 100% rename from .trajectories/completed/2026-05/traj_5nzj6v56id4z.json rename to .agentworkforce/trajectories/completed/2026-05/traj_5nzj6v56id4z.json diff --git a/.trajectories/completed/2026-05/traj_5q8i0iz4klpo.json b/.agentworkforce/trajectories/completed/2026-05/traj_5q8i0iz4klpo.json similarity index 100% rename from .trajectories/completed/2026-05/traj_5q8i0iz4klpo.json rename to .agentworkforce/trajectories/completed/2026-05/traj_5q8i0iz4klpo.json diff --git a/.trajectories/completed/2026-05/traj_5q8i0iz4klpo.md b/.agentworkforce/trajectories/completed/2026-05/traj_5q8i0iz4klpo.md similarity index 100% rename from .trajectories/completed/2026-05/traj_5q8i0iz4klpo.md rename to .agentworkforce/trajectories/completed/2026-05/traj_5q8i0iz4klpo.md diff --git a/.trajectories/completed/2026-05/traj_5qbla7w4kzoi.json b/.agentworkforce/trajectories/completed/2026-05/traj_5qbla7w4kzoi.json similarity index 100% rename from .trajectories/completed/2026-05/traj_5qbla7w4kzoi.json rename to .agentworkforce/trajectories/completed/2026-05/traj_5qbla7w4kzoi.json diff --git a/.trajectories/completed/2026-05/traj_5qbla7w4kzoi.md b/.agentworkforce/trajectories/completed/2026-05/traj_5qbla7w4kzoi.md similarity index 100% rename from .trajectories/completed/2026-05/traj_5qbla7w4kzoi.md rename to .agentworkforce/trajectories/completed/2026-05/traj_5qbla7w4kzoi.md diff --git a/.trajectories/completed/2026-05/traj_60qc24ufr96g.json b/.agentworkforce/trajectories/completed/2026-05/traj_60qc24ufr96g.json similarity index 100% rename from .trajectories/completed/2026-05/traj_60qc24ufr96g.json rename to .agentworkforce/trajectories/completed/2026-05/traj_60qc24ufr96g.json diff --git a/.trajectories/completed/2026-05/traj_60qc24ufr96g.md b/.agentworkforce/trajectories/completed/2026-05/traj_60qc24ufr96g.md similarity index 100% rename from .trajectories/completed/2026-05/traj_60qc24ufr96g.md rename to .agentworkforce/trajectories/completed/2026-05/traj_60qc24ufr96g.md diff --git a/.trajectories/completed/2026-05/traj_6sjeohtm3php.json b/.agentworkforce/trajectories/completed/2026-05/traj_6sjeohtm3php.json similarity index 100% rename from .trajectories/completed/2026-05/traj_6sjeohtm3php.json rename to .agentworkforce/trajectories/completed/2026-05/traj_6sjeohtm3php.json diff --git a/.trajectories/completed/2026-05/traj_6sjeohtm3php.md b/.agentworkforce/trajectories/completed/2026-05/traj_6sjeohtm3php.md similarity index 100% rename from .trajectories/completed/2026-05/traj_6sjeohtm3php.md rename to .agentworkforce/trajectories/completed/2026-05/traj_6sjeohtm3php.md diff --git a/.trajectories/completed/2026-05/traj_6ujzpx82gqs9.json b/.agentworkforce/trajectories/completed/2026-05/traj_6ujzpx82gqs9.json similarity index 100% rename from .trajectories/completed/2026-05/traj_6ujzpx82gqs9.json rename to .agentworkforce/trajectories/completed/2026-05/traj_6ujzpx82gqs9.json diff --git a/.trajectories/completed/2026-05/traj_6ujzpx82gqs9.md b/.agentworkforce/trajectories/completed/2026-05/traj_6ujzpx82gqs9.md similarity index 100% rename from .trajectories/completed/2026-05/traj_6ujzpx82gqs9.md rename to .agentworkforce/trajectories/completed/2026-05/traj_6ujzpx82gqs9.md diff --git a/.trajectories/completed/2026-05/traj_78ytpicts778.json b/.agentworkforce/trajectories/completed/2026-05/traj_78ytpicts778.json similarity index 100% rename from .trajectories/completed/2026-05/traj_78ytpicts778.json rename to .agentworkforce/trajectories/completed/2026-05/traj_78ytpicts778.json diff --git a/.trajectories/completed/2026-05/traj_78ytpicts778.md b/.agentworkforce/trajectories/completed/2026-05/traj_78ytpicts778.md similarity index 100% rename from .trajectories/completed/2026-05/traj_78ytpicts778.md rename to .agentworkforce/trajectories/completed/2026-05/traj_78ytpicts778.md diff --git a/.trajectories/completed/2026-05/traj_7i9tigaejfje.json b/.agentworkforce/trajectories/completed/2026-05/traj_7i9tigaejfje.json similarity index 100% rename from .trajectories/completed/2026-05/traj_7i9tigaejfje.json rename to .agentworkforce/trajectories/completed/2026-05/traj_7i9tigaejfje.json diff --git a/.trajectories/completed/2026-05/traj_7i9tigaejfje.md b/.agentworkforce/trajectories/completed/2026-05/traj_7i9tigaejfje.md similarity index 100% rename from .trajectories/completed/2026-05/traj_7i9tigaejfje.md rename to .agentworkforce/trajectories/completed/2026-05/traj_7i9tigaejfje.md diff --git a/.trajectories/completed/2026-05/traj_7uznwzoxbao6.json b/.agentworkforce/trajectories/completed/2026-05/traj_7uznwzoxbao6.json similarity index 100% rename from .trajectories/completed/2026-05/traj_7uznwzoxbao6.json rename to .agentworkforce/trajectories/completed/2026-05/traj_7uznwzoxbao6.json diff --git a/.trajectories/completed/2026-05/traj_7uznwzoxbao6.md b/.agentworkforce/trajectories/completed/2026-05/traj_7uznwzoxbao6.md similarity index 100% rename from .trajectories/completed/2026-05/traj_7uznwzoxbao6.md rename to .agentworkforce/trajectories/completed/2026-05/traj_7uznwzoxbao6.md diff --git a/.trajectories/completed/2026-05/traj_7zu7et53ph3l.json b/.agentworkforce/trajectories/completed/2026-05/traj_7zu7et53ph3l.json similarity index 100% rename from .trajectories/completed/2026-05/traj_7zu7et53ph3l.json rename to .agentworkforce/trajectories/completed/2026-05/traj_7zu7et53ph3l.json diff --git a/.trajectories/completed/2026-05/traj_7zu7et53ph3l.md b/.agentworkforce/trajectories/completed/2026-05/traj_7zu7et53ph3l.md similarity index 100% rename from .trajectories/completed/2026-05/traj_7zu7et53ph3l.md rename to .agentworkforce/trajectories/completed/2026-05/traj_7zu7et53ph3l.md diff --git a/.trajectories/completed/2026-05/traj_81kobstnzzwk.json b/.agentworkforce/trajectories/completed/2026-05/traj_81kobstnzzwk.json similarity index 100% rename from .trajectories/completed/2026-05/traj_81kobstnzzwk.json rename to .agentworkforce/trajectories/completed/2026-05/traj_81kobstnzzwk.json diff --git a/.trajectories/completed/2026-05/traj_8ljgydz61do5.json b/.agentworkforce/trajectories/completed/2026-05/traj_8ljgydz61do5.json similarity index 100% rename from .trajectories/completed/2026-05/traj_8ljgydz61do5.json rename to .agentworkforce/trajectories/completed/2026-05/traj_8ljgydz61do5.json diff --git a/.trajectories/completed/2026-05/traj_8ljgydz61do5.md b/.agentworkforce/trajectories/completed/2026-05/traj_8ljgydz61do5.md similarity index 100% rename from .trajectories/completed/2026-05/traj_8ljgydz61do5.md rename to .agentworkforce/trajectories/completed/2026-05/traj_8ljgydz61do5.md diff --git a/.trajectories/completed/2026-05/traj_8nhd9lljhbsw.json b/.agentworkforce/trajectories/completed/2026-05/traj_8nhd9lljhbsw.json similarity index 100% rename from .trajectories/completed/2026-05/traj_8nhd9lljhbsw.json rename to .agentworkforce/trajectories/completed/2026-05/traj_8nhd9lljhbsw.json diff --git a/.trajectories/completed/2026-05/traj_8nhd9lljhbsw.md b/.agentworkforce/trajectories/completed/2026-05/traj_8nhd9lljhbsw.md similarity index 100% rename from .trajectories/completed/2026-05/traj_8nhd9lljhbsw.md rename to .agentworkforce/trajectories/completed/2026-05/traj_8nhd9lljhbsw.md diff --git a/.trajectories/completed/2026-05/traj_90jmd9z27oap.json b/.agentworkforce/trajectories/completed/2026-05/traj_90jmd9z27oap.json similarity index 100% rename from .trajectories/completed/2026-05/traj_90jmd9z27oap.json rename to .agentworkforce/trajectories/completed/2026-05/traj_90jmd9z27oap.json diff --git a/.trajectories/completed/2026-05/traj_90jmd9z27oap.md b/.agentworkforce/trajectories/completed/2026-05/traj_90jmd9z27oap.md similarity index 100% rename from .trajectories/completed/2026-05/traj_90jmd9z27oap.md rename to .agentworkforce/trajectories/completed/2026-05/traj_90jmd9z27oap.md diff --git a/.trajectories/completed/2026-05/traj_947wzpddsg9j.json b/.agentworkforce/trajectories/completed/2026-05/traj_947wzpddsg9j.json similarity index 100% rename from .trajectories/completed/2026-05/traj_947wzpddsg9j.json rename to .agentworkforce/trajectories/completed/2026-05/traj_947wzpddsg9j.json diff --git a/.trajectories/completed/2026-05/traj_947wzpddsg9j.md b/.agentworkforce/trajectories/completed/2026-05/traj_947wzpddsg9j.md similarity index 100% rename from .trajectories/completed/2026-05/traj_947wzpddsg9j.md rename to .agentworkforce/trajectories/completed/2026-05/traj_947wzpddsg9j.md diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_9d5mdl0oj0ao.json b/.agentworkforce/trajectories/completed/2026-05/traj_9d5mdl0oj0ao.json new file mode 100644 index 000000000..cd748f438 --- /dev/null +++ b/.agentworkforce/trajectories/completed/2026-05/traj_9d5mdl0oj0ao.json @@ -0,0 +1,25 @@ +{ + "id": "traj_9d5mdl0oj0ao", + "version": 1, + "task": { + "title": "fix trajectories" + }, + "status": "completed", + "startedAt": "2026-05-26T11:47:03.748Z", + "completedAt": "2026-05-26T11:48:31.592Z", + "agents": [], + "chapters": [], + "retrospective": { + "summary": "updated and fixed pathing issues", + "approach": "Standard approach", + "confidence": 0.8 + }, + "commits": [], + "filesChanged": [], + "projectId": "/Users/will/Projects/AgentWorkforce/relay", + "tags": [], + "_trace": { + "startRef": "9061a034dca4763de6957ea4b74974fab99e63ce", + "endRef": "9061a034dca4763de6957ea4b74974fab99e63ce" + } +} \ No newline at end of file diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_9d5mdl0oj0ao.md b/.agentworkforce/trajectories/completed/2026-05/traj_9d5mdl0oj0ao.md new file mode 100644 index 000000000..f0fdc1517 --- /dev/null +++ b/.agentworkforce/trajectories/completed/2026-05/traj_9d5mdl0oj0ao.md @@ -0,0 +1,14 @@ +# Trajectory: fix trajectories + +> **Status:** ✅ Completed +> **Confidence:** 80% +> **Started:** May 26, 2026 at 07:47 AM +> **Completed:** May 26, 2026 at 07:48 AM + +--- + +## Summary + +updated and fixed pathing issues + +**Approach:** Standard approach diff --git a/.trajectories/completed/2026-05/traj_9dj3qiugt26j.json b/.agentworkforce/trajectories/completed/2026-05/traj_9dj3qiugt26j.json similarity index 100% rename from .trajectories/completed/2026-05/traj_9dj3qiugt26j.json rename to .agentworkforce/trajectories/completed/2026-05/traj_9dj3qiugt26j.json diff --git a/.trajectories/completed/2026-05/traj_9dj3qiugt26j.md b/.agentworkforce/trajectories/completed/2026-05/traj_9dj3qiugt26j.md similarity index 100% rename from .trajectories/completed/2026-05/traj_9dj3qiugt26j.md rename to .agentworkforce/trajectories/completed/2026-05/traj_9dj3qiugt26j.md diff --git a/.trajectories/completed/2026-05/traj_9fdv7hxm0b60.json b/.agentworkforce/trajectories/completed/2026-05/traj_9fdv7hxm0b60.json similarity index 100% rename from .trajectories/completed/2026-05/traj_9fdv7hxm0b60.json rename to .agentworkforce/trajectories/completed/2026-05/traj_9fdv7hxm0b60.json diff --git a/.trajectories/completed/2026-05/traj_9fdv7hxm0b60.md b/.agentworkforce/trajectories/completed/2026-05/traj_9fdv7hxm0b60.md similarity index 100% rename from .trajectories/completed/2026-05/traj_9fdv7hxm0b60.md rename to .agentworkforce/trajectories/completed/2026-05/traj_9fdv7hxm0b60.md diff --git a/.trajectories/completed/2026-05/traj_9gq96irkj00s.json b/.agentworkforce/trajectories/completed/2026-05/traj_9gq96irkj00s.json similarity index 100% rename from .trajectories/completed/2026-05/traj_9gq96irkj00s.json rename to .agentworkforce/trajectories/completed/2026-05/traj_9gq96irkj00s.json diff --git a/.trajectories/completed/2026-05/traj_9gq96irkj00s.md b/.agentworkforce/trajectories/completed/2026-05/traj_9gq96irkj00s.md similarity index 100% rename from .trajectories/completed/2026-05/traj_9gq96irkj00s.md rename to .agentworkforce/trajectories/completed/2026-05/traj_9gq96irkj00s.md diff --git a/.trajectories/completed/2026-05/traj_aw7stgf4qau0.json b/.agentworkforce/trajectories/completed/2026-05/traj_aw7stgf4qau0.json similarity index 100% rename from .trajectories/completed/2026-05/traj_aw7stgf4qau0.json rename to .agentworkforce/trajectories/completed/2026-05/traj_aw7stgf4qau0.json diff --git a/.trajectories/completed/2026-05/traj_aw7stgf4qau0.md b/.agentworkforce/trajectories/completed/2026-05/traj_aw7stgf4qau0.md similarity index 100% rename from .trajectories/completed/2026-05/traj_aw7stgf4qau0.md rename to .agentworkforce/trajectories/completed/2026-05/traj_aw7stgf4qau0.md diff --git a/.trajectories/completed/2026-05/traj_bd431l65n9lg.json b/.agentworkforce/trajectories/completed/2026-05/traj_bd431l65n9lg.json similarity index 100% rename from .trajectories/completed/2026-05/traj_bd431l65n9lg.json rename to .agentworkforce/trajectories/completed/2026-05/traj_bd431l65n9lg.json diff --git a/.trajectories/completed/2026-05/traj_bd431l65n9lg.md b/.agentworkforce/trajectories/completed/2026-05/traj_bd431l65n9lg.md similarity index 100% rename from .trajectories/completed/2026-05/traj_bd431l65n9lg.md rename to .agentworkforce/trajectories/completed/2026-05/traj_bd431l65n9lg.md diff --git a/.trajectories/completed/2026-05/traj_bdrlknyl8twj.json b/.agentworkforce/trajectories/completed/2026-05/traj_bdrlknyl8twj.json similarity index 100% rename from .trajectories/completed/2026-05/traj_bdrlknyl8twj.json rename to .agentworkforce/trajectories/completed/2026-05/traj_bdrlknyl8twj.json diff --git a/.trajectories/completed/2026-05/traj_bdrlknyl8twj.md b/.agentworkforce/trajectories/completed/2026-05/traj_bdrlknyl8twj.md similarity index 100% rename from .trajectories/completed/2026-05/traj_bdrlknyl8twj.md rename to .agentworkforce/trajectories/completed/2026-05/traj_bdrlknyl8twj.md diff --git a/.trajectories/completed/2026-05/traj_bz1a1o15p7px.json b/.agentworkforce/trajectories/completed/2026-05/traj_bz1a1o15p7px.json similarity index 100% rename from .trajectories/completed/2026-05/traj_bz1a1o15p7px.json rename to .agentworkforce/trajectories/completed/2026-05/traj_bz1a1o15p7px.json diff --git a/.trajectories/completed/2026-05/traj_bz1a1o15p7px.md b/.agentworkforce/trajectories/completed/2026-05/traj_bz1a1o15p7px.md similarity index 100% rename from .trajectories/completed/2026-05/traj_bz1a1o15p7px.md rename to .agentworkforce/trajectories/completed/2026-05/traj_bz1a1o15p7px.md diff --git a/.trajectories/completed/2026-05/traj_cbmwd07phhm2.json b/.agentworkforce/trajectories/completed/2026-05/traj_cbmwd07phhm2.json similarity index 100% rename from .trajectories/completed/2026-05/traj_cbmwd07phhm2.json rename to .agentworkforce/trajectories/completed/2026-05/traj_cbmwd07phhm2.json diff --git a/.trajectories/completed/2026-05/traj_cbmwd07phhm2.md b/.agentworkforce/trajectories/completed/2026-05/traj_cbmwd07phhm2.md similarity index 100% rename from .trajectories/completed/2026-05/traj_cbmwd07phhm2.md rename to .agentworkforce/trajectories/completed/2026-05/traj_cbmwd07phhm2.md diff --git a/.trajectories/completed/2026-05/traj_ceo5q9bh2od3.json b/.agentworkforce/trajectories/completed/2026-05/traj_ceo5q9bh2od3.json similarity index 100% rename from .trajectories/completed/2026-05/traj_ceo5q9bh2od3.json rename to .agentworkforce/trajectories/completed/2026-05/traj_ceo5q9bh2od3.json diff --git a/.trajectories/completed/2026-05/traj_ceo5q9bh2od3.md b/.agentworkforce/trajectories/completed/2026-05/traj_ceo5q9bh2od3.md similarity index 100% rename from .trajectories/completed/2026-05/traj_ceo5q9bh2od3.md rename to .agentworkforce/trajectories/completed/2026-05/traj_ceo5q9bh2od3.md diff --git a/.trajectories/completed/2026-05/traj_cszfl2icaj2t.json b/.agentworkforce/trajectories/completed/2026-05/traj_cszfl2icaj2t.json similarity index 100% rename from .trajectories/completed/2026-05/traj_cszfl2icaj2t.json rename to .agentworkforce/trajectories/completed/2026-05/traj_cszfl2icaj2t.json diff --git a/.trajectories/completed/2026-05/traj_cszfl2icaj2t.md b/.agentworkforce/trajectories/completed/2026-05/traj_cszfl2icaj2t.md similarity index 100% rename from .trajectories/completed/2026-05/traj_cszfl2icaj2t.md rename to .agentworkforce/trajectories/completed/2026-05/traj_cszfl2icaj2t.md diff --git a/.trajectories/completed/2026-05/traj_d89s38ddu7cj.json b/.agentworkforce/trajectories/completed/2026-05/traj_d89s38ddu7cj.json similarity index 100% rename from .trajectories/completed/2026-05/traj_d89s38ddu7cj.json rename to .agentworkforce/trajectories/completed/2026-05/traj_d89s38ddu7cj.json diff --git a/.trajectories/completed/2026-05/traj_d89s38ddu7cj.md b/.agentworkforce/trajectories/completed/2026-05/traj_d89s38ddu7cj.md similarity index 100% rename from .trajectories/completed/2026-05/traj_d89s38ddu7cj.md rename to .agentworkforce/trajectories/completed/2026-05/traj_d89s38ddu7cj.md diff --git a/.trajectories/completed/2026-05/traj_dbsnr453nxjw.json b/.agentworkforce/trajectories/completed/2026-05/traj_dbsnr453nxjw.json similarity index 100% rename from .trajectories/completed/2026-05/traj_dbsnr453nxjw.json rename to .agentworkforce/trajectories/completed/2026-05/traj_dbsnr453nxjw.json diff --git a/.trajectories/completed/2026-05/traj_dbsnr453nxjw.md b/.agentworkforce/trajectories/completed/2026-05/traj_dbsnr453nxjw.md similarity index 100% rename from .trajectories/completed/2026-05/traj_dbsnr453nxjw.md rename to .agentworkforce/trajectories/completed/2026-05/traj_dbsnr453nxjw.md diff --git a/.trajectories/completed/2026-05/traj_dcl9hgoiuac5.json b/.agentworkforce/trajectories/completed/2026-05/traj_dcl9hgoiuac5.json similarity index 100% rename from .trajectories/completed/2026-05/traj_dcl9hgoiuac5.json rename to .agentworkforce/trajectories/completed/2026-05/traj_dcl9hgoiuac5.json diff --git a/.trajectories/completed/2026-05/traj_dcl9hgoiuac5.md b/.agentworkforce/trajectories/completed/2026-05/traj_dcl9hgoiuac5.md similarity index 100% rename from .trajectories/completed/2026-05/traj_dcl9hgoiuac5.md rename to .agentworkforce/trajectories/completed/2026-05/traj_dcl9hgoiuac5.md diff --git a/.trajectories/completed/2026-05/traj_dpgn0am1jq1c.json b/.agentworkforce/trajectories/completed/2026-05/traj_dpgn0am1jq1c.json similarity index 100% rename from .trajectories/completed/2026-05/traj_dpgn0am1jq1c.json rename to .agentworkforce/trajectories/completed/2026-05/traj_dpgn0am1jq1c.json diff --git a/.trajectories/completed/2026-05/traj_dpgn0am1jq1c.md b/.agentworkforce/trajectories/completed/2026-05/traj_dpgn0am1jq1c.md similarity index 100% rename from .trajectories/completed/2026-05/traj_dpgn0am1jq1c.md rename to .agentworkforce/trajectories/completed/2026-05/traj_dpgn0am1jq1c.md diff --git a/.trajectories/completed/2026-05/traj_e1b7ww3un1u3.json b/.agentworkforce/trajectories/completed/2026-05/traj_e1b7ww3un1u3.json similarity index 100% rename from .trajectories/completed/2026-05/traj_e1b7ww3un1u3.json rename to .agentworkforce/trajectories/completed/2026-05/traj_e1b7ww3un1u3.json diff --git a/.trajectories/completed/2026-05/traj_e1b7ww3un1u3.md b/.agentworkforce/trajectories/completed/2026-05/traj_e1b7ww3un1u3.md similarity index 100% rename from .trajectories/completed/2026-05/traj_e1b7ww3un1u3.md rename to .agentworkforce/trajectories/completed/2026-05/traj_e1b7ww3un1u3.md diff --git a/.trajectories/completed/2026-05/traj_elx0fcwgs37x.json b/.agentworkforce/trajectories/completed/2026-05/traj_elx0fcwgs37x.json similarity index 100% rename from .trajectories/completed/2026-05/traj_elx0fcwgs37x.json rename to .agentworkforce/trajectories/completed/2026-05/traj_elx0fcwgs37x.json diff --git a/.trajectories/completed/2026-05/traj_elx0fcwgs37x.md b/.agentworkforce/trajectories/completed/2026-05/traj_elx0fcwgs37x.md similarity index 100% rename from .trajectories/completed/2026-05/traj_elx0fcwgs37x.md rename to .agentworkforce/trajectories/completed/2026-05/traj_elx0fcwgs37x.md diff --git a/.trajectories/completed/2026-05/traj_erzd7j9nto9r.json b/.agentworkforce/trajectories/completed/2026-05/traj_erzd7j9nto9r.json similarity index 100% rename from .trajectories/completed/2026-05/traj_erzd7j9nto9r.json rename to .agentworkforce/trajectories/completed/2026-05/traj_erzd7j9nto9r.json diff --git a/.trajectories/completed/2026-05/traj_erzd7j9nto9r.md b/.agentworkforce/trajectories/completed/2026-05/traj_erzd7j9nto9r.md similarity index 100% rename from .trajectories/completed/2026-05/traj_erzd7j9nto9r.md rename to .agentworkforce/trajectories/completed/2026-05/traj_erzd7j9nto9r.md diff --git a/.trajectories/completed/2026-05/traj_f1iac9ngymlj.json b/.agentworkforce/trajectories/completed/2026-05/traj_f1iac9ngymlj.json similarity index 100% rename from .trajectories/completed/2026-05/traj_f1iac9ngymlj.json rename to .agentworkforce/trajectories/completed/2026-05/traj_f1iac9ngymlj.json diff --git a/.trajectories/completed/2026-05/traj_f1iac9ngymlj.md b/.agentworkforce/trajectories/completed/2026-05/traj_f1iac9ngymlj.md similarity index 100% rename from .trajectories/completed/2026-05/traj_f1iac9ngymlj.md rename to .agentworkforce/trajectories/completed/2026-05/traj_f1iac9ngymlj.md diff --git a/.trajectories/completed/2026-05/traj_f3arvbmmlomn.json b/.agentworkforce/trajectories/completed/2026-05/traj_f3arvbmmlomn.json similarity index 100% rename from .trajectories/completed/2026-05/traj_f3arvbmmlomn.json rename to .agentworkforce/trajectories/completed/2026-05/traj_f3arvbmmlomn.json diff --git a/.trajectories/completed/2026-05/traj_f3arvbmmlomn.md b/.agentworkforce/trajectories/completed/2026-05/traj_f3arvbmmlomn.md similarity index 100% rename from .trajectories/completed/2026-05/traj_f3arvbmmlomn.md rename to .agentworkforce/trajectories/completed/2026-05/traj_f3arvbmmlomn.md diff --git a/.trajectories/completed/2026-05/traj_f9wxa8ujeg78.json b/.agentworkforce/trajectories/completed/2026-05/traj_f9wxa8ujeg78.json similarity index 100% rename from .trajectories/completed/2026-05/traj_f9wxa8ujeg78.json rename to .agentworkforce/trajectories/completed/2026-05/traj_f9wxa8ujeg78.json diff --git a/.trajectories/completed/2026-05/traj_f9wxa8ujeg78.md b/.agentworkforce/trajectories/completed/2026-05/traj_f9wxa8ujeg78.md similarity index 100% rename from .trajectories/completed/2026-05/traj_f9wxa8ujeg78.md rename to .agentworkforce/trajectories/completed/2026-05/traj_f9wxa8ujeg78.md diff --git a/.trajectories/completed/2026-05/traj_fh8oosbijpwc.json b/.agentworkforce/trajectories/completed/2026-05/traj_fh8oosbijpwc.json similarity index 100% rename from .trajectories/completed/2026-05/traj_fh8oosbijpwc.json rename to .agentworkforce/trajectories/completed/2026-05/traj_fh8oosbijpwc.json diff --git a/.trajectories/completed/2026-05/traj_fh8oosbijpwc.md b/.agentworkforce/trajectories/completed/2026-05/traj_fh8oosbijpwc.md similarity index 100% rename from .trajectories/completed/2026-05/traj_fh8oosbijpwc.md rename to .agentworkforce/trajectories/completed/2026-05/traj_fh8oosbijpwc.md diff --git a/.trajectories/completed/2026-05/traj_fh8oosbijpwc.trace.json b/.agentworkforce/trajectories/completed/2026-05/traj_fh8oosbijpwc.trace.json similarity index 100% rename from .trajectories/completed/2026-05/traj_fh8oosbijpwc.trace.json rename to .agentworkforce/trajectories/completed/2026-05/traj_fh8oosbijpwc.trace.json diff --git a/.trajectories/completed/2026-05/traj_fiygtgr3tfey.json b/.agentworkforce/trajectories/completed/2026-05/traj_fiygtgr3tfey.json similarity index 100% rename from .trajectories/completed/2026-05/traj_fiygtgr3tfey.json rename to .agentworkforce/trajectories/completed/2026-05/traj_fiygtgr3tfey.json diff --git a/.trajectories/completed/2026-05/traj_fiygtgr3tfey.md b/.agentworkforce/trajectories/completed/2026-05/traj_fiygtgr3tfey.md similarity index 100% rename from .trajectories/completed/2026-05/traj_fiygtgr3tfey.md rename to .agentworkforce/trajectories/completed/2026-05/traj_fiygtgr3tfey.md diff --git a/.trajectories/completed/2026-05/traj_gh05rj5gwsap.json b/.agentworkforce/trajectories/completed/2026-05/traj_gh05rj5gwsap.json similarity index 100% rename from .trajectories/completed/2026-05/traj_gh05rj5gwsap.json rename to .agentworkforce/trajectories/completed/2026-05/traj_gh05rj5gwsap.json diff --git a/.trajectories/completed/2026-05/traj_gh05rj5gwsap.md b/.agentworkforce/trajectories/completed/2026-05/traj_gh05rj5gwsap.md similarity index 100% rename from .trajectories/completed/2026-05/traj_gh05rj5gwsap.md rename to .agentworkforce/trajectories/completed/2026-05/traj_gh05rj5gwsap.md diff --git a/.trajectories/completed/2026-05/traj_gh05rj5gwsap.trace.json b/.agentworkforce/trajectories/completed/2026-05/traj_gh05rj5gwsap.trace.json similarity index 100% rename from .trajectories/completed/2026-05/traj_gh05rj5gwsap.trace.json rename to .agentworkforce/trajectories/completed/2026-05/traj_gh05rj5gwsap.trace.json diff --git a/.trajectories/completed/2026-05/traj_gkxajksmwoea.json b/.agentworkforce/trajectories/completed/2026-05/traj_gkxajksmwoea.json similarity index 100% rename from .trajectories/completed/2026-05/traj_gkxajksmwoea.json rename to .agentworkforce/trajectories/completed/2026-05/traj_gkxajksmwoea.json diff --git a/.trajectories/completed/2026-05/traj_gkxajksmwoea.md b/.agentworkforce/trajectories/completed/2026-05/traj_gkxajksmwoea.md similarity index 100% rename from .trajectories/completed/2026-05/traj_gkxajksmwoea.md rename to .agentworkforce/trajectories/completed/2026-05/traj_gkxajksmwoea.md diff --git a/.trajectories/completed/2026-05/traj_gnqvtoxtc8dy.json b/.agentworkforce/trajectories/completed/2026-05/traj_gnqvtoxtc8dy.json similarity index 100% rename from .trajectories/completed/2026-05/traj_gnqvtoxtc8dy.json rename to .agentworkforce/trajectories/completed/2026-05/traj_gnqvtoxtc8dy.json diff --git a/.trajectories/completed/2026-05/traj_gnqvtoxtc8dy.md b/.agentworkforce/trajectories/completed/2026-05/traj_gnqvtoxtc8dy.md similarity index 100% rename from .trajectories/completed/2026-05/traj_gnqvtoxtc8dy.md rename to .agentworkforce/trajectories/completed/2026-05/traj_gnqvtoxtc8dy.md diff --git a/.trajectories/completed/2026-05/traj_hfkww5z7trxn.json b/.agentworkforce/trajectories/completed/2026-05/traj_hfkww5z7trxn.json similarity index 100% rename from .trajectories/completed/2026-05/traj_hfkww5z7trxn.json rename to .agentworkforce/trajectories/completed/2026-05/traj_hfkww5z7trxn.json diff --git a/.trajectories/completed/2026-05/traj_hfkww5z7trxn.md b/.agentworkforce/trajectories/completed/2026-05/traj_hfkww5z7trxn.md similarity index 100% rename from .trajectories/completed/2026-05/traj_hfkww5z7trxn.md rename to .agentworkforce/trajectories/completed/2026-05/traj_hfkww5z7trxn.md diff --git a/.trajectories/completed/2026-05/traj_hrsndfzk0qay.json b/.agentworkforce/trajectories/completed/2026-05/traj_hrsndfzk0qay.json similarity index 100% rename from .trajectories/completed/2026-05/traj_hrsndfzk0qay.json rename to .agentworkforce/trajectories/completed/2026-05/traj_hrsndfzk0qay.json diff --git a/.trajectories/completed/2026-05/traj_hrsndfzk0qay.md b/.agentworkforce/trajectories/completed/2026-05/traj_hrsndfzk0qay.md similarity index 100% rename from .trajectories/completed/2026-05/traj_hrsndfzk0qay.md rename to .agentworkforce/trajectories/completed/2026-05/traj_hrsndfzk0qay.md diff --git a/.trajectories/completed/2026-05/traj_hysw5o7idqas.json b/.agentworkforce/trajectories/completed/2026-05/traj_hysw5o7idqas.json similarity index 100% rename from .trajectories/completed/2026-05/traj_hysw5o7idqas.json rename to .agentworkforce/trajectories/completed/2026-05/traj_hysw5o7idqas.json diff --git a/.trajectories/completed/2026-05/traj_hysw5o7idqas.md b/.agentworkforce/trajectories/completed/2026-05/traj_hysw5o7idqas.md similarity index 100% rename from .trajectories/completed/2026-05/traj_hysw5o7idqas.md rename to .agentworkforce/trajectories/completed/2026-05/traj_hysw5o7idqas.md diff --git a/.trajectories/completed/2026-05/traj_i2pjnx3dll5b.json b/.agentworkforce/trajectories/completed/2026-05/traj_i2pjnx3dll5b.json similarity index 100% rename from .trajectories/completed/2026-05/traj_i2pjnx3dll5b.json rename to .agentworkforce/trajectories/completed/2026-05/traj_i2pjnx3dll5b.json diff --git a/.trajectories/completed/2026-05/traj_i2pjnx3dll5b.md b/.agentworkforce/trajectories/completed/2026-05/traj_i2pjnx3dll5b.md similarity index 100% rename from .trajectories/completed/2026-05/traj_i2pjnx3dll5b.md rename to .agentworkforce/trajectories/completed/2026-05/traj_i2pjnx3dll5b.md diff --git a/.trajectories/completed/2026-05/traj_i2pjnx3dll5b.trace.json b/.agentworkforce/trajectories/completed/2026-05/traj_i2pjnx3dll5b.trace.json similarity index 100% rename from .trajectories/completed/2026-05/traj_i2pjnx3dll5b.trace.json rename to .agentworkforce/trajectories/completed/2026-05/traj_i2pjnx3dll5b.trace.json diff --git a/.trajectories/completed/2026-05/traj_ij5b3kcatvwn.json b/.agentworkforce/trajectories/completed/2026-05/traj_ij5b3kcatvwn.json similarity index 100% rename from .trajectories/completed/2026-05/traj_ij5b3kcatvwn.json rename to .agentworkforce/trajectories/completed/2026-05/traj_ij5b3kcatvwn.json diff --git a/.trajectories/completed/2026-05/traj_ij5b3kcatvwn.md b/.agentworkforce/trajectories/completed/2026-05/traj_ij5b3kcatvwn.md similarity index 100% rename from .trajectories/completed/2026-05/traj_ij5b3kcatvwn.md rename to .agentworkforce/trajectories/completed/2026-05/traj_ij5b3kcatvwn.md diff --git a/.trajectories/completed/2026-05/traj_iole5zdt9orr.json b/.agentworkforce/trajectories/completed/2026-05/traj_iole5zdt9orr.json similarity index 100% rename from .trajectories/completed/2026-05/traj_iole5zdt9orr.json rename to .agentworkforce/trajectories/completed/2026-05/traj_iole5zdt9orr.json diff --git a/.trajectories/completed/2026-05/traj_iole5zdt9orr.md b/.agentworkforce/trajectories/completed/2026-05/traj_iole5zdt9orr.md similarity index 100% rename from .trajectories/completed/2026-05/traj_iole5zdt9orr.md rename to .agentworkforce/trajectories/completed/2026-05/traj_iole5zdt9orr.md diff --git a/.trajectories/completed/2026-05/traj_irafiyk6wpw0.json b/.agentworkforce/trajectories/completed/2026-05/traj_irafiyk6wpw0.json similarity index 100% rename from .trajectories/completed/2026-05/traj_irafiyk6wpw0.json rename to .agentworkforce/trajectories/completed/2026-05/traj_irafiyk6wpw0.json diff --git a/.trajectories/completed/2026-05/traj_itgr2w8qs3xn.json b/.agentworkforce/trajectories/completed/2026-05/traj_itgr2w8qs3xn.json similarity index 100% rename from .trajectories/completed/2026-05/traj_itgr2w8qs3xn.json rename to .agentworkforce/trajectories/completed/2026-05/traj_itgr2w8qs3xn.json diff --git a/.trajectories/completed/2026-05/traj_itgr2w8qs3xn.md b/.agentworkforce/trajectories/completed/2026-05/traj_itgr2w8qs3xn.md similarity index 100% rename from .trajectories/completed/2026-05/traj_itgr2w8qs3xn.md rename to .agentworkforce/trajectories/completed/2026-05/traj_itgr2w8qs3xn.md diff --git a/.trajectories/completed/2026-05/traj_j9k10fez3e81.json b/.agentworkforce/trajectories/completed/2026-05/traj_j9k10fez3e81.json similarity index 100% rename from .trajectories/completed/2026-05/traj_j9k10fez3e81.json rename to .agentworkforce/trajectories/completed/2026-05/traj_j9k10fez3e81.json diff --git a/.trajectories/completed/2026-05/traj_j9k10fez3e81.md b/.agentworkforce/trajectories/completed/2026-05/traj_j9k10fez3e81.md similarity index 100% rename from .trajectories/completed/2026-05/traj_j9k10fez3e81.md rename to .agentworkforce/trajectories/completed/2026-05/traj_j9k10fez3e81.md diff --git a/.trajectories/completed/2026-05/traj_jbo2x14y7ovt.json b/.agentworkforce/trajectories/completed/2026-05/traj_jbo2x14y7ovt.json similarity index 100% rename from .trajectories/completed/2026-05/traj_jbo2x14y7ovt.json rename to .agentworkforce/trajectories/completed/2026-05/traj_jbo2x14y7ovt.json diff --git a/.trajectories/completed/2026-05/traj_jbo2x14y7ovt.md b/.agentworkforce/trajectories/completed/2026-05/traj_jbo2x14y7ovt.md similarity index 100% rename from .trajectories/completed/2026-05/traj_jbo2x14y7ovt.md rename to .agentworkforce/trajectories/completed/2026-05/traj_jbo2x14y7ovt.md diff --git a/.trajectories/completed/2026-05/traj_jmf9pyt3zikn.json b/.agentworkforce/trajectories/completed/2026-05/traj_jmf9pyt3zikn.json similarity index 100% rename from .trajectories/completed/2026-05/traj_jmf9pyt3zikn.json rename to .agentworkforce/trajectories/completed/2026-05/traj_jmf9pyt3zikn.json diff --git a/.trajectories/completed/2026-05/traj_jmf9pyt3zikn.md b/.agentworkforce/trajectories/completed/2026-05/traj_jmf9pyt3zikn.md similarity index 100% rename from .trajectories/completed/2026-05/traj_jmf9pyt3zikn.md rename to .agentworkforce/trajectories/completed/2026-05/traj_jmf9pyt3zikn.md diff --git a/.trajectories/completed/2026-05/traj_k7njijv51iq4.json b/.agentworkforce/trajectories/completed/2026-05/traj_k7njijv51iq4.json similarity index 100% rename from .trajectories/completed/2026-05/traj_k7njijv51iq4.json rename to .agentworkforce/trajectories/completed/2026-05/traj_k7njijv51iq4.json diff --git a/.trajectories/completed/2026-05/traj_k7njijv51iq4.md b/.agentworkforce/trajectories/completed/2026-05/traj_k7njijv51iq4.md similarity index 100% rename from .trajectories/completed/2026-05/traj_k7njijv51iq4.md rename to .agentworkforce/trajectories/completed/2026-05/traj_k7njijv51iq4.md diff --git a/.trajectories/completed/2026-05/traj_kgl2opmmfvus.json b/.agentworkforce/trajectories/completed/2026-05/traj_kgl2opmmfvus.json similarity index 100% rename from .trajectories/completed/2026-05/traj_kgl2opmmfvus.json rename to .agentworkforce/trajectories/completed/2026-05/traj_kgl2opmmfvus.json diff --git a/.trajectories/completed/2026-05/traj_kgl2opmmfvus.md b/.agentworkforce/trajectories/completed/2026-05/traj_kgl2opmmfvus.md similarity index 100% rename from .trajectories/completed/2026-05/traj_kgl2opmmfvus.md rename to .agentworkforce/trajectories/completed/2026-05/traj_kgl2opmmfvus.md diff --git a/.trajectories/completed/2026-05/traj_l1349adi1g0o.json b/.agentworkforce/trajectories/completed/2026-05/traj_l1349adi1g0o.json similarity index 100% rename from .trajectories/completed/2026-05/traj_l1349adi1g0o.json rename to .agentworkforce/trajectories/completed/2026-05/traj_l1349adi1g0o.json diff --git a/.trajectories/completed/2026-05/traj_l1349adi1g0o.md b/.agentworkforce/trajectories/completed/2026-05/traj_l1349adi1g0o.md similarity index 100% rename from .trajectories/completed/2026-05/traj_l1349adi1g0o.md rename to .agentworkforce/trajectories/completed/2026-05/traj_l1349adi1g0o.md diff --git a/.trajectories/completed/2026-05/traj_l67sex3nkzfq.json b/.agentworkforce/trajectories/completed/2026-05/traj_l67sex3nkzfq.json similarity index 100% rename from .trajectories/completed/2026-05/traj_l67sex3nkzfq.json rename to .agentworkforce/trajectories/completed/2026-05/traj_l67sex3nkzfq.json diff --git a/.trajectories/completed/2026-05/traj_l67sex3nkzfq.md b/.agentworkforce/trajectories/completed/2026-05/traj_l67sex3nkzfq.md similarity index 100% rename from .trajectories/completed/2026-05/traj_l67sex3nkzfq.md rename to .agentworkforce/trajectories/completed/2026-05/traj_l67sex3nkzfq.md diff --git a/.trajectories/completed/2026-05/traj_lhyrcib40kao.json b/.agentworkforce/trajectories/completed/2026-05/traj_lhyrcib40kao.json similarity index 100% rename from .trajectories/completed/2026-05/traj_lhyrcib40kao.json rename to .agentworkforce/trajectories/completed/2026-05/traj_lhyrcib40kao.json diff --git a/.trajectories/completed/2026-05/traj_lhyrcib40kao.md b/.agentworkforce/trajectories/completed/2026-05/traj_lhyrcib40kao.md similarity index 100% rename from .trajectories/completed/2026-05/traj_lhyrcib40kao.md rename to .agentworkforce/trajectories/completed/2026-05/traj_lhyrcib40kao.md diff --git a/.trajectories/completed/2026-05/traj_lieyyspidhfj.json b/.agentworkforce/trajectories/completed/2026-05/traj_lieyyspidhfj.json similarity index 100% rename from .trajectories/completed/2026-05/traj_lieyyspidhfj.json rename to .agentworkforce/trajectories/completed/2026-05/traj_lieyyspidhfj.json diff --git a/.trajectories/completed/2026-05/traj_lieyyspidhfj.md b/.agentworkforce/trajectories/completed/2026-05/traj_lieyyspidhfj.md similarity index 100% rename from .trajectories/completed/2026-05/traj_lieyyspidhfj.md rename to .agentworkforce/trajectories/completed/2026-05/traj_lieyyspidhfj.md diff --git a/.trajectories/completed/2026-05/traj_lieyyspidhfj.trace.json b/.agentworkforce/trajectories/completed/2026-05/traj_lieyyspidhfj.trace.json similarity index 100% rename from .trajectories/completed/2026-05/traj_lieyyspidhfj.trace.json rename to .agentworkforce/trajectories/completed/2026-05/traj_lieyyspidhfj.trace.json diff --git a/.trajectories/completed/2026-05/traj_m7mpv7j8n78h.json b/.agentworkforce/trajectories/completed/2026-05/traj_m7mpv7j8n78h.json similarity index 100% rename from .trajectories/completed/2026-05/traj_m7mpv7j8n78h.json rename to .agentworkforce/trajectories/completed/2026-05/traj_m7mpv7j8n78h.json diff --git a/.trajectories/completed/2026-05/traj_m7mpv7j8n78h.md b/.agentworkforce/trajectories/completed/2026-05/traj_m7mpv7j8n78h.md similarity index 100% rename from .trajectories/completed/2026-05/traj_m7mpv7j8n78h.md rename to .agentworkforce/trajectories/completed/2026-05/traj_m7mpv7j8n78h.md diff --git a/.trajectories/completed/2026-05/traj_mi9eqd4rjfea.json b/.agentworkforce/trajectories/completed/2026-05/traj_mi9eqd4rjfea.json similarity index 100% rename from .trajectories/completed/2026-05/traj_mi9eqd4rjfea.json rename to .agentworkforce/trajectories/completed/2026-05/traj_mi9eqd4rjfea.json diff --git a/.trajectories/completed/2026-05/traj_mi9eqd4rjfea.md b/.agentworkforce/trajectories/completed/2026-05/traj_mi9eqd4rjfea.md similarity index 100% rename from .trajectories/completed/2026-05/traj_mi9eqd4rjfea.md rename to .agentworkforce/trajectories/completed/2026-05/traj_mi9eqd4rjfea.md diff --git a/.trajectories/completed/2026-05/traj_mytnzgfayj3d.json b/.agentworkforce/trajectories/completed/2026-05/traj_mytnzgfayj3d.json similarity index 100% rename from .trajectories/completed/2026-05/traj_mytnzgfayj3d.json rename to .agentworkforce/trajectories/completed/2026-05/traj_mytnzgfayj3d.json diff --git a/.trajectories/completed/2026-05/traj_mytnzgfayj3d.md b/.agentworkforce/trajectories/completed/2026-05/traj_mytnzgfayj3d.md similarity index 100% rename from .trajectories/completed/2026-05/traj_mytnzgfayj3d.md rename to .agentworkforce/trajectories/completed/2026-05/traj_mytnzgfayj3d.md diff --git a/.trajectories/completed/2026-05/traj_mz5m5ysjj31e.json b/.agentworkforce/trajectories/completed/2026-05/traj_mz5m5ysjj31e.json similarity index 100% rename from .trajectories/completed/2026-05/traj_mz5m5ysjj31e.json rename to .agentworkforce/trajectories/completed/2026-05/traj_mz5m5ysjj31e.json diff --git a/.trajectories/completed/2026-05/traj_mz5m5ysjj31e.md b/.agentworkforce/trajectories/completed/2026-05/traj_mz5m5ysjj31e.md similarity index 100% rename from .trajectories/completed/2026-05/traj_mz5m5ysjj31e.md rename to .agentworkforce/trajectories/completed/2026-05/traj_mz5m5ysjj31e.md diff --git a/.trajectories/completed/2026-05/traj_n0qwpjvmdl2s.json b/.agentworkforce/trajectories/completed/2026-05/traj_n0qwpjvmdl2s.json similarity index 100% rename from .trajectories/completed/2026-05/traj_n0qwpjvmdl2s.json rename to .agentworkforce/trajectories/completed/2026-05/traj_n0qwpjvmdl2s.json diff --git a/.trajectories/completed/2026-05/traj_n0qwpjvmdl2s.md b/.agentworkforce/trajectories/completed/2026-05/traj_n0qwpjvmdl2s.md similarity index 100% rename from .trajectories/completed/2026-05/traj_n0qwpjvmdl2s.md rename to .agentworkforce/trajectories/completed/2026-05/traj_n0qwpjvmdl2s.md diff --git a/.trajectories/completed/2026-05/traj_n8duofq5vq1a.json b/.agentworkforce/trajectories/completed/2026-05/traj_n8duofq5vq1a.json similarity index 100% rename from .trajectories/completed/2026-05/traj_n8duofq5vq1a.json rename to .agentworkforce/trajectories/completed/2026-05/traj_n8duofq5vq1a.json diff --git a/.trajectories/completed/2026-05/traj_n8duofq5vq1a.md b/.agentworkforce/trajectories/completed/2026-05/traj_n8duofq5vq1a.md similarity index 100% rename from .trajectories/completed/2026-05/traj_n8duofq5vq1a.md rename to .agentworkforce/trajectories/completed/2026-05/traj_n8duofq5vq1a.md diff --git a/.trajectories/completed/2026-05/traj_o251whkvy9rl.json b/.agentworkforce/trajectories/completed/2026-05/traj_o251whkvy9rl.json similarity index 100% rename from .trajectories/completed/2026-05/traj_o251whkvy9rl.json rename to .agentworkforce/trajectories/completed/2026-05/traj_o251whkvy9rl.json diff --git a/.trajectories/completed/2026-05/traj_o251whkvy9rl.md b/.agentworkforce/trajectories/completed/2026-05/traj_o251whkvy9rl.md similarity index 100% rename from .trajectories/completed/2026-05/traj_o251whkvy9rl.md rename to .agentworkforce/trajectories/completed/2026-05/traj_o251whkvy9rl.md diff --git a/.trajectories/completed/2026-05/traj_o9cx33xn5u39.json b/.agentworkforce/trajectories/completed/2026-05/traj_o9cx33xn5u39.json similarity index 100% rename from .trajectories/completed/2026-05/traj_o9cx33xn5u39.json rename to .agentworkforce/trajectories/completed/2026-05/traj_o9cx33xn5u39.json diff --git a/.trajectories/completed/2026-05/traj_o9cx33xn5u39.md b/.agentworkforce/trajectories/completed/2026-05/traj_o9cx33xn5u39.md similarity index 100% rename from .trajectories/completed/2026-05/traj_o9cx33xn5u39.md rename to .agentworkforce/trajectories/completed/2026-05/traj_o9cx33xn5u39.md diff --git a/.trajectories/completed/2026-05/traj_ootb5rt3tozd.json b/.agentworkforce/trajectories/completed/2026-05/traj_ootb5rt3tozd.json similarity index 100% rename from .trajectories/completed/2026-05/traj_ootb5rt3tozd.json rename to .agentworkforce/trajectories/completed/2026-05/traj_ootb5rt3tozd.json diff --git a/.trajectories/completed/2026-05/traj_ootb5rt3tozd.md b/.agentworkforce/trajectories/completed/2026-05/traj_ootb5rt3tozd.md similarity index 100% rename from .trajectories/completed/2026-05/traj_ootb5rt3tozd.md rename to .agentworkforce/trajectories/completed/2026-05/traj_ootb5rt3tozd.md diff --git a/.trajectories/completed/2026-05/traj_oyc528j7suvo.json b/.agentworkforce/trajectories/completed/2026-05/traj_oyc528j7suvo.json similarity index 100% rename from .trajectories/completed/2026-05/traj_oyc528j7suvo.json rename to .agentworkforce/trajectories/completed/2026-05/traj_oyc528j7suvo.json diff --git a/.trajectories/completed/2026-05/traj_oyc528j7suvo.md b/.agentworkforce/trajectories/completed/2026-05/traj_oyc528j7suvo.md similarity index 100% rename from .trajectories/completed/2026-05/traj_oyc528j7suvo.md rename to .agentworkforce/trajectories/completed/2026-05/traj_oyc528j7suvo.md diff --git a/.trajectories/completed/2026-05/traj_piik8r6zu3i7.json b/.agentworkforce/trajectories/completed/2026-05/traj_piik8r6zu3i7.json similarity index 100% rename from .trajectories/completed/2026-05/traj_piik8r6zu3i7.json rename to .agentworkforce/trajectories/completed/2026-05/traj_piik8r6zu3i7.json diff --git a/.trajectories/completed/2026-05/traj_piik8r6zu3i7.md b/.agentworkforce/trajectories/completed/2026-05/traj_piik8r6zu3i7.md similarity index 100% rename from .trajectories/completed/2026-05/traj_piik8r6zu3i7.md rename to .agentworkforce/trajectories/completed/2026-05/traj_piik8r6zu3i7.md diff --git a/.trajectories/completed/2026-05/traj_pmrcfj6or3pz.json b/.agentworkforce/trajectories/completed/2026-05/traj_pmrcfj6or3pz.json similarity index 100% rename from .trajectories/completed/2026-05/traj_pmrcfj6or3pz.json rename to .agentworkforce/trajectories/completed/2026-05/traj_pmrcfj6or3pz.json diff --git a/.trajectories/completed/2026-05/traj_pmrcfj6or3pz.md b/.agentworkforce/trajectories/completed/2026-05/traj_pmrcfj6or3pz.md similarity index 100% rename from .trajectories/completed/2026-05/traj_pmrcfj6or3pz.md rename to .agentworkforce/trajectories/completed/2026-05/traj_pmrcfj6or3pz.md diff --git a/.trajectories/completed/2026-05/traj_q2r3c9dmdep7.json b/.agentworkforce/trajectories/completed/2026-05/traj_q2r3c9dmdep7.json similarity index 100% rename from .trajectories/completed/2026-05/traj_q2r3c9dmdep7.json rename to .agentworkforce/trajectories/completed/2026-05/traj_q2r3c9dmdep7.json diff --git a/.trajectories/completed/2026-05/traj_q2r3c9dmdep7.md b/.agentworkforce/trajectories/completed/2026-05/traj_q2r3c9dmdep7.md similarity index 100% rename from .trajectories/completed/2026-05/traj_q2r3c9dmdep7.md rename to .agentworkforce/trajectories/completed/2026-05/traj_q2r3c9dmdep7.md diff --git a/.trajectories/completed/2026-05/traj_qbq3laxbvhzf.json b/.agentworkforce/trajectories/completed/2026-05/traj_qbq3laxbvhzf.json similarity index 100% rename from .trajectories/completed/2026-05/traj_qbq3laxbvhzf.json rename to .agentworkforce/trajectories/completed/2026-05/traj_qbq3laxbvhzf.json diff --git a/.trajectories/completed/2026-05/traj_qbq3laxbvhzf.md b/.agentworkforce/trajectories/completed/2026-05/traj_qbq3laxbvhzf.md similarity index 100% rename from .trajectories/completed/2026-05/traj_qbq3laxbvhzf.md rename to .agentworkforce/trajectories/completed/2026-05/traj_qbq3laxbvhzf.md diff --git a/.trajectories/completed/2026-05/traj_qtmid2nzz0kz.json b/.agentworkforce/trajectories/completed/2026-05/traj_qtmid2nzz0kz.json similarity index 100% rename from .trajectories/completed/2026-05/traj_qtmid2nzz0kz.json rename to .agentworkforce/trajectories/completed/2026-05/traj_qtmid2nzz0kz.json diff --git a/.trajectories/completed/2026-05/traj_qtmid2nzz0kz.md b/.agentworkforce/trajectories/completed/2026-05/traj_qtmid2nzz0kz.md similarity index 100% rename from .trajectories/completed/2026-05/traj_qtmid2nzz0kz.md rename to .agentworkforce/trajectories/completed/2026-05/traj_qtmid2nzz0kz.md diff --git a/.trajectories/completed/2026-05/traj_ryf5sstno6p3.json b/.agentworkforce/trajectories/completed/2026-05/traj_ryf5sstno6p3.json similarity index 100% rename from .trajectories/completed/2026-05/traj_ryf5sstno6p3.json rename to .agentworkforce/trajectories/completed/2026-05/traj_ryf5sstno6p3.json diff --git a/.trajectories/completed/2026-05/traj_ryf5sstno6p3.md b/.agentworkforce/trajectories/completed/2026-05/traj_ryf5sstno6p3.md similarity index 100% rename from .trajectories/completed/2026-05/traj_ryf5sstno6p3.md rename to .agentworkforce/trajectories/completed/2026-05/traj_ryf5sstno6p3.md diff --git a/.trajectories/completed/2026-05/traj_s5ojo1f4srz4.json b/.agentworkforce/trajectories/completed/2026-05/traj_s5ojo1f4srz4.json similarity index 100% rename from .trajectories/completed/2026-05/traj_s5ojo1f4srz4.json rename to .agentworkforce/trajectories/completed/2026-05/traj_s5ojo1f4srz4.json diff --git a/.trajectories/completed/2026-05/traj_s5ojo1f4srz4.md b/.agentworkforce/trajectories/completed/2026-05/traj_s5ojo1f4srz4.md similarity index 100% rename from .trajectories/completed/2026-05/traj_s5ojo1f4srz4.md rename to .agentworkforce/trajectories/completed/2026-05/traj_s5ojo1f4srz4.md diff --git a/.trajectories/completed/2026-05/traj_sh2ahp9z2xg6.json b/.agentworkforce/trajectories/completed/2026-05/traj_sh2ahp9z2xg6.json similarity index 100% rename from .trajectories/completed/2026-05/traj_sh2ahp9z2xg6.json rename to .agentworkforce/trajectories/completed/2026-05/traj_sh2ahp9z2xg6.json diff --git a/.trajectories/completed/2026-05/traj_sh2ahp9z2xg6.md b/.agentworkforce/trajectories/completed/2026-05/traj_sh2ahp9z2xg6.md similarity index 100% rename from .trajectories/completed/2026-05/traj_sh2ahp9z2xg6.md rename to .agentworkforce/trajectories/completed/2026-05/traj_sh2ahp9z2xg6.md diff --git a/.trajectories/completed/2026-05/traj_sqerp89tc436.json b/.agentworkforce/trajectories/completed/2026-05/traj_sqerp89tc436.json similarity index 100% rename from .trajectories/completed/2026-05/traj_sqerp89tc436.json rename to .agentworkforce/trajectories/completed/2026-05/traj_sqerp89tc436.json diff --git a/.trajectories/completed/2026-05/traj_sqerp89tc436.md b/.agentworkforce/trajectories/completed/2026-05/traj_sqerp89tc436.md similarity index 100% rename from .trajectories/completed/2026-05/traj_sqerp89tc436.md rename to .agentworkforce/trajectories/completed/2026-05/traj_sqerp89tc436.md diff --git a/.trajectories/completed/2026-05/traj_t5uknesn2fcw.json b/.agentworkforce/trajectories/completed/2026-05/traj_t5uknesn2fcw.json similarity index 100% rename from .trajectories/completed/2026-05/traj_t5uknesn2fcw.json rename to .agentworkforce/trajectories/completed/2026-05/traj_t5uknesn2fcw.json diff --git a/.trajectories/completed/2026-05/traj_t5uknesn2fcw.md b/.agentworkforce/trajectories/completed/2026-05/traj_t5uknesn2fcw.md similarity index 100% rename from .trajectories/completed/2026-05/traj_t5uknesn2fcw.md rename to .agentworkforce/trajectories/completed/2026-05/traj_t5uknesn2fcw.md diff --git a/.trajectories/completed/2026-05/traj_t6h534vn0bpg.json b/.agentworkforce/trajectories/completed/2026-05/traj_t6h534vn0bpg.json similarity index 100% rename from .trajectories/completed/2026-05/traj_t6h534vn0bpg.json rename to .agentworkforce/trajectories/completed/2026-05/traj_t6h534vn0bpg.json diff --git a/.trajectories/completed/2026-05/traj_t6h534vn0bpg.md b/.agentworkforce/trajectories/completed/2026-05/traj_t6h534vn0bpg.md similarity index 100% rename from .trajectories/completed/2026-05/traj_t6h534vn0bpg.md rename to .agentworkforce/trajectories/completed/2026-05/traj_t6h534vn0bpg.md diff --git a/.trajectories/completed/2026-05/traj_tavtex0db4b0.json b/.agentworkforce/trajectories/completed/2026-05/traj_tavtex0db4b0.json similarity index 100% rename from .trajectories/completed/2026-05/traj_tavtex0db4b0.json rename to .agentworkforce/trajectories/completed/2026-05/traj_tavtex0db4b0.json diff --git a/.trajectories/completed/2026-05/traj_tavtex0db4b0.md b/.agentworkforce/trajectories/completed/2026-05/traj_tavtex0db4b0.md similarity index 100% rename from .trajectories/completed/2026-05/traj_tavtex0db4b0.md rename to .agentworkforce/trajectories/completed/2026-05/traj_tavtex0db4b0.md diff --git a/.trajectories/completed/2026-05/traj_tgism98me5na.json b/.agentworkforce/trajectories/completed/2026-05/traj_tgism98me5na.json similarity index 100% rename from .trajectories/completed/2026-05/traj_tgism98me5na.json rename to .agentworkforce/trajectories/completed/2026-05/traj_tgism98me5na.json diff --git a/.trajectories/completed/2026-05/traj_tgism98me5na.md b/.agentworkforce/trajectories/completed/2026-05/traj_tgism98me5na.md similarity index 100% rename from .trajectories/completed/2026-05/traj_tgism98me5na.md rename to .agentworkforce/trajectories/completed/2026-05/traj_tgism98me5na.md diff --git a/.trajectories/completed/2026-05/traj_u33qn99ijbh4.json b/.agentworkforce/trajectories/completed/2026-05/traj_u33qn99ijbh4.json similarity index 100% rename from .trajectories/completed/2026-05/traj_u33qn99ijbh4.json rename to .agentworkforce/trajectories/completed/2026-05/traj_u33qn99ijbh4.json diff --git a/.trajectories/completed/2026-05/traj_u33qn99ijbh4.md b/.agentworkforce/trajectories/completed/2026-05/traj_u33qn99ijbh4.md similarity index 100% rename from .trajectories/completed/2026-05/traj_u33qn99ijbh4.md rename to .agentworkforce/trajectories/completed/2026-05/traj_u33qn99ijbh4.md diff --git a/.trajectories/completed/2026-05/traj_u3loicehnwb4.json b/.agentworkforce/trajectories/completed/2026-05/traj_u3loicehnwb4.json similarity index 100% rename from .trajectories/completed/2026-05/traj_u3loicehnwb4.json rename to .agentworkforce/trajectories/completed/2026-05/traj_u3loicehnwb4.json diff --git a/.trajectories/completed/2026-05/traj_u3loicehnwb4.md b/.agentworkforce/trajectories/completed/2026-05/traj_u3loicehnwb4.md similarity index 100% rename from .trajectories/completed/2026-05/traj_u3loicehnwb4.md rename to .agentworkforce/trajectories/completed/2026-05/traj_u3loicehnwb4.md diff --git a/.trajectories/completed/2026-05/traj_u4ixmbqqm2y1.json b/.agentworkforce/trajectories/completed/2026-05/traj_u4ixmbqqm2y1.json similarity index 100% rename from .trajectories/completed/2026-05/traj_u4ixmbqqm2y1.json rename to .agentworkforce/trajectories/completed/2026-05/traj_u4ixmbqqm2y1.json diff --git a/.trajectories/completed/2026-05/traj_u4ixmbqqm2y1.md b/.agentworkforce/trajectories/completed/2026-05/traj_u4ixmbqqm2y1.md similarity index 100% rename from .trajectories/completed/2026-05/traj_u4ixmbqqm2y1.md rename to .agentworkforce/trajectories/completed/2026-05/traj_u4ixmbqqm2y1.md diff --git a/.trajectories/completed/2026-05/traj_uf8y40ewrfh0.json b/.agentworkforce/trajectories/completed/2026-05/traj_uf8y40ewrfh0.json similarity index 100% rename from .trajectories/completed/2026-05/traj_uf8y40ewrfh0.json rename to .agentworkforce/trajectories/completed/2026-05/traj_uf8y40ewrfh0.json diff --git a/.trajectories/completed/2026-05/traj_uf8y40ewrfh0.md b/.agentworkforce/trajectories/completed/2026-05/traj_uf8y40ewrfh0.md similarity index 100% rename from .trajectories/completed/2026-05/traj_uf8y40ewrfh0.md rename to .agentworkforce/trajectories/completed/2026-05/traj_uf8y40ewrfh0.md diff --git a/.trajectories/completed/2026-05/traj_v1wexlfur5zr.json b/.agentworkforce/trajectories/completed/2026-05/traj_v1wexlfur5zr.json similarity index 100% rename from .trajectories/completed/2026-05/traj_v1wexlfur5zr.json rename to .agentworkforce/trajectories/completed/2026-05/traj_v1wexlfur5zr.json diff --git a/.trajectories/completed/2026-05/traj_v1wexlfur5zr.md b/.agentworkforce/trajectories/completed/2026-05/traj_v1wexlfur5zr.md similarity index 100% rename from .trajectories/completed/2026-05/traj_v1wexlfur5zr.md rename to .agentworkforce/trajectories/completed/2026-05/traj_v1wexlfur5zr.md diff --git a/.trajectories/completed/2026-05/traj_v87cyrs8dke9.json b/.agentworkforce/trajectories/completed/2026-05/traj_v87cyrs8dke9.json similarity index 100% rename from .trajectories/completed/2026-05/traj_v87cyrs8dke9.json rename to .agentworkforce/trajectories/completed/2026-05/traj_v87cyrs8dke9.json diff --git a/.trajectories/completed/2026-05/traj_v87cyrs8dke9.md b/.agentworkforce/trajectories/completed/2026-05/traj_v87cyrs8dke9.md similarity index 100% rename from .trajectories/completed/2026-05/traj_v87cyrs8dke9.md rename to .agentworkforce/trajectories/completed/2026-05/traj_v87cyrs8dke9.md diff --git a/.trajectories/completed/2026-05/traj_v87cyrs8dke9.trace.json b/.agentworkforce/trajectories/completed/2026-05/traj_v87cyrs8dke9.trace.json similarity index 100% rename from .trajectories/completed/2026-05/traj_v87cyrs8dke9.trace.json rename to .agentworkforce/trajectories/completed/2026-05/traj_v87cyrs8dke9.trace.json diff --git a/.trajectories/completed/2026-05/traj_v9x3o92ag682.json b/.agentworkforce/trajectories/completed/2026-05/traj_v9x3o92ag682.json similarity index 100% rename from .trajectories/completed/2026-05/traj_v9x3o92ag682.json rename to .agentworkforce/trajectories/completed/2026-05/traj_v9x3o92ag682.json diff --git a/.trajectories/completed/2026-05/traj_v9x3o92ag682.md b/.agentworkforce/trajectories/completed/2026-05/traj_v9x3o92ag682.md similarity index 100% rename from .trajectories/completed/2026-05/traj_v9x3o92ag682.md rename to .agentworkforce/trajectories/completed/2026-05/traj_v9x3o92ag682.md diff --git a/.trajectories/completed/2026-05/traj_vfa1jr6otnjn.json b/.agentworkforce/trajectories/completed/2026-05/traj_vfa1jr6otnjn.json similarity index 100% rename from .trajectories/completed/2026-05/traj_vfa1jr6otnjn.json rename to .agentworkforce/trajectories/completed/2026-05/traj_vfa1jr6otnjn.json diff --git a/.trajectories/completed/2026-05/traj_vfa1jr6otnjn.md b/.agentworkforce/trajectories/completed/2026-05/traj_vfa1jr6otnjn.md similarity index 100% rename from .trajectories/completed/2026-05/traj_vfa1jr6otnjn.md rename to .agentworkforce/trajectories/completed/2026-05/traj_vfa1jr6otnjn.md diff --git a/.trajectories/completed/2026-05/traj_vkozdglobkyg.json b/.agentworkforce/trajectories/completed/2026-05/traj_vkozdglobkyg.json similarity index 100% rename from .trajectories/completed/2026-05/traj_vkozdglobkyg.json rename to .agentworkforce/trajectories/completed/2026-05/traj_vkozdglobkyg.json diff --git a/.trajectories/completed/2026-05/traj_vkozdglobkyg.md b/.agentworkforce/trajectories/completed/2026-05/traj_vkozdglobkyg.md similarity index 100% rename from .trajectories/completed/2026-05/traj_vkozdglobkyg.md rename to .agentworkforce/trajectories/completed/2026-05/traj_vkozdglobkyg.md diff --git a/.trajectories/completed/2026-05/traj_wbn62q4cq16h.json b/.agentworkforce/trajectories/completed/2026-05/traj_wbn62q4cq16h.json similarity index 100% rename from .trajectories/completed/2026-05/traj_wbn62q4cq16h.json rename to .agentworkforce/trajectories/completed/2026-05/traj_wbn62q4cq16h.json diff --git a/.trajectories/completed/2026-05/traj_wbn62q4cq16h.md b/.agentworkforce/trajectories/completed/2026-05/traj_wbn62q4cq16h.md similarity index 100% rename from .trajectories/completed/2026-05/traj_wbn62q4cq16h.md rename to .agentworkforce/trajectories/completed/2026-05/traj_wbn62q4cq16h.md diff --git a/.trajectories/completed/2026-05/traj_whd40oxptlhn.json b/.agentworkforce/trajectories/completed/2026-05/traj_whd40oxptlhn.json similarity index 100% rename from .trajectories/completed/2026-05/traj_whd40oxptlhn.json rename to .agentworkforce/trajectories/completed/2026-05/traj_whd40oxptlhn.json diff --git a/.trajectories/completed/2026-05/traj_whd40oxptlhn.md b/.agentworkforce/trajectories/completed/2026-05/traj_whd40oxptlhn.md similarity index 100% rename from .trajectories/completed/2026-05/traj_whd40oxptlhn.md rename to .agentworkforce/trajectories/completed/2026-05/traj_whd40oxptlhn.md diff --git a/.trajectories/completed/2026-05/traj_whd40oxptlhn.trace.json b/.agentworkforce/trajectories/completed/2026-05/traj_whd40oxptlhn.trace.json similarity index 100% rename from .trajectories/completed/2026-05/traj_whd40oxptlhn.trace.json rename to .agentworkforce/trajectories/completed/2026-05/traj_whd40oxptlhn.trace.json diff --git a/.trajectories/completed/2026-05/traj_wx00tjvpptvg.json b/.agentworkforce/trajectories/completed/2026-05/traj_wx00tjvpptvg.json similarity index 100% rename from .trajectories/completed/2026-05/traj_wx00tjvpptvg.json rename to .agentworkforce/trajectories/completed/2026-05/traj_wx00tjvpptvg.json diff --git a/.trajectories/completed/2026-05/traj_wx00tjvpptvg.md b/.agentworkforce/trajectories/completed/2026-05/traj_wx00tjvpptvg.md similarity index 100% rename from .trajectories/completed/2026-05/traj_wx00tjvpptvg.md rename to .agentworkforce/trajectories/completed/2026-05/traj_wx00tjvpptvg.md diff --git a/.trajectories/completed/2026-05/traj_wzzboitm85ee.json b/.agentworkforce/trajectories/completed/2026-05/traj_wzzboitm85ee.json similarity index 100% rename from .trajectories/completed/2026-05/traj_wzzboitm85ee.json rename to .agentworkforce/trajectories/completed/2026-05/traj_wzzboitm85ee.json diff --git a/.trajectories/completed/2026-05/traj_wzzboitm85ee.md b/.agentworkforce/trajectories/completed/2026-05/traj_wzzboitm85ee.md similarity index 100% rename from .trajectories/completed/2026-05/traj_wzzboitm85ee.md rename to .agentworkforce/trajectories/completed/2026-05/traj_wzzboitm85ee.md diff --git a/.trajectories/completed/2026-05/traj_x37bhga2j5ph.json b/.agentworkforce/trajectories/completed/2026-05/traj_x37bhga2j5ph.json similarity index 100% rename from .trajectories/completed/2026-05/traj_x37bhga2j5ph.json rename to .agentworkforce/trajectories/completed/2026-05/traj_x37bhga2j5ph.json diff --git a/.trajectories/completed/2026-05/traj_x37bhga2j5ph.md b/.agentworkforce/trajectories/completed/2026-05/traj_x37bhga2j5ph.md similarity index 100% rename from .trajectories/completed/2026-05/traj_x37bhga2j5ph.md rename to .agentworkforce/trajectories/completed/2026-05/traj_x37bhga2j5ph.md diff --git a/.trajectories/completed/2026-05/traj_ybcrij9wg8m1.json b/.agentworkforce/trajectories/completed/2026-05/traj_ybcrij9wg8m1.json similarity index 100% rename from .trajectories/completed/2026-05/traj_ybcrij9wg8m1.json rename to .agentworkforce/trajectories/completed/2026-05/traj_ybcrij9wg8m1.json diff --git a/.trajectories/completed/2026-05/traj_ybcrij9wg8m1.md b/.agentworkforce/trajectories/completed/2026-05/traj_ybcrij9wg8m1.md similarity index 100% rename from .trajectories/completed/2026-05/traj_ybcrij9wg8m1.md rename to .agentworkforce/trajectories/completed/2026-05/traj_ybcrij9wg8m1.md diff --git a/.trajectories/completed/2026-05/traj_z171lng2fbbi.json b/.agentworkforce/trajectories/completed/2026-05/traj_z171lng2fbbi.json similarity index 100% rename from .trajectories/completed/2026-05/traj_z171lng2fbbi.json rename to .agentworkforce/trajectories/completed/2026-05/traj_z171lng2fbbi.json diff --git a/.trajectories/completed/2026-05/traj_z171lng2fbbi.md b/.agentworkforce/trajectories/completed/2026-05/traj_z171lng2fbbi.md similarity index 100% rename from .trajectories/completed/2026-05/traj_z171lng2fbbi.md rename to .agentworkforce/trajectories/completed/2026-05/traj_z171lng2fbbi.md diff --git a/.trajectories/completed/2026-05/traj_zfa6skfr32vy.json b/.agentworkforce/trajectories/completed/2026-05/traj_zfa6skfr32vy.json similarity index 100% rename from .trajectories/completed/2026-05/traj_zfa6skfr32vy.json rename to .agentworkforce/trajectories/completed/2026-05/traj_zfa6skfr32vy.json diff --git a/.trajectories/completed/2026-05/traj_zfa6skfr32vy.md b/.agentworkforce/trajectories/completed/2026-05/traj_zfa6skfr32vy.md similarity index 100% rename from .trajectories/completed/2026-05/traj_zfa6skfr32vy.md rename to .agentworkforce/trajectories/completed/2026-05/traj_zfa6skfr32vy.md diff --git a/.trajectories/completed/2026-05/traj_zqwco4gl76g3.json b/.agentworkforce/trajectories/completed/2026-05/traj_zqwco4gl76g3.json similarity index 100% rename from .trajectories/completed/2026-05/traj_zqwco4gl76g3.json rename to .agentworkforce/trajectories/completed/2026-05/traj_zqwco4gl76g3.json diff --git a/.trajectories/completed/2026-05/traj_zqwco4gl76g3.md b/.agentworkforce/trajectories/completed/2026-05/traj_zqwco4gl76g3.md similarity index 100% rename from .trajectories/completed/2026-05/traj_zqwco4gl76g3.md rename to .agentworkforce/trajectories/completed/2026-05/traj_zqwco4gl76g3.md diff --git a/.trajectories/completed/2026-05/traj_zu3252hxzoqh.json b/.agentworkforce/trajectories/completed/2026-05/traj_zu3252hxzoqh.json similarity index 100% rename from .trajectories/completed/2026-05/traj_zu3252hxzoqh.json rename to .agentworkforce/trajectories/completed/2026-05/traj_zu3252hxzoqh.json diff --git a/.trajectories/completed/2026-05/traj_zu3252hxzoqh.md b/.agentworkforce/trajectories/completed/2026-05/traj_zu3252hxzoqh.md similarity index 100% rename from .trajectories/completed/2026-05/traj_zu3252hxzoqh.md rename to .agentworkforce/trajectories/completed/2026-05/traj_zu3252hxzoqh.md diff --git a/.trajectories/completed/2026-05/traj_zyluvmlqo5j7.json b/.agentworkforce/trajectories/completed/2026-05/traj_zyluvmlqo5j7.json similarity index 100% rename from .trajectories/completed/2026-05/traj_zyluvmlqo5j7.json rename to .agentworkforce/trajectories/completed/2026-05/traj_zyluvmlqo5j7.json diff --git a/.trajectories/completed/2026-05/traj_zyluvmlqo5j7.md b/.agentworkforce/trajectories/completed/2026-05/traj_zyluvmlqo5j7.md similarity index 100% rename from .trajectories/completed/2026-05/traj_zyluvmlqo5j7.md rename to .agentworkforce/trajectories/completed/2026-05/traj_zyluvmlqo5j7.md diff --git a/.trajectories/completed/traj_1775914296101_a4397efe.json b/.agentworkforce/trajectories/completed/traj_1775914296101_a4397efe.json similarity index 100% rename from .trajectories/completed/traj_1775914296101_a4397efe.json rename to .agentworkforce/trajectories/completed/traj_1775914296101_a4397efe.json diff --git a/.trajectories/completed/traj_1776024661304_cfc829b9.json b/.agentworkforce/trajectories/completed/traj_1776024661304_cfc829b9.json similarity index 100% rename from .trajectories/completed/traj_1776024661304_cfc829b9.json rename to .agentworkforce/trajectories/completed/traj_1776024661304_cfc829b9.json diff --git a/.trajectories/completed/traj_1776105620545_9dcebb3d.json b/.agentworkforce/trajectories/completed/traj_1776105620545_9dcebb3d.json similarity index 100% rename from .trajectories/completed/traj_1776105620545_9dcebb3d.json rename to .agentworkforce/trajectories/completed/traj_1776105620545_9dcebb3d.json diff --git a/.trajectories/completed/traj_1778873052429_03a4dacb.json b/.agentworkforce/trajectories/completed/traj_1778873052429_03a4dacb.json similarity index 100% rename from .trajectories/completed/traj_1778873052429_03a4dacb.json rename to .agentworkforce/trajectories/completed/traj_1778873052429_03a4dacb.json diff --git a/.trajectories/completed/traj_1778873197540_01102ade.json b/.agentworkforce/trajectories/completed/traj_1778873197540_01102ade.json similarity index 100% rename from .trajectories/completed/traj_1778873197540_01102ade.json rename to .agentworkforce/trajectories/completed/traj_1778873197540_01102ade.json diff --git a/.trajectories/completed/traj_1778873199489_f2ce4060.json b/.agentworkforce/trajectories/completed/traj_1778873199489_f2ce4060.json similarity index 100% rename from .trajectories/completed/traj_1778873199489_f2ce4060.json rename to .agentworkforce/trajectories/completed/traj_1778873199489_f2ce4060.json diff --git a/.trajectories/completed/traj_1778873201502_0dacf7c5.json b/.agentworkforce/trajectories/completed/traj_1778873201502_0dacf7c5.json similarity index 100% rename from .trajectories/completed/traj_1778873201502_0dacf7c5.json rename to .agentworkforce/trajectories/completed/traj_1778873201502_0dacf7c5.json diff --git a/.trajectories/completed/traj_1778873203502_4c225b7e.json b/.agentworkforce/trajectories/completed/traj_1778873203502_4c225b7e.json similarity index 100% rename from .trajectories/completed/traj_1778873203502_4c225b7e.json rename to .agentworkforce/trajectories/completed/traj_1778873203502_4c225b7e.json diff --git a/.trajectories/completed/traj_1778873205470_a4e5f0cb.json b/.agentworkforce/trajectories/completed/traj_1778873205470_a4e5f0cb.json similarity index 100% rename from .trajectories/completed/traj_1778873205470_a4e5f0cb.json rename to .agentworkforce/trajectories/completed/traj_1778873205470_a4e5f0cb.json diff --git a/.trajectories/completed/traj_1778873207471_b7def991.json b/.agentworkforce/trajectories/completed/traj_1778873207471_b7def991.json similarity index 100% rename from .trajectories/completed/traj_1778873207471_b7def991.json rename to .agentworkforce/trajectories/completed/traj_1778873207471_b7def991.json diff --git a/.trajectories/completed/traj_1778873209642_c70e32ab.json b/.agentworkforce/trajectories/completed/traj_1778873209642_c70e32ab.json similarity index 100% rename from .trajectories/completed/traj_1778873209642_c70e32ab.json rename to .agentworkforce/trajectories/completed/traj_1778873209642_c70e32ab.json diff --git a/.trajectories/completed/traj_1778873211616_6db3b2cd.json b/.agentworkforce/trajectories/completed/traj_1778873211616_6db3b2cd.json similarity index 100% rename from .trajectories/completed/traj_1778873211616_6db3b2cd.json rename to .agentworkforce/trajectories/completed/traj_1778873211616_6db3b2cd.json diff --git a/.trajectories/completed/traj_1778874205797_81e92307.json b/.agentworkforce/trajectories/completed/traj_1778874205797_81e92307.json similarity index 100% rename from .trajectories/completed/traj_1778874205797_81e92307.json rename to .agentworkforce/trajectories/completed/traj_1778874205797_81e92307.json diff --git a/.trajectories/completed/traj_1778874216773_c6b12ab2.json b/.agentworkforce/trajectories/completed/traj_1778874216773_c6b12ab2.json similarity index 100% rename from .trajectories/completed/traj_1778874216773_c6b12ab2.json rename to .agentworkforce/trajectories/completed/traj_1778874216773_c6b12ab2.json diff --git a/.trajectories/completed/traj_1778874218579_a0225559.json b/.agentworkforce/trajectories/completed/traj_1778874218579_a0225559.json similarity index 100% rename from .trajectories/completed/traj_1778874218579_a0225559.json rename to .agentworkforce/trajectories/completed/traj_1778874218579_a0225559.json diff --git a/.trajectories/completed/traj_1778874224855_9c722c4b.json b/.agentworkforce/trajectories/completed/traj_1778874224855_9c722c4b.json similarity index 100% rename from .trajectories/completed/traj_1778874224855_9c722c4b.json rename to .agentworkforce/trajectories/completed/traj_1778874224855_9c722c4b.json diff --git a/.trajectories/completed/traj_1778874226983_3367d527.json b/.agentworkforce/trajectories/completed/traj_1778874226983_3367d527.json similarity index 100% rename from .trajectories/completed/traj_1778874226983_3367d527.json rename to .agentworkforce/trajectories/completed/traj_1778874226983_3367d527.json diff --git a/.trajectories/completed/traj_1778874229373_9cce9465.json b/.agentworkforce/trajectories/completed/traj_1778874229373_9cce9465.json similarity index 100% rename from .trajectories/completed/traj_1778874229373_9cce9465.json rename to .agentworkforce/trajectories/completed/traj_1778874229373_9cce9465.json diff --git a/.trajectories/completed/traj_1778874240339_51b823cd.json b/.agentworkforce/trajectories/completed/traj_1778874240339_51b823cd.json similarity index 100% rename from .trajectories/completed/traj_1778874240339_51b823cd.json rename to .agentworkforce/trajectories/completed/traj_1778874240339_51b823cd.json diff --git a/.trajectories/completed/traj_1778874241076_caa675a9.json b/.agentworkforce/trajectories/completed/traj_1778874241076_caa675a9.json similarity index 100% rename from .trajectories/completed/traj_1778874241076_caa675a9.json rename to .agentworkforce/trajectories/completed/traj_1778874241076_caa675a9.json diff --git a/.trajectories/completed/traj_1778874248966_e29c4c54.json b/.agentworkforce/trajectories/completed/traj_1778874248966_e29c4c54.json similarity index 100% rename from .trajectories/completed/traj_1778874248966_e29c4c54.json rename to .agentworkforce/trajectories/completed/traj_1778874248966_e29c4c54.json diff --git a/.trajectories/completed/traj_1778874249983_12a98df3.json b/.agentworkforce/trajectories/completed/traj_1778874249983_12a98df3.json similarity index 100% rename from .trajectories/completed/traj_1778874249983_12a98df3.json rename to .agentworkforce/trajectories/completed/traj_1778874249983_12a98df3.json diff --git a/.trajectories/completed/traj_1778874258229_0bdc53d8.json b/.agentworkforce/trajectories/completed/traj_1778874258229_0bdc53d8.json similarity index 100% rename from .trajectories/completed/traj_1778874258229_0bdc53d8.json rename to .agentworkforce/trajectories/completed/traj_1778874258229_0bdc53d8.json diff --git a/.trajectories/completed/traj_1778874261453_55f49624.json b/.agentworkforce/trajectories/completed/traj_1778874261453_55f49624.json similarity index 100% rename from .trajectories/completed/traj_1778874261453_55f49624.json rename to .agentworkforce/trajectories/completed/traj_1778874261453_55f49624.json diff --git a/.trajectories/completed/traj_1778874261608_48fb9bf5.json b/.agentworkforce/trajectories/completed/traj_1778874261608_48fb9bf5.json similarity index 100% rename from .trajectories/completed/traj_1778874261608_48fb9bf5.json rename to .agentworkforce/trajectories/completed/traj_1778874261608_48fb9bf5.json diff --git a/.trajectories/completed/traj_1778874269139_d7d7485a.json b/.agentworkforce/trajectories/completed/traj_1778874269139_d7d7485a.json similarity index 100% rename from .trajectories/completed/traj_1778874269139_d7d7485a.json rename to .agentworkforce/trajectories/completed/traj_1778874269139_d7d7485a.json diff --git a/.trajectories/completed/traj_1778874274412_70843e0e.json b/.agentworkforce/trajectories/completed/traj_1778874274412_70843e0e.json similarity index 100% rename from .trajectories/completed/traj_1778874274412_70843e0e.json rename to .agentworkforce/trajectories/completed/traj_1778874274412_70843e0e.json diff --git a/.trajectories/completed/traj_1778874274581_71efa470.json b/.agentworkforce/trajectories/completed/traj_1778874274581_71efa470.json similarity index 100% rename from .trajectories/completed/traj_1778874274581_71efa470.json rename to .agentworkforce/trajectories/completed/traj_1778874274581_71efa470.json diff --git a/.trajectories/completed/traj_1778874282200_39ad11db.json b/.agentworkforce/trajectories/completed/traj_1778874282200_39ad11db.json similarity index 100% rename from .trajectories/completed/traj_1778874282200_39ad11db.json rename to .agentworkforce/trajectories/completed/traj_1778874282200_39ad11db.json diff --git a/.trajectories/completed/traj_1778874283570_ce3585b8.json b/.agentworkforce/trajectories/completed/traj_1778874283570_ce3585b8.json similarity index 100% rename from .trajectories/completed/traj_1778874283570_ce3585b8.json rename to .agentworkforce/trajectories/completed/traj_1778874283570_ce3585b8.json diff --git a/.trajectories/completed/traj_1778874289674_e3f868c8.json b/.agentworkforce/trajectories/completed/traj_1778874289674_e3f868c8.json similarity index 100% rename from .trajectories/completed/traj_1778874289674_e3f868c8.json rename to .agentworkforce/trajectories/completed/traj_1778874289674_e3f868c8.json diff --git a/.trajectories/completed/traj_1778874291950_0b1b5c1f.json b/.agentworkforce/trajectories/completed/traj_1778874291950_0b1b5c1f.json similarity index 100% rename from .trajectories/completed/traj_1778874291950_0b1b5c1f.json rename to .agentworkforce/trajectories/completed/traj_1778874291950_0b1b5c1f.json diff --git a/.trajectories/completed/traj_1778874295927_4083d181.json b/.agentworkforce/trajectories/completed/traj_1778874295927_4083d181.json similarity index 100% rename from .trajectories/completed/traj_1778874295927_4083d181.json rename to .agentworkforce/trajectories/completed/traj_1778874295927_4083d181.json diff --git a/.trajectories/completed/traj_1778874296362_bdf727ff.json b/.agentworkforce/trajectories/completed/traj_1778874296362_bdf727ff.json similarity index 100% rename from .trajectories/completed/traj_1778874296362_bdf727ff.json rename to .agentworkforce/trajectories/completed/traj_1778874296362_bdf727ff.json diff --git a/.trajectories/index.json b/.trajectories/index.json deleted file mode 100644 index 54c4575ca..000000000 --- a/.trajectories/index.json +++ /dev/null @@ -1,1245 +0,0 @@ -{ - "version": 1, - "lastUpdated": "2026-05-26T11:26:52.761Z", - "trajectories": { - "traj_05xg7j388bc4": { - "title": "Add browser workflow step integration", - "status": "completed", - "startedAt": "2026-04-10T14:56:33.229Z", - "completedAt": "2026-04-10T15:05:14.660Z", - "path": ".trajectories/completed/2026-04/traj_05xg7j388bc4.json" - }, - "traj_0t92gxaz6igh": { - "title": "Move docs sidebar into the mobile hamburger menu", - "status": "completed", - "startedAt": "2026-04-10T16:29:40.674Z", - "completedAt": "2026-04-10T16:32:14.544Z", - "path": ".trajectories/completed/2026-04/traj_0t92gxaz6igh.json" - }, - "traj_1776105620545_9dcebb3d": { - "title": "fix-inbox-agent-flag-workflow", - "status": "completed", - "startedAt": "2026-04-13T18:40:20.545Z", - "completedAt": "2026-04-13T18:41:52.831Z", - "path": ".trajectories/completed/2026-04/traj_1776105620545_9dcebb3d.json" - }, - "traj_1776105988184_29f1270c": { - "title": "fix-inbox-agent-flag-workflow", - "status": "completed", - "startedAt": "2026-04-13T18:46:28.184Z", - "completedAt": "2026-04-13T20:23:54.308Z", - "path": ".trajectories/completed/2026-04/traj_1776105988184_29f1270c.json" - }, - "traj_222ha5671idc": { - "title": "validate-cloud-connect-e2e-workflow", - "status": "completed", - "startedAt": "2026-04-15T21:32:51.980Z", - "completedAt": "2026-04-15T21:45:41.024Z", - "path": ".trajectories/completed/2026-04/traj_222ha5671idc.json" - }, - "traj_3b3p1z4y7qlo": { - "title": "add-mcp-args-subcommand-workflow", - "status": "completed", - "startedAt": "2026-04-20T13:16:22.009Z", - "completedAt": "2026-04-20T13:26:35.142Z", - "path": ".trajectories/completed/2026-04/traj_3b3p1z4y7qlo.json" - }, - "traj_4zqhfqw7g28l": { - "title": "Investigate GitHub Actions failure for run 24255758219 job 70826792063", - "status": "completed", - "startedAt": "2026-04-10T17:48:33.502Z", - "completedAt": "2026-04-10T17:49:14.485Z", - "path": ".trajectories/completed/2026-04/traj_4zqhfqw7g28l.json" - }, - "traj_530xmbfeljyb": { - "title": "Implement GitHub primitive adapter base layer", - "status": "completed", - "startedAt": "2026-04-10T15:16:25.682Z", - "completedAt": "2026-04-10T15:25:16.937Z", - "path": ".trajectories/completed/2026-04/traj_530xmbfeljyb.json" - }, - "traj_703m7sqyq89t": { - "title": "Fix production docs loader using build-machine absolute MDX paths", - "status": "completed", - "startedAt": "2026-04-10T16:33:10.601Z", - "completedAt": "2026-04-10T16:35:33.660Z", - "path": ".trajectories/completed/2026-04/traj_703m7sqyq89t.json" - }, - "traj_8oh4r5km5eic": { - "title": "Implement GitHub primitive actions", - "status": "completed", - "startedAt": "2026-04-10T15:26:11.355Z", - "completedAt": "2026-04-10T15:33:35.150Z", - "path": ".trajectories/completed/2026-04/traj_8oh4r5km5eic.json" - }, - "traj_9tt55is74dq5": { - "title": "Pin TypeScript build resolution for acp-bridge, memory, trajectory, and cloud", - "status": "completed", - "startedAt": "2026-04-11T13:34:46.304Z", - "completedAt": "2026-04-11T13:35:22.677Z", - "path": ".trajectories/completed/2026-04/traj_9tt55is74dq5.json" - }, - "traj_abjovknvcijv": { - "title": "Scope CI so web-only changes do not run unrelated relay and SDK tests", - "status": "completed", - "startedAt": "2026-04-10T16:08:30.070Z", - "completedAt": "2026-04-10T16:11:08.673Z", - "path": ".trajectories/completed/2026-04/traj_abjovknvcijv.json" - }, - "traj_avmkyoo2s3rt": { - "title": "Implement Browser primitive client", - "status": "completed", - "startedAt": "2026-04-10T14:42:17.242Z", - "completedAt": "2026-04-10T14:55:45.196Z", - "path": ".trajectories/completed/2026-04/traj_avmkyoo2s3rt.json" - }, - "traj_d48czxmgx4ac": { - "title": "Shift dark-mode footer from black to Relay blue", - "status": "completed", - "startedAt": "2026-04-10T16:12:27.477Z", - "completedAt": "2026-04-10T16:13:14.348Z", - "path": ".trajectories/completed/2026-04/traj_d48czxmgx4ac.json" - }, - "traj_dw8ihhdb8ip7": { - "title": "fix-dm-history-workflow", - "status": "abandoned", - "startedAt": "2026-04-13T19:51:57.984Z", - "completedAt": "2026-04-13T19:57:27.195Z", - "path": ".trajectories/completed/2026-04/traj_dw8ihhdb8ip7.json" - }, - "traj_e5i62wdjx0jd": { - "title": "Plan autofix finding groups", - "status": "completed", - "startedAt": "2026-04-13T09:40:42.044Z", - "completedAt": "2026-04-13T09:41:07.789Z", - "path": ".trajectories/completed/2026-04/traj_e5i62wdjx0jd.json" - }, - "traj_g3muawdq6bsb": { - "title": "Invert dark footer gradient so the lighter blue is at the top", - "status": "completed", - "startedAt": "2026-04-10T16:13:19.744Z", - "completedAt": "2026-04-10T16:13:43.289Z", - "path": ".trajectories/completed/2026-04/traj_g3muawdq6bsb.json" - }, - "traj_mk0t0cgn4ytq": { - "title": "Merge origin/main into better-nav and resolve trajectory conflicts", - "status": "completed", - "startedAt": "2026-04-10T15:10:03.877Z", - "completedAt": "2026-04-10T15:10:29.410Z", - "path": ".trajectories/completed/2026-04/traj_mk0t0cgn4ytq.json" - }, - "traj_o8kgzhfu6jth": { - "title": "Add /cloud link to footer", - "status": "completed", - "startedAt": "2026-04-10T16:07:15.131Z", - "completedAt": "2026-04-10T16:07:42.930Z", - "path": ".trajectories/completed/2026-04/traj_o8kgzhfu6jth.json" - }, - "traj_qb54w47qwod6": { - "title": "fix-history-from-workflow", - "status": "completed", - "startedAt": "2026-04-13T20:16:10.459Z", - "completedAt": "2026-04-13T20:25:09.219Z", - "path": ".trajectories/completed/2026-04/traj_qb54w47qwod6.json" - }, - "traj_rs2bt3x0fqba": { - "title": "Compare failed web deploy to prior deploys and identify no-downtime fix", - "status": "completed", - "startedAt": "2026-04-10T17:50:43.088Z", - "completedAt": "2026-04-10T18:00:44.095Z", - "path": ".trajectories/completed/2026-04/traj_rs2bt3x0fqba.json" - }, - "traj_tjadoebpscps": { - "title": "fix-dm-history-workflow", - "status": "completed", - "startedAt": "2026-04-13T20:02:27.719Z", - "completedAt": "2026-04-13T20:02:35.662Z", - "path": ".trajectories/completed/2026-04/traj_tjadoebpscps.json" - }, - "traj_tv1x9pamkqad": { - "title": "Add GitHub primitive workflow step integration", - "status": "completed", - "startedAt": "2026-04-10T15:34:36.611Z", - "completedAt": "2026-04-10T15:42:17.590Z", - "path": ".trajectories/completed/2026-04/traj_tv1x9pamkqad.json" - }, - "traj_ui5omrgz819d": { - "title": "cloud-run-start-from-workflow", - "status": "completed", - "startedAt": "2026-04-27T20:00:33.269Z", - "completedAt": "2026-04-27T20:08:46.379Z", - "path": ".trajectories/completed/2026-04/traj_ui5omrgz819d.json" - }, - "traj_w0xpsaoxuiyw": { - "title": "Pin TypeScript compiler version and build invocation in selected packages", - "status": "completed", - "startedAt": "2026-04-11T13:35:52.600Z", - "completedAt": "2026-04-11T13:36:48.341Z", - "path": ".trajectories/completed/2026-04/traj_w0xpsaoxuiyw.json" - }, - "traj_0e8i20oitwvz": { - "title": "Final fresh-eyes review Codex GPT-5.5 fix", - "status": "completed", - "startedAt": "2026-05-15T12:46:11.342Z", - "completedAt": "2026-05-15T12:46:11.500Z", - "path": ".trajectories/completed/2026-05/traj_0e8i20oitwvz.json" - }, - "traj_0o6gb2wvk59t": { - "title": "Fresh end-to-end validation for headless readiness", - "status": "completed", - "startedAt": "2026-05-15T10:55:49.188Z", - "completedAt": "2026-05-15T11:11:52.324Z", - "path": ".trajectories/completed/2026-05/traj_0o6gb2wvk59t.json" - }, - "traj_0z98tkaigaxg": { - "title": "ricky-child-update-issue-860-transcript-test-workflow", - "status": "completed", - "startedAt": "2026-05-15T21:06:58.558Z", - "completedAt": "2026-05-15T21:35:56.724Z", - "path": ".trajectories/completed/2026-05/traj_0z98tkaigaxg.json" - }, - "traj_1775914133873_35667beb": { - "title": "fix-sdk-build-resolution-workflow", - "status": "completed", - "startedAt": "2026-04-11T13:28:53.873Z", - "completedAt": "2026-05-08T13:33:48.161Z", - "path": ".trajectories/completed/2026-05/traj_1775914133873_35667beb.json" - }, - "traj_1776073106646_1839be2d": { - "title": "autofix-swarm-Agentworkforce-relay-workflow", - "status": "completed", - "startedAt": "2026-04-13T09:38:26.646Z", - "completedAt": "2026-05-08T13:33:45.944Z", - "path": ".trajectories/completed/2026-05/traj_1776073106646_1839be2d.json" - }, - "traj_1776113772922_bc92f121": { - "title": "autofix-swarm-Agentworkforce-relay-workflow", - "status": "completed", - "startedAt": "2026-04-13T20:56:12.922Z", - "completedAt": "2026-05-08T13:33:43.489Z", - "path": ".trajectories/completed/2026-05/traj_1776113772922_bc92f121.json" - }, - "traj_1778873209642_c70e32ab": { - "title": "ricky-child-update-2-workflow", - "status": "completed", - "startedAt": "2026-05-15T19:26:49.642Z", - "completedAt": "2026-05-15T19:36:18.257Z", - "path": ".trajectories/completed/2026-05/traj_1778873209642_c70e32ab.json" - }, - "traj_1778873211616_6db3b2cd": { - "title": "ricky-child-update-docs-sync-workflow", - "status": "completed", - "startedAt": "2026-05-15T19:26:51.616Z", - "completedAt": "2026-05-15T19:35:07.059Z", - "path": ".trajectories/completed/2026-05/traj_1778873211616_6db3b2cd.json" - }, - "traj_1rrpe2r7fyem": { - "title": "Use streaming PTY input in CLI drive", - "status": "completed", - "startedAt": "2026-05-20T07:20:33.009Z", - "completedAt": "2026-05-20T07:26:17.567Z", - "path": ".trajectories/completed/2026-05/traj_1rrpe2r7fyem.json" - }, - "traj_2gpglosdsq7s": { - "title": "Fix broker session read paths and agent listing errors", - "status": "completed", - "startedAt": "2026-05-19T12:37:18.367Z", - "completedAt": "2026-05-19T12:48:50.116Z", - "path": ".trajectories/completed/2026-05/traj_2gpglosdsq7s.json" - }, - "traj_2tqxnib25omk": { - "title": "Add workflow reliability contract coverage", - "status": "completed", - "startedAt": "2026-05-08T15:27:50.875Z", - "completedAt": "2026-05-08T15:28:02.639Z", - "path": ".trajectories/completed/2026-05/traj_2tqxnib25omk.json" - }, - "traj_2yicjxgajt0a": { - "title": "Review GPT-5.5 hardening", - "status": "completed", - "startedAt": "2026-05-15T10:54:19.300Z", - "completedAt": "2026-05-15T10:54:19.476Z", - "path": ".trajectories/completed/2026-05/traj_2yicjxgajt0a.json" - }, - "traj_34b1u84b19gz": { - "title": "Address PR 827 review feedback", - "status": "completed", - "startedAt": "2026-05-08T18:29:34.717Z", - "completedAt": "2026-05-08T18:33:55.607Z", - "path": ".trajectories/completed/2026-05/traj_34b1u84b19gz.json" - }, - "traj_3gjtcykvybt5": { - "title": "Fix PR CI failures", - "status": "completed", - "startedAt": "2026-05-15T11:24:06.054Z", - "completedAt": "2026-05-15T11:25:49.087Z", - "path": ".trajectories/completed/2026-05/traj_3gjtcykvybt5.json" - }, - "traj_47akjihewlow": { - "title": "Further split broker runtime module for issue 875", - "status": "completed", - "startedAt": "2026-05-19T01:28:35.746Z", - "completedAt": "2026-05-19T01:38:29.105Z", - "path": ".trajectories/completed/2026-05/traj_47akjihewlow.json" - }, - "traj_4chzkm724ufo": { - "title": "Fix headless orchestrator worktree CLI E2E issues", - "status": "completed", - "startedAt": "2026-05-15T11:44:28.338Z", - "completedAt": "2026-05-15T11:51:05.319Z", - "path": ".trajectories/completed/2026-05/traj_4chzkm724ufo.json" - }, - "traj_4t07itef99ug": { - "title": "Implement relay CLI bootstrap commands for proactive runtime M1", - "status": "completed", - "startedAt": "2026-05-11T21:47:37.805Z", - "completedAt": "2026-05-11T21:49:49.859Z", - "path": ".trajectories/completed/2026-05/traj_4t07itef99ug.json" - }, - "traj_4vucir4qvqa2": { - "title": "Harden headless broker readiness semantics", - "status": "completed", - "startedAt": "2026-05-15T09:46:07.617Z", - "completedAt": "2026-05-15T09:59:00.460Z", - "path": ".trajectories/completed/2026-05/traj_4vucir4qvqa2.json" - }, - "traj_5k0jtc1g5l33": { - "title": "Resolve PR 932 conflicts and review comments", - "status": "completed", - "startedAt": "2026-05-22T19:13:09.359Z", - "completedAt": "2026-05-22T19:13:16.971Z", - "path": ".trajectories/completed/2026-05/traj_5k0jtc1g5l33.json" - }, - "traj_5nzj6v56id4z": { - "title": "Fix PR914 review comments", - "status": "completed", - "startedAt": "2026-05-19T13:20:42.407Z", - "completedAt": "2026-05-19T13:26:28.697Z", - "path": ".trajectories/completed/2026-05/traj_5nzj6v56id4z.json" - }, - "traj_5q8i0iz4klpo": { - "title": "ricky-child-update-2-workflow", - "status": "completed", - "startedAt": "2026-05-15T21:07:02.452Z", - "completedAt": "2026-05-15T21:36:03.688Z", - "path": ".trajectories/completed/2026-05/traj_5q8i0iz4klpo.json" - }, - "traj_5qbla7w4kzoi": { - "title": "Fix issue 877", - "status": "completed", - "startedAt": "2026-05-19T03:40:40.798Z", - "completedAt": "2026-05-19T03:54:06.889Z", - "path": ".trajectories/completed/2026-05/traj_5qbla7w4kzoi.json" - }, - "traj_60qc24ufr96g": { - "title": "Expand workflow reliability contract matrix", - "status": "completed", - "startedAt": "2026-05-08T15:40:11.699Z", - "completedAt": "2026-05-08T15:40:22.521Z", - "path": ".trajectories/completed/2026-05/traj_60qc24ufr96g.json" - }, - "traj_6sjeohtm3php": { - "title": "Address broker headless reliability review findings", - "status": "completed", - "startedAt": "2026-05-15T09:30:56.316Z", - "completedAt": "2026-05-15T09:32:47.870Z", - "path": ".trajectories/completed/2026-05/traj_6sjeohtm3php.json" - }, - "traj_6ujzpx82gqs9": { - "title": "ricky-slack-primitive-implementation-workflow-status-r-workflow", - "status": "completed", - "startedAt": "2026-05-08T16:06:54.844Z", - "completedAt": "2026-05-08T16:18:16.119Z", - "path": ".trajectories/completed/2026-05/traj_6ujzpx82gqs9.json" - }, - "traj_78ytpicts778": { - "title": "Address PR 932 result callback review findings", - "status": "completed", - "startedAt": "2026-05-22T15:59:25.187Z", - "completedAt": "2026-05-22T16:05:12.320Z", - "path": ".trajectories/completed/2026-05/traj_78ytpicts778.json" - }, - "traj_7uznwzoxbao6": { - "title": "Fix standalone detached headless startup", - "status": "completed", - "startedAt": "2026-05-15T10:18:46.273Z", - "completedAt": "2026-05-15T10:25:00.598Z", - "path": ".trajectories/completed/2026-05/traj_7uznwzoxbao6.json" - }, - "traj_7zu7et53ph3l": { - "title": "Harden Codex GPT-5.5 local CLI compatibility", - "status": "completed", - "startedAt": "2026-05-15T10:35:25.212Z", - "completedAt": "2026-05-15T10:40:53.355Z", - "path": ".trajectories/completed/2026-05/traj_7zu7et53ph3l.json" - }, - "traj_81kobstnzzwk": { - "title": "Orchestrate team review cycle for #892 #893 #894 #895", - "status": "completed", - "startedAt": "2026-05-19T08:16:32.762Z", - "completedAt": "2026-05-19T08:37:32.966Z", - "path": ".trajectories/completed/2026-05/traj_81kobstnzzwk.json" - }, - "traj_8ljgydz61do5": { - "title": "ricky-child-update-messaging-2-workflow", - "status": "completed", - "startedAt": "2026-05-15T21:06:54.217Z", - "completedAt": "2026-05-15T21:41:56.478Z", - "path": ".trajectories/completed/2026-05/traj_8ljgydz61do5.json" - }, - "traj_90jmd9z27oap": { - "title": "Resolve PR 948 merge conflicts", - "status": "completed", - "startedAt": "2026-05-22T19:49:08.797Z", - "completedAt": "2026-05-22T20:45:01.262Z", - "path": ".trajectories/completed/2026-05/traj_90jmd9z27oap.json" - }, - "traj_947wzpddsg9j": { - "title": "Implement relay CLI bootstrap commands for proactive runtime M1", - "status": "completed", - "startedAt": "2026-05-11T23:11:57.326Z", - "completedAt": "2026-05-11T23:14:23.136Z", - "path": ".trajectories/completed/2026-05/traj_947wzpddsg9j.json" - }, - "traj_9fdv7hxm0b60": { - "title": "Strict standalone smoke follow-up", - "status": "completed", - "startedAt": "2026-05-15T10:37:17.693Z", - "completedAt": "2026-05-15T10:43:11.587Z", - "path": ".trajectories/completed/2026-05/traj_9fdv7hxm0b60.json" - }, - "traj_9gq96irkj00s": { - "title": "Update relay to use published relaycast Rust reclaim fix", - "status": "completed", - "startedAt": "2026-05-10T18:45:02.118Z", - "completedAt": "2026-05-10T18:48:11.532Z", - "path": ".trajectories/completed/2026-05/traj_9gq96irkj00s.json" - }, - "traj_aw7stgf4qau0": { - "title": "Fix publish smoke cloud tarball dependency", - "status": "completed", - "startedAt": "2026-05-11T07:49:42.778Z", - "completedAt": "2026-05-11T07:50:37.848Z", - "path": ".trajectories/completed/2026-05/traj_aw7stgf4qau0.json" - }, - "traj_bdrlknyl8twj": { - "title": "Add workflow reliability defaults and E2E matrix", - "status": "completed", - "startedAt": "2026-05-08T17:54:45.069Z", - "completedAt": "2026-05-08T18:05:37.305Z", - "path": ".trajectories/completed/2026-05/traj_bdrlknyl8twj.json" - }, - "traj_bz1a1o15p7px": { - "title": "Fix PR 949 CI failure", - "status": "completed", - "startedAt": "2026-05-22T16:56:55.021Z", - "completedAt": "2026-05-22T16:57:55.372Z", - "path": ".trajectories/completed/2026-05/traj_bz1a1o15p7px.json" - }, - "traj_cbmwd07phhm2": { - "title": "Implement #869 snapshot module + dump-pty command", - "status": "completed", - "startedAt": "2026-05-17T14:19:10.603Z", - "completedAt": "2026-05-17T14:33:32.293Z", - "path": ".trajectories/completed/2026-05/traj_cbmwd07phhm2.json" - }, - "traj_ceo5q9bh2od3": { - "title": "Add structured spawned-agent results", - "status": "completed", - "startedAt": "2026-05-20T21:24:17.929Z", - "completedAt": "2026-05-20T21:43:51.936Z", - "path": ".trajectories/completed/2026-05/traj_ceo5q9bh2od3.json" - }, - "traj_d89s38ddu7cj": { - "title": "Review Codex GPT-5.5 spawn fix", - "status": "completed", - "startedAt": "2026-05-15T12:25:39.946Z", - "completedAt": "2026-05-15T12:25:40.708Z", - "path": ".trajectories/completed/2026-05/traj_d89s38ddu7cj.json" - }, - "traj_dbsnr453nxjw": { - "title": "Confirm and remove unused package dependencies", - "status": "completed", - "startedAt": "2026-05-22T16:01:11.967Z", - "completedAt": "2026-05-22T16:12:01.466Z", - "path": ".trajectories/completed/2026-05/traj_dbsnr453nxjw.json" - }, - "traj_dcl9hgoiuac5": { - "title": "Verify --broker-name override for agent-relay up", - "status": "completed", - "startedAt": "2026-05-21T18:56:55.532Z", - "completedAt": "2026-05-21T19:00:06.831Z", - "path": ".trajectories/completed/2026-05/traj_dcl9hgoiuac5.json" - }, - "traj_dpgn0am1jq1c": { - "title": "Implement M1 relay CLI bootstrap commands", - "status": "completed", - "startedAt": "2026-05-11T18:43:20.429Z", - "completedAt": "2026-05-11T18:43:20.733Z", - "path": ".trajectories/completed/2026-05/traj_dpgn0am1jq1c.json" - }, - "traj_e1b7ww3un1u3": { - "title": "Harden agents logs raw and follow output", - "status": "completed", - "startedAt": "2026-05-19T10:59:00.118Z", - "completedAt": "2026-05-19T11:04:44.466Z", - "path": ".trajectories/completed/2026-05/traj_e1b7ww3un1u3.json" - }, - "traj_elx0fcwgs37x": { - "title": "ricky-child-update-messaging-workflow", - "status": "completed", - "startedAt": "2026-05-15T21:06:50.250Z", - "completedAt": "2026-05-15T21:46:46.167Z", - "path": ".trajectories/completed/2026-05/traj_elx0fcwgs37x.json" - }, - "traj_erzd7j9nto9r": { - "title": "Strict review and PR prep for headless broker readiness", - "status": "completed", - "startedAt": "2026-05-15T10:02:10.164Z", - "completedAt": "2026-05-15T10:06:38.127Z", - "path": ".trajectories/completed/2026-05/traj_erzd7j9nto9r.json" - }, - "traj_f1iac9ngymlj": { - "title": "Fix reliability review findings 892-895", - "status": "completed", - "startedAt": "2026-05-19T09:52:54.932Z", - "completedAt": "2026-05-19T10:01:19.068Z", - "path": ".trajectories/completed/2026-05/traj_f1iac9ngymlj.json" - }, - "traj_f3arvbmmlomn": { - "title": "Address PR feedback for headless broker reliability", - "status": "completed", - "startedAt": "2026-05-15T12:09:02.122Z", - "completedAt": "2026-05-15T12:15:11.435Z", - "path": ".trajectories/completed/2026-05/traj_f3arvbmmlomn.json" - }, - "traj_f9wxa8ujeg78": { - "title": "Refactor broker main for issue 875", - "status": "completed", - "startedAt": "2026-05-19T00:54:40.328Z", - "completedAt": "2026-05-19T00:55:57.506Z", - "path": ".trajectories/completed/2026-05/traj_f9wxa8ujeg78.json" - }, - "traj_fh8oosbijpwc": { - "title": "Track A: relaycast subscribe + @self DM routing", - "status": "completed", - "startedAt": "2026-05-12T06:28:56.427Z", - "completedAt": "2026-05-12T11:21:33.352Z", - "path": ".trajectories/completed/2026-05/traj_fh8oosbijpwc.json" - }, - "traj_gh05rj5gwsap": { - "title": "Bump relaycast Rust SDK in relay", - "status": "completed", - "startedAt": "2026-05-14T16:41:17.430Z", - "completedAt": "2026-05-14T16:42:32.485Z", - "path": ".trajectories/completed/2026-05/traj_gh05rj5gwsap.json" - }, - "traj_gnqvtoxtc8dy": { - "title": "Fix broker half-start recovery", - "status": "completed", - "startedAt": "2026-05-19T12:34:36.057Z", - "completedAt": "2026-05-19T12:47:18.115Z", - "path": ".trajectories/completed/2026-05/traj_gnqvtoxtc8dy.json" - }, - "traj_hfkww5z7trxn": { - "title": "Fresh comprehensive review of PR 856", - "status": "completed", - "startedAt": "2026-05-15T12:56:14.439Z", - "completedAt": "2026-05-15T13:00:15.366Z", - "path": ".trajectories/completed/2026-05/traj_hfkww5z7trxn.json" - }, - "traj_hrsndfzk0qay": { - "title": "Tighten Codex 5.5 fallback coverage", - "status": "completed", - "startedAt": "2026-05-15T10:57:41.681Z", - "completedAt": "2026-05-15T10:57:41.827Z", - "path": ".trajectories/completed/2026-05/traj_hrsndfzk0qay.json" - }, - "traj_hysw5o7idqas": { - "title": "Fix issue 924", - "status": "completed", - "startedAt": "2026-05-20T05:35:07.262Z", - "completedAt": "2026-05-20T05:47:54.189Z", - "path": ".trajectories/completed/2026-05/traj_hysw5o7idqas.json" - }, - "traj_ij5b3kcatvwn": { - "title": "ricky-reading-worker-dm-replies-design-spec-status-draft-date-2026-05-15-issue-860-hea-workflow", - "status": "completed", - "startedAt": "2026-05-15T21:06:45.545Z", - "completedAt": "2026-05-15T21:50:07.842Z", - "path": ".trajectories/completed/2026-05/traj_ij5b3kcatvwn.json" - }, - "traj_iole5zdt9orr": { - "title": "Fix PR 831 CI conflicts", - "status": "completed", - "startedAt": "2026-05-10T15:18:12.326Z", - "completedAt": "2026-05-10T15:29:41.840Z", - "path": ".trajectories/completed/2026-05/traj_iole5zdt9orr.json" - }, - "traj_irafiyk6wpw0": { - "title": "Fix agents:logs near-unparseable TTY redraw garbage (codex implement, claude review)", - "status": "completed", - "startedAt": "2026-05-19T10:30:38.222Z", - "completedAt": "2026-05-19T10:44:24.757Z", - "path": ".trajectories/completed/2026-05/traj_irafiyk6wpw0.json" - }, - "traj_itgr2w8qs3xn": { - "title": "Make workflow deterministic failures repairable by agents", - "status": "completed", - "startedAt": "2026-05-08T14:44:45.732Z", - "completedAt": "2026-05-08T14:44:45.984Z", - "path": ".trajectories/completed/2026-05/traj_itgr2w8qs3xn.json" - }, - "traj_j9k10fez3e81": { - "title": "review-loop-mpb2bvnf-1-workflow", - "status": "completed", - "startedAt": "2026-05-18T10:30:09.927Z", - "completedAt": "2026-05-18T14:53:04.092Z", - "path": ".trajectories/completed/2026-05/traj_j9k10fez3e81.json" - }, - "traj_jbo2x14y7ovt": { - "title": "Fix issue 876", - "status": "completed", - "startedAt": "2026-05-19T02:48:10.768Z", - "completedAt": "2026-05-19T02:56:24.584Z", - "path": ".trajectories/completed/2026-05/traj_jbo2x14y7ovt.json" - }, - "traj_jmf9pyt3zikn": { - "title": "Fix issue 874", - "status": "completed", - "startedAt": "2026-05-19T00:07:13.993Z", - "completedAt": "2026-05-19T00:17:27.680Z", - "path": ".trajectories/completed/2026-05/traj_jmf9pyt3zikn.json" - }, - "traj_k7njijv51iq4": { - "title": "ricky-slack-primitive-implementation-workflow-status-r-workflow", - "status": "completed", - "startedAt": "2026-05-08T16:18:55.300Z", - "completedAt": "2026-05-08T16:26:03.266Z", - "path": ".trajectories/completed/2026-05/traj_k7njijv51iq4.json" - }, - "traj_lhyrcib40kao": { - "title": "Address PR #914 CodeRabbit reliability review findings", - "status": "completed", - "startedAt": "2026-05-19T11:52:46.110Z", - "completedAt": "2026-05-19T12:07:22.401Z", - "path": ".trajectories/completed/2026-05/traj_lhyrcib40kao.json" - }, - "traj_lieyyspidhfj": { - "title": "Fix PR 823 conflicts checks and comments", - "status": "completed", - "startedAt": "2026-05-09T08:37:17.563Z", - "completedAt": "2026-05-09T08:47:54.686Z", - "path": ".trajectories/completed/2026-05/traj_lieyyspidhfj.json" - }, - "traj_m7mpv7j8n78h": { - "title": "Address Relay PR 826 review feedback", - "status": "completed", - "startedAt": "2026-05-08T15:17:53.113Z", - "completedAt": "2026-05-08T15:24:32.409Z", - "path": ".trajectories/completed/2026-05/traj_m7mpv7j8n78h.json" - }, - "traj_mi9eqd4rjfea": { - "title": "Address stdio fresh review findings", - "status": "abandoned", - "startedAt": "2026-05-11T18:25:24.626Z", - "completedAt": "2026-05-11T18:37:05.318Z", - "path": ".trajectories/completed/2026-05/traj_mi9eqd4rjfea.json" - }, - "traj_mytnzgfayj3d": { - "title": "Fix PR 948 telemetry package validation failure", - "status": "completed", - "startedAt": "2026-05-22T23:34:27.422Z", - "completedAt": "2026-05-22T23:36:15.152Z", - "path": ".trajectories/completed/2026-05/traj_mytnzgfayj3d.json" - }, - "traj_mz5m5ysjj31e": { - "title": "Fix Relay SDK broker stdout drain", - "status": "completed", - "startedAt": "2026-05-10T20:24:43.831Z", - "completedAt": "2026-05-10T20:35:47.359Z", - "path": ".trajectories/completed/2026-05/traj_mz5m5ysjj31e.json" - }, - "traj_n8duofq5vq1a": { - "title": "Update Codex registry for GPT-5.5", - "status": "completed", - "startedAt": "2026-05-15T10:27:57.532Z", - "completedAt": "2026-05-15T10:33:19.705Z", - "path": ".trajectories/completed/2026-05/traj_n8duofq5vq1a.json" - }, - "traj_o251whkvy9rl": { - "title": "Fix Codex GPT-5.5 E2E rough edges", - "status": "completed", - "startedAt": "2026-05-15T11:59:26.764Z", - "completedAt": "2026-05-15T12:12:25.515Z", - "path": ".trajectories/completed/2026-05/traj_o251whkvy9rl.json" - }, - "traj_o9cx33xn5u39": { - "title": "add-mcp-args-register-flag-workflow", - "status": "completed", - "startedAt": "2026-04-20T15:06:23.387Z", - "completedAt": "2026-05-08T13:33:35.341Z", - "path": ".trajectories/completed/2026-05/traj_o9cx33xn5u39.json" - }, - "traj_ootb5rt3tozd": { - "title": "ricky-child-update-docs-sync-workflow", - "status": "completed", - "startedAt": "2026-05-15T21:07:04.494Z", - "completedAt": "2026-05-15T21:45:20.368Z", - "path": ".trajectories/completed/2026-05/traj_ootb5rt3tozd.json" - }, - "traj_oyc528j7suvo": { - "title": "Expose cloud workflow scheduling through Relay SDK", - "status": "completed", - "startedAt": "2026-05-09T19:43:34.805Z", - "completedAt": "2026-05-09T19:44:00.107Z", - "path": ".trajectories/completed/2026-05/traj_oyc528j7suvo.json" - }, - "traj_piik8r6zu3i7": { - "title": "Issue 867: RelayEventListener", - "status": "completed", - "startedAt": "2026-05-18T01:56:18.236Z", - "completedAt": "2026-05-18T02:01:49.991Z", - "path": ".trajectories/completed/2026-05/traj_piik8r6zu3i7.json" - }, - "traj_pmrcfj6or3pz": { - "title": "Address runtime split review comments", - "status": "completed", - "startedAt": "2026-05-19T02:03:43.962Z", - "completedAt": "2026-05-19T02:09:31.002Z", - "path": ".trajectories/completed/2026-05/traj_pmrcfj6or3pz.json" - }, - "traj_qtmid2nzz0kz": { - "title": "Address PR 929 review comments", - "status": "completed", - "startedAt": "2026-05-20T06:21:54.721Z", - "completedAt": "2026-05-20T06:26:56.700Z", - "path": ".trajectories/completed/2026-05/traj_qtmid2nzz0kz.json" - }, - "traj_ryf5sstno6p3": { - "title": "Telemetry key from env (P0.5 of #881)", - "status": "completed", - "startedAt": "2026-05-18T02:56:55.314Z", - "completedAt": "2026-05-18T03:02:35.202Z", - "path": ".trajectories/completed/2026-05/traj_ryf5sstno6p3.json" - }, - "traj_s5ojo1f4srz4": { - "title": "Remove unused user-directory package", - "status": "completed", - "startedAt": "2026-05-22T16:27:44.927Z", - "completedAt": "2026-05-22T16:36:20.545Z", - "path": ".trajectories/completed/2026-05/traj_s5ojo1f4srz4.json" - }, - "traj_sh2ahp9z2xg6": { - "title": "Fix uuid install deprecation warning", - "status": "completed", - "startedAt": "2026-05-19T17:21:40.756Z", - "completedAt": "2026-05-19T17:21:49.702Z", - "path": ".trajectories/completed/2026-05/traj_sh2ahp9z2xg6.json" - }, - "traj_sqerp89tc436": { - "title": "Remove legacy root bin fallback", - "status": "completed", - "startedAt": "2026-05-19T00:45:33.159Z", - "completedAt": "2026-05-19T00:50:03.857Z", - "path": ".trajectories/completed/2026-05/traj_sqerp89tc436.json" - }, - "traj_t5uknesn2fcw": { - "title": "ricky-child-update-skill-workflow", - "status": "completed", - "startedAt": "2026-05-15T21:06:52.453Z", - "completedAt": "2026-05-15T21:40:04.209Z", - "path": ".trajectories/completed/2026-05/traj_t5uknesn2fcw.json" - }, - "traj_tavtex0db4b0": { - "title": "Make workflow failures repairable by agents", - "status": "completed", - "startedAt": "2026-05-08T14:34:19.969Z", - "completedAt": "2026-05-08T14:44:45.719Z", - "path": ".trajectories/completed/2026-05/traj_tavtex0db4b0.json" - }, - "traj_tgism98me5na": { - "title": "Implement relay CLI proactive runtime bootstrap commands", - "status": "completed", - "startedAt": "2026-05-11T20:04:48.053Z", - "completedAt": "2026-05-11T20:05:54.956Z", - "path": ".trajectories/completed/2026-05/traj_tgism98me5na.json" - }, - "traj_u33qn99ijbh4": { - "title": "ricky-child-update-workflow", - "status": "completed", - "startedAt": "2026-05-15T21:07:00.444Z", - "completedAt": "2026-05-15T21:30:50.445Z", - "path": ".trajectories/completed/2026-05/traj_u33qn99ijbh4.json" - }, - "traj_u3loicehnwb4": { - "title": "Gate broker diagnostic logs behind env flag", - "status": "completed", - "startedAt": "2026-05-21T04:14:44.815Z", - "completedAt": "2026-05-21T04:14:45.063Z", - "path": ".trajectories/completed/2026-05/traj_u3loicehnwb4.json" - }, - "traj_u4ixmbqqm2y1": { - "title": "Add cloud workflow schedule CLI", - "status": "completed", - "startedAt": "2026-05-09T19:26:42.106Z", - "completedAt": "2026-05-09T19:29:18.024Z", - "path": ".trajectories/completed/2026-05/traj_u4ixmbqqm2y1.json" - }, - "traj_uf8y40ewrfh0": { - "title": "Address PR 831 review feedback and conflicts", - "status": "completed", - "startedAt": "2026-05-09T19:59:24.197Z", - "completedAt": "2026-05-09T19:59:24.403Z", - "path": ".trajectories/completed/2026-05/traj_uf8y40ewrfh0.json" - }, - "traj_v1wexlfur5zr": { - "title": "Fix broker headless reliability doc", - "status": "completed", - "startedAt": "2026-05-15T09:04:51.316Z", - "completedAt": "2026-05-15T09:13:50.970Z", - "path": ".trajectories/completed/2026-05/traj_v1wexlfur5zr.json" - }, - "traj_v87cyrs8dke9": { - "title": "Refactor runDriveSession below complexity 15 (#897)", - "status": "completed", - "startedAt": "2026-05-14T14:28:34.155Z", - "completedAt": "2026-05-18T18:06:04.950Z", - "path": ".trajectories/completed/2026-05/traj_v87cyrs8dke9.json" - }, - "traj_v9x3o92ag682": { - "title": "ricky-child-update-messaging-test-workflow", - "status": "completed", - "startedAt": "2026-05-15T21:06:56.418Z", - "completedAt": "2026-05-15T21:34:35.623Z", - "path": ".trajectories/completed/2026-05/traj_v9x3o92ag682.json" - }, - "traj_vfa1jr6otnjn": { - "title": "Refresh PR 948 after main advanced", - "status": "completed", - "startedAt": "2026-05-22T23:23:16.807Z", - "completedAt": "2026-05-22T23:23:26.380Z", - "path": ".trajectories/completed/2026-05/traj_vfa1jr6otnjn.json" - }, - "traj_vkozdglobkyg": { - "title": "Address Relay PR 826 review comments", - "status": "completed", - "startedAt": "2026-05-08T15:50:35.978Z", - "completedAt": "2026-05-08T15:51:38.854Z", - "path": ".trajectories/completed/2026-05/traj_vkozdglobkyg.json" - }, - "traj_wbn62q4cq16h": { - "title": "Update generated workflow to Codex agents only", - "status": "completed", - "startedAt": "2026-05-15T21:03:02.671Z", - "completedAt": "2026-05-15T21:06:00.384Z", - "path": ".trajectories/completed/2026-05/traj_wbn62q4cq16h.json" - }, - "traj_whd40oxptlhn": { - "title": "Review spawn persistence fix and open PR", - "status": "completed", - "startedAt": "2026-05-13T10:57:02.796Z", - "completedAt": "2026-05-13T11:00:43.100Z", - "path": ".trajectories/completed/2026-05/traj_whd40oxptlhn.json" - }, - "traj_wx00tjvpptvg": { - "title": "Investigate agent-relay spawn persistence", - "status": "completed", - "startedAt": "2026-05-13T10:49:12.464Z", - "completedAt": "2026-05-13T10:53:03.748Z", - "path": ".trajectories/completed/2026-05/traj_wx00tjvpptvg.json" - }, - "traj_wzzboitm85ee": { - "title": "Resolve PR conflicts around platform tradeoff copy", - "status": "completed", - "startedAt": "2026-05-15T12:47:36.508Z", - "completedAt": "2026-05-15T12:50:14.358Z", - "path": ".trajectories/completed/2026-05/traj_wzzboitm85ee.json" - }, - "traj_x37bhga2j5ph": { - "title": "Deepen broker runtime refactor for PR 906", - "status": "completed", - "startedAt": "2026-05-19T01:42:10.602Z", - "completedAt": "2026-05-19T01:50:40.359Z", - "path": ".trajectories/completed/2026-05/traj_x37bhga2j5ph.json" - }, - "traj_ybcrij9wg8m1": { - "title": "Implement agent-relay view read-only stream client (#864 sub-1)", - "status": "completed", - "startedAt": "2026-05-18T02:02:07.524Z", - "completedAt": "2026-05-18T02:05:41.120Z", - "path": ".trajectories/completed/2026-05/traj_ybcrij9wg8m1.json" - }, - "traj_z171lng2fbbi": { - "title": "Address PR 840 review feedback", - "status": "completed", - "startedAt": "2026-05-11T08:06:37.977Z", - "completedAt": "2026-05-11T08:07:48.097Z", - "path": ".trajectories/completed/2026-05/traj_z171lng2fbbi.json" - }, - "traj_zfa6skfr32vy": { - "title": "Implement relay CLI M1 bootstrap commands", - "status": "completed", - "startedAt": "2026-05-11T19:31:44.734Z", - "completedAt": "2026-05-11T19:34:54.971Z", - "path": ".trajectories/completed/2026-05/traj_zfa6skfr32vy.json" - }, - "traj_zqwco4gl76g3": { - "title": "Fix issue 878", - "status": "completed", - "startedAt": "2026-05-19T04:18:25.024Z", - "completedAt": "2026-05-19T04:27:18.903Z", - "path": ".trajectories/completed/2026-05/traj_zqwco4gl76g3.json" - }, - "traj_zu3252hxzoqh": { - "title": "Open PR for reading worker DM replies", - "status": "completed", - "startedAt": "2026-05-16T06:08:22.396Z", - "completedAt": "2026-05-16T06:09:24.599Z", - "path": ".trajectories/completed/2026-05/traj_zu3252hxzoqh.json" - }, - "traj_1775914296101_a4397efe": { - "title": "fix-sdk-build-resolution-workflow", - "status": "completed", - "startedAt": "2026-04-11T13:31:36.101Z", - "completedAt": "2026-04-11T13:39:53.105Z", - "path": ".trajectories/completed/traj_1775914296101_a4397efe.json" - }, - "traj_1776024661304_cfc829b9": { - "title": "fix-workflow-resume-elegant-workflow", - "status": "abandoned", - "startedAt": "2026-04-12T20:11:01.304Z", - "completedAt": "2026-04-12T20:11:16.381Z", - "path": ".trajectories/completed/traj_1776024661304_cfc829b9.json" - }, - "traj_1778873052429_03a4dacb": { - "title": "ricky-reading-worker-dm-replies-design-spec-status-draft-date-2026-05-15-issue-860-hea-workflow", - "status": "abandoned", - "startedAt": "2026-05-15T19:24:12.429Z", - "completedAt": "2026-05-15T20:01:57.036Z", - "path": ".trajectories/completed/traj_1778873052429_03a4dacb.json" - }, - "traj_1778873197540_01102ade": { - "title": "ricky-child-update-messaging-workflow", - "status": "abandoned", - "startedAt": "2026-05-15T19:26:37.540Z", - "completedAt": "2026-05-15T19:43:47.629Z", - "path": ".trajectories/completed/traj_1778873197540_01102ade.json" - }, - "traj_1778873199489_f2ce4060": { - "title": "ricky-child-update-skill-workflow", - "status": "abandoned", - "startedAt": "2026-05-15T19:26:39.489Z", - "completedAt": "2026-05-15T19:43:43.149Z", - "path": ".trajectories/completed/traj_1778873199489_f2ce4060.json" - }, - "traj_1778873201502_0dacf7c5": { - "title": "ricky-child-update-messaging-2-workflow", - "status": "abandoned", - "startedAt": "2026-05-15T19:26:41.502Z", - "completedAt": "2026-05-15T19:43:35.011Z", - "path": ".trajectories/completed/traj_1778873201502_0dacf7c5.json" - }, - "traj_1778873203502_4c225b7e": { - "title": "ricky-child-update-messaging-test-workflow", - "status": "abandoned", - "startedAt": "2026-05-15T19:26:43.502Z", - "completedAt": "2026-05-15T19:44:33.074Z", - "path": ".trajectories/completed/traj_1778873203502_4c225b7e.json" - }, - "traj_1778873205470_a4e5f0cb": { - "title": "ricky-child-update-issue-860-transcript-test-workflow", - "status": "abandoned", - "startedAt": "2026-05-15T19:26:45.470Z", - "completedAt": "2026-05-15T19:43:37.134Z", - "path": ".trajectories/completed/traj_1778873205470_a4e5f0cb.json" - }, - "traj_1778873207471_b7def991": { - "title": "ricky-child-update-workflow", - "status": "abandoned", - "startedAt": "2026-05-15T19:26:47.471Z", - "completedAt": "2026-05-15T19:43:24.329Z", - "path": ".trajectories/completed/traj_1778873207471_b7def991.json" - }, - "traj_1778874205797_81e92307": { - "title": "ricky-child-update-workflow", - "status": "abandoned", - "startedAt": "2026-05-15T19:43:25.797Z", - "completedAt": "2026-05-15T19:43:43.995Z", - "path": ".trajectories/completed/traj_1778874205797_81e92307.json" - }, - "traj_1778874216773_c6b12ab2": { - "title": "ricky-child-update-messaging-2-workflow", - "status": "abandoned", - "startedAt": "2026-05-15T19:43:36.773Z", - "completedAt": "2026-05-15T19:44:08.270Z", - "path": ".trajectories/completed/traj_1778874216773_c6b12ab2.json" - }, - "traj_1778874218579_a0225559": { - "title": "ricky-child-update-issue-860-transcript-test-workflow", - "status": "abandoned", - "startedAt": "2026-05-15T19:43:38.579Z", - "completedAt": "2026-05-15T19:43:58.721Z", - "path": ".trajectories/completed/traj_1778874218579_a0225559.json" - }, - "traj_1778874224855_9c722c4b": { - "title": "ricky-child-update-skill-workflow", - "status": "abandoned", - "startedAt": "2026-05-15T19:43:44.855Z", - "completedAt": "2026-05-15T19:44:16.528Z", - "path": ".trajectories/completed/traj_1778874224855_9c722c4b.json" - }, - "traj_1778874226983_3367d527": { - "title": "ricky-child-update-workflow", - "status": "abandoned", - "startedAt": "2026-05-15T19:43:46.983Z", - "completedAt": "2026-05-15T19:44:05.612Z", - "path": ".trajectories/completed/traj_1778874226983_3367d527.json" - }, - "traj_1778874229373_9cce9465": { - "title": "ricky-child-update-messaging-workflow", - "status": "abandoned", - "startedAt": "2026-05-15T19:43:49.374Z", - "completedAt": "2026-05-15T19:44:20.096Z", - "path": ".trajectories/completed/traj_1778874229373_9cce9465.json" - }, - "traj_1778874240339_51b823cd": { - "title": "ricky-child-update-issue-860-transcript-test-workflow", - "status": "abandoned", - "startedAt": "2026-05-15T19:44:00.339Z", - "completedAt": "2026-05-15T19:44:18.916Z", - "path": ".trajectories/completed/traj_1778874240339_51b823cd.json" - }, - "traj_1778874241076_caa675a9": { - "title": "ricky-child-update-2-workflow", - "status": "abandoned", - "startedAt": "2026-05-15T19:44:01.076Z", - "completedAt": "2026-05-15T19:44:32.521Z", - "path": ".trajectories/completed/traj_1778874241076_caa675a9.json" - }, - "traj_1778874248966_e29c4c54": { - "title": "ricky-child-update-workflow", - "status": "abandoned", - "startedAt": "2026-05-15T19:44:08.966Z", - "completedAt": "2026-05-15T19:44:27.330Z", - "path": ".trajectories/completed/traj_1778874248966_e29c4c54.json" - }, - "traj_1778874249983_12a98df3": { - "title": "ricky-child-update-messaging-2-workflow", - "status": "abandoned", - "startedAt": "2026-05-15T19:44:09.983Z", - "completedAt": "2026-05-15T19:44:41.100Z", - "path": ".trajectories/completed/traj_1778874249983_12a98df3.json" - }, - "traj_1778874258229_0bdc53d8": { - "title": "ricky-child-update-skill-workflow", - "status": "abandoned", - "startedAt": "2026-05-15T19:44:18.229Z", - "completedAt": "2026-05-15T19:44:49.274Z", - "path": ".trajectories/completed/traj_1778874258229_0bdc53d8.json" - }, - "traj_1778874261453_55f49624": { - "title": "ricky-child-update-messaging-workflow", - "status": "abandoned", - "startedAt": "2026-05-15T19:44:21.453Z", - "completedAt": "2026-05-15T19:44:53.643Z", - "path": ".trajectories/completed/traj_1778874261453_55f49624.json" - }, - "traj_1778874261608_48fb9bf5": { - "title": "ricky-child-update-issue-860-transcript-test-workflow", - "status": "abandoned", - "startedAt": "2026-05-15T19:44:21.608Z", - "completedAt": "2026-05-15T19:44:40.761Z", - "path": ".trajectories/completed/traj_1778874261608_48fb9bf5.json" - }, - "traj_1778874269139_d7d7485a": { - "title": "ricky-child-update-workflow", - "status": "abandoned", - "startedAt": "2026-05-15T19:44:29.139Z", - "completedAt": "2026-05-15T19:44:48.083Z", - "path": ".trajectories/completed/traj_1778874269139_d7d7485a.json" - }, - "traj_1778874274412_70843e0e": { - "title": "ricky-child-update-2-workflow", - "status": "abandoned", - "startedAt": "2026-05-15T19:44:34.412Z", - "completedAt": "2026-05-15T19:45:06.798Z", - "path": ".trajectories/completed/traj_1778874274412_70843e0e.json" - }, - "traj_1778874274581_71efa470": { - "title": "ricky-child-update-messaging-test-workflow", - "status": "abandoned", - "startedAt": "2026-05-15T19:44:34.581Z", - "completedAt": "2026-05-15T19:44:54.182Z", - "path": ".trajectories/completed/traj_1778874274581_71efa470.json" - }, - "traj_1778874282200_39ad11db": { - "title": "ricky-child-update-issue-860-transcript-test-workflow", - "status": "abandoned", - "startedAt": "2026-05-15T19:44:42.200Z", - "completedAt": "2026-05-15T19:45:02.477Z", - "path": ".trajectories/completed/traj_1778874282200_39ad11db.json" - }, - "traj_1778874283570_ce3585b8": { - "title": "ricky-child-update-messaging-2-workflow", - "status": "abandoned", - "startedAt": "2026-05-15T19:44:43.570Z", - "completedAt": "2026-05-15T19:45:14.888Z", - "path": ".trajectories/completed/traj_1778874283570_ce3585b8.json" - }, - "traj_1778874289674_e3f868c8": { - "title": "ricky-child-update-workflow", - "status": "abandoned", - "startedAt": "2026-05-15T19:44:49.674Z", - "completedAt": "2026-05-15T19:45:08.337Z", - "path": ".trajectories/completed/traj_1778874289674_e3f868c8.json" - }, - "traj_1778874291950_0b1b5c1f": { - "title": "ricky-child-update-skill-workflow", - "status": "abandoned", - "startedAt": "2026-05-15T19:44:51.950Z", - "completedAt": "2026-05-15T19:45:23.421Z", - "path": ".trajectories/completed/traj_1778874291950_0b1b5c1f.json" - }, - "traj_1778874295927_4083d181": { - "title": "ricky-child-update-messaging-test-workflow", - "status": "abandoned", - "startedAt": "2026-05-15T19:44:55.927Z", - "completedAt": "2026-05-15T19:45:15.333Z", - "path": ".trajectories/completed/traj_1778874295927_4083d181.json" - }, - "traj_1778874296362_bdf727ff": { - "title": "ricky-child-update-messaging-workflow", - "status": "abandoned", - "startedAt": "2026-05-15T19:44:56.362Z", - "completedAt": "2026-05-15T19:45:27.624Z", - "path": ".trajectories/completed/traj_1778874296362_bdf727ff.json" - }, - "traj_l1349adi1g0o": { - "title": "Fix agent relay MCP PR CI failures", - "status": "completed", - "startedAt": "2026-05-25T21:42:41.236Z", - "completedAt": "2026-05-25T21:42:57.292Z", - "path": ".trajectories/completed/2026-05/traj_l1349adi1g0o.json" - }, - "traj_8nhd9lljhbsw": { - "title": "Switch owned MCP tool names to underscores", - "status": "completed", - "startedAt": "2026-05-25T22:05:23.828Z", - "completedAt": "2026-05-25T22:14:25.886Z", - "path": ".trajectories/completed/2026-05/traj_8nhd9lljhbsw.json" - }, - "traj_gkxajksmwoea": { - "title": "Document owned MCP tool table", - "status": "completed", - "startedAt": "2026-05-25T22:17:18.278Z", - "completedAt": "2026-05-25T22:19:29.639Z", - "path": ".trajectories/completed/2026-05/traj_gkxajksmwoea.json" - }, - "traj_t6h534vn0bpg": { - "title": "Resolve PR merge conflicts", - "status": "completed", - "startedAt": "2026-05-26T10:11:15.356Z", - "completedAt": "2026-05-26T10:21:56.502Z", - "path": ".trajectories/completed/2026-05/traj_t6h534vn0bpg.json" - }, - "traj_cszfl2icaj2t": { - "title": "Add Prettier auto-format workflow", - "status": "completed", - "startedAt": "2026-05-26T11:04:15.563Z", - "completedAt": "2026-05-26T11:05:23.716Z", - "path": ".trajectories/completed/2026-05/traj_cszfl2icaj2t.json" - }, - "traj_i2pjnx3dll5b": { - "title": "Fresh harness runtime plan and implementation", - "status": "completed", - "startedAt": "2026-05-25T15:49:27.102Z", - "completedAt": "2026-05-25T16:22:35.339Z", - "path": ".trajectories/completed/2026-05/traj_i2pjnx3dll5b.json" - }, - "traj_7i9tigaejfje": { - "title": "Clarify headless app-server harness terminology", - "status": "completed", - "startedAt": "2026-05-25T16:34:21.397Z", - "completedAt": "2026-05-25T16:34:33.412Z", - "path": ".trajectories/completed/2026-05/traj_7i9tigaejfje.json" - }, - "traj_1fjub7c9rlap": { - "title": "Rewrite harness docs around SDK adapters", - "status": "completed", - "startedAt": "2026-05-25T16:53:04.706Z", - "completedAt": "2026-05-25T16:53:16.077Z", - "path": ".trajectories/completed/2026-05/traj_1fjub7c9rlap.json" - }, - "traj_0d1efjk6aeo2": { - "title": "Respond to harness PR review comments", - "status": "completed", - "startedAt": "2026-05-25T17:14:45.927Z", - "completedAt": "2026-05-25T17:14:53.457Z", - "path": ".trajectories/completed/2026-05/traj_0d1efjk6aeo2.json" - }, - "traj_9dj3qiugt26j": { - "title": "Fix harness runtime review issues", - "status": "completed", - "startedAt": "2026-05-25T17:41:16.384Z", - "completedAt": "2026-05-25T17:53:06.394Z", - "path": ".trajectories/completed/2026-05/traj_9dj3qiugt26j.json" - }, - "traj_q2r3c9dmdep7": { - "title": "Rename harness plans to harness configs", - "status": "completed", - "startedAt": "2026-05-25T18:00:40.591Z", - "completedAt": "2026-05-25T18:06:34.954Z", - "path": ".trajectories/completed/2026-05/traj_q2r3c9dmdep7.json" - }, - "traj_fiygtgr3tfey": { - "title": "Fix harness config clippy issues", - "status": "completed", - "startedAt": "2026-05-25T18:31:39.975Z", - "completedAt": "2026-05-25T18:34:10.562Z", - "path": ".trajectories/completed/2026-05/traj_fiygtgr3tfey.json" - }, - "traj_n0qwpjvmdl2s": { - "title": "Default headless harness driver", - "status": "completed", - "startedAt": "2026-05-25T19:50:47.661Z", - "completedAt": "2026-05-25T19:52:52.791Z", - "path": ".trajectories/completed/2026-05/traj_n0qwpjvmdl2s.json" - }, - "traj_kgl2opmmfvus": { - "title": "Simplify harness config PR around broker-owned configs", - "status": "completed", - "startedAt": "2026-05-25T21:32:14.085Z", - "completedAt": "2026-05-25T21:47:15.455Z", - "path": ".trajectories/completed/2026-05/traj_kgl2opmmfvus.json" - }, - "traj_bd431l65n9lg": { - "title": "Remove broker harness registry footgun", - "status": "completed", - "startedAt": "2026-05-25T21:55:14.197Z", - "completedAt": "2026-05-25T22:02:22.902Z", - "path": ".trajectories/completed/2026-05/traj_bd431l65n9lg.json" - }, - "traj_qbq3laxbvhzf": { - "title": "Resolve harness PR conflicts and comments", - "status": "completed", - "startedAt": "2026-05-25T22:03:51.255Z", - "completedAt": "2026-05-25T22:25:18.889Z", - "path": ".trajectories/completed/2026-05/traj_qbq3laxbvhzf.json" - }, - "traj_l67sex3nkzfq": { - "title": "Fix failing harness PR e2e tests", - "status": "completed", - "startedAt": "2026-05-25T23:22:50.714Z", - "completedAt": "2026-05-25T23:32:19.352Z", - "path": ".trajectories/completed/2026-05/traj_l67sex3nkzfq.json" - }, - "traj_zyluvmlqo5j7": { - "title": "Resolve harness PR merge conflicts", - "status": "completed", - "startedAt": "2026-05-26T11:24:20.682Z", - "completedAt": "2026-05-26T11:26:52.563Z", - "path": ".trajectories/completed/2026-05/traj_zyluvmlqo5j7.json" - } - } -} diff --git a/example.ts b/example.ts new file mode 100644 index 000000000..8ef9c3f4e --- /dev/null +++ b/example.ts @@ -0,0 +1,38 @@ +import { AgentRelay, defaultHarnesses } from '@agent-relay/sdk'; +import { myApi } from '../my-internal-api' + + +const { codex, claude } = defaultHarnesses; + +const piCoding = { + runtime: 'pty', + command: 'pid', + args: [ + '--dangerously-skip-permissions', + '--append-system-prompt', + 'Follow the company review rubric.', + '{modelArgs}', + '{args}', + ], + modelArgs: ['--model', '{model}'], + env: { + FUN_SETTING: '1', + }, + beforeSpawn: async (ctx) => { + const hasCreditsAvailable = await myApi.hasCreditsAvailable() + + if (!hasCreditsAvailable) { + return { error: 'No credits available', status: 402 } + } + + const sessionId = await createPiResumableSessionId(ctx.cwd, ctx.task, ctx.env) + return { sessionId } + } + +} + + + +const relay = new AgentRelay( + harnesses: [ piCoding, codex, claude ] +); diff --git a/package-lock.json b/package-lock.json index cb7aeb6b4..83082b6d8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1235,6 +1235,7 @@ }, "node_modules/@clack/prompts/node_modules/is-unicode-supported": { "version": "1.3.0", + "extraneous": true, "inBundle": true, "license": "MIT", "engines": { @@ -6702,9 +6703,9 @@ "link": true }, "node_modules/agent-trajectories": { - "version": "0.5.8", - "resolved": "https://registry.npmjs.org/agent-trajectories/-/agent-trajectories-0.5.8.tgz", - "integrity": "sha512-Cu/+uyxAy+eNSlpzuOhk62kM/i0BdlfG8Z4avyzfbHbQ3I9EQLqiUikl3WcG75m3v+4MwTbJq9e6YTG8/ykKPw==", + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/agent-trajectories/-/agent-trajectories-0.6.0.tgz", + "integrity": "sha512-wCOHGO7gWw6lA/4e794+YMOLWpfRnlCZiLN5i5lHj3oNHzFYEBlSEEBJXLM3moDM9x0UvLEAEsz+bYrlxW80mQ==", "license": "MIT", "dependencies": { "@clack/prompts": "^0.7.0", @@ -16232,7 +16233,7 @@ "@relayfile/local-mount": "^0.2.2", "@relayfile/sdk": "^0.6.0", "@slack/web-api": "^7.16.0", - "agent-trajectories": "^0.5.8", + "agent-trajectories": "^0.6.0", "commander": "^12.1.0", "dotenv": "^17.2.3", "esbuild": "^0.27.2", @@ -17202,7 +17203,7 @@ "@relaycast/sdk": "^1.1.0", "@relayfile/sdk": ">=0.1.2 <1", "@sinclair/typebox": "^0.34.48", - "agent-trajectories": "^0.5.4", + "agent-trajectories": "^0.6.0", "chalk": "^4.1.2", "ignore": "^7.0.5", "listr2": "^10.2.1", diff --git a/packages/cli/package.json b/packages/cli/package.json index 5fec1bac9..04eb89075 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -63,7 +63,7 @@ "@relayfile/local-mount": "^0.2.2", "@relayfile/sdk": "^0.6.0", "@slack/web-api": "^7.16.0", - "agent-trajectories": "^0.5.8", + "agent-trajectories": "^0.6.0", "commander": "^12.1.0", "dotenv": "^17.2.3", "esbuild": "^0.27.2", diff --git a/packages/sdk/package.json b/packages/sdk/package.json index 7a2173ebf..380fc60c1 100644 --- a/packages/sdk/package.json +++ b/packages/sdk/package.json @@ -179,7 +179,7 @@ "@relaycast/sdk": "^1.1.0", "@relayfile/sdk": ">=0.1.2 <1", "@sinclair/typebox": "^0.34.48", - "agent-trajectories": "^0.5.4", + "agent-trajectories": "^0.6.0", "chalk": "^4.1.2", "ignore": "^7.0.5", "listr2": "^10.2.1", From 936645d6b1c839235bf5b80ae43f9343126cf1ac Mon Sep 17 00:00:00 2001 From: Will Washburn Date: Tue, 26 May 2026 11:00:58 -0400 Subject: [PATCH 15/19] Revert "Move trajectories into .agentworkforce" This reverts commit 7dd7af66d2cb418345959e9de6dbae094cc7534c. --- .../completed/2026-05/traj_9d5mdl0oj0ao.json | 25 - .../completed/2026-05/traj_9d5mdl0oj0ao.md | 14 - .../compact_gqmrna24cmm4_2026-05-19.json | 0 .../compact_gqmrna24cmm4_2026-05-19.md | 0 .../compact_j5u7qhaw4q6a_2026-05-08.json | 0 .../compact_j5u7qhaw4q6a_2026-05-08.md | 0 .../compacted/release-6.0.13.json | 0 .../compacted/release-6.0.13.md | 0 .../compacted/release-6.2.3.json | 0 .../compacted/release-6.2.3.md | 0 .../completed/2026-04/traj_05xg7j388bc4.json | 0 .../completed/2026-04/traj_05xg7j388bc4.md | 0 .../completed/2026-04/traj_0t92gxaz6igh.json | 0 .../completed/2026-04/traj_0t92gxaz6igh.md | 0 .../2026-04/traj_1776105620545_9dcebb3d.json | 0 .../2026-04/traj_1776105620545_9dcebb3d.md | 0 .../2026-04/traj_1776105988184_29f1270c.json | 0 .../2026-04/traj_1776105988184_29f1270c.md | 0 .../completed/2026-04/traj_222ha5671idc.json | 0 .../completed/2026-04/traj_222ha5671idc.md | 0 .../completed/2026-04/traj_3b3p1z4y7qlo.json | 0 .../completed/2026-04/traj_3b3p1z4y7qlo.md | 0 .../completed/2026-04/traj_4zqhfqw7g28l.json | 0 .../completed/2026-04/traj_4zqhfqw7g28l.md | 0 .../completed/2026-04/traj_530xmbfeljyb.json | 0 .../completed/2026-04/traj_530xmbfeljyb.md | 0 .../completed/2026-04/traj_703m7sqyq89t.json | 0 .../completed/2026-04/traj_703m7sqyq89t.md | 0 .../completed/2026-04/traj_8oh4r5km5eic.json | 0 .../completed/2026-04/traj_8oh4r5km5eic.md | 0 .../completed/2026-04/traj_9tt55is74dq5.json | 0 .../completed/2026-04/traj_9tt55is74dq5.md | 0 .../completed/2026-04/traj_abjovknvcijv.json | 0 .../completed/2026-04/traj_abjovknvcijv.md | 0 .../completed/2026-04/traj_avmkyoo2s3rt.json | 0 .../completed/2026-04/traj_avmkyoo2s3rt.md | 0 .../completed/2026-04/traj_d48czxmgx4ac.json | 0 .../completed/2026-04/traj_d48czxmgx4ac.md | 0 .../completed/2026-04/traj_dw8ihhdb8ip7.json | 0 .../completed/2026-04/traj_dw8ihhdb8ip7.md | 0 .../completed/2026-04/traj_e5i62wdjx0jd.json | 0 .../completed/2026-04/traj_e5i62wdjx0jd.md | 0 .../completed/2026-04/traj_g3muawdq6bsb.json | 0 .../completed/2026-04/traj_g3muawdq6bsb.md | 0 .../completed/2026-04/traj_mk0t0cgn4ytq.json | 0 .../completed/2026-04/traj_mk0t0cgn4ytq.md | 0 .../completed/2026-04/traj_o8kgzhfu6jth.json | 0 .../completed/2026-04/traj_o8kgzhfu6jth.md | 0 .../completed/2026-04/traj_qb54w47qwod6.json | 0 .../completed/2026-04/traj_qb54w47qwod6.md | 0 .../completed/2026-04/traj_rs2bt3x0fqba.json | 0 .../completed/2026-04/traj_rs2bt3x0fqba.md | 0 .../completed/2026-04/traj_tjadoebpscps.json | 0 .../completed/2026-04/traj_tjadoebpscps.md | 0 .../completed/2026-04/traj_tv1x9pamkqad.json | 0 .../completed/2026-04/traj_tv1x9pamkqad.md | 0 .../completed/2026-04/traj_ui5omrgz819d.json | 0 .../completed/2026-04/traj_ui5omrgz819d.md | 0 .../completed/2026-04/traj_w0xpsaoxuiyw.json | 0 .../completed/2026-04/traj_w0xpsaoxuiyw.md | 0 .../completed/2026-05/traj_0d1efjk6aeo2.json | 0 .../completed/2026-05/traj_0d1efjk6aeo2.md | 0 .../completed/2026-05/traj_0e8i20oitwvz.json | 0 .../completed/2026-05/traj_0e8i20oitwvz.md | 0 .../completed/2026-05/traj_0o6gb2wvk59t.json | 0 .../completed/2026-05/traj_0o6gb2wvk59t.md | 0 .../completed/2026-05/traj_0z98tkaigaxg.json | 0 .../completed/2026-05/traj_0z98tkaigaxg.md | 0 .../2026-05/traj_1775914133873_35667beb.json | 0 .../2026-05/traj_1775914133873_35667beb.md | 0 .../2026-05/traj_1776073106646_1839be2d.json | 0 .../2026-05/traj_1776073106646_1839be2d.md | 0 .../2026-05/traj_1776113772922_bc92f121.json | 0 .../2026-05/traj_1776113772922_bc92f121.md | 0 .../2026-05/traj_1778873209642_c70e32ab.json | 0 .../2026-05/traj_1778873209642_c70e32ab.md | 0 .../2026-05/traj_1778873211616_6db3b2cd.json | 0 .../2026-05/traj_1778873211616_6db3b2cd.md | 0 .../completed/2026-05/traj_1fjub7c9rlap.json | 0 .../completed/2026-05/traj_1fjub7c9rlap.md | 0 .../completed/2026-05/traj_1rrpe2r7fyem.json | 0 .../completed/2026-05/traj_1rrpe2r7fyem.md | 0 .../completed/2026-05/traj_2gpglosdsq7s.json | 0 .../completed/2026-05/traj_2gpglosdsq7s.md | 0 .../completed/2026-05/traj_2tqxnib25omk.json | 0 .../completed/2026-05/traj_2tqxnib25omk.md | 0 .../completed/2026-05/traj_2yicjxgajt0a.json | 0 .../completed/2026-05/traj_2yicjxgajt0a.md | 0 .../completed/2026-05/traj_34b1u84b19gz.json | 0 .../completed/2026-05/traj_34b1u84b19gz.md | 0 .../completed/2026-05/traj_3b3p1z4y7qlo.json | 0 .../completed/2026-05/traj_3b3p1z4y7qlo.md | 0 .../completed/2026-05/traj_3gjtcykvybt5.json | 0 .../completed/2026-05/traj_3gjtcykvybt5.md | 0 .../completed/2026-05/traj_47akjihewlow.json | 0 .../completed/2026-05/traj_47akjihewlow.md | 0 .../2026-05/traj_47akjihewlow.trace.json | 0 .../completed/2026-05/traj_4chzkm724ufo.json | 0 .../completed/2026-05/traj_4chzkm724ufo.md | 0 .../completed/2026-05/traj_4t07itef99ug.json | 0 .../completed/2026-05/traj_4t07itef99ug.md | 0 .../completed/2026-05/traj_4vucir4qvqa2.json | 0 .../completed/2026-05/traj_4vucir4qvqa2.md | 0 .../completed/2026-05/traj_5k0jtc1g5l33.json | 0 .../completed/2026-05/traj_5k0jtc1g5l33.md | 0 .../completed/2026-05/traj_5nzj6v56id4z.json | 0 .../completed/2026-05/traj_5q8i0iz4klpo.json | 0 .../completed/2026-05/traj_5q8i0iz4klpo.md | 0 .../completed/2026-05/traj_5qbla7w4kzoi.json | 0 .../completed/2026-05/traj_5qbla7w4kzoi.md | 0 .../completed/2026-05/traj_60qc24ufr96g.json | 0 .../completed/2026-05/traj_60qc24ufr96g.md | 0 .../completed/2026-05/traj_6sjeohtm3php.json | 0 .../completed/2026-05/traj_6sjeohtm3php.md | 0 .../completed/2026-05/traj_6ujzpx82gqs9.json | 0 .../completed/2026-05/traj_6ujzpx82gqs9.md | 0 .../completed/2026-05/traj_78ytpicts778.json | 0 .../completed/2026-05/traj_78ytpicts778.md | 0 .../completed/2026-05/traj_7i9tigaejfje.json | 0 .../completed/2026-05/traj_7i9tigaejfje.md | 0 .../completed/2026-05/traj_7uznwzoxbao6.json | 0 .../completed/2026-05/traj_7uznwzoxbao6.md | 0 .../completed/2026-05/traj_7zu7et53ph3l.json | 0 .../completed/2026-05/traj_7zu7et53ph3l.md | 0 .../completed/2026-05/traj_81kobstnzzwk.json | 0 .../completed/2026-05/traj_8ljgydz61do5.json | 0 .../completed/2026-05/traj_8ljgydz61do5.md | 0 .../completed/2026-05/traj_8nhd9lljhbsw.json | 0 .../completed/2026-05/traj_8nhd9lljhbsw.md | 0 .../completed/2026-05/traj_90jmd9z27oap.json | 0 .../completed/2026-05/traj_90jmd9z27oap.md | 0 .../completed/2026-05/traj_947wzpddsg9j.json | 0 .../completed/2026-05/traj_947wzpddsg9j.md | 0 .../completed/2026-05/traj_9dj3qiugt26j.json | 0 .../completed/2026-05/traj_9dj3qiugt26j.md | 0 .../completed/2026-05/traj_9fdv7hxm0b60.json | 0 .../completed/2026-05/traj_9fdv7hxm0b60.md | 0 .../completed/2026-05/traj_9gq96irkj00s.json | 0 .../completed/2026-05/traj_9gq96irkj00s.md | 0 .../completed/2026-05/traj_aw7stgf4qau0.json | 0 .../completed/2026-05/traj_aw7stgf4qau0.md | 0 .../completed/2026-05/traj_bd431l65n9lg.json | 0 .../completed/2026-05/traj_bd431l65n9lg.md | 0 .../completed/2026-05/traj_bdrlknyl8twj.json | 0 .../completed/2026-05/traj_bdrlknyl8twj.md | 0 .../completed/2026-05/traj_bz1a1o15p7px.json | 0 .../completed/2026-05/traj_bz1a1o15p7px.md | 0 .../completed/2026-05/traj_cbmwd07phhm2.json | 0 .../completed/2026-05/traj_cbmwd07phhm2.md | 0 .../completed/2026-05/traj_ceo5q9bh2od3.json | 0 .../completed/2026-05/traj_ceo5q9bh2od3.md | 0 .../completed/2026-05/traj_cszfl2icaj2t.json | 0 .../completed/2026-05/traj_cszfl2icaj2t.md | 0 .../completed/2026-05/traj_d89s38ddu7cj.json | 0 .../completed/2026-05/traj_d89s38ddu7cj.md | 0 .../completed/2026-05/traj_dbsnr453nxjw.json | 0 .../completed/2026-05/traj_dbsnr453nxjw.md | 0 .../completed/2026-05/traj_dcl9hgoiuac5.json | 0 .../completed/2026-05/traj_dcl9hgoiuac5.md | 0 .../completed/2026-05/traj_dpgn0am1jq1c.json | 0 .../completed/2026-05/traj_dpgn0am1jq1c.md | 0 .../completed/2026-05/traj_e1b7ww3un1u3.json | 0 .../completed/2026-05/traj_e1b7ww3un1u3.md | 0 .../completed/2026-05/traj_elx0fcwgs37x.json | 0 .../completed/2026-05/traj_elx0fcwgs37x.md | 0 .../completed/2026-05/traj_erzd7j9nto9r.json | 0 .../completed/2026-05/traj_erzd7j9nto9r.md | 0 .../completed/2026-05/traj_f1iac9ngymlj.json | 0 .../completed/2026-05/traj_f1iac9ngymlj.md | 0 .../completed/2026-05/traj_f3arvbmmlomn.json | 0 .../completed/2026-05/traj_f3arvbmmlomn.md | 0 .../completed/2026-05/traj_f9wxa8ujeg78.json | 0 .../completed/2026-05/traj_f9wxa8ujeg78.md | 0 .../completed/2026-05/traj_fh8oosbijpwc.json | 0 .../completed/2026-05/traj_fh8oosbijpwc.md | 0 .../2026-05/traj_fh8oosbijpwc.trace.json | 0 .../completed/2026-05/traj_fiygtgr3tfey.json | 0 .../completed/2026-05/traj_fiygtgr3tfey.md | 0 .../completed/2026-05/traj_gh05rj5gwsap.json | 0 .../completed/2026-05/traj_gh05rj5gwsap.md | 0 .../2026-05/traj_gh05rj5gwsap.trace.json | 0 .../completed/2026-05/traj_gkxajksmwoea.json | 0 .../completed/2026-05/traj_gkxajksmwoea.md | 0 .../completed/2026-05/traj_gnqvtoxtc8dy.json | 0 .../completed/2026-05/traj_gnqvtoxtc8dy.md | 0 .../completed/2026-05/traj_hfkww5z7trxn.json | 0 .../completed/2026-05/traj_hfkww5z7trxn.md | 0 .../completed/2026-05/traj_hrsndfzk0qay.json | 0 .../completed/2026-05/traj_hrsndfzk0qay.md | 0 .../completed/2026-05/traj_hysw5o7idqas.json | 0 .../completed/2026-05/traj_hysw5o7idqas.md | 0 .../completed/2026-05/traj_i2pjnx3dll5b.json | 0 .../completed/2026-05/traj_i2pjnx3dll5b.md | 0 .../2026-05/traj_i2pjnx3dll5b.trace.json | 0 .../completed/2026-05/traj_ij5b3kcatvwn.json | 0 .../completed/2026-05/traj_ij5b3kcatvwn.md | 0 .../completed/2026-05/traj_iole5zdt9orr.json | 0 .../completed/2026-05/traj_iole5zdt9orr.md | 0 .../completed/2026-05/traj_irafiyk6wpw0.json | 0 .../completed/2026-05/traj_itgr2w8qs3xn.json | 0 .../completed/2026-05/traj_itgr2w8qs3xn.md | 0 .../completed/2026-05/traj_j9k10fez3e81.json | 0 .../completed/2026-05/traj_j9k10fez3e81.md | 0 .../completed/2026-05/traj_jbo2x14y7ovt.json | 0 .../completed/2026-05/traj_jbo2x14y7ovt.md | 0 .../completed/2026-05/traj_jmf9pyt3zikn.json | 0 .../completed/2026-05/traj_jmf9pyt3zikn.md | 0 .../completed/2026-05/traj_k7njijv51iq4.json | 0 .../completed/2026-05/traj_k7njijv51iq4.md | 0 .../completed/2026-05/traj_kgl2opmmfvus.json | 0 .../completed/2026-05/traj_kgl2opmmfvus.md | 0 .../completed/2026-05/traj_l1349adi1g0o.json | 0 .../completed/2026-05/traj_l1349adi1g0o.md | 0 .../completed/2026-05/traj_l67sex3nkzfq.json | 0 .../completed/2026-05/traj_l67sex3nkzfq.md | 0 .../completed/2026-05/traj_lhyrcib40kao.json | 0 .../completed/2026-05/traj_lhyrcib40kao.md | 0 .../completed/2026-05/traj_lieyyspidhfj.json | 0 .../completed/2026-05/traj_lieyyspidhfj.md | 0 .../2026-05/traj_lieyyspidhfj.trace.json | 0 .../completed/2026-05/traj_m7mpv7j8n78h.json | 0 .../completed/2026-05/traj_m7mpv7j8n78h.md | 0 .../completed/2026-05/traj_mi9eqd4rjfea.json | 0 .../completed/2026-05/traj_mi9eqd4rjfea.md | 0 .../completed/2026-05/traj_mytnzgfayj3d.json | 0 .../completed/2026-05/traj_mytnzgfayj3d.md | 0 .../completed/2026-05/traj_mz5m5ysjj31e.json | 0 .../completed/2026-05/traj_mz5m5ysjj31e.md | 0 .../completed/2026-05/traj_n0qwpjvmdl2s.json | 0 .../completed/2026-05/traj_n0qwpjvmdl2s.md | 0 .../completed/2026-05/traj_n8duofq5vq1a.json | 0 .../completed/2026-05/traj_n8duofq5vq1a.md | 0 .../completed/2026-05/traj_o251whkvy9rl.json | 0 .../completed/2026-05/traj_o251whkvy9rl.md | 0 .../completed/2026-05/traj_o9cx33xn5u39.json | 0 .../completed/2026-05/traj_o9cx33xn5u39.md | 0 .../completed/2026-05/traj_ootb5rt3tozd.json | 0 .../completed/2026-05/traj_ootb5rt3tozd.md | 0 .../completed/2026-05/traj_oyc528j7suvo.json | 0 .../completed/2026-05/traj_oyc528j7suvo.md | 0 .../completed/2026-05/traj_piik8r6zu3i7.json | 0 .../completed/2026-05/traj_piik8r6zu3i7.md | 0 .../completed/2026-05/traj_pmrcfj6or3pz.json | 0 .../completed/2026-05/traj_pmrcfj6or3pz.md | 0 .../completed/2026-05/traj_q2r3c9dmdep7.json | 0 .../completed/2026-05/traj_q2r3c9dmdep7.md | 0 .../completed/2026-05/traj_qbq3laxbvhzf.json | 0 .../completed/2026-05/traj_qbq3laxbvhzf.md | 0 .../completed/2026-05/traj_qtmid2nzz0kz.json | 0 .../completed/2026-05/traj_qtmid2nzz0kz.md | 0 .../completed/2026-05/traj_ryf5sstno6p3.json | 0 .../completed/2026-05/traj_ryf5sstno6p3.md | 0 .../completed/2026-05/traj_s5ojo1f4srz4.json | 0 .../completed/2026-05/traj_s5ojo1f4srz4.md | 0 .../completed/2026-05/traj_sh2ahp9z2xg6.json | 0 .../completed/2026-05/traj_sh2ahp9z2xg6.md | 0 .../completed/2026-05/traj_sqerp89tc436.json | 0 .../completed/2026-05/traj_sqerp89tc436.md | 0 .../completed/2026-05/traj_t5uknesn2fcw.json | 0 .../completed/2026-05/traj_t5uknesn2fcw.md | 0 .../completed/2026-05/traj_t6h534vn0bpg.json | 0 .../completed/2026-05/traj_t6h534vn0bpg.md | 0 .../completed/2026-05/traj_tavtex0db4b0.json | 0 .../completed/2026-05/traj_tavtex0db4b0.md | 0 .../completed/2026-05/traj_tgism98me5na.json | 0 .../completed/2026-05/traj_tgism98me5na.md | 0 .../completed/2026-05/traj_u33qn99ijbh4.json | 0 .../completed/2026-05/traj_u33qn99ijbh4.md | 0 .../completed/2026-05/traj_u3loicehnwb4.json | 0 .../completed/2026-05/traj_u3loicehnwb4.md | 0 .../completed/2026-05/traj_u4ixmbqqm2y1.json | 0 .../completed/2026-05/traj_u4ixmbqqm2y1.md | 0 .../completed/2026-05/traj_uf8y40ewrfh0.json | 0 .../completed/2026-05/traj_uf8y40ewrfh0.md | 0 .../completed/2026-05/traj_v1wexlfur5zr.json | 0 .../completed/2026-05/traj_v1wexlfur5zr.md | 0 .../completed/2026-05/traj_v87cyrs8dke9.json | 0 .../completed/2026-05/traj_v87cyrs8dke9.md | 0 .../2026-05/traj_v87cyrs8dke9.trace.json | 0 .../completed/2026-05/traj_v9x3o92ag682.json | 0 .../completed/2026-05/traj_v9x3o92ag682.md | 0 .../completed/2026-05/traj_vfa1jr6otnjn.json | 0 .../completed/2026-05/traj_vfa1jr6otnjn.md | 0 .../completed/2026-05/traj_vkozdglobkyg.json | 0 .../completed/2026-05/traj_vkozdglobkyg.md | 0 .../completed/2026-05/traj_wbn62q4cq16h.json | 0 .../completed/2026-05/traj_wbn62q4cq16h.md | 0 .../completed/2026-05/traj_whd40oxptlhn.json | 0 .../completed/2026-05/traj_whd40oxptlhn.md | 0 .../2026-05/traj_whd40oxptlhn.trace.json | 0 .../completed/2026-05/traj_wx00tjvpptvg.json | 0 .../completed/2026-05/traj_wx00tjvpptvg.md | 0 .../completed/2026-05/traj_wzzboitm85ee.json | 0 .../completed/2026-05/traj_wzzboitm85ee.md | 0 .../completed/2026-05/traj_x37bhga2j5ph.json | 0 .../completed/2026-05/traj_x37bhga2j5ph.md | 0 .../completed/2026-05/traj_ybcrij9wg8m1.json | 0 .../completed/2026-05/traj_ybcrij9wg8m1.md | 0 .../completed/2026-05/traj_z171lng2fbbi.json | 0 .../completed/2026-05/traj_z171lng2fbbi.md | 0 .../completed/2026-05/traj_zfa6skfr32vy.json | 0 .../completed/2026-05/traj_zfa6skfr32vy.md | 0 .../completed/2026-05/traj_zqwco4gl76g3.json | 0 .../completed/2026-05/traj_zqwco4gl76g3.md | 0 .../completed/2026-05/traj_zu3252hxzoqh.json | 0 .../completed/2026-05/traj_zu3252hxzoqh.md | 0 .../completed/2026-05/traj_zyluvmlqo5j7.json | 0 .../completed/2026-05/traj_zyluvmlqo5j7.md | 0 .../traj_1775914296101_a4397efe.json | 0 .../traj_1776024661304_cfc829b9.json | 0 .../traj_1776105620545_9dcebb3d.json | 0 .../traj_1778873052429_03a4dacb.json | 0 .../traj_1778873197540_01102ade.json | 0 .../traj_1778873199489_f2ce4060.json | 0 .../traj_1778873201502_0dacf7c5.json | 0 .../traj_1778873203502_4c225b7e.json | 0 .../traj_1778873205470_a4e5f0cb.json | 0 .../traj_1778873207471_b7def991.json | 0 .../traj_1778873209642_c70e32ab.json | 0 .../traj_1778873211616_6db3b2cd.json | 0 .../traj_1778874205797_81e92307.json | 0 .../traj_1778874216773_c6b12ab2.json | 0 .../traj_1778874218579_a0225559.json | 0 .../traj_1778874224855_9c722c4b.json | 0 .../traj_1778874226983_3367d527.json | 0 .../traj_1778874229373_9cce9465.json | 0 .../traj_1778874240339_51b823cd.json | 0 .../traj_1778874241076_caa675a9.json | 0 .../traj_1778874248966_e29c4c54.json | 0 .../traj_1778874249983_12a98df3.json | 0 .../traj_1778874258229_0bdc53d8.json | 0 .../traj_1778874261453_55f49624.json | 0 .../traj_1778874261608_48fb9bf5.json | 0 .../traj_1778874269139_d7d7485a.json | 0 .../traj_1778874274412_70843e0e.json | 0 .../traj_1778874274581_71efa470.json | 0 .../traj_1778874282200_39ad11db.json | 0 .../traj_1778874283570_ce3585b8.json | 0 .../traj_1778874289674_e3f868c8.json | 0 .../traj_1778874291950_0b1b5c1f.json | 0 .../traj_1778874295927_4083d181.json | 0 .../traj_1778874296362_bdf727ff.json | 0 .trajectories/index.json | 1245 +++++++++++++++++ example.ts | 38 - package-lock.json | 11 +- packages/cli/package.json | 2 +- packages/sdk/package.json | 2 +- 347 files changed, 1252 insertions(+), 85 deletions(-) delete mode 100644 .agentworkforce/trajectories/completed/2026-05/traj_9d5mdl0oj0ao.json delete mode 100644 .agentworkforce/trajectories/completed/2026-05/traj_9d5mdl0oj0ao.md rename {.agentworkforce/trajectories => .trajectories}/compacted/compact_gqmrna24cmm4_2026-05-19.json (100%) rename {.agentworkforce/trajectories => .trajectories}/compacted/compact_gqmrna24cmm4_2026-05-19.md (100%) rename {.agentworkforce/trajectories => .trajectories}/compacted/compact_j5u7qhaw4q6a_2026-05-08.json (100%) rename {.agentworkforce/trajectories => .trajectories}/compacted/compact_j5u7qhaw4q6a_2026-05-08.md (100%) rename {.agentworkforce/trajectories => .trajectories}/compacted/release-6.0.13.json (100%) rename {.agentworkforce/trajectories => .trajectories}/compacted/release-6.0.13.md (100%) rename {.agentworkforce/trajectories => .trajectories}/compacted/release-6.2.3.json (100%) rename {.agentworkforce/trajectories => .trajectories}/compacted/release-6.2.3.md (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-04/traj_05xg7j388bc4.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-04/traj_05xg7j388bc4.md (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-04/traj_0t92gxaz6igh.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-04/traj_0t92gxaz6igh.md (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-04/traj_1776105620545_9dcebb3d.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-04/traj_1776105620545_9dcebb3d.md (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-04/traj_1776105988184_29f1270c.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-04/traj_1776105988184_29f1270c.md (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-04/traj_222ha5671idc.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-04/traj_222ha5671idc.md (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-04/traj_3b3p1z4y7qlo.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-04/traj_3b3p1z4y7qlo.md (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-04/traj_4zqhfqw7g28l.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-04/traj_4zqhfqw7g28l.md (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-04/traj_530xmbfeljyb.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-04/traj_530xmbfeljyb.md (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-04/traj_703m7sqyq89t.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-04/traj_703m7sqyq89t.md (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-04/traj_8oh4r5km5eic.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-04/traj_8oh4r5km5eic.md (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-04/traj_9tt55is74dq5.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-04/traj_9tt55is74dq5.md (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-04/traj_abjovknvcijv.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-04/traj_abjovknvcijv.md (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-04/traj_avmkyoo2s3rt.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-04/traj_avmkyoo2s3rt.md (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-04/traj_d48czxmgx4ac.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-04/traj_d48czxmgx4ac.md (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-04/traj_dw8ihhdb8ip7.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-04/traj_dw8ihhdb8ip7.md (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-04/traj_e5i62wdjx0jd.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-04/traj_e5i62wdjx0jd.md (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-04/traj_g3muawdq6bsb.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-04/traj_g3muawdq6bsb.md (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-04/traj_mk0t0cgn4ytq.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-04/traj_mk0t0cgn4ytq.md (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-04/traj_o8kgzhfu6jth.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-04/traj_o8kgzhfu6jth.md (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-04/traj_qb54w47qwod6.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-04/traj_qb54w47qwod6.md (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-04/traj_rs2bt3x0fqba.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-04/traj_rs2bt3x0fqba.md (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-04/traj_tjadoebpscps.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-04/traj_tjadoebpscps.md (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-04/traj_tv1x9pamkqad.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-04/traj_tv1x9pamkqad.md (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-04/traj_ui5omrgz819d.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-04/traj_ui5omrgz819d.md (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-04/traj_w0xpsaoxuiyw.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-04/traj_w0xpsaoxuiyw.md (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_0d1efjk6aeo2.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_0d1efjk6aeo2.md (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_0e8i20oitwvz.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_0e8i20oitwvz.md (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_0o6gb2wvk59t.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_0o6gb2wvk59t.md (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_0z98tkaigaxg.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_0z98tkaigaxg.md (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_1775914133873_35667beb.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_1775914133873_35667beb.md (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_1776073106646_1839be2d.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_1776073106646_1839be2d.md (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_1776113772922_bc92f121.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_1776113772922_bc92f121.md (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_1778873209642_c70e32ab.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_1778873209642_c70e32ab.md (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_1778873211616_6db3b2cd.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_1778873211616_6db3b2cd.md (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_1fjub7c9rlap.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_1fjub7c9rlap.md (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_1rrpe2r7fyem.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_1rrpe2r7fyem.md (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_2gpglosdsq7s.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_2gpglosdsq7s.md (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_2tqxnib25omk.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_2tqxnib25omk.md (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_2yicjxgajt0a.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_2yicjxgajt0a.md (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_34b1u84b19gz.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_34b1u84b19gz.md (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_3b3p1z4y7qlo.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_3b3p1z4y7qlo.md (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_3gjtcykvybt5.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_3gjtcykvybt5.md (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_47akjihewlow.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_47akjihewlow.md (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_47akjihewlow.trace.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_4chzkm724ufo.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_4chzkm724ufo.md (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_4t07itef99ug.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_4t07itef99ug.md (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_4vucir4qvqa2.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_4vucir4qvqa2.md (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_5k0jtc1g5l33.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_5k0jtc1g5l33.md (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_5nzj6v56id4z.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_5q8i0iz4klpo.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_5q8i0iz4klpo.md (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_5qbla7w4kzoi.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_5qbla7w4kzoi.md (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_60qc24ufr96g.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_60qc24ufr96g.md (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_6sjeohtm3php.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_6sjeohtm3php.md (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_6ujzpx82gqs9.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_6ujzpx82gqs9.md (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_78ytpicts778.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_78ytpicts778.md (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_7i9tigaejfje.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_7i9tigaejfje.md (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_7uznwzoxbao6.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_7uznwzoxbao6.md (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_7zu7et53ph3l.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_7zu7et53ph3l.md (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_81kobstnzzwk.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_8ljgydz61do5.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_8ljgydz61do5.md (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_8nhd9lljhbsw.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_8nhd9lljhbsw.md (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_90jmd9z27oap.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_90jmd9z27oap.md (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_947wzpddsg9j.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_947wzpddsg9j.md (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_9dj3qiugt26j.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_9dj3qiugt26j.md (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_9fdv7hxm0b60.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_9fdv7hxm0b60.md (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_9gq96irkj00s.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_9gq96irkj00s.md (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_aw7stgf4qau0.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_aw7stgf4qau0.md (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_bd431l65n9lg.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_bd431l65n9lg.md (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_bdrlknyl8twj.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_bdrlknyl8twj.md (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_bz1a1o15p7px.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_bz1a1o15p7px.md (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_cbmwd07phhm2.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_cbmwd07phhm2.md (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_ceo5q9bh2od3.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_ceo5q9bh2od3.md (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_cszfl2icaj2t.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_cszfl2icaj2t.md (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_d89s38ddu7cj.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_d89s38ddu7cj.md (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_dbsnr453nxjw.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_dbsnr453nxjw.md (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_dcl9hgoiuac5.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_dcl9hgoiuac5.md (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_dpgn0am1jq1c.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_dpgn0am1jq1c.md (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_e1b7ww3un1u3.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_e1b7ww3un1u3.md (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_elx0fcwgs37x.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_elx0fcwgs37x.md (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_erzd7j9nto9r.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_erzd7j9nto9r.md (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_f1iac9ngymlj.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_f1iac9ngymlj.md (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_f3arvbmmlomn.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_f3arvbmmlomn.md (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_f9wxa8ujeg78.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_f9wxa8ujeg78.md (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_fh8oosbijpwc.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_fh8oosbijpwc.md (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_fh8oosbijpwc.trace.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_fiygtgr3tfey.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_fiygtgr3tfey.md (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_gh05rj5gwsap.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_gh05rj5gwsap.md (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_gh05rj5gwsap.trace.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_gkxajksmwoea.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_gkxajksmwoea.md (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_gnqvtoxtc8dy.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_gnqvtoxtc8dy.md (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_hfkww5z7trxn.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_hfkww5z7trxn.md (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_hrsndfzk0qay.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_hrsndfzk0qay.md (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_hysw5o7idqas.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_hysw5o7idqas.md (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_i2pjnx3dll5b.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_i2pjnx3dll5b.md (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_i2pjnx3dll5b.trace.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_ij5b3kcatvwn.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_ij5b3kcatvwn.md (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_iole5zdt9orr.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_iole5zdt9orr.md (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_irafiyk6wpw0.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_itgr2w8qs3xn.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_itgr2w8qs3xn.md (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_j9k10fez3e81.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_j9k10fez3e81.md (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_jbo2x14y7ovt.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_jbo2x14y7ovt.md (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_jmf9pyt3zikn.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_jmf9pyt3zikn.md (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_k7njijv51iq4.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_k7njijv51iq4.md (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_kgl2opmmfvus.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_kgl2opmmfvus.md (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_l1349adi1g0o.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_l1349adi1g0o.md (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_l67sex3nkzfq.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_l67sex3nkzfq.md (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_lhyrcib40kao.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_lhyrcib40kao.md (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_lieyyspidhfj.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_lieyyspidhfj.md (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_lieyyspidhfj.trace.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_m7mpv7j8n78h.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_m7mpv7j8n78h.md (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_mi9eqd4rjfea.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_mi9eqd4rjfea.md (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_mytnzgfayj3d.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_mytnzgfayj3d.md (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_mz5m5ysjj31e.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_mz5m5ysjj31e.md (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_n0qwpjvmdl2s.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_n0qwpjvmdl2s.md (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_n8duofq5vq1a.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_n8duofq5vq1a.md (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_o251whkvy9rl.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_o251whkvy9rl.md (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_o9cx33xn5u39.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_o9cx33xn5u39.md (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_ootb5rt3tozd.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_ootb5rt3tozd.md (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_oyc528j7suvo.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_oyc528j7suvo.md (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_piik8r6zu3i7.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_piik8r6zu3i7.md (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_pmrcfj6or3pz.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_pmrcfj6or3pz.md (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_q2r3c9dmdep7.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_q2r3c9dmdep7.md (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_qbq3laxbvhzf.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_qbq3laxbvhzf.md (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_qtmid2nzz0kz.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_qtmid2nzz0kz.md (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_ryf5sstno6p3.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_ryf5sstno6p3.md (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_s5ojo1f4srz4.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_s5ojo1f4srz4.md (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_sh2ahp9z2xg6.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_sh2ahp9z2xg6.md (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_sqerp89tc436.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_sqerp89tc436.md (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_t5uknesn2fcw.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_t5uknesn2fcw.md (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_t6h534vn0bpg.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_t6h534vn0bpg.md (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_tavtex0db4b0.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_tavtex0db4b0.md (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_tgism98me5na.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_tgism98me5na.md (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_u33qn99ijbh4.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_u33qn99ijbh4.md (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_u3loicehnwb4.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_u3loicehnwb4.md (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_u4ixmbqqm2y1.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_u4ixmbqqm2y1.md (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_uf8y40ewrfh0.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_uf8y40ewrfh0.md (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_v1wexlfur5zr.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_v1wexlfur5zr.md (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_v87cyrs8dke9.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_v87cyrs8dke9.md (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_v87cyrs8dke9.trace.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_v9x3o92ag682.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_v9x3o92ag682.md (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_vfa1jr6otnjn.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_vfa1jr6otnjn.md (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_vkozdglobkyg.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_vkozdglobkyg.md (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_wbn62q4cq16h.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_wbn62q4cq16h.md (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_whd40oxptlhn.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_whd40oxptlhn.md (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_whd40oxptlhn.trace.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_wx00tjvpptvg.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_wx00tjvpptvg.md (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_wzzboitm85ee.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_wzzboitm85ee.md (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_x37bhga2j5ph.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_x37bhga2j5ph.md (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_ybcrij9wg8m1.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_ybcrij9wg8m1.md (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_z171lng2fbbi.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_z171lng2fbbi.md (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_zfa6skfr32vy.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_zfa6skfr32vy.md (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_zqwco4gl76g3.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_zqwco4gl76g3.md (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_zu3252hxzoqh.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_zu3252hxzoqh.md (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_zyluvmlqo5j7.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/2026-05/traj_zyluvmlqo5j7.md (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/traj_1775914296101_a4397efe.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/traj_1776024661304_cfc829b9.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/traj_1776105620545_9dcebb3d.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/traj_1778873052429_03a4dacb.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/traj_1778873197540_01102ade.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/traj_1778873199489_f2ce4060.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/traj_1778873201502_0dacf7c5.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/traj_1778873203502_4c225b7e.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/traj_1778873205470_a4e5f0cb.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/traj_1778873207471_b7def991.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/traj_1778873209642_c70e32ab.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/traj_1778873211616_6db3b2cd.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/traj_1778874205797_81e92307.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/traj_1778874216773_c6b12ab2.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/traj_1778874218579_a0225559.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/traj_1778874224855_9c722c4b.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/traj_1778874226983_3367d527.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/traj_1778874229373_9cce9465.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/traj_1778874240339_51b823cd.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/traj_1778874241076_caa675a9.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/traj_1778874248966_e29c4c54.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/traj_1778874249983_12a98df3.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/traj_1778874258229_0bdc53d8.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/traj_1778874261453_55f49624.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/traj_1778874261608_48fb9bf5.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/traj_1778874269139_d7d7485a.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/traj_1778874274412_70843e0e.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/traj_1778874274581_71efa470.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/traj_1778874282200_39ad11db.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/traj_1778874283570_ce3585b8.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/traj_1778874289674_e3f868c8.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/traj_1778874291950_0b1b5c1f.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/traj_1778874295927_4083d181.json (100%) rename {.agentworkforce/trajectories => .trajectories}/completed/traj_1778874296362_bdf727ff.json (100%) create mode 100644 .trajectories/index.json delete mode 100644 example.ts diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_9d5mdl0oj0ao.json b/.agentworkforce/trajectories/completed/2026-05/traj_9d5mdl0oj0ao.json deleted file mode 100644 index cd748f438..000000000 --- a/.agentworkforce/trajectories/completed/2026-05/traj_9d5mdl0oj0ao.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "id": "traj_9d5mdl0oj0ao", - "version": 1, - "task": { - "title": "fix trajectories" - }, - "status": "completed", - "startedAt": "2026-05-26T11:47:03.748Z", - "completedAt": "2026-05-26T11:48:31.592Z", - "agents": [], - "chapters": [], - "retrospective": { - "summary": "updated and fixed pathing issues", - "approach": "Standard approach", - "confidence": 0.8 - }, - "commits": [], - "filesChanged": [], - "projectId": "/Users/will/Projects/AgentWorkforce/relay", - "tags": [], - "_trace": { - "startRef": "9061a034dca4763de6957ea4b74974fab99e63ce", - "endRef": "9061a034dca4763de6957ea4b74974fab99e63ce" - } -} \ No newline at end of file diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_9d5mdl0oj0ao.md b/.agentworkforce/trajectories/completed/2026-05/traj_9d5mdl0oj0ao.md deleted file mode 100644 index f0fdc1517..000000000 --- a/.agentworkforce/trajectories/completed/2026-05/traj_9d5mdl0oj0ao.md +++ /dev/null @@ -1,14 +0,0 @@ -# Trajectory: fix trajectories - -> **Status:** ✅ Completed -> **Confidence:** 80% -> **Started:** May 26, 2026 at 07:47 AM -> **Completed:** May 26, 2026 at 07:48 AM - ---- - -## Summary - -updated and fixed pathing issues - -**Approach:** Standard approach diff --git a/.agentworkforce/trajectories/compacted/compact_gqmrna24cmm4_2026-05-19.json b/.trajectories/compacted/compact_gqmrna24cmm4_2026-05-19.json similarity index 100% rename from .agentworkforce/trajectories/compacted/compact_gqmrna24cmm4_2026-05-19.json rename to .trajectories/compacted/compact_gqmrna24cmm4_2026-05-19.json diff --git a/.agentworkforce/trajectories/compacted/compact_gqmrna24cmm4_2026-05-19.md b/.trajectories/compacted/compact_gqmrna24cmm4_2026-05-19.md similarity index 100% rename from .agentworkforce/trajectories/compacted/compact_gqmrna24cmm4_2026-05-19.md rename to .trajectories/compacted/compact_gqmrna24cmm4_2026-05-19.md diff --git a/.agentworkforce/trajectories/compacted/compact_j5u7qhaw4q6a_2026-05-08.json b/.trajectories/compacted/compact_j5u7qhaw4q6a_2026-05-08.json similarity index 100% rename from .agentworkforce/trajectories/compacted/compact_j5u7qhaw4q6a_2026-05-08.json rename to .trajectories/compacted/compact_j5u7qhaw4q6a_2026-05-08.json diff --git a/.agentworkforce/trajectories/compacted/compact_j5u7qhaw4q6a_2026-05-08.md b/.trajectories/compacted/compact_j5u7qhaw4q6a_2026-05-08.md similarity index 100% rename from .agentworkforce/trajectories/compacted/compact_j5u7qhaw4q6a_2026-05-08.md rename to .trajectories/compacted/compact_j5u7qhaw4q6a_2026-05-08.md diff --git a/.agentworkforce/trajectories/compacted/release-6.0.13.json b/.trajectories/compacted/release-6.0.13.json similarity index 100% rename from .agentworkforce/trajectories/compacted/release-6.0.13.json rename to .trajectories/compacted/release-6.0.13.json diff --git a/.agentworkforce/trajectories/compacted/release-6.0.13.md b/.trajectories/compacted/release-6.0.13.md similarity index 100% rename from .agentworkforce/trajectories/compacted/release-6.0.13.md rename to .trajectories/compacted/release-6.0.13.md diff --git a/.agentworkforce/trajectories/compacted/release-6.2.3.json b/.trajectories/compacted/release-6.2.3.json similarity index 100% rename from .agentworkforce/trajectories/compacted/release-6.2.3.json rename to .trajectories/compacted/release-6.2.3.json diff --git a/.agentworkforce/trajectories/compacted/release-6.2.3.md b/.trajectories/compacted/release-6.2.3.md similarity index 100% rename from .agentworkforce/trajectories/compacted/release-6.2.3.md rename to .trajectories/compacted/release-6.2.3.md diff --git a/.agentworkforce/trajectories/completed/2026-04/traj_05xg7j388bc4.json b/.trajectories/completed/2026-04/traj_05xg7j388bc4.json similarity index 100% rename from .agentworkforce/trajectories/completed/2026-04/traj_05xg7j388bc4.json rename to .trajectories/completed/2026-04/traj_05xg7j388bc4.json diff --git a/.agentworkforce/trajectories/completed/2026-04/traj_05xg7j388bc4.md b/.trajectories/completed/2026-04/traj_05xg7j388bc4.md similarity index 100% rename from .agentworkforce/trajectories/completed/2026-04/traj_05xg7j388bc4.md rename to .trajectories/completed/2026-04/traj_05xg7j388bc4.md diff --git a/.agentworkforce/trajectories/completed/2026-04/traj_0t92gxaz6igh.json b/.trajectories/completed/2026-04/traj_0t92gxaz6igh.json similarity index 100% rename from .agentworkforce/trajectories/completed/2026-04/traj_0t92gxaz6igh.json rename to .trajectories/completed/2026-04/traj_0t92gxaz6igh.json diff --git a/.agentworkforce/trajectories/completed/2026-04/traj_0t92gxaz6igh.md b/.trajectories/completed/2026-04/traj_0t92gxaz6igh.md similarity index 100% rename from .agentworkforce/trajectories/completed/2026-04/traj_0t92gxaz6igh.md rename to .trajectories/completed/2026-04/traj_0t92gxaz6igh.md diff --git a/.agentworkforce/trajectories/completed/2026-04/traj_1776105620545_9dcebb3d.json b/.trajectories/completed/2026-04/traj_1776105620545_9dcebb3d.json similarity index 100% rename from .agentworkforce/trajectories/completed/2026-04/traj_1776105620545_9dcebb3d.json rename to .trajectories/completed/2026-04/traj_1776105620545_9dcebb3d.json diff --git a/.agentworkforce/trajectories/completed/2026-04/traj_1776105620545_9dcebb3d.md b/.trajectories/completed/2026-04/traj_1776105620545_9dcebb3d.md similarity index 100% rename from .agentworkforce/trajectories/completed/2026-04/traj_1776105620545_9dcebb3d.md rename to .trajectories/completed/2026-04/traj_1776105620545_9dcebb3d.md diff --git a/.agentworkforce/trajectories/completed/2026-04/traj_1776105988184_29f1270c.json b/.trajectories/completed/2026-04/traj_1776105988184_29f1270c.json similarity index 100% rename from .agentworkforce/trajectories/completed/2026-04/traj_1776105988184_29f1270c.json rename to .trajectories/completed/2026-04/traj_1776105988184_29f1270c.json diff --git a/.agentworkforce/trajectories/completed/2026-04/traj_1776105988184_29f1270c.md b/.trajectories/completed/2026-04/traj_1776105988184_29f1270c.md similarity index 100% rename from .agentworkforce/trajectories/completed/2026-04/traj_1776105988184_29f1270c.md rename to .trajectories/completed/2026-04/traj_1776105988184_29f1270c.md diff --git a/.agentworkforce/trajectories/completed/2026-04/traj_222ha5671idc.json b/.trajectories/completed/2026-04/traj_222ha5671idc.json similarity index 100% rename from .agentworkforce/trajectories/completed/2026-04/traj_222ha5671idc.json rename to .trajectories/completed/2026-04/traj_222ha5671idc.json diff --git a/.agentworkforce/trajectories/completed/2026-04/traj_222ha5671idc.md b/.trajectories/completed/2026-04/traj_222ha5671idc.md similarity index 100% rename from .agentworkforce/trajectories/completed/2026-04/traj_222ha5671idc.md rename to .trajectories/completed/2026-04/traj_222ha5671idc.md diff --git a/.agentworkforce/trajectories/completed/2026-04/traj_3b3p1z4y7qlo.json b/.trajectories/completed/2026-04/traj_3b3p1z4y7qlo.json similarity index 100% rename from .agentworkforce/trajectories/completed/2026-04/traj_3b3p1z4y7qlo.json rename to .trajectories/completed/2026-04/traj_3b3p1z4y7qlo.json diff --git a/.agentworkforce/trajectories/completed/2026-04/traj_3b3p1z4y7qlo.md b/.trajectories/completed/2026-04/traj_3b3p1z4y7qlo.md similarity index 100% rename from .agentworkforce/trajectories/completed/2026-04/traj_3b3p1z4y7qlo.md rename to .trajectories/completed/2026-04/traj_3b3p1z4y7qlo.md diff --git a/.agentworkforce/trajectories/completed/2026-04/traj_4zqhfqw7g28l.json b/.trajectories/completed/2026-04/traj_4zqhfqw7g28l.json similarity index 100% rename from .agentworkforce/trajectories/completed/2026-04/traj_4zqhfqw7g28l.json rename to .trajectories/completed/2026-04/traj_4zqhfqw7g28l.json diff --git a/.agentworkforce/trajectories/completed/2026-04/traj_4zqhfqw7g28l.md b/.trajectories/completed/2026-04/traj_4zqhfqw7g28l.md similarity index 100% rename from .agentworkforce/trajectories/completed/2026-04/traj_4zqhfqw7g28l.md rename to .trajectories/completed/2026-04/traj_4zqhfqw7g28l.md diff --git a/.agentworkforce/trajectories/completed/2026-04/traj_530xmbfeljyb.json b/.trajectories/completed/2026-04/traj_530xmbfeljyb.json similarity index 100% rename from .agentworkforce/trajectories/completed/2026-04/traj_530xmbfeljyb.json rename to .trajectories/completed/2026-04/traj_530xmbfeljyb.json diff --git a/.agentworkforce/trajectories/completed/2026-04/traj_530xmbfeljyb.md b/.trajectories/completed/2026-04/traj_530xmbfeljyb.md similarity index 100% rename from .agentworkforce/trajectories/completed/2026-04/traj_530xmbfeljyb.md rename to .trajectories/completed/2026-04/traj_530xmbfeljyb.md diff --git a/.agentworkforce/trajectories/completed/2026-04/traj_703m7sqyq89t.json b/.trajectories/completed/2026-04/traj_703m7sqyq89t.json similarity index 100% rename from .agentworkforce/trajectories/completed/2026-04/traj_703m7sqyq89t.json rename to .trajectories/completed/2026-04/traj_703m7sqyq89t.json diff --git a/.agentworkforce/trajectories/completed/2026-04/traj_703m7sqyq89t.md b/.trajectories/completed/2026-04/traj_703m7sqyq89t.md similarity index 100% rename from .agentworkforce/trajectories/completed/2026-04/traj_703m7sqyq89t.md rename to .trajectories/completed/2026-04/traj_703m7sqyq89t.md diff --git a/.agentworkforce/trajectories/completed/2026-04/traj_8oh4r5km5eic.json b/.trajectories/completed/2026-04/traj_8oh4r5km5eic.json similarity index 100% rename from .agentworkforce/trajectories/completed/2026-04/traj_8oh4r5km5eic.json rename to .trajectories/completed/2026-04/traj_8oh4r5km5eic.json diff --git a/.agentworkforce/trajectories/completed/2026-04/traj_8oh4r5km5eic.md b/.trajectories/completed/2026-04/traj_8oh4r5km5eic.md similarity index 100% rename from .agentworkforce/trajectories/completed/2026-04/traj_8oh4r5km5eic.md rename to .trajectories/completed/2026-04/traj_8oh4r5km5eic.md diff --git a/.agentworkforce/trajectories/completed/2026-04/traj_9tt55is74dq5.json b/.trajectories/completed/2026-04/traj_9tt55is74dq5.json similarity index 100% rename from .agentworkforce/trajectories/completed/2026-04/traj_9tt55is74dq5.json rename to .trajectories/completed/2026-04/traj_9tt55is74dq5.json diff --git a/.agentworkforce/trajectories/completed/2026-04/traj_9tt55is74dq5.md b/.trajectories/completed/2026-04/traj_9tt55is74dq5.md similarity index 100% rename from .agentworkforce/trajectories/completed/2026-04/traj_9tt55is74dq5.md rename to .trajectories/completed/2026-04/traj_9tt55is74dq5.md diff --git a/.agentworkforce/trajectories/completed/2026-04/traj_abjovknvcijv.json b/.trajectories/completed/2026-04/traj_abjovknvcijv.json similarity index 100% rename from .agentworkforce/trajectories/completed/2026-04/traj_abjovknvcijv.json rename to .trajectories/completed/2026-04/traj_abjovknvcijv.json diff --git a/.agentworkforce/trajectories/completed/2026-04/traj_abjovknvcijv.md b/.trajectories/completed/2026-04/traj_abjovknvcijv.md similarity index 100% rename from .agentworkforce/trajectories/completed/2026-04/traj_abjovknvcijv.md rename to .trajectories/completed/2026-04/traj_abjovknvcijv.md diff --git a/.agentworkforce/trajectories/completed/2026-04/traj_avmkyoo2s3rt.json b/.trajectories/completed/2026-04/traj_avmkyoo2s3rt.json similarity index 100% rename from .agentworkforce/trajectories/completed/2026-04/traj_avmkyoo2s3rt.json rename to .trajectories/completed/2026-04/traj_avmkyoo2s3rt.json diff --git a/.agentworkforce/trajectories/completed/2026-04/traj_avmkyoo2s3rt.md b/.trajectories/completed/2026-04/traj_avmkyoo2s3rt.md similarity index 100% rename from .agentworkforce/trajectories/completed/2026-04/traj_avmkyoo2s3rt.md rename to .trajectories/completed/2026-04/traj_avmkyoo2s3rt.md diff --git a/.agentworkforce/trajectories/completed/2026-04/traj_d48czxmgx4ac.json b/.trajectories/completed/2026-04/traj_d48czxmgx4ac.json similarity index 100% rename from .agentworkforce/trajectories/completed/2026-04/traj_d48czxmgx4ac.json rename to .trajectories/completed/2026-04/traj_d48czxmgx4ac.json diff --git a/.agentworkforce/trajectories/completed/2026-04/traj_d48czxmgx4ac.md b/.trajectories/completed/2026-04/traj_d48czxmgx4ac.md similarity index 100% rename from .agentworkforce/trajectories/completed/2026-04/traj_d48czxmgx4ac.md rename to .trajectories/completed/2026-04/traj_d48czxmgx4ac.md diff --git a/.agentworkforce/trajectories/completed/2026-04/traj_dw8ihhdb8ip7.json b/.trajectories/completed/2026-04/traj_dw8ihhdb8ip7.json similarity index 100% rename from .agentworkforce/trajectories/completed/2026-04/traj_dw8ihhdb8ip7.json rename to .trajectories/completed/2026-04/traj_dw8ihhdb8ip7.json diff --git a/.agentworkforce/trajectories/completed/2026-04/traj_dw8ihhdb8ip7.md b/.trajectories/completed/2026-04/traj_dw8ihhdb8ip7.md similarity index 100% rename from .agentworkforce/trajectories/completed/2026-04/traj_dw8ihhdb8ip7.md rename to .trajectories/completed/2026-04/traj_dw8ihhdb8ip7.md diff --git a/.agentworkforce/trajectories/completed/2026-04/traj_e5i62wdjx0jd.json b/.trajectories/completed/2026-04/traj_e5i62wdjx0jd.json similarity index 100% rename from .agentworkforce/trajectories/completed/2026-04/traj_e5i62wdjx0jd.json rename to .trajectories/completed/2026-04/traj_e5i62wdjx0jd.json diff --git a/.agentworkforce/trajectories/completed/2026-04/traj_e5i62wdjx0jd.md b/.trajectories/completed/2026-04/traj_e5i62wdjx0jd.md similarity index 100% rename from .agentworkforce/trajectories/completed/2026-04/traj_e5i62wdjx0jd.md rename to .trajectories/completed/2026-04/traj_e5i62wdjx0jd.md diff --git a/.agentworkforce/trajectories/completed/2026-04/traj_g3muawdq6bsb.json b/.trajectories/completed/2026-04/traj_g3muawdq6bsb.json similarity index 100% rename from .agentworkforce/trajectories/completed/2026-04/traj_g3muawdq6bsb.json rename to .trajectories/completed/2026-04/traj_g3muawdq6bsb.json diff --git a/.agentworkforce/trajectories/completed/2026-04/traj_g3muawdq6bsb.md b/.trajectories/completed/2026-04/traj_g3muawdq6bsb.md similarity index 100% rename from .agentworkforce/trajectories/completed/2026-04/traj_g3muawdq6bsb.md rename to .trajectories/completed/2026-04/traj_g3muawdq6bsb.md diff --git a/.agentworkforce/trajectories/completed/2026-04/traj_mk0t0cgn4ytq.json b/.trajectories/completed/2026-04/traj_mk0t0cgn4ytq.json similarity index 100% rename from .agentworkforce/trajectories/completed/2026-04/traj_mk0t0cgn4ytq.json rename to .trajectories/completed/2026-04/traj_mk0t0cgn4ytq.json diff --git a/.agentworkforce/trajectories/completed/2026-04/traj_mk0t0cgn4ytq.md b/.trajectories/completed/2026-04/traj_mk0t0cgn4ytq.md similarity index 100% rename from .agentworkforce/trajectories/completed/2026-04/traj_mk0t0cgn4ytq.md rename to .trajectories/completed/2026-04/traj_mk0t0cgn4ytq.md diff --git a/.agentworkforce/trajectories/completed/2026-04/traj_o8kgzhfu6jth.json b/.trajectories/completed/2026-04/traj_o8kgzhfu6jth.json similarity index 100% rename from .agentworkforce/trajectories/completed/2026-04/traj_o8kgzhfu6jth.json rename to .trajectories/completed/2026-04/traj_o8kgzhfu6jth.json diff --git a/.agentworkforce/trajectories/completed/2026-04/traj_o8kgzhfu6jth.md b/.trajectories/completed/2026-04/traj_o8kgzhfu6jth.md similarity index 100% rename from .agentworkforce/trajectories/completed/2026-04/traj_o8kgzhfu6jth.md rename to .trajectories/completed/2026-04/traj_o8kgzhfu6jth.md diff --git a/.agentworkforce/trajectories/completed/2026-04/traj_qb54w47qwod6.json b/.trajectories/completed/2026-04/traj_qb54w47qwod6.json similarity index 100% rename from .agentworkforce/trajectories/completed/2026-04/traj_qb54w47qwod6.json rename to .trajectories/completed/2026-04/traj_qb54w47qwod6.json diff --git a/.agentworkforce/trajectories/completed/2026-04/traj_qb54w47qwod6.md b/.trajectories/completed/2026-04/traj_qb54w47qwod6.md similarity index 100% rename from .agentworkforce/trajectories/completed/2026-04/traj_qb54w47qwod6.md rename to .trajectories/completed/2026-04/traj_qb54w47qwod6.md diff --git a/.agentworkforce/trajectories/completed/2026-04/traj_rs2bt3x0fqba.json b/.trajectories/completed/2026-04/traj_rs2bt3x0fqba.json similarity index 100% rename from .agentworkforce/trajectories/completed/2026-04/traj_rs2bt3x0fqba.json rename to .trajectories/completed/2026-04/traj_rs2bt3x0fqba.json diff --git a/.agentworkforce/trajectories/completed/2026-04/traj_rs2bt3x0fqba.md b/.trajectories/completed/2026-04/traj_rs2bt3x0fqba.md similarity index 100% rename from .agentworkforce/trajectories/completed/2026-04/traj_rs2bt3x0fqba.md rename to .trajectories/completed/2026-04/traj_rs2bt3x0fqba.md diff --git a/.agentworkforce/trajectories/completed/2026-04/traj_tjadoebpscps.json b/.trajectories/completed/2026-04/traj_tjadoebpscps.json similarity index 100% rename from .agentworkforce/trajectories/completed/2026-04/traj_tjadoebpscps.json rename to .trajectories/completed/2026-04/traj_tjadoebpscps.json diff --git a/.agentworkforce/trajectories/completed/2026-04/traj_tjadoebpscps.md b/.trajectories/completed/2026-04/traj_tjadoebpscps.md similarity index 100% rename from .agentworkforce/trajectories/completed/2026-04/traj_tjadoebpscps.md rename to .trajectories/completed/2026-04/traj_tjadoebpscps.md diff --git a/.agentworkforce/trajectories/completed/2026-04/traj_tv1x9pamkqad.json b/.trajectories/completed/2026-04/traj_tv1x9pamkqad.json similarity index 100% rename from .agentworkforce/trajectories/completed/2026-04/traj_tv1x9pamkqad.json rename to .trajectories/completed/2026-04/traj_tv1x9pamkqad.json diff --git a/.agentworkforce/trajectories/completed/2026-04/traj_tv1x9pamkqad.md b/.trajectories/completed/2026-04/traj_tv1x9pamkqad.md similarity index 100% rename from .agentworkforce/trajectories/completed/2026-04/traj_tv1x9pamkqad.md rename to .trajectories/completed/2026-04/traj_tv1x9pamkqad.md diff --git a/.agentworkforce/trajectories/completed/2026-04/traj_ui5omrgz819d.json b/.trajectories/completed/2026-04/traj_ui5omrgz819d.json similarity index 100% rename from .agentworkforce/trajectories/completed/2026-04/traj_ui5omrgz819d.json rename to .trajectories/completed/2026-04/traj_ui5omrgz819d.json diff --git a/.agentworkforce/trajectories/completed/2026-04/traj_ui5omrgz819d.md b/.trajectories/completed/2026-04/traj_ui5omrgz819d.md similarity index 100% rename from .agentworkforce/trajectories/completed/2026-04/traj_ui5omrgz819d.md rename to .trajectories/completed/2026-04/traj_ui5omrgz819d.md diff --git a/.agentworkforce/trajectories/completed/2026-04/traj_w0xpsaoxuiyw.json b/.trajectories/completed/2026-04/traj_w0xpsaoxuiyw.json similarity index 100% rename from .agentworkforce/trajectories/completed/2026-04/traj_w0xpsaoxuiyw.json rename to .trajectories/completed/2026-04/traj_w0xpsaoxuiyw.json diff --git a/.agentworkforce/trajectories/completed/2026-04/traj_w0xpsaoxuiyw.md b/.trajectories/completed/2026-04/traj_w0xpsaoxuiyw.md similarity index 100% rename from .agentworkforce/trajectories/completed/2026-04/traj_w0xpsaoxuiyw.md rename to .trajectories/completed/2026-04/traj_w0xpsaoxuiyw.md diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_0d1efjk6aeo2.json b/.trajectories/completed/2026-05/traj_0d1efjk6aeo2.json similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_0d1efjk6aeo2.json rename to .trajectories/completed/2026-05/traj_0d1efjk6aeo2.json diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_0d1efjk6aeo2.md b/.trajectories/completed/2026-05/traj_0d1efjk6aeo2.md similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_0d1efjk6aeo2.md rename to .trajectories/completed/2026-05/traj_0d1efjk6aeo2.md diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_0e8i20oitwvz.json b/.trajectories/completed/2026-05/traj_0e8i20oitwvz.json similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_0e8i20oitwvz.json rename to .trajectories/completed/2026-05/traj_0e8i20oitwvz.json diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_0e8i20oitwvz.md b/.trajectories/completed/2026-05/traj_0e8i20oitwvz.md similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_0e8i20oitwvz.md rename to .trajectories/completed/2026-05/traj_0e8i20oitwvz.md diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_0o6gb2wvk59t.json b/.trajectories/completed/2026-05/traj_0o6gb2wvk59t.json similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_0o6gb2wvk59t.json rename to .trajectories/completed/2026-05/traj_0o6gb2wvk59t.json diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_0o6gb2wvk59t.md b/.trajectories/completed/2026-05/traj_0o6gb2wvk59t.md similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_0o6gb2wvk59t.md rename to .trajectories/completed/2026-05/traj_0o6gb2wvk59t.md diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_0z98tkaigaxg.json b/.trajectories/completed/2026-05/traj_0z98tkaigaxg.json similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_0z98tkaigaxg.json rename to .trajectories/completed/2026-05/traj_0z98tkaigaxg.json diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_0z98tkaigaxg.md b/.trajectories/completed/2026-05/traj_0z98tkaigaxg.md similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_0z98tkaigaxg.md rename to .trajectories/completed/2026-05/traj_0z98tkaigaxg.md diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_1775914133873_35667beb.json b/.trajectories/completed/2026-05/traj_1775914133873_35667beb.json similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_1775914133873_35667beb.json rename to .trajectories/completed/2026-05/traj_1775914133873_35667beb.json diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_1775914133873_35667beb.md b/.trajectories/completed/2026-05/traj_1775914133873_35667beb.md similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_1775914133873_35667beb.md rename to .trajectories/completed/2026-05/traj_1775914133873_35667beb.md diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_1776073106646_1839be2d.json b/.trajectories/completed/2026-05/traj_1776073106646_1839be2d.json similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_1776073106646_1839be2d.json rename to .trajectories/completed/2026-05/traj_1776073106646_1839be2d.json diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_1776073106646_1839be2d.md b/.trajectories/completed/2026-05/traj_1776073106646_1839be2d.md similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_1776073106646_1839be2d.md rename to .trajectories/completed/2026-05/traj_1776073106646_1839be2d.md diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_1776113772922_bc92f121.json b/.trajectories/completed/2026-05/traj_1776113772922_bc92f121.json similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_1776113772922_bc92f121.json rename to .trajectories/completed/2026-05/traj_1776113772922_bc92f121.json diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_1776113772922_bc92f121.md b/.trajectories/completed/2026-05/traj_1776113772922_bc92f121.md similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_1776113772922_bc92f121.md rename to .trajectories/completed/2026-05/traj_1776113772922_bc92f121.md diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_1778873209642_c70e32ab.json b/.trajectories/completed/2026-05/traj_1778873209642_c70e32ab.json similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_1778873209642_c70e32ab.json rename to .trajectories/completed/2026-05/traj_1778873209642_c70e32ab.json diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_1778873209642_c70e32ab.md b/.trajectories/completed/2026-05/traj_1778873209642_c70e32ab.md similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_1778873209642_c70e32ab.md rename to .trajectories/completed/2026-05/traj_1778873209642_c70e32ab.md diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_1778873211616_6db3b2cd.json b/.trajectories/completed/2026-05/traj_1778873211616_6db3b2cd.json similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_1778873211616_6db3b2cd.json rename to .trajectories/completed/2026-05/traj_1778873211616_6db3b2cd.json diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_1778873211616_6db3b2cd.md b/.trajectories/completed/2026-05/traj_1778873211616_6db3b2cd.md similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_1778873211616_6db3b2cd.md rename to .trajectories/completed/2026-05/traj_1778873211616_6db3b2cd.md diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_1fjub7c9rlap.json b/.trajectories/completed/2026-05/traj_1fjub7c9rlap.json similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_1fjub7c9rlap.json rename to .trajectories/completed/2026-05/traj_1fjub7c9rlap.json diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_1fjub7c9rlap.md b/.trajectories/completed/2026-05/traj_1fjub7c9rlap.md similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_1fjub7c9rlap.md rename to .trajectories/completed/2026-05/traj_1fjub7c9rlap.md diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_1rrpe2r7fyem.json b/.trajectories/completed/2026-05/traj_1rrpe2r7fyem.json similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_1rrpe2r7fyem.json rename to .trajectories/completed/2026-05/traj_1rrpe2r7fyem.json diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_1rrpe2r7fyem.md b/.trajectories/completed/2026-05/traj_1rrpe2r7fyem.md similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_1rrpe2r7fyem.md rename to .trajectories/completed/2026-05/traj_1rrpe2r7fyem.md diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_2gpglosdsq7s.json b/.trajectories/completed/2026-05/traj_2gpglosdsq7s.json similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_2gpglosdsq7s.json rename to .trajectories/completed/2026-05/traj_2gpglosdsq7s.json diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_2gpglosdsq7s.md b/.trajectories/completed/2026-05/traj_2gpglosdsq7s.md similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_2gpglosdsq7s.md rename to .trajectories/completed/2026-05/traj_2gpglosdsq7s.md diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_2tqxnib25omk.json b/.trajectories/completed/2026-05/traj_2tqxnib25omk.json similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_2tqxnib25omk.json rename to .trajectories/completed/2026-05/traj_2tqxnib25omk.json diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_2tqxnib25omk.md b/.trajectories/completed/2026-05/traj_2tqxnib25omk.md similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_2tqxnib25omk.md rename to .trajectories/completed/2026-05/traj_2tqxnib25omk.md diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_2yicjxgajt0a.json b/.trajectories/completed/2026-05/traj_2yicjxgajt0a.json similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_2yicjxgajt0a.json rename to .trajectories/completed/2026-05/traj_2yicjxgajt0a.json diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_2yicjxgajt0a.md b/.trajectories/completed/2026-05/traj_2yicjxgajt0a.md similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_2yicjxgajt0a.md rename to .trajectories/completed/2026-05/traj_2yicjxgajt0a.md diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_34b1u84b19gz.json b/.trajectories/completed/2026-05/traj_34b1u84b19gz.json similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_34b1u84b19gz.json rename to .trajectories/completed/2026-05/traj_34b1u84b19gz.json diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_34b1u84b19gz.md b/.trajectories/completed/2026-05/traj_34b1u84b19gz.md similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_34b1u84b19gz.md rename to .trajectories/completed/2026-05/traj_34b1u84b19gz.md diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_3b3p1z4y7qlo.json b/.trajectories/completed/2026-05/traj_3b3p1z4y7qlo.json similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_3b3p1z4y7qlo.json rename to .trajectories/completed/2026-05/traj_3b3p1z4y7qlo.json diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_3b3p1z4y7qlo.md b/.trajectories/completed/2026-05/traj_3b3p1z4y7qlo.md similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_3b3p1z4y7qlo.md rename to .trajectories/completed/2026-05/traj_3b3p1z4y7qlo.md diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_3gjtcykvybt5.json b/.trajectories/completed/2026-05/traj_3gjtcykvybt5.json similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_3gjtcykvybt5.json rename to .trajectories/completed/2026-05/traj_3gjtcykvybt5.json diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_3gjtcykvybt5.md b/.trajectories/completed/2026-05/traj_3gjtcykvybt5.md similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_3gjtcykvybt5.md rename to .trajectories/completed/2026-05/traj_3gjtcykvybt5.md diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_47akjihewlow.json b/.trajectories/completed/2026-05/traj_47akjihewlow.json similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_47akjihewlow.json rename to .trajectories/completed/2026-05/traj_47akjihewlow.json diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_47akjihewlow.md b/.trajectories/completed/2026-05/traj_47akjihewlow.md similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_47akjihewlow.md rename to .trajectories/completed/2026-05/traj_47akjihewlow.md diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_47akjihewlow.trace.json b/.trajectories/completed/2026-05/traj_47akjihewlow.trace.json similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_47akjihewlow.trace.json rename to .trajectories/completed/2026-05/traj_47akjihewlow.trace.json diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_4chzkm724ufo.json b/.trajectories/completed/2026-05/traj_4chzkm724ufo.json similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_4chzkm724ufo.json rename to .trajectories/completed/2026-05/traj_4chzkm724ufo.json diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_4chzkm724ufo.md b/.trajectories/completed/2026-05/traj_4chzkm724ufo.md similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_4chzkm724ufo.md rename to .trajectories/completed/2026-05/traj_4chzkm724ufo.md diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_4t07itef99ug.json b/.trajectories/completed/2026-05/traj_4t07itef99ug.json similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_4t07itef99ug.json rename to .trajectories/completed/2026-05/traj_4t07itef99ug.json diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_4t07itef99ug.md b/.trajectories/completed/2026-05/traj_4t07itef99ug.md similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_4t07itef99ug.md rename to .trajectories/completed/2026-05/traj_4t07itef99ug.md diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_4vucir4qvqa2.json b/.trajectories/completed/2026-05/traj_4vucir4qvqa2.json similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_4vucir4qvqa2.json rename to .trajectories/completed/2026-05/traj_4vucir4qvqa2.json diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_4vucir4qvqa2.md b/.trajectories/completed/2026-05/traj_4vucir4qvqa2.md similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_4vucir4qvqa2.md rename to .trajectories/completed/2026-05/traj_4vucir4qvqa2.md diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_5k0jtc1g5l33.json b/.trajectories/completed/2026-05/traj_5k0jtc1g5l33.json similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_5k0jtc1g5l33.json rename to .trajectories/completed/2026-05/traj_5k0jtc1g5l33.json diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_5k0jtc1g5l33.md b/.trajectories/completed/2026-05/traj_5k0jtc1g5l33.md similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_5k0jtc1g5l33.md rename to .trajectories/completed/2026-05/traj_5k0jtc1g5l33.md diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_5nzj6v56id4z.json b/.trajectories/completed/2026-05/traj_5nzj6v56id4z.json similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_5nzj6v56id4z.json rename to .trajectories/completed/2026-05/traj_5nzj6v56id4z.json diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_5q8i0iz4klpo.json b/.trajectories/completed/2026-05/traj_5q8i0iz4klpo.json similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_5q8i0iz4klpo.json rename to .trajectories/completed/2026-05/traj_5q8i0iz4klpo.json diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_5q8i0iz4klpo.md b/.trajectories/completed/2026-05/traj_5q8i0iz4klpo.md similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_5q8i0iz4klpo.md rename to .trajectories/completed/2026-05/traj_5q8i0iz4klpo.md diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_5qbla7w4kzoi.json b/.trajectories/completed/2026-05/traj_5qbla7w4kzoi.json similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_5qbla7w4kzoi.json rename to .trajectories/completed/2026-05/traj_5qbla7w4kzoi.json diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_5qbla7w4kzoi.md b/.trajectories/completed/2026-05/traj_5qbla7w4kzoi.md similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_5qbla7w4kzoi.md rename to .trajectories/completed/2026-05/traj_5qbla7w4kzoi.md diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_60qc24ufr96g.json b/.trajectories/completed/2026-05/traj_60qc24ufr96g.json similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_60qc24ufr96g.json rename to .trajectories/completed/2026-05/traj_60qc24ufr96g.json diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_60qc24ufr96g.md b/.trajectories/completed/2026-05/traj_60qc24ufr96g.md similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_60qc24ufr96g.md rename to .trajectories/completed/2026-05/traj_60qc24ufr96g.md diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_6sjeohtm3php.json b/.trajectories/completed/2026-05/traj_6sjeohtm3php.json similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_6sjeohtm3php.json rename to .trajectories/completed/2026-05/traj_6sjeohtm3php.json diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_6sjeohtm3php.md b/.trajectories/completed/2026-05/traj_6sjeohtm3php.md similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_6sjeohtm3php.md rename to .trajectories/completed/2026-05/traj_6sjeohtm3php.md diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_6ujzpx82gqs9.json b/.trajectories/completed/2026-05/traj_6ujzpx82gqs9.json similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_6ujzpx82gqs9.json rename to .trajectories/completed/2026-05/traj_6ujzpx82gqs9.json diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_6ujzpx82gqs9.md b/.trajectories/completed/2026-05/traj_6ujzpx82gqs9.md similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_6ujzpx82gqs9.md rename to .trajectories/completed/2026-05/traj_6ujzpx82gqs9.md diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_78ytpicts778.json b/.trajectories/completed/2026-05/traj_78ytpicts778.json similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_78ytpicts778.json rename to .trajectories/completed/2026-05/traj_78ytpicts778.json diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_78ytpicts778.md b/.trajectories/completed/2026-05/traj_78ytpicts778.md similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_78ytpicts778.md rename to .trajectories/completed/2026-05/traj_78ytpicts778.md diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_7i9tigaejfje.json b/.trajectories/completed/2026-05/traj_7i9tigaejfje.json similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_7i9tigaejfje.json rename to .trajectories/completed/2026-05/traj_7i9tigaejfje.json diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_7i9tigaejfje.md b/.trajectories/completed/2026-05/traj_7i9tigaejfje.md similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_7i9tigaejfje.md rename to .trajectories/completed/2026-05/traj_7i9tigaejfje.md diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_7uznwzoxbao6.json b/.trajectories/completed/2026-05/traj_7uznwzoxbao6.json similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_7uznwzoxbao6.json rename to .trajectories/completed/2026-05/traj_7uznwzoxbao6.json diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_7uznwzoxbao6.md b/.trajectories/completed/2026-05/traj_7uznwzoxbao6.md similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_7uznwzoxbao6.md rename to .trajectories/completed/2026-05/traj_7uznwzoxbao6.md diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_7zu7et53ph3l.json b/.trajectories/completed/2026-05/traj_7zu7et53ph3l.json similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_7zu7et53ph3l.json rename to .trajectories/completed/2026-05/traj_7zu7et53ph3l.json diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_7zu7et53ph3l.md b/.trajectories/completed/2026-05/traj_7zu7et53ph3l.md similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_7zu7et53ph3l.md rename to .trajectories/completed/2026-05/traj_7zu7et53ph3l.md diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_81kobstnzzwk.json b/.trajectories/completed/2026-05/traj_81kobstnzzwk.json similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_81kobstnzzwk.json rename to .trajectories/completed/2026-05/traj_81kobstnzzwk.json diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_8ljgydz61do5.json b/.trajectories/completed/2026-05/traj_8ljgydz61do5.json similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_8ljgydz61do5.json rename to .trajectories/completed/2026-05/traj_8ljgydz61do5.json diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_8ljgydz61do5.md b/.trajectories/completed/2026-05/traj_8ljgydz61do5.md similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_8ljgydz61do5.md rename to .trajectories/completed/2026-05/traj_8ljgydz61do5.md diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_8nhd9lljhbsw.json b/.trajectories/completed/2026-05/traj_8nhd9lljhbsw.json similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_8nhd9lljhbsw.json rename to .trajectories/completed/2026-05/traj_8nhd9lljhbsw.json diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_8nhd9lljhbsw.md b/.trajectories/completed/2026-05/traj_8nhd9lljhbsw.md similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_8nhd9lljhbsw.md rename to .trajectories/completed/2026-05/traj_8nhd9lljhbsw.md diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_90jmd9z27oap.json b/.trajectories/completed/2026-05/traj_90jmd9z27oap.json similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_90jmd9z27oap.json rename to .trajectories/completed/2026-05/traj_90jmd9z27oap.json diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_90jmd9z27oap.md b/.trajectories/completed/2026-05/traj_90jmd9z27oap.md similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_90jmd9z27oap.md rename to .trajectories/completed/2026-05/traj_90jmd9z27oap.md diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_947wzpddsg9j.json b/.trajectories/completed/2026-05/traj_947wzpddsg9j.json similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_947wzpddsg9j.json rename to .trajectories/completed/2026-05/traj_947wzpddsg9j.json diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_947wzpddsg9j.md b/.trajectories/completed/2026-05/traj_947wzpddsg9j.md similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_947wzpddsg9j.md rename to .trajectories/completed/2026-05/traj_947wzpddsg9j.md diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_9dj3qiugt26j.json b/.trajectories/completed/2026-05/traj_9dj3qiugt26j.json similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_9dj3qiugt26j.json rename to .trajectories/completed/2026-05/traj_9dj3qiugt26j.json diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_9dj3qiugt26j.md b/.trajectories/completed/2026-05/traj_9dj3qiugt26j.md similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_9dj3qiugt26j.md rename to .trajectories/completed/2026-05/traj_9dj3qiugt26j.md diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_9fdv7hxm0b60.json b/.trajectories/completed/2026-05/traj_9fdv7hxm0b60.json similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_9fdv7hxm0b60.json rename to .trajectories/completed/2026-05/traj_9fdv7hxm0b60.json diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_9fdv7hxm0b60.md b/.trajectories/completed/2026-05/traj_9fdv7hxm0b60.md similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_9fdv7hxm0b60.md rename to .trajectories/completed/2026-05/traj_9fdv7hxm0b60.md diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_9gq96irkj00s.json b/.trajectories/completed/2026-05/traj_9gq96irkj00s.json similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_9gq96irkj00s.json rename to .trajectories/completed/2026-05/traj_9gq96irkj00s.json diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_9gq96irkj00s.md b/.trajectories/completed/2026-05/traj_9gq96irkj00s.md similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_9gq96irkj00s.md rename to .trajectories/completed/2026-05/traj_9gq96irkj00s.md diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_aw7stgf4qau0.json b/.trajectories/completed/2026-05/traj_aw7stgf4qau0.json similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_aw7stgf4qau0.json rename to .trajectories/completed/2026-05/traj_aw7stgf4qau0.json diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_aw7stgf4qau0.md b/.trajectories/completed/2026-05/traj_aw7stgf4qau0.md similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_aw7stgf4qau0.md rename to .trajectories/completed/2026-05/traj_aw7stgf4qau0.md diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_bd431l65n9lg.json b/.trajectories/completed/2026-05/traj_bd431l65n9lg.json similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_bd431l65n9lg.json rename to .trajectories/completed/2026-05/traj_bd431l65n9lg.json diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_bd431l65n9lg.md b/.trajectories/completed/2026-05/traj_bd431l65n9lg.md similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_bd431l65n9lg.md rename to .trajectories/completed/2026-05/traj_bd431l65n9lg.md diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_bdrlknyl8twj.json b/.trajectories/completed/2026-05/traj_bdrlknyl8twj.json similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_bdrlknyl8twj.json rename to .trajectories/completed/2026-05/traj_bdrlknyl8twj.json diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_bdrlknyl8twj.md b/.trajectories/completed/2026-05/traj_bdrlknyl8twj.md similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_bdrlknyl8twj.md rename to .trajectories/completed/2026-05/traj_bdrlknyl8twj.md diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_bz1a1o15p7px.json b/.trajectories/completed/2026-05/traj_bz1a1o15p7px.json similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_bz1a1o15p7px.json rename to .trajectories/completed/2026-05/traj_bz1a1o15p7px.json diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_bz1a1o15p7px.md b/.trajectories/completed/2026-05/traj_bz1a1o15p7px.md similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_bz1a1o15p7px.md rename to .trajectories/completed/2026-05/traj_bz1a1o15p7px.md diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_cbmwd07phhm2.json b/.trajectories/completed/2026-05/traj_cbmwd07phhm2.json similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_cbmwd07phhm2.json rename to .trajectories/completed/2026-05/traj_cbmwd07phhm2.json diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_cbmwd07phhm2.md b/.trajectories/completed/2026-05/traj_cbmwd07phhm2.md similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_cbmwd07phhm2.md rename to .trajectories/completed/2026-05/traj_cbmwd07phhm2.md diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_ceo5q9bh2od3.json b/.trajectories/completed/2026-05/traj_ceo5q9bh2od3.json similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_ceo5q9bh2od3.json rename to .trajectories/completed/2026-05/traj_ceo5q9bh2od3.json diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_ceo5q9bh2od3.md b/.trajectories/completed/2026-05/traj_ceo5q9bh2od3.md similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_ceo5q9bh2od3.md rename to .trajectories/completed/2026-05/traj_ceo5q9bh2od3.md diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_cszfl2icaj2t.json b/.trajectories/completed/2026-05/traj_cszfl2icaj2t.json similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_cszfl2icaj2t.json rename to .trajectories/completed/2026-05/traj_cszfl2icaj2t.json diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_cszfl2icaj2t.md b/.trajectories/completed/2026-05/traj_cszfl2icaj2t.md similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_cszfl2icaj2t.md rename to .trajectories/completed/2026-05/traj_cszfl2icaj2t.md diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_d89s38ddu7cj.json b/.trajectories/completed/2026-05/traj_d89s38ddu7cj.json similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_d89s38ddu7cj.json rename to .trajectories/completed/2026-05/traj_d89s38ddu7cj.json diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_d89s38ddu7cj.md b/.trajectories/completed/2026-05/traj_d89s38ddu7cj.md similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_d89s38ddu7cj.md rename to .trajectories/completed/2026-05/traj_d89s38ddu7cj.md diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_dbsnr453nxjw.json b/.trajectories/completed/2026-05/traj_dbsnr453nxjw.json similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_dbsnr453nxjw.json rename to .trajectories/completed/2026-05/traj_dbsnr453nxjw.json diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_dbsnr453nxjw.md b/.trajectories/completed/2026-05/traj_dbsnr453nxjw.md similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_dbsnr453nxjw.md rename to .trajectories/completed/2026-05/traj_dbsnr453nxjw.md diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_dcl9hgoiuac5.json b/.trajectories/completed/2026-05/traj_dcl9hgoiuac5.json similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_dcl9hgoiuac5.json rename to .trajectories/completed/2026-05/traj_dcl9hgoiuac5.json diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_dcl9hgoiuac5.md b/.trajectories/completed/2026-05/traj_dcl9hgoiuac5.md similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_dcl9hgoiuac5.md rename to .trajectories/completed/2026-05/traj_dcl9hgoiuac5.md diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_dpgn0am1jq1c.json b/.trajectories/completed/2026-05/traj_dpgn0am1jq1c.json similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_dpgn0am1jq1c.json rename to .trajectories/completed/2026-05/traj_dpgn0am1jq1c.json diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_dpgn0am1jq1c.md b/.trajectories/completed/2026-05/traj_dpgn0am1jq1c.md similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_dpgn0am1jq1c.md rename to .trajectories/completed/2026-05/traj_dpgn0am1jq1c.md diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_e1b7ww3un1u3.json b/.trajectories/completed/2026-05/traj_e1b7ww3un1u3.json similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_e1b7ww3un1u3.json rename to .trajectories/completed/2026-05/traj_e1b7ww3un1u3.json diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_e1b7ww3un1u3.md b/.trajectories/completed/2026-05/traj_e1b7ww3un1u3.md similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_e1b7ww3un1u3.md rename to .trajectories/completed/2026-05/traj_e1b7ww3un1u3.md diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_elx0fcwgs37x.json b/.trajectories/completed/2026-05/traj_elx0fcwgs37x.json similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_elx0fcwgs37x.json rename to .trajectories/completed/2026-05/traj_elx0fcwgs37x.json diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_elx0fcwgs37x.md b/.trajectories/completed/2026-05/traj_elx0fcwgs37x.md similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_elx0fcwgs37x.md rename to .trajectories/completed/2026-05/traj_elx0fcwgs37x.md diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_erzd7j9nto9r.json b/.trajectories/completed/2026-05/traj_erzd7j9nto9r.json similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_erzd7j9nto9r.json rename to .trajectories/completed/2026-05/traj_erzd7j9nto9r.json diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_erzd7j9nto9r.md b/.trajectories/completed/2026-05/traj_erzd7j9nto9r.md similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_erzd7j9nto9r.md rename to .trajectories/completed/2026-05/traj_erzd7j9nto9r.md diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_f1iac9ngymlj.json b/.trajectories/completed/2026-05/traj_f1iac9ngymlj.json similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_f1iac9ngymlj.json rename to .trajectories/completed/2026-05/traj_f1iac9ngymlj.json diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_f1iac9ngymlj.md b/.trajectories/completed/2026-05/traj_f1iac9ngymlj.md similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_f1iac9ngymlj.md rename to .trajectories/completed/2026-05/traj_f1iac9ngymlj.md diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_f3arvbmmlomn.json b/.trajectories/completed/2026-05/traj_f3arvbmmlomn.json similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_f3arvbmmlomn.json rename to .trajectories/completed/2026-05/traj_f3arvbmmlomn.json diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_f3arvbmmlomn.md b/.trajectories/completed/2026-05/traj_f3arvbmmlomn.md similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_f3arvbmmlomn.md rename to .trajectories/completed/2026-05/traj_f3arvbmmlomn.md diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_f9wxa8ujeg78.json b/.trajectories/completed/2026-05/traj_f9wxa8ujeg78.json similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_f9wxa8ujeg78.json rename to .trajectories/completed/2026-05/traj_f9wxa8ujeg78.json diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_f9wxa8ujeg78.md b/.trajectories/completed/2026-05/traj_f9wxa8ujeg78.md similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_f9wxa8ujeg78.md rename to .trajectories/completed/2026-05/traj_f9wxa8ujeg78.md diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_fh8oosbijpwc.json b/.trajectories/completed/2026-05/traj_fh8oosbijpwc.json similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_fh8oosbijpwc.json rename to .trajectories/completed/2026-05/traj_fh8oosbijpwc.json diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_fh8oosbijpwc.md b/.trajectories/completed/2026-05/traj_fh8oosbijpwc.md similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_fh8oosbijpwc.md rename to .trajectories/completed/2026-05/traj_fh8oosbijpwc.md diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_fh8oosbijpwc.trace.json b/.trajectories/completed/2026-05/traj_fh8oosbijpwc.trace.json similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_fh8oosbijpwc.trace.json rename to .trajectories/completed/2026-05/traj_fh8oosbijpwc.trace.json diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_fiygtgr3tfey.json b/.trajectories/completed/2026-05/traj_fiygtgr3tfey.json similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_fiygtgr3tfey.json rename to .trajectories/completed/2026-05/traj_fiygtgr3tfey.json diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_fiygtgr3tfey.md b/.trajectories/completed/2026-05/traj_fiygtgr3tfey.md similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_fiygtgr3tfey.md rename to .trajectories/completed/2026-05/traj_fiygtgr3tfey.md diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_gh05rj5gwsap.json b/.trajectories/completed/2026-05/traj_gh05rj5gwsap.json similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_gh05rj5gwsap.json rename to .trajectories/completed/2026-05/traj_gh05rj5gwsap.json diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_gh05rj5gwsap.md b/.trajectories/completed/2026-05/traj_gh05rj5gwsap.md similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_gh05rj5gwsap.md rename to .trajectories/completed/2026-05/traj_gh05rj5gwsap.md diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_gh05rj5gwsap.trace.json b/.trajectories/completed/2026-05/traj_gh05rj5gwsap.trace.json similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_gh05rj5gwsap.trace.json rename to .trajectories/completed/2026-05/traj_gh05rj5gwsap.trace.json diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_gkxajksmwoea.json b/.trajectories/completed/2026-05/traj_gkxajksmwoea.json similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_gkxajksmwoea.json rename to .trajectories/completed/2026-05/traj_gkxajksmwoea.json diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_gkxajksmwoea.md b/.trajectories/completed/2026-05/traj_gkxajksmwoea.md similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_gkxajksmwoea.md rename to .trajectories/completed/2026-05/traj_gkxajksmwoea.md diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_gnqvtoxtc8dy.json b/.trajectories/completed/2026-05/traj_gnqvtoxtc8dy.json similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_gnqvtoxtc8dy.json rename to .trajectories/completed/2026-05/traj_gnqvtoxtc8dy.json diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_gnqvtoxtc8dy.md b/.trajectories/completed/2026-05/traj_gnqvtoxtc8dy.md similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_gnqvtoxtc8dy.md rename to .trajectories/completed/2026-05/traj_gnqvtoxtc8dy.md diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_hfkww5z7trxn.json b/.trajectories/completed/2026-05/traj_hfkww5z7trxn.json similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_hfkww5z7trxn.json rename to .trajectories/completed/2026-05/traj_hfkww5z7trxn.json diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_hfkww5z7trxn.md b/.trajectories/completed/2026-05/traj_hfkww5z7trxn.md similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_hfkww5z7trxn.md rename to .trajectories/completed/2026-05/traj_hfkww5z7trxn.md diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_hrsndfzk0qay.json b/.trajectories/completed/2026-05/traj_hrsndfzk0qay.json similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_hrsndfzk0qay.json rename to .trajectories/completed/2026-05/traj_hrsndfzk0qay.json diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_hrsndfzk0qay.md b/.trajectories/completed/2026-05/traj_hrsndfzk0qay.md similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_hrsndfzk0qay.md rename to .trajectories/completed/2026-05/traj_hrsndfzk0qay.md diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_hysw5o7idqas.json b/.trajectories/completed/2026-05/traj_hysw5o7idqas.json similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_hysw5o7idqas.json rename to .trajectories/completed/2026-05/traj_hysw5o7idqas.json diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_hysw5o7idqas.md b/.trajectories/completed/2026-05/traj_hysw5o7idqas.md similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_hysw5o7idqas.md rename to .trajectories/completed/2026-05/traj_hysw5o7idqas.md diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_i2pjnx3dll5b.json b/.trajectories/completed/2026-05/traj_i2pjnx3dll5b.json similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_i2pjnx3dll5b.json rename to .trajectories/completed/2026-05/traj_i2pjnx3dll5b.json diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_i2pjnx3dll5b.md b/.trajectories/completed/2026-05/traj_i2pjnx3dll5b.md similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_i2pjnx3dll5b.md rename to .trajectories/completed/2026-05/traj_i2pjnx3dll5b.md diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_i2pjnx3dll5b.trace.json b/.trajectories/completed/2026-05/traj_i2pjnx3dll5b.trace.json similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_i2pjnx3dll5b.trace.json rename to .trajectories/completed/2026-05/traj_i2pjnx3dll5b.trace.json diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_ij5b3kcatvwn.json b/.trajectories/completed/2026-05/traj_ij5b3kcatvwn.json similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_ij5b3kcatvwn.json rename to .trajectories/completed/2026-05/traj_ij5b3kcatvwn.json diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_ij5b3kcatvwn.md b/.trajectories/completed/2026-05/traj_ij5b3kcatvwn.md similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_ij5b3kcatvwn.md rename to .trajectories/completed/2026-05/traj_ij5b3kcatvwn.md diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_iole5zdt9orr.json b/.trajectories/completed/2026-05/traj_iole5zdt9orr.json similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_iole5zdt9orr.json rename to .trajectories/completed/2026-05/traj_iole5zdt9orr.json diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_iole5zdt9orr.md b/.trajectories/completed/2026-05/traj_iole5zdt9orr.md similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_iole5zdt9orr.md rename to .trajectories/completed/2026-05/traj_iole5zdt9orr.md diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_irafiyk6wpw0.json b/.trajectories/completed/2026-05/traj_irafiyk6wpw0.json similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_irafiyk6wpw0.json rename to .trajectories/completed/2026-05/traj_irafiyk6wpw0.json diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_itgr2w8qs3xn.json b/.trajectories/completed/2026-05/traj_itgr2w8qs3xn.json similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_itgr2w8qs3xn.json rename to .trajectories/completed/2026-05/traj_itgr2w8qs3xn.json diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_itgr2w8qs3xn.md b/.trajectories/completed/2026-05/traj_itgr2w8qs3xn.md similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_itgr2w8qs3xn.md rename to .trajectories/completed/2026-05/traj_itgr2w8qs3xn.md diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_j9k10fez3e81.json b/.trajectories/completed/2026-05/traj_j9k10fez3e81.json similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_j9k10fez3e81.json rename to .trajectories/completed/2026-05/traj_j9k10fez3e81.json diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_j9k10fez3e81.md b/.trajectories/completed/2026-05/traj_j9k10fez3e81.md similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_j9k10fez3e81.md rename to .trajectories/completed/2026-05/traj_j9k10fez3e81.md diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_jbo2x14y7ovt.json b/.trajectories/completed/2026-05/traj_jbo2x14y7ovt.json similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_jbo2x14y7ovt.json rename to .trajectories/completed/2026-05/traj_jbo2x14y7ovt.json diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_jbo2x14y7ovt.md b/.trajectories/completed/2026-05/traj_jbo2x14y7ovt.md similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_jbo2x14y7ovt.md rename to .trajectories/completed/2026-05/traj_jbo2x14y7ovt.md diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_jmf9pyt3zikn.json b/.trajectories/completed/2026-05/traj_jmf9pyt3zikn.json similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_jmf9pyt3zikn.json rename to .trajectories/completed/2026-05/traj_jmf9pyt3zikn.json diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_jmf9pyt3zikn.md b/.trajectories/completed/2026-05/traj_jmf9pyt3zikn.md similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_jmf9pyt3zikn.md rename to .trajectories/completed/2026-05/traj_jmf9pyt3zikn.md diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_k7njijv51iq4.json b/.trajectories/completed/2026-05/traj_k7njijv51iq4.json similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_k7njijv51iq4.json rename to .trajectories/completed/2026-05/traj_k7njijv51iq4.json diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_k7njijv51iq4.md b/.trajectories/completed/2026-05/traj_k7njijv51iq4.md similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_k7njijv51iq4.md rename to .trajectories/completed/2026-05/traj_k7njijv51iq4.md diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_kgl2opmmfvus.json b/.trajectories/completed/2026-05/traj_kgl2opmmfvus.json similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_kgl2opmmfvus.json rename to .trajectories/completed/2026-05/traj_kgl2opmmfvus.json diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_kgl2opmmfvus.md b/.trajectories/completed/2026-05/traj_kgl2opmmfvus.md similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_kgl2opmmfvus.md rename to .trajectories/completed/2026-05/traj_kgl2opmmfvus.md diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_l1349adi1g0o.json b/.trajectories/completed/2026-05/traj_l1349adi1g0o.json similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_l1349adi1g0o.json rename to .trajectories/completed/2026-05/traj_l1349adi1g0o.json diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_l1349adi1g0o.md b/.trajectories/completed/2026-05/traj_l1349adi1g0o.md similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_l1349adi1g0o.md rename to .trajectories/completed/2026-05/traj_l1349adi1g0o.md diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_l67sex3nkzfq.json b/.trajectories/completed/2026-05/traj_l67sex3nkzfq.json similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_l67sex3nkzfq.json rename to .trajectories/completed/2026-05/traj_l67sex3nkzfq.json diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_l67sex3nkzfq.md b/.trajectories/completed/2026-05/traj_l67sex3nkzfq.md similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_l67sex3nkzfq.md rename to .trajectories/completed/2026-05/traj_l67sex3nkzfq.md diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_lhyrcib40kao.json b/.trajectories/completed/2026-05/traj_lhyrcib40kao.json similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_lhyrcib40kao.json rename to .trajectories/completed/2026-05/traj_lhyrcib40kao.json diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_lhyrcib40kao.md b/.trajectories/completed/2026-05/traj_lhyrcib40kao.md similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_lhyrcib40kao.md rename to .trajectories/completed/2026-05/traj_lhyrcib40kao.md diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_lieyyspidhfj.json b/.trajectories/completed/2026-05/traj_lieyyspidhfj.json similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_lieyyspidhfj.json rename to .trajectories/completed/2026-05/traj_lieyyspidhfj.json diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_lieyyspidhfj.md b/.trajectories/completed/2026-05/traj_lieyyspidhfj.md similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_lieyyspidhfj.md rename to .trajectories/completed/2026-05/traj_lieyyspidhfj.md diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_lieyyspidhfj.trace.json b/.trajectories/completed/2026-05/traj_lieyyspidhfj.trace.json similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_lieyyspidhfj.trace.json rename to .trajectories/completed/2026-05/traj_lieyyspidhfj.trace.json diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_m7mpv7j8n78h.json b/.trajectories/completed/2026-05/traj_m7mpv7j8n78h.json similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_m7mpv7j8n78h.json rename to .trajectories/completed/2026-05/traj_m7mpv7j8n78h.json diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_m7mpv7j8n78h.md b/.trajectories/completed/2026-05/traj_m7mpv7j8n78h.md similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_m7mpv7j8n78h.md rename to .trajectories/completed/2026-05/traj_m7mpv7j8n78h.md diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_mi9eqd4rjfea.json b/.trajectories/completed/2026-05/traj_mi9eqd4rjfea.json similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_mi9eqd4rjfea.json rename to .trajectories/completed/2026-05/traj_mi9eqd4rjfea.json diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_mi9eqd4rjfea.md b/.trajectories/completed/2026-05/traj_mi9eqd4rjfea.md similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_mi9eqd4rjfea.md rename to .trajectories/completed/2026-05/traj_mi9eqd4rjfea.md diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_mytnzgfayj3d.json b/.trajectories/completed/2026-05/traj_mytnzgfayj3d.json similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_mytnzgfayj3d.json rename to .trajectories/completed/2026-05/traj_mytnzgfayj3d.json diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_mytnzgfayj3d.md b/.trajectories/completed/2026-05/traj_mytnzgfayj3d.md similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_mytnzgfayj3d.md rename to .trajectories/completed/2026-05/traj_mytnzgfayj3d.md diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_mz5m5ysjj31e.json b/.trajectories/completed/2026-05/traj_mz5m5ysjj31e.json similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_mz5m5ysjj31e.json rename to .trajectories/completed/2026-05/traj_mz5m5ysjj31e.json diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_mz5m5ysjj31e.md b/.trajectories/completed/2026-05/traj_mz5m5ysjj31e.md similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_mz5m5ysjj31e.md rename to .trajectories/completed/2026-05/traj_mz5m5ysjj31e.md diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_n0qwpjvmdl2s.json b/.trajectories/completed/2026-05/traj_n0qwpjvmdl2s.json similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_n0qwpjvmdl2s.json rename to .trajectories/completed/2026-05/traj_n0qwpjvmdl2s.json diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_n0qwpjvmdl2s.md b/.trajectories/completed/2026-05/traj_n0qwpjvmdl2s.md similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_n0qwpjvmdl2s.md rename to .trajectories/completed/2026-05/traj_n0qwpjvmdl2s.md diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_n8duofq5vq1a.json b/.trajectories/completed/2026-05/traj_n8duofq5vq1a.json similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_n8duofq5vq1a.json rename to .trajectories/completed/2026-05/traj_n8duofq5vq1a.json diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_n8duofq5vq1a.md b/.trajectories/completed/2026-05/traj_n8duofq5vq1a.md similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_n8duofq5vq1a.md rename to .trajectories/completed/2026-05/traj_n8duofq5vq1a.md diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_o251whkvy9rl.json b/.trajectories/completed/2026-05/traj_o251whkvy9rl.json similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_o251whkvy9rl.json rename to .trajectories/completed/2026-05/traj_o251whkvy9rl.json diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_o251whkvy9rl.md b/.trajectories/completed/2026-05/traj_o251whkvy9rl.md similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_o251whkvy9rl.md rename to .trajectories/completed/2026-05/traj_o251whkvy9rl.md diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_o9cx33xn5u39.json b/.trajectories/completed/2026-05/traj_o9cx33xn5u39.json similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_o9cx33xn5u39.json rename to .trajectories/completed/2026-05/traj_o9cx33xn5u39.json diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_o9cx33xn5u39.md b/.trajectories/completed/2026-05/traj_o9cx33xn5u39.md similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_o9cx33xn5u39.md rename to .trajectories/completed/2026-05/traj_o9cx33xn5u39.md diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_ootb5rt3tozd.json b/.trajectories/completed/2026-05/traj_ootb5rt3tozd.json similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_ootb5rt3tozd.json rename to .trajectories/completed/2026-05/traj_ootb5rt3tozd.json diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_ootb5rt3tozd.md b/.trajectories/completed/2026-05/traj_ootb5rt3tozd.md similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_ootb5rt3tozd.md rename to .trajectories/completed/2026-05/traj_ootb5rt3tozd.md diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_oyc528j7suvo.json b/.trajectories/completed/2026-05/traj_oyc528j7suvo.json similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_oyc528j7suvo.json rename to .trajectories/completed/2026-05/traj_oyc528j7suvo.json diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_oyc528j7suvo.md b/.trajectories/completed/2026-05/traj_oyc528j7suvo.md similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_oyc528j7suvo.md rename to .trajectories/completed/2026-05/traj_oyc528j7suvo.md diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_piik8r6zu3i7.json b/.trajectories/completed/2026-05/traj_piik8r6zu3i7.json similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_piik8r6zu3i7.json rename to .trajectories/completed/2026-05/traj_piik8r6zu3i7.json diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_piik8r6zu3i7.md b/.trajectories/completed/2026-05/traj_piik8r6zu3i7.md similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_piik8r6zu3i7.md rename to .trajectories/completed/2026-05/traj_piik8r6zu3i7.md diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_pmrcfj6or3pz.json b/.trajectories/completed/2026-05/traj_pmrcfj6or3pz.json similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_pmrcfj6or3pz.json rename to .trajectories/completed/2026-05/traj_pmrcfj6or3pz.json diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_pmrcfj6or3pz.md b/.trajectories/completed/2026-05/traj_pmrcfj6or3pz.md similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_pmrcfj6or3pz.md rename to .trajectories/completed/2026-05/traj_pmrcfj6or3pz.md diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_q2r3c9dmdep7.json b/.trajectories/completed/2026-05/traj_q2r3c9dmdep7.json similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_q2r3c9dmdep7.json rename to .trajectories/completed/2026-05/traj_q2r3c9dmdep7.json diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_q2r3c9dmdep7.md b/.trajectories/completed/2026-05/traj_q2r3c9dmdep7.md similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_q2r3c9dmdep7.md rename to .trajectories/completed/2026-05/traj_q2r3c9dmdep7.md diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_qbq3laxbvhzf.json b/.trajectories/completed/2026-05/traj_qbq3laxbvhzf.json similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_qbq3laxbvhzf.json rename to .trajectories/completed/2026-05/traj_qbq3laxbvhzf.json diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_qbq3laxbvhzf.md b/.trajectories/completed/2026-05/traj_qbq3laxbvhzf.md similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_qbq3laxbvhzf.md rename to .trajectories/completed/2026-05/traj_qbq3laxbvhzf.md diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_qtmid2nzz0kz.json b/.trajectories/completed/2026-05/traj_qtmid2nzz0kz.json similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_qtmid2nzz0kz.json rename to .trajectories/completed/2026-05/traj_qtmid2nzz0kz.json diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_qtmid2nzz0kz.md b/.trajectories/completed/2026-05/traj_qtmid2nzz0kz.md similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_qtmid2nzz0kz.md rename to .trajectories/completed/2026-05/traj_qtmid2nzz0kz.md diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_ryf5sstno6p3.json b/.trajectories/completed/2026-05/traj_ryf5sstno6p3.json similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_ryf5sstno6p3.json rename to .trajectories/completed/2026-05/traj_ryf5sstno6p3.json diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_ryf5sstno6p3.md b/.trajectories/completed/2026-05/traj_ryf5sstno6p3.md similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_ryf5sstno6p3.md rename to .trajectories/completed/2026-05/traj_ryf5sstno6p3.md diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_s5ojo1f4srz4.json b/.trajectories/completed/2026-05/traj_s5ojo1f4srz4.json similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_s5ojo1f4srz4.json rename to .trajectories/completed/2026-05/traj_s5ojo1f4srz4.json diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_s5ojo1f4srz4.md b/.trajectories/completed/2026-05/traj_s5ojo1f4srz4.md similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_s5ojo1f4srz4.md rename to .trajectories/completed/2026-05/traj_s5ojo1f4srz4.md diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_sh2ahp9z2xg6.json b/.trajectories/completed/2026-05/traj_sh2ahp9z2xg6.json similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_sh2ahp9z2xg6.json rename to .trajectories/completed/2026-05/traj_sh2ahp9z2xg6.json diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_sh2ahp9z2xg6.md b/.trajectories/completed/2026-05/traj_sh2ahp9z2xg6.md similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_sh2ahp9z2xg6.md rename to .trajectories/completed/2026-05/traj_sh2ahp9z2xg6.md diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_sqerp89tc436.json b/.trajectories/completed/2026-05/traj_sqerp89tc436.json similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_sqerp89tc436.json rename to .trajectories/completed/2026-05/traj_sqerp89tc436.json diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_sqerp89tc436.md b/.trajectories/completed/2026-05/traj_sqerp89tc436.md similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_sqerp89tc436.md rename to .trajectories/completed/2026-05/traj_sqerp89tc436.md diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_t5uknesn2fcw.json b/.trajectories/completed/2026-05/traj_t5uknesn2fcw.json similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_t5uknesn2fcw.json rename to .trajectories/completed/2026-05/traj_t5uknesn2fcw.json diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_t5uknesn2fcw.md b/.trajectories/completed/2026-05/traj_t5uknesn2fcw.md similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_t5uknesn2fcw.md rename to .trajectories/completed/2026-05/traj_t5uknesn2fcw.md diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_t6h534vn0bpg.json b/.trajectories/completed/2026-05/traj_t6h534vn0bpg.json similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_t6h534vn0bpg.json rename to .trajectories/completed/2026-05/traj_t6h534vn0bpg.json diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_t6h534vn0bpg.md b/.trajectories/completed/2026-05/traj_t6h534vn0bpg.md similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_t6h534vn0bpg.md rename to .trajectories/completed/2026-05/traj_t6h534vn0bpg.md diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_tavtex0db4b0.json b/.trajectories/completed/2026-05/traj_tavtex0db4b0.json similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_tavtex0db4b0.json rename to .trajectories/completed/2026-05/traj_tavtex0db4b0.json diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_tavtex0db4b0.md b/.trajectories/completed/2026-05/traj_tavtex0db4b0.md similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_tavtex0db4b0.md rename to .trajectories/completed/2026-05/traj_tavtex0db4b0.md diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_tgism98me5na.json b/.trajectories/completed/2026-05/traj_tgism98me5na.json similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_tgism98me5na.json rename to .trajectories/completed/2026-05/traj_tgism98me5na.json diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_tgism98me5na.md b/.trajectories/completed/2026-05/traj_tgism98me5na.md similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_tgism98me5na.md rename to .trajectories/completed/2026-05/traj_tgism98me5na.md diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_u33qn99ijbh4.json b/.trajectories/completed/2026-05/traj_u33qn99ijbh4.json similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_u33qn99ijbh4.json rename to .trajectories/completed/2026-05/traj_u33qn99ijbh4.json diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_u33qn99ijbh4.md b/.trajectories/completed/2026-05/traj_u33qn99ijbh4.md similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_u33qn99ijbh4.md rename to .trajectories/completed/2026-05/traj_u33qn99ijbh4.md diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_u3loicehnwb4.json b/.trajectories/completed/2026-05/traj_u3loicehnwb4.json similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_u3loicehnwb4.json rename to .trajectories/completed/2026-05/traj_u3loicehnwb4.json diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_u3loicehnwb4.md b/.trajectories/completed/2026-05/traj_u3loicehnwb4.md similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_u3loicehnwb4.md rename to .trajectories/completed/2026-05/traj_u3loicehnwb4.md diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_u4ixmbqqm2y1.json b/.trajectories/completed/2026-05/traj_u4ixmbqqm2y1.json similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_u4ixmbqqm2y1.json rename to .trajectories/completed/2026-05/traj_u4ixmbqqm2y1.json diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_u4ixmbqqm2y1.md b/.trajectories/completed/2026-05/traj_u4ixmbqqm2y1.md similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_u4ixmbqqm2y1.md rename to .trajectories/completed/2026-05/traj_u4ixmbqqm2y1.md diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_uf8y40ewrfh0.json b/.trajectories/completed/2026-05/traj_uf8y40ewrfh0.json similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_uf8y40ewrfh0.json rename to .trajectories/completed/2026-05/traj_uf8y40ewrfh0.json diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_uf8y40ewrfh0.md b/.trajectories/completed/2026-05/traj_uf8y40ewrfh0.md similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_uf8y40ewrfh0.md rename to .trajectories/completed/2026-05/traj_uf8y40ewrfh0.md diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_v1wexlfur5zr.json b/.trajectories/completed/2026-05/traj_v1wexlfur5zr.json similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_v1wexlfur5zr.json rename to .trajectories/completed/2026-05/traj_v1wexlfur5zr.json diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_v1wexlfur5zr.md b/.trajectories/completed/2026-05/traj_v1wexlfur5zr.md similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_v1wexlfur5zr.md rename to .trajectories/completed/2026-05/traj_v1wexlfur5zr.md diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_v87cyrs8dke9.json b/.trajectories/completed/2026-05/traj_v87cyrs8dke9.json similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_v87cyrs8dke9.json rename to .trajectories/completed/2026-05/traj_v87cyrs8dke9.json diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_v87cyrs8dke9.md b/.trajectories/completed/2026-05/traj_v87cyrs8dke9.md similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_v87cyrs8dke9.md rename to .trajectories/completed/2026-05/traj_v87cyrs8dke9.md diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_v87cyrs8dke9.trace.json b/.trajectories/completed/2026-05/traj_v87cyrs8dke9.trace.json similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_v87cyrs8dke9.trace.json rename to .trajectories/completed/2026-05/traj_v87cyrs8dke9.trace.json diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_v9x3o92ag682.json b/.trajectories/completed/2026-05/traj_v9x3o92ag682.json similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_v9x3o92ag682.json rename to .trajectories/completed/2026-05/traj_v9x3o92ag682.json diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_v9x3o92ag682.md b/.trajectories/completed/2026-05/traj_v9x3o92ag682.md similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_v9x3o92ag682.md rename to .trajectories/completed/2026-05/traj_v9x3o92ag682.md diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_vfa1jr6otnjn.json b/.trajectories/completed/2026-05/traj_vfa1jr6otnjn.json similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_vfa1jr6otnjn.json rename to .trajectories/completed/2026-05/traj_vfa1jr6otnjn.json diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_vfa1jr6otnjn.md b/.trajectories/completed/2026-05/traj_vfa1jr6otnjn.md similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_vfa1jr6otnjn.md rename to .trajectories/completed/2026-05/traj_vfa1jr6otnjn.md diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_vkozdglobkyg.json b/.trajectories/completed/2026-05/traj_vkozdglobkyg.json similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_vkozdglobkyg.json rename to .trajectories/completed/2026-05/traj_vkozdglobkyg.json diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_vkozdglobkyg.md b/.trajectories/completed/2026-05/traj_vkozdglobkyg.md similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_vkozdglobkyg.md rename to .trajectories/completed/2026-05/traj_vkozdglobkyg.md diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_wbn62q4cq16h.json b/.trajectories/completed/2026-05/traj_wbn62q4cq16h.json similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_wbn62q4cq16h.json rename to .trajectories/completed/2026-05/traj_wbn62q4cq16h.json diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_wbn62q4cq16h.md b/.trajectories/completed/2026-05/traj_wbn62q4cq16h.md similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_wbn62q4cq16h.md rename to .trajectories/completed/2026-05/traj_wbn62q4cq16h.md diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_whd40oxptlhn.json b/.trajectories/completed/2026-05/traj_whd40oxptlhn.json similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_whd40oxptlhn.json rename to .trajectories/completed/2026-05/traj_whd40oxptlhn.json diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_whd40oxptlhn.md b/.trajectories/completed/2026-05/traj_whd40oxptlhn.md similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_whd40oxptlhn.md rename to .trajectories/completed/2026-05/traj_whd40oxptlhn.md diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_whd40oxptlhn.trace.json b/.trajectories/completed/2026-05/traj_whd40oxptlhn.trace.json similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_whd40oxptlhn.trace.json rename to .trajectories/completed/2026-05/traj_whd40oxptlhn.trace.json diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_wx00tjvpptvg.json b/.trajectories/completed/2026-05/traj_wx00tjvpptvg.json similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_wx00tjvpptvg.json rename to .trajectories/completed/2026-05/traj_wx00tjvpptvg.json diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_wx00tjvpptvg.md b/.trajectories/completed/2026-05/traj_wx00tjvpptvg.md similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_wx00tjvpptvg.md rename to .trajectories/completed/2026-05/traj_wx00tjvpptvg.md diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_wzzboitm85ee.json b/.trajectories/completed/2026-05/traj_wzzboitm85ee.json similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_wzzboitm85ee.json rename to .trajectories/completed/2026-05/traj_wzzboitm85ee.json diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_wzzboitm85ee.md b/.trajectories/completed/2026-05/traj_wzzboitm85ee.md similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_wzzboitm85ee.md rename to .trajectories/completed/2026-05/traj_wzzboitm85ee.md diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_x37bhga2j5ph.json b/.trajectories/completed/2026-05/traj_x37bhga2j5ph.json similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_x37bhga2j5ph.json rename to .trajectories/completed/2026-05/traj_x37bhga2j5ph.json diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_x37bhga2j5ph.md b/.trajectories/completed/2026-05/traj_x37bhga2j5ph.md similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_x37bhga2j5ph.md rename to .trajectories/completed/2026-05/traj_x37bhga2j5ph.md diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_ybcrij9wg8m1.json b/.trajectories/completed/2026-05/traj_ybcrij9wg8m1.json similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_ybcrij9wg8m1.json rename to .trajectories/completed/2026-05/traj_ybcrij9wg8m1.json diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_ybcrij9wg8m1.md b/.trajectories/completed/2026-05/traj_ybcrij9wg8m1.md similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_ybcrij9wg8m1.md rename to .trajectories/completed/2026-05/traj_ybcrij9wg8m1.md diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_z171lng2fbbi.json b/.trajectories/completed/2026-05/traj_z171lng2fbbi.json similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_z171lng2fbbi.json rename to .trajectories/completed/2026-05/traj_z171lng2fbbi.json diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_z171lng2fbbi.md b/.trajectories/completed/2026-05/traj_z171lng2fbbi.md similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_z171lng2fbbi.md rename to .trajectories/completed/2026-05/traj_z171lng2fbbi.md diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_zfa6skfr32vy.json b/.trajectories/completed/2026-05/traj_zfa6skfr32vy.json similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_zfa6skfr32vy.json rename to .trajectories/completed/2026-05/traj_zfa6skfr32vy.json diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_zfa6skfr32vy.md b/.trajectories/completed/2026-05/traj_zfa6skfr32vy.md similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_zfa6skfr32vy.md rename to .trajectories/completed/2026-05/traj_zfa6skfr32vy.md diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_zqwco4gl76g3.json b/.trajectories/completed/2026-05/traj_zqwco4gl76g3.json similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_zqwco4gl76g3.json rename to .trajectories/completed/2026-05/traj_zqwco4gl76g3.json diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_zqwco4gl76g3.md b/.trajectories/completed/2026-05/traj_zqwco4gl76g3.md similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_zqwco4gl76g3.md rename to .trajectories/completed/2026-05/traj_zqwco4gl76g3.md diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_zu3252hxzoqh.json b/.trajectories/completed/2026-05/traj_zu3252hxzoqh.json similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_zu3252hxzoqh.json rename to .trajectories/completed/2026-05/traj_zu3252hxzoqh.json diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_zu3252hxzoqh.md b/.trajectories/completed/2026-05/traj_zu3252hxzoqh.md similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_zu3252hxzoqh.md rename to .trajectories/completed/2026-05/traj_zu3252hxzoqh.md diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_zyluvmlqo5j7.json b/.trajectories/completed/2026-05/traj_zyluvmlqo5j7.json similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_zyluvmlqo5j7.json rename to .trajectories/completed/2026-05/traj_zyluvmlqo5j7.json diff --git a/.agentworkforce/trajectories/completed/2026-05/traj_zyluvmlqo5j7.md b/.trajectories/completed/2026-05/traj_zyluvmlqo5j7.md similarity index 100% rename from .agentworkforce/trajectories/completed/2026-05/traj_zyluvmlqo5j7.md rename to .trajectories/completed/2026-05/traj_zyluvmlqo5j7.md diff --git a/.agentworkforce/trajectories/completed/traj_1775914296101_a4397efe.json b/.trajectories/completed/traj_1775914296101_a4397efe.json similarity index 100% rename from .agentworkforce/trajectories/completed/traj_1775914296101_a4397efe.json rename to .trajectories/completed/traj_1775914296101_a4397efe.json diff --git a/.agentworkforce/trajectories/completed/traj_1776024661304_cfc829b9.json b/.trajectories/completed/traj_1776024661304_cfc829b9.json similarity index 100% rename from .agentworkforce/trajectories/completed/traj_1776024661304_cfc829b9.json rename to .trajectories/completed/traj_1776024661304_cfc829b9.json diff --git a/.agentworkforce/trajectories/completed/traj_1776105620545_9dcebb3d.json b/.trajectories/completed/traj_1776105620545_9dcebb3d.json similarity index 100% rename from .agentworkforce/trajectories/completed/traj_1776105620545_9dcebb3d.json rename to .trajectories/completed/traj_1776105620545_9dcebb3d.json diff --git a/.agentworkforce/trajectories/completed/traj_1778873052429_03a4dacb.json b/.trajectories/completed/traj_1778873052429_03a4dacb.json similarity index 100% rename from .agentworkforce/trajectories/completed/traj_1778873052429_03a4dacb.json rename to .trajectories/completed/traj_1778873052429_03a4dacb.json diff --git a/.agentworkforce/trajectories/completed/traj_1778873197540_01102ade.json b/.trajectories/completed/traj_1778873197540_01102ade.json similarity index 100% rename from .agentworkforce/trajectories/completed/traj_1778873197540_01102ade.json rename to .trajectories/completed/traj_1778873197540_01102ade.json diff --git a/.agentworkforce/trajectories/completed/traj_1778873199489_f2ce4060.json b/.trajectories/completed/traj_1778873199489_f2ce4060.json similarity index 100% rename from .agentworkforce/trajectories/completed/traj_1778873199489_f2ce4060.json rename to .trajectories/completed/traj_1778873199489_f2ce4060.json diff --git a/.agentworkforce/trajectories/completed/traj_1778873201502_0dacf7c5.json b/.trajectories/completed/traj_1778873201502_0dacf7c5.json similarity index 100% rename from .agentworkforce/trajectories/completed/traj_1778873201502_0dacf7c5.json rename to .trajectories/completed/traj_1778873201502_0dacf7c5.json diff --git a/.agentworkforce/trajectories/completed/traj_1778873203502_4c225b7e.json b/.trajectories/completed/traj_1778873203502_4c225b7e.json similarity index 100% rename from .agentworkforce/trajectories/completed/traj_1778873203502_4c225b7e.json rename to .trajectories/completed/traj_1778873203502_4c225b7e.json diff --git a/.agentworkforce/trajectories/completed/traj_1778873205470_a4e5f0cb.json b/.trajectories/completed/traj_1778873205470_a4e5f0cb.json similarity index 100% rename from .agentworkforce/trajectories/completed/traj_1778873205470_a4e5f0cb.json rename to .trajectories/completed/traj_1778873205470_a4e5f0cb.json diff --git a/.agentworkforce/trajectories/completed/traj_1778873207471_b7def991.json b/.trajectories/completed/traj_1778873207471_b7def991.json similarity index 100% rename from .agentworkforce/trajectories/completed/traj_1778873207471_b7def991.json rename to .trajectories/completed/traj_1778873207471_b7def991.json diff --git a/.agentworkforce/trajectories/completed/traj_1778873209642_c70e32ab.json b/.trajectories/completed/traj_1778873209642_c70e32ab.json similarity index 100% rename from .agentworkforce/trajectories/completed/traj_1778873209642_c70e32ab.json rename to .trajectories/completed/traj_1778873209642_c70e32ab.json diff --git a/.agentworkforce/trajectories/completed/traj_1778873211616_6db3b2cd.json b/.trajectories/completed/traj_1778873211616_6db3b2cd.json similarity index 100% rename from .agentworkforce/trajectories/completed/traj_1778873211616_6db3b2cd.json rename to .trajectories/completed/traj_1778873211616_6db3b2cd.json diff --git a/.agentworkforce/trajectories/completed/traj_1778874205797_81e92307.json b/.trajectories/completed/traj_1778874205797_81e92307.json similarity index 100% rename from .agentworkforce/trajectories/completed/traj_1778874205797_81e92307.json rename to .trajectories/completed/traj_1778874205797_81e92307.json diff --git a/.agentworkforce/trajectories/completed/traj_1778874216773_c6b12ab2.json b/.trajectories/completed/traj_1778874216773_c6b12ab2.json similarity index 100% rename from .agentworkforce/trajectories/completed/traj_1778874216773_c6b12ab2.json rename to .trajectories/completed/traj_1778874216773_c6b12ab2.json diff --git a/.agentworkforce/trajectories/completed/traj_1778874218579_a0225559.json b/.trajectories/completed/traj_1778874218579_a0225559.json similarity index 100% rename from .agentworkforce/trajectories/completed/traj_1778874218579_a0225559.json rename to .trajectories/completed/traj_1778874218579_a0225559.json diff --git a/.agentworkforce/trajectories/completed/traj_1778874224855_9c722c4b.json b/.trajectories/completed/traj_1778874224855_9c722c4b.json similarity index 100% rename from .agentworkforce/trajectories/completed/traj_1778874224855_9c722c4b.json rename to .trajectories/completed/traj_1778874224855_9c722c4b.json diff --git a/.agentworkforce/trajectories/completed/traj_1778874226983_3367d527.json b/.trajectories/completed/traj_1778874226983_3367d527.json similarity index 100% rename from .agentworkforce/trajectories/completed/traj_1778874226983_3367d527.json rename to .trajectories/completed/traj_1778874226983_3367d527.json diff --git a/.agentworkforce/trajectories/completed/traj_1778874229373_9cce9465.json b/.trajectories/completed/traj_1778874229373_9cce9465.json similarity index 100% rename from .agentworkforce/trajectories/completed/traj_1778874229373_9cce9465.json rename to .trajectories/completed/traj_1778874229373_9cce9465.json diff --git a/.agentworkforce/trajectories/completed/traj_1778874240339_51b823cd.json b/.trajectories/completed/traj_1778874240339_51b823cd.json similarity index 100% rename from .agentworkforce/trajectories/completed/traj_1778874240339_51b823cd.json rename to .trajectories/completed/traj_1778874240339_51b823cd.json diff --git a/.agentworkforce/trajectories/completed/traj_1778874241076_caa675a9.json b/.trajectories/completed/traj_1778874241076_caa675a9.json similarity index 100% rename from .agentworkforce/trajectories/completed/traj_1778874241076_caa675a9.json rename to .trajectories/completed/traj_1778874241076_caa675a9.json diff --git a/.agentworkforce/trajectories/completed/traj_1778874248966_e29c4c54.json b/.trajectories/completed/traj_1778874248966_e29c4c54.json similarity index 100% rename from .agentworkforce/trajectories/completed/traj_1778874248966_e29c4c54.json rename to .trajectories/completed/traj_1778874248966_e29c4c54.json diff --git a/.agentworkforce/trajectories/completed/traj_1778874249983_12a98df3.json b/.trajectories/completed/traj_1778874249983_12a98df3.json similarity index 100% rename from .agentworkforce/trajectories/completed/traj_1778874249983_12a98df3.json rename to .trajectories/completed/traj_1778874249983_12a98df3.json diff --git a/.agentworkforce/trajectories/completed/traj_1778874258229_0bdc53d8.json b/.trajectories/completed/traj_1778874258229_0bdc53d8.json similarity index 100% rename from .agentworkforce/trajectories/completed/traj_1778874258229_0bdc53d8.json rename to .trajectories/completed/traj_1778874258229_0bdc53d8.json diff --git a/.agentworkforce/trajectories/completed/traj_1778874261453_55f49624.json b/.trajectories/completed/traj_1778874261453_55f49624.json similarity index 100% rename from .agentworkforce/trajectories/completed/traj_1778874261453_55f49624.json rename to .trajectories/completed/traj_1778874261453_55f49624.json diff --git a/.agentworkforce/trajectories/completed/traj_1778874261608_48fb9bf5.json b/.trajectories/completed/traj_1778874261608_48fb9bf5.json similarity index 100% rename from .agentworkforce/trajectories/completed/traj_1778874261608_48fb9bf5.json rename to .trajectories/completed/traj_1778874261608_48fb9bf5.json diff --git a/.agentworkforce/trajectories/completed/traj_1778874269139_d7d7485a.json b/.trajectories/completed/traj_1778874269139_d7d7485a.json similarity index 100% rename from .agentworkforce/trajectories/completed/traj_1778874269139_d7d7485a.json rename to .trajectories/completed/traj_1778874269139_d7d7485a.json diff --git a/.agentworkforce/trajectories/completed/traj_1778874274412_70843e0e.json b/.trajectories/completed/traj_1778874274412_70843e0e.json similarity index 100% rename from .agentworkforce/trajectories/completed/traj_1778874274412_70843e0e.json rename to .trajectories/completed/traj_1778874274412_70843e0e.json diff --git a/.agentworkforce/trajectories/completed/traj_1778874274581_71efa470.json b/.trajectories/completed/traj_1778874274581_71efa470.json similarity index 100% rename from .agentworkforce/trajectories/completed/traj_1778874274581_71efa470.json rename to .trajectories/completed/traj_1778874274581_71efa470.json diff --git a/.agentworkforce/trajectories/completed/traj_1778874282200_39ad11db.json b/.trajectories/completed/traj_1778874282200_39ad11db.json similarity index 100% rename from .agentworkforce/trajectories/completed/traj_1778874282200_39ad11db.json rename to .trajectories/completed/traj_1778874282200_39ad11db.json diff --git a/.agentworkforce/trajectories/completed/traj_1778874283570_ce3585b8.json b/.trajectories/completed/traj_1778874283570_ce3585b8.json similarity index 100% rename from .agentworkforce/trajectories/completed/traj_1778874283570_ce3585b8.json rename to .trajectories/completed/traj_1778874283570_ce3585b8.json diff --git a/.agentworkforce/trajectories/completed/traj_1778874289674_e3f868c8.json b/.trajectories/completed/traj_1778874289674_e3f868c8.json similarity index 100% rename from .agentworkforce/trajectories/completed/traj_1778874289674_e3f868c8.json rename to .trajectories/completed/traj_1778874289674_e3f868c8.json diff --git a/.agentworkforce/trajectories/completed/traj_1778874291950_0b1b5c1f.json b/.trajectories/completed/traj_1778874291950_0b1b5c1f.json similarity index 100% rename from .agentworkforce/trajectories/completed/traj_1778874291950_0b1b5c1f.json rename to .trajectories/completed/traj_1778874291950_0b1b5c1f.json diff --git a/.agentworkforce/trajectories/completed/traj_1778874295927_4083d181.json b/.trajectories/completed/traj_1778874295927_4083d181.json similarity index 100% rename from .agentworkforce/trajectories/completed/traj_1778874295927_4083d181.json rename to .trajectories/completed/traj_1778874295927_4083d181.json diff --git a/.agentworkforce/trajectories/completed/traj_1778874296362_bdf727ff.json b/.trajectories/completed/traj_1778874296362_bdf727ff.json similarity index 100% rename from .agentworkforce/trajectories/completed/traj_1778874296362_bdf727ff.json rename to .trajectories/completed/traj_1778874296362_bdf727ff.json diff --git a/.trajectories/index.json b/.trajectories/index.json new file mode 100644 index 000000000..54c4575ca --- /dev/null +++ b/.trajectories/index.json @@ -0,0 +1,1245 @@ +{ + "version": 1, + "lastUpdated": "2026-05-26T11:26:52.761Z", + "trajectories": { + "traj_05xg7j388bc4": { + "title": "Add browser workflow step integration", + "status": "completed", + "startedAt": "2026-04-10T14:56:33.229Z", + "completedAt": "2026-04-10T15:05:14.660Z", + "path": ".trajectories/completed/2026-04/traj_05xg7j388bc4.json" + }, + "traj_0t92gxaz6igh": { + "title": "Move docs sidebar into the mobile hamburger menu", + "status": "completed", + "startedAt": "2026-04-10T16:29:40.674Z", + "completedAt": "2026-04-10T16:32:14.544Z", + "path": ".trajectories/completed/2026-04/traj_0t92gxaz6igh.json" + }, + "traj_1776105620545_9dcebb3d": { + "title": "fix-inbox-agent-flag-workflow", + "status": "completed", + "startedAt": "2026-04-13T18:40:20.545Z", + "completedAt": "2026-04-13T18:41:52.831Z", + "path": ".trajectories/completed/2026-04/traj_1776105620545_9dcebb3d.json" + }, + "traj_1776105988184_29f1270c": { + "title": "fix-inbox-agent-flag-workflow", + "status": "completed", + "startedAt": "2026-04-13T18:46:28.184Z", + "completedAt": "2026-04-13T20:23:54.308Z", + "path": ".trajectories/completed/2026-04/traj_1776105988184_29f1270c.json" + }, + "traj_222ha5671idc": { + "title": "validate-cloud-connect-e2e-workflow", + "status": "completed", + "startedAt": "2026-04-15T21:32:51.980Z", + "completedAt": "2026-04-15T21:45:41.024Z", + "path": ".trajectories/completed/2026-04/traj_222ha5671idc.json" + }, + "traj_3b3p1z4y7qlo": { + "title": "add-mcp-args-subcommand-workflow", + "status": "completed", + "startedAt": "2026-04-20T13:16:22.009Z", + "completedAt": "2026-04-20T13:26:35.142Z", + "path": ".trajectories/completed/2026-04/traj_3b3p1z4y7qlo.json" + }, + "traj_4zqhfqw7g28l": { + "title": "Investigate GitHub Actions failure for run 24255758219 job 70826792063", + "status": "completed", + "startedAt": "2026-04-10T17:48:33.502Z", + "completedAt": "2026-04-10T17:49:14.485Z", + "path": ".trajectories/completed/2026-04/traj_4zqhfqw7g28l.json" + }, + "traj_530xmbfeljyb": { + "title": "Implement GitHub primitive adapter base layer", + "status": "completed", + "startedAt": "2026-04-10T15:16:25.682Z", + "completedAt": "2026-04-10T15:25:16.937Z", + "path": ".trajectories/completed/2026-04/traj_530xmbfeljyb.json" + }, + "traj_703m7sqyq89t": { + "title": "Fix production docs loader using build-machine absolute MDX paths", + "status": "completed", + "startedAt": "2026-04-10T16:33:10.601Z", + "completedAt": "2026-04-10T16:35:33.660Z", + "path": ".trajectories/completed/2026-04/traj_703m7sqyq89t.json" + }, + "traj_8oh4r5km5eic": { + "title": "Implement GitHub primitive actions", + "status": "completed", + "startedAt": "2026-04-10T15:26:11.355Z", + "completedAt": "2026-04-10T15:33:35.150Z", + "path": ".trajectories/completed/2026-04/traj_8oh4r5km5eic.json" + }, + "traj_9tt55is74dq5": { + "title": "Pin TypeScript build resolution for acp-bridge, memory, trajectory, and cloud", + "status": "completed", + "startedAt": "2026-04-11T13:34:46.304Z", + "completedAt": "2026-04-11T13:35:22.677Z", + "path": ".trajectories/completed/2026-04/traj_9tt55is74dq5.json" + }, + "traj_abjovknvcijv": { + "title": "Scope CI so web-only changes do not run unrelated relay and SDK tests", + "status": "completed", + "startedAt": "2026-04-10T16:08:30.070Z", + "completedAt": "2026-04-10T16:11:08.673Z", + "path": ".trajectories/completed/2026-04/traj_abjovknvcijv.json" + }, + "traj_avmkyoo2s3rt": { + "title": "Implement Browser primitive client", + "status": "completed", + "startedAt": "2026-04-10T14:42:17.242Z", + "completedAt": "2026-04-10T14:55:45.196Z", + "path": ".trajectories/completed/2026-04/traj_avmkyoo2s3rt.json" + }, + "traj_d48czxmgx4ac": { + "title": "Shift dark-mode footer from black to Relay blue", + "status": "completed", + "startedAt": "2026-04-10T16:12:27.477Z", + "completedAt": "2026-04-10T16:13:14.348Z", + "path": ".trajectories/completed/2026-04/traj_d48czxmgx4ac.json" + }, + "traj_dw8ihhdb8ip7": { + "title": "fix-dm-history-workflow", + "status": "abandoned", + "startedAt": "2026-04-13T19:51:57.984Z", + "completedAt": "2026-04-13T19:57:27.195Z", + "path": ".trajectories/completed/2026-04/traj_dw8ihhdb8ip7.json" + }, + "traj_e5i62wdjx0jd": { + "title": "Plan autofix finding groups", + "status": "completed", + "startedAt": "2026-04-13T09:40:42.044Z", + "completedAt": "2026-04-13T09:41:07.789Z", + "path": ".trajectories/completed/2026-04/traj_e5i62wdjx0jd.json" + }, + "traj_g3muawdq6bsb": { + "title": "Invert dark footer gradient so the lighter blue is at the top", + "status": "completed", + "startedAt": "2026-04-10T16:13:19.744Z", + "completedAt": "2026-04-10T16:13:43.289Z", + "path": ".trajectories/completed/2026-04/traj_g3muawdq6bsb.json" + }, + "traj_mk0t0cgn4ytq": { + "title": "Merge origin/main into better-nav and resolve trajectory conflicts", + "status": "completed", + "startedAt": "2026-04-10T15:10:03.877Z", + "completedAt": "2026-04-10T15:10:29.410Z", + "path": ".trajectories/completed/2026-04/traj_mk0t0cgn4ytq.json" + }, + "traj_o8kgzhfu6jth": { + "title": "Add /cloud link to footer", + "status": "completed", + "startedAt": "2026-04-10T16:07:15.131Z", + "completedAt": "2026-04-10T16:07:42.930Z", + "path": ".trajectories/completed/2026-04/traj_o8kgzhfu6jth.json" + }, + "traj_qb54w47qwod6": { + "title": "fix-history-from-workflow", + "status": "completed", + "startedAt": "2026-04-13T20:16:10.459Z", + "completedAt": "2026-04-13T20:25:09.219Z", + "path": ".trajectories/completed/2026-04/traj_qb54w47qwod6.json" + }, + "traj_rs2bt3x0fqba": { + "title": "Compare failed web deploy to prior deploys and identify no-downtime fix", + "status": "completed", + "startedAt": "2026-04-10T17:50:43.088Z", + "completedAt": "2026-04-10T18:00:44.095Z", + "path": ".trajectories/completed/2026-04/traj_rs2bt3x0fqba.json" + }, + "traj_tjadoebpscps": { + "title": "fix-dm-history-workflow", + "status": "completed", + "startedAt": "2026-04-13T20:02:27.719Z", + "completedAt": "2026-04-13T20:02:35.662Z", + "path": ".trajectories/completed/2026-04/traj_tjadoebpscps.json" + }, + "traj_tv1x9pamkqad": { + "title": "Add GitHub primitive workflow step integration", + "status": "completed", + "startedAt": "2026-04-10T15:34:36.611Z", + "completedAt": "2026-04-10T15:42:17.590Z", + "path": ".trajectories/completed/2026-04/traj_tv1x9pamkqad.json" + }, + "traj_ui5omrgz819d": { + "title": "cloud-run-start-from-workflow", + "status": "completed", + "startedAt": "2026-04-27T20:00:33.269Z", + "completedAt": "2026-04-27T20:08:46.379Z", + "path": ".trajectories/completed/2026-04/traj_ui5omrgz819d.json" + }, + "traj_w0xpsaoxuiyw": { + "title": "Pin TypeScript compiler version and build invocation in selected packages", + "status": "completed", + "startedAt": "2026-04-11T13:35:52.600Z", + "completedAt": "2026-04-11T13:36:48.341Z", + "path": ".trajectories/completed/2026-04/traj_w0xpsaoxuiyw.json" + }, + "traj_0e8i20oitwvz": { + "title": "Final fresh-eyes review Codex GPT-5.5 fix", + "status": "completed", + "startedAt": "2026-05-15T12:46:11.342Z", + "completedAt": "2026-05-15T12:46:11.500Z", + "path": ".trajectories/completed/2026-05/traj_0e8i20oitwvz.json" + }, + "traj_0o6gb2wvk59t": { + "title": "Fresh end-to-end validation for headless readiness", + "status": "completed", + "startedAt": "2026-05-15T10:55:49.188Z", + "completedAt": "2026-05-15T11:11:52.324Z", + "path": ".trajectories/completed/2026-05/traj_0o6gb2wvk59t.json" + }, + "traj_0z98tkaigaxg": { + "title": "ricky-child-update-issue-860-transcript-test-workflow", + "status": "completed", + "startedAt": "2026-05-15T21:06:58.558Z", + "completedAt": "2026-05-15T21:35:56.724Z", + "path": ".trajectories/completed/2026-05/traj_0z98tkaigaxg.json" + }, + "traj_1775914133873_35667beb": { + "title": "fix-sdk-build-resolution-workflow", + "status": "completed", + "startedAt": "2026-04-11T13:28:53.873Z", + "completedAt": "2026-05-08T13:33:48.161Z", + "path": ".trajectories/completed/2026-05/traj_1775914133873_35667beb.json" + }, + "traj_1776073106646_1839be2d": { + "title": "autofix-swarm-Agentworkforce-relay-workflow", + "status": "completed", + "startedAt": "2026-04-13T09:38:26.646Z", + "completedAt": "2026-05-08T13:33:45.944Z", + "path": ".trajectories/completed/2026-05/traj_1776073106646_1839be2d.json" + }, + "traj_1776113772922_bc92f121": { + "title": "autofix-swarm-Agentworkforce-relay-workflow", + "status": "completed", + "startedAt": "2026-04-13T20:56:12.922Z", + "completedAt": "2026-05-08T13:33:43.489Z", + "path": ".trajectories/completed/2026-05/traj_1776113772922_bc92f121.json" + }, + "traj_1778873209642_c70e32ab": { + "title": "ricky-child-update-2-workflow", + "status": "completed", + "startedAt": "2026-05-15T19:26:49.642Z", + "completedAt": "2026-05-15T19:36:18.257Z", + "path": ".trajectories/completed/2026-05/traj_1778873209642_c70e32ab.json" + }, + "traj_1778873211616_6db3b2cd": { + "title": "ricky-child-update-docs-sync-workflow", + "status": "completed", + "startedAt": "2026-05-15T19:26:51.616Z", + "completedAt": "2026-05-15T19:35:07.059Z", + "path": ".trajectories/completed/2026-05/traj_1778873211616_6db3b2cd.json" + }, + "traj_1rrpe2r7fyem": { + "title": "Use streaming PTY input in CLI drive", + "status": "completed", + "startedAt": "2026-05-20T07:20:33.009Z", + "completedAt": "2026-05-20T07:26:17.567Z", + "path": ".trajectories/completed/2026-05/traj_1rrpe2r7fyem.json" + }, + "traj_2gpglosdsq7s": { + "title": "Fix broker session read paths and agent listing errors", + "status": "completed", + "startedAt": "2026-05-19T12:37:18.367Z", + "completedAt": "2026-05-19T12:48:50.116Z", + "path": ".trajectories/completed/2026-05/traj_2gpglosdsq7s.json" + }, + "traj_2tqxnib25omk": { + "title": "Add workflow reliability contract coverage", + "status": "completed", + "startedAt": "2026-05-08T15:27:50.875Z", + "completedAt": "2026-05-08T15:28:02.639Z", + "path": ".trajectories/completed/2026-05/traj_2tqxnib25omk.json" + }, + "traj_2yicjxgajt0a": { + "title": "Review GPT-5.5 hardening", + "status": "completed", + "startedAt": "2026-05-15T10:54:19.300Z", + "completedAt": "2026-05-15T10:54:19.476Z", + "path": ".trajectories/completed/2026-05/traj_2yicjxgajt0a.json" + }, + "traj_34b1u84b19gz": { + "title": "Address PR 827 review feedback", + "status": "completed", + "startedAt": "2026-05-08T18:29:34.717Z", + "completedAt": "2026-05-08T18:33:55.607Z", + "path": ".trajectories/completed/2026-05/traj_34b1u84b19gz.json" + }, + "traj_3gjtcykvybt5": { + "title": "Fix PR CI failures", + "status": "completed", + "startedAt": "2026-05-15T11:24:06.054Z", + "completedAt": "2026-05-15T11:25:49.087Z", + "path": ".trajectories/completed/2026-05/traj_3gjtcykvybt5.json" + }, + "traj_47akjihewlow": { + "title": "Further split broker runtime module for issue 875", + "status": "completed", + "startedAt": "2026-05-19T01:28:35.746Z", + "completedAt": "2026-05-19T01:38:29.105Z", + "path": ".trajectories/completed/2026-05/traj_47akjihewlow.json" + }, + "traj_4chzkm724ufo": { + "title": "Fix headless orchestrator worktree CLI E2E issues", + "status": "completed", + "startedAt": "2026-05-15T11:44:28.338Z", + "completedAt": "2026-05-15T11:51:05.319Z", + "path": ".trajectories/completed/2026-05/traj_4chzkm724ufo.json" + }, + "traj_4t07itef99ug": { + "title": "Implement relay CLI bootstrap commands for proactive runtime M1", + "status": "completed", + "startedAt": "2026-05-11T21:47:37.805Z", + "completedAt": "2026-05-11T21:49:49.859Z", + "path": ".trajectories/completed/2026-05/traj_4t07itef99ug.json" + }, + "traj_4vucir4qvqa2": { + "title": "Harden headless broker readiness semantics", + "status": "completed", + "startedAt": "2026-05-15T09:46:07.617Z", + "completedAt": "2026-05-15T09:59:00.460Z", + "path": ".trajectories/completed/2026-05/traj_4vucir4qvqa2.json" + }, + "traj_5k0jtc1g5l33": { + "title": "Resolve PR 932 conflicts and review comments", + "status": "completed", + "startedAt": "2026-05-22T19:13:09.359Z", + "completedAt": "2026-05-22T19:13:16.971Z", + "path": ".trajectories/completed/2026-05/traj_5k0jtc1g5l33.json" + }, + "traj_5nzj6v56id4z": { + "title": "Fix PR914 review comments", + "status": "completed", + "startedAt": "2026-05-19T13:20:42.407Z", + "completedAt": "2026-05-19T13:26:28.697Z", + "path": ".trajectories/completed/2026-05/traj_5nzj6v56id4z.json" + }, + "traj_5q8i0iz4klpo": { + "title": "ricky-child-update-2-workflow", + "status": "completed", + "startedAt": "2026-05-15T21:07:02.452Z", + "completedAt": "2026-05-15T21:36:03.688Z", + "path": ".trajectories/completed/2026-05/traj_5q8i0iz4klpo.json" + }, + "traj_5qbla7w4kzoi": { + "title": "Fix issue 877", + "status": "completed", + "startedAt": "2026-05-19T03:40:40.798Z", + "completedAt": "2026-05-19T03:54:06.889Z", + "path": ".trajectories/completed/2026-05/traj_5qbla7w4kzoi.json" + }, + "traj_60qc24ufr96g": { + "title": "Expand workflow reliability contract matrix", + "status": "completed", + "startedAt": "2026-05-08T15:40:11.699Z", + "completedAt": "2026-05-08T15:40:22.521Z", + "path": ".trajectories/completed/2026-05/traj_60qc24ufr96g.json" + }, + "traj_6sjeohtm3php": { + "title": "Address broker headless reliability review findings", + "status": "completed", + "startedAt": "2026-05-15T09:30:56.316Z", + "completedAt": "2026-05-15T09:32:47.870Z", + "path": ".trajectories/completed/2026-05/traj_6sjeohtm3php.json" + }, + "traj_6ujzpx82gqs9": { + "title": "ricky-slack-primitive-implementation-workflow-status-r-workflow", + "status": "completed", + "startedAt": "2026-05-08T16:06:54.844Z", + "completedAt": "2026-05-08T16:18:16.119Z", + "path": ".trajectories/completed/2026-05/traj_6ujzpx82gqs9.json" + }, + "traj_78ytpicts778": { + "title": "Address PR 932 result callback review findings", + "status": "completed", + "startedAt": "2026-05-22T15:59:25.187Z", + "completedAt": "2026-05-22T16:05:12.320Z", + "path": ".trajectories/completed/2026-05/traj_78ytpicts778.json" + }, + "traj_7uznwzoxbao6": { + "title": "Fix standalone detached headless startup", + "status": "completed", + "startedAt": "2026-05-15T10:18:46.273Z", + "completedAt": "2026-05-15T10:25:00.598Z", + "path": ".trajectories/completed/2026-05/traj_7uznwzoxbao6.json" + }, + "traj_7zu7et53ph3l": { + "title": "Harden Codex GPT-5.5 local CLI compatibility", + "status": "completed", + "startedAt": "2026-05-15T10:35:25.212Z", + "completedAt": "2026-05-15T10:40:53.355Z", + "path": ".trajectories/completed/2026-05/traj_7zu7et53ph3l.json" + }, + "traj_81kobstnzzwk": { + "title": "Orchestrate team review cycle for #892 #893 #894 #895", + "status": "completed", + "startedAt": "2026-05-19T08:16:32.762Z", + "completedAt": "2026-05-19T08:37:32.966Z", + "path": ".trajectories/completed/2026-05/traj_81kobstnzzwk.json" + }, + "traj_8ljgydz61do5": { + "title": "ricky-child-update-messaging-2-workflow", + "status": "completed", + "startedAt": "2026-05-15T21:06:54.217Z", + "completedAt": "2026-05-15T21:41:56.478Z", + "path": ".trajectories/completed/2026-05/traj_8ljgydz61do5.json" + }, + "traj_90jmd9z27oap": { + "title": "Resolve PR 948 merge conflicts", + "status": "completed", + "startedAt": "2026-05-22T19:49:08.797Z", + "completedAt": "2026-05-22T20:45:01.262Z", + "path": ".trajectories/completed/2026-05/traj_90jmd9z27oap.json" + }, + "traj_947wzpddsg9j": { + "title": "Implement relay CLI bootstrap commands for proactive runtime M1", + "status": "completed", + "startedAt": "2026-05-11T23:11:57.326Z", + "completedAt": "2026-05-11T23:14:23.136Z", + "path": ".trajectories/completed/2026-05/traj_947wzpddsg9j.json" + }, + "traj_9fdv7hxm0b60": { + "title": "Strict standalone smoke follow-up", + "status": "completed", + "startedAt": "2026-05-15T10:37:17.693Z", + "completedAt": "2026-05-15T10:43:11.587Z", + "path": ".trajectories/completed/2026-05/traj_9fdv7hxm0b60.json" + }, + "traj_9gq96irkj00s": { + "title": "Update relay to use published relaycast Rust reclaim fix", + "status": "completed", + "startedAt": "2026-05-10T18:45:02.118Z", + "completedAt": "2026-05-10T18:48:11.532Z", + "path": ".trajectories/completed/2026-05/traj_9gq96irkj00s.json" + }, + "traj_aw7stgf4qau0": { + "title": "Fix publish smoke cloud tarball dependency", + "status": "completed", + "startedAt": "2026-05-11T07:49:42.778Z", + "completedAt": "2026-05-11T07:50:37.848Z", + "path": ".trajectories/completed/2026-05/traj_aw7stgf4qau0.json" + }, + "traj_bdrlknyl8twj": { + "title": "Add workflow reliability defaults and E2E matrix", + "status": "completed", + "startedAt": "2026-05-08T17:54:45.069Z", + "completedAt": "2026-05-08T18:05:37.305Z", + "path": ".trajectories/completed/2026-05/traj_bdrlknyl8twj.json" + }, + "traj_bz1a1o15p7px": { + "title": "Fix PR 949 CI failure", + "status": "completed", + "startedAt": "2026-05-22T16:56:55.021Z", + "completedAt": "2026-05-22T16:57:55.372Z", + "path": ".trajectories/completed/2026-05/traj_bz1a1o15p7px.json" + }, + "traj_cbmwd07phhm2": { + "title": "Implement #869 snapshot module + dump-pty command", + "status": "completed", + "startedAt": "2026-05-17T14:19:10.603Z", + "completedAt": "2026-05-17T14:33:32.293Z", + "path": ".trajectories/completed/2026-05/traj_cbmwd07phhm2.json" + }, + "traj_ceo5q9bh2od3": { + "title": "Add structured spawned-agent results", + "status": "completed", + "startedAt": "2026-05-20T21:24:17.929Z", + "completedAt": "2026-05-20T21:43:51.936Z", + "path": ".trajectories/completed/2026-05/traj_ceo5q9bh2od3.json" + }, + "traj_d89s38ddu7cj": { + "title": "Review Codex GPT-5.5 spawn fix", + "status": "completed", + "startedAt": "2026-05-15T12:25:39.946Z", + "completedAt": "2026-05-15T12:25:40.708Z", + "path": ".trajectories/completed/2026-05/traj_d89s38ddu7cj.json" + }, + "traj_dbsnr453nxjw": { + "title": "Confirm and remove unused package dependencies", + "status": "completed", + "startedAt": "2026-05-22T16:01:11.967Z", + "completedAt": "2026-05-22T16:12:01.466Z", + "path": ".trajectories/completed/2026-05/traj_dbsnr453nxjw.json" + }, + "traj_dcl9hgoiuac5": { + "title": "Verify --broker-name override for agent-relay up", + "status": "completed", + "startedAt": "2026-05-21T18:56:55.532Z", + "completedAt": "2026-05-21T19:00:06.831Z", + "path": ".trajectories/completed/2026-05/traj_dcl9hgoiuac5.json" + }, + "traj_dpgn0am1jq1c": { + "title": "Implement M1 relay CLI bootstrap commands", + "status": "completed", + "startedAt": "2026-05-11T18:43:20.429Z", + "completedAt": "2026-05-11T18:43:20.733Z", + "path": ".trajectories/completed/2026-05/traj_dpgn0am1jq1c.json" + }, + "traj_e1b7ww3un1u3": { + "title": "Harden agents logs raw and follow output", + "status": "completed", + "startedAt": "2026-05-19T10:59:00.118Z", + "completedAt": "2026-05-19T11:04:44.466Z", + "path": ".trajectories/completed/2026-05/traj_e1b7ww3un1u3.json" + }, + "traj_elx0fcwgs37x": { + "title": "ricky-child-update-messaging-workflow", + "status": "completed", + "startedAt": "2026-05-15T21:06:50.250Z", + "completedAt": "2026-05-15T21:46:46.167Z", + "path": ".trajectories/completed/2026-05/traj_elx0fcwgs37x.json" + }, + "traj_erzd7j9nto9r": { + "title": "Strict review and PR prep for headless broker readiness", + "status": "completed", + "startedAt": "2026-05-15T10:02:10.164Z", + "completedAt": "2026-05-15T10:06:38.127Z", + "path": ".trajectories/completed/2026-05/traj_erzd7j9nto9r.json" + }, + "traj_f1iac9ngymlj": { + "title": "Fix reliability review findings 892-895", + "status": "completed", + "startedAt": "2026-05-19T09:52:54.932Z", + "completedAt": "2026-05-19T10:01:19.068Z", + "path": ".trajectories/completed/2026-05/traj_f1iac9ngymlj.json" + }, + "traj_f3arvbmmlomn": { + "title": "Address PR feedback for headless broker reliability", + "status": "completed", + "startedAt": "2026-05-15T12:09:02.122Z", + "completedAt": "2026-05-15T12:15:11.435Z", + "path": ".trajectories/completed/2026-05/traj_f3arvbmmlomn.json" + }, + "traj_f9wxa8ujeg78": { + "title": "Refactor broker main for issue 875", + "status": "completed", + "startedAt": "2026-05-19T00:54:40.328Z", + "completedAt": "2026-05-19T00:55:57.506Z", + "path": ".trajectories/completed/2026-05/traj_f9wxa8ujeg78.json" + }, + "traj_fh8oosbijpwc": { + "title": "Track A: relaycast subscribe + @self DM routing", + "status": "completed", + "startedAt": "2026-05-12T06:28:56.427Z", + "completedAt": "2026-05-12T11:21:33.352Z", + "path": ".trajectories/completed/2026-05/traj_fh8oosbijpwc.json" + }, + "traj_gh05rj5gwsap": { + "title": "Bump relaycast Rust SDK in relay", + "status": "completed", + "startedAt": "2026-05-14T16:41:17.430Z", + "completedAt": "2026-05-14T16:42:32.485Z", + "path": ".trajectories/completed/2026-05/traj_gh05rj5gwsap.json" + }, + "traj_gnqvtoxtc8dy": { + "title": "Fix broker half-start recovery", + "status": "completed", + "startedAt": "2026-05-19T12:34:36.057Z", + "completedAt": "2026-05-19T12:47:18.115Z", + "path": ".trajectories/completed/2026-05/traj_gnqvtoxtc8dy.json" + }, + "traj_hfkww5z7trxn": { + "title": "Fresh comprehensive review of PR 856", + "status": "completed", + "startedAt": "2026-05-15T12:56:14.439Z", + "completedAt": "2026-05-15T13:00:15.366Z", + "path": ".trajectories/completed/2026-05/traj_hfkww5z7trxn.json" + }, + "traj_hrsndfzk0qay": { + "title": "Tighten Codex 5.5 fallback coverage", + "status": "completed", + "startedAt": "2026-05-15T10:57:41.681Z", + "completedAt": "2026-05-15T10:57:41.827Z", + "path": ".trajectories/completed/2026-05/traj_hrsndfzk0qay.json" + }, + "traj_hysw5o7idqas": { + "title": "Fix issue 924", + "status": "completed", + "startedAt": "2026-05-20T05:35:07.262Z", + "completedAt": "2026-05-20T05:47:54.189Z", + "path": ".trajectories/completed/2026-05/traj_hysw5o7idqas.json" + }, + "traj_ij5b3kcatvwn": { + "title": "ricky-reading-worker-dm-replies-design-spec-status-draft-date-2026-05-15-issue-860-hea-workflow", + "status": "completed", + "startedAt": "2026-05-15T21:06:45.545Z", + "completedAt": "2026-05-15T21:50:07.842Z", + "path": ".trajectories/completed/2026-05/traj_ij5b3kcatvwn.json" + }, + "traj_iole5zdt9orr": { + "title": "Fix PR 831 CI conflicts", + "status": "completed", + "startedAt": "2026-05-10T15:18:12.326Z", + "completedAt": "2026-05-10T15:29:41.840Z", + "path": ".trajectories/completed/2026-05/traj_iole5zdt9orr.json" + }, + "traj_irafiyk6wpw0": { + "title": "Fix agents:logs near-unparseable TTY redraw garbage (codex implement, claude review)", + "status": "completed", + "startedAt": "2026-05-19T10:30:38.222Z", + "completedAt": "2026-05-19T10:44:24.757Z", + "path": ".trajectories/completed/2026-05/traj_irafiyk6wpw0.json" + }, + "traj_itgr2w8qs3xn": { + "title": "Make workflow deterministic failures repairable by agents", + "status": "completed", + "startedAt": "2026-05-08T14:44:45.732Z", + "completedAt": "2026-05-08T14:44:45.984Z", + "path": ".trajectories/completed/2026-05/traj_itgr2w8qs3xn.json" + }, + "traj_j9k10fez3e81": { + "title": "review-loop-mpb2bvnf-1-workflow", + "status": "completed", + "startedAt": "2026-05-18T10:30:09.927Z", + "completedAt": "2026-05-18T14:53:04.092Z", + "path": ".trajectories/completed/2026-05/traj_j9k10fez3e81.json" + }, + "traj_jbo2x14y7ovt": { + "title": "Fix issue 876", + "status": "completed", + "startedAt": "2026-05-19T02:48:10.768Z", + "completedAt": "2026-05-19T02:56:24.584Z", + "path": ".trajectories/completed/2026-05/traj_jbo2x14y7ovt.json" + }, + "traj_jmf9pyt3zikn": { + "title": "Fix issue 874", + "status": "completed", + "startedAt": "2026-05-19T00:07:13.993Z", + "completedAt": "2026-05-19T00:17:27.680Z", + "path": ".trajectories/completed/2026-05/traj_jmf9pyt3zikn.json" + }, + "traj_k7njijv51iq4": { + "title": "ricky-slack-primitive-implementation-workflow-status-r-workflow", + "status": "completed", + "startedAt": "2026-05-08T16:18:55.300Z", + "completedAt": "2026-05-08T16:26:03.266Z", + "path": ".trajectories/completed/2026-05/traj_k7njijv51iq4.json" + }, + "traj_lhyrcib40kao": { + "title": "Address PR #914 CodeRabbit reliability review findings", + "status": "completed", + "startedAt": "2026-05-19T11:52:46.110Z", + "completedAt": "2026-05-19T12:07:22.401Z", + "path": ".trajectories/completed/2026-05/traj_lhyrcib40kao.json" + }, + "traj_lieyyspidhfj": { + "title": "Fix PR 823 conflicts checks and comments", + "status": "completed", + "startedAt": "2026-05-09T08:37:17.563Z", + "completedAt": "2026-05-09T08:47:54.686Z", + "path": ".trajectories/completed/2026-05/traj_lieyyspidhfj.json" + }, + "traj_m7mpv7j8n78h": { + "title": "Address Relay PR 826 review feedback", + "status": "completed", + "startedAt": "2026-05-08T15:17:53.113Z", + "completedAt": "2026-05-08T15:24:32.409Z", + "path": ".trajectories/completed/2026-05/traj_m7mpv7j8n78h.json" + }, + "traj_mi9eqd4rjfea": { + "title": "Address stdio fresh review findings", + "status": "abandoned", + "startedAt": "2026-05-11T18:25:24.626Z", + "completedAt": "2026-05-11T18:37:05.318Z", + "path": ".trajectories/completed/2026-05/traj_mi9eqd4rjfea.json" + }, + "traj_mytnzgfayj3d": { + "title": "Fix PR 948 telemetry package validation failure", + "status": "completed", + "startedAt": "2026-05-22T23:34:27.422Z", + "completedAt": "2026-05-22T23:36:15.152Z", + "path": ".trajectories/completed/2026-05/traj_mytnzgfayj3d.json" + }, + "traj_mz5m5ysjj31e": { + "title": "Fix Relay SDK broker stdout drain", + "status": "completed", + "startedAt": "2026-05-10T20:24:43.831Z", + "completedAt": "2026-05-10T20:35:47.359Z", + "path": ".trajectories/completed/2026-05/traj_mz5m5ysjj31e.json" + }, + "traj_n8duofq5vq1a": { + "title": "Update Codex registry for GPT-5.5", + "status": "completed", + "startedAt": "2026-05-15T10:27:57.532Z", + "completedAt": "2026-05-15T10:33:19.705Z", + "path": ".trajectories/completed/2026-05/traj_n8duofq5vq1a.json" + }, + "traj_o251whkvy9rl": { + "title": "Fix Codex GPT-5.5 E2E rough edges", + "status": "completed", + "startedAt": "2026-05-15T11:59:26.764Z", + "completedAt": "2026-05-15T12:12:25.515Z", + "path": ".trajectories/completed/2026-05/traj_o251whkvy9rl.json" + }, + "traj_o9cx33xn5u39": { + "title": "add-mcp-args-register-flag-workflow", + "status": "completed", + "startedAt": "2026-04-20T15:06:23.387Z", + "completedAt": "2026-05-08T13:33:35.341Z", + "path": ".trajectories/completed/2026-05/traj_o9cx33xn5u39.json" + }, + "traj_ootb5rt3tozd": { + "title": "ricky-child-update-docs-sync-workflow", + "status": "completed", + "startedAt": "2026-05-15T21:07:04.494Z", + "completedAt": "2026-05-15T21:45:20.368Z", + "path": ".trajectories/completed/2026-05/traj_ootb5rt3tozd.json" + }, + "traj_oyc528j7suvo": { + "title": "Expose cloud workflow scheduling through Relay SDK", + "status": "completed", + "startedAt": "2026-05-09T19:43:34.805Z", + "completedAt": "2026-05-09T19:44:00.107Z", + "path": ".trajectories/completed/2026-05/traj_oyc528j7suvo.json" + }, + "traj_piik8r6zu3i7": { + "title": "Issue 867: RelayEventListener", + "status": "completed", + "startedAt": "2026-05-18T01:56:18.236Z", + "completedAt": "2026-05-18T02:01:49.991Z", + "path": ".trajectories/completed/2026-05/traj_piik8r6zu3i7.json" + }, + "traj_pmrcfj6or3pz": { + "title": "Address runtime split review comments", + "status": "completed", + "startedAt": "2026-05-19T02:03:43.962Z", + "completedAt": "2026-05-19T02:09:31.002Z", + "path": ".trajectories/completed/2026-05/traj_pmrcfj6or3pz.json" + }, + "traj_qtmid2nzz0kz": { + "title": "Address PR 929 review comments", + "status": "completed", + "startedAt": "2026-05-20T06:21:54.721Z", + "completedAt": "2026-05-20T06:26:56.700Z", + "path": ".trajectories/completed/2026-05/traj_qtmid2nzz0kz.json" + }, + "traj_ryf5sstno6p3": { + "title": "Telemetry key from env (P0.5 of #881)", + "status": "completed", + "startedAt": "2026-05-18T02:56:55.314Z", + "completedAt": "2026-05-18T03:02:35.202Z", + "path": ".trajectories/completed/2026-05/traj_ryf5sstno6p3.json" + }, + "traj_s5ojo1f4srz4": { + "title": "Remove unused user-directory package", + "status": "completed", + "startedAt": "2026-05-22T16:27:44.927Z", + "completedAt": "2026-05-22T16:36:20.545Z", + "path": ".trajectories/completed/2026-05/traj_s5ojo1f4srz4.json" + }, + "traj_sh2ahp9z2xg6": { + "title": "Fix uuid install deprecation warning", + "status": "completed", + "startedAt": "2026-05-19T17:21:40.756Z", + "completedAt": "2026-05-19T17:21:49.702Z", + "path": ".trajectories/completed/2026-05/traj_sh2ahp9z2xg6.json" + }, + "traj_sqerp89tc436": { + "title": "Remove legacy root bin fallback", + "status": "completed", + "startedAt": "2026-05-19T00:45:33.159Z", + "completedAt": "2026-05-19T00:50:03.857Z", + "path": ".trajectories/completed/2026-05/traj_sqerp89tc436.json" + }, + "traj_t5uknesn2fcw": { + "title": "ricky-child-update-skill-workflow", + "status": "completed", + "startedAt": "2026-05-15T21:06:52.453Z", + "completedAt": "2026-05-15T21:40:04.209Z", + "path": ".trajectories/completed/2026-05/traj_t5uknesn2fcw.json" + }, + "traj_tavtex0db4b0": { + "title": "Make workflow failures repairable by agents", + "status": "completed", + "startedAt": "2026-05-08T14:34:19.969Z", + "completedAt": "2026-05-08T14:44:45.719Z", + "path": ".trajectories/completed/2026-05/traj_tavtex0db4b0.json" + }, + "traj_tgism98me5na": { + "title": "Implement relay CLI proactive runtime bootstrap commands", + "status": "completed", + "startedAt": "2026-05-11T20:04:48.053Z", + "completedAt": "2026-05-11T20:05:54.956Z", + "path": ".trajectories/completed/2026-05/traj_tgism98me5na.json" + }, + "traj_u33qn99ijbh4": { + "title": "ricky-child-update-workflow", + "status": "completed", + "startedAt": "2026-05-15T21:07:00.444Z", + "completedAt": "2026-05-15T21:30:50.445Z", + "path": ".trajectories/completed/2026-05/traj_u33qn99ijbh4.json" + }, + "traj_u3loicehnwb4": { + "title": "Gate broker diagnostic logs behind env flag", + "status": "completed", + "startedAt": "2026-05-21T04:14:44.815Z", + "completedAt": "2026-05-21T04:14:45.063Z", + "path": ".trajectories/completed/2026-05/traj_u3loicehnwb4.json" + }, + "traj_u4ixmbqqm2y1": { + "title": "Add cloud workflow schedule CLI", + "status": "completed", + "startedAt": "2026-05-09T19:26:42.106Z", + "completedAt": "2026-05-09T19:29:18.024Z", + "path": ".trajectories/completed/2026-05/traj_u4ixmbqqm2y1.json" + }, + "traj_uf8y40ewrfh0": { + "title": "Address PR 831 review feedback and conflicts", + "status": "completed", + "startedAt": "2026-05-09T19:59:24.197Z", + "completedAt": "2026-05-09T19:59:24.403Z", + "path": ".trajectories/completed/2026-05/traj_uf8y40ewrfh0.json" + }, + "traj_v1wexlfur5zr": { + "title": "Fix broker headless reliability doc", + "status": "completed", + "startedAt": "2026-05-15T09:04:51.316Z", + "completedAt": "2026-05-15T09:13:50.970Z", + "path": ".trajectories/completed/2026-05/traj_v1wexlfur5zr.json" + }, + "traj_v87cyrs8dke9": { + "title": "Refactor runDriveSession below complexity 15 (#897)", + "status": "completed", + "startedAt": "2026-05-14T14:28:34.155Z", + "completedAt": "2026-05-18T18:06:04.950Z", + "path": ".trajectories/completed/2026-05/traj_v87cyrs8dke9.json" + }, + "traj_v9x3o92ag682": { + "title": "ricky-child-update-messaging-test-workflow", + "status": "completed", + "startedAt": "2026-05-15T21:06:56.418Z", + "completedAt": "2026-05-15T21:34:35.623Z", + "path": ".trajectories/completed/2026-05/traj_v9x3o92ag682.json" + }, + "traj_vfa1jr6otnjn": { + "title": "Refresh PR 948 after main advanced", + "status": "completed", + "startedAt": "2026-05-22T23:23:16.807Z", + "completedAt": "2026-05-22T23:23:26.380Z", + "path": ".trajectories/completed/2026-05/traj_vfa1jr6otnjn.json" + }, + "traj_vkozdglobkyg": { + "title": "Address Relay PR 826 review comments", + "status": "completed", + "startedAt": "2026-05-08T15:50:35.978Z", + "completedAt": "2026-05-08T15:51:38.854Z", + "path": ".trajectories/completed/2026-05/traj_vkozdglobkyg.json" + }, + "traj_wbn62q4cq16h": { + "title": "Update generated workflow to Codex agents only", + "status": "completed", + "startedAt": "2026-05-15T21:03:02.671Z", + "completedAt": "2026-05-15T21:06:00.384Z", + "path": ".trajectories/completed/2026-05/traj_wbn62q4cq16h.json" + }, + "traj_whd40oxptlhn": { + "title": "Review spawn persistence fix and open PR", + "status": "completed", + "startedAt": "2026-05-13T10:57:02.796Z", + "completedAt": "2026-05-13T11:00:43.100Z", + "path": ".trajectories/completed/2026-05/traj_whd40oxptlhn.json" + }, + "traj_wx00tjvpptvg": { + "title": "Investigate agent-relay spawn persistence", + "status": "completed", + "startedAt": "2026-05-13T10:49:12.464Z", + "completedAt": "2026-05-13T10:53:03.748Z", + "path": ".trajectories/completed/2026-05/traj_wx00tjvpptvg.json" + }, + "traj_wzzboitm85ee": { + "title": "Resolve PR conflicts around platform tradeoff copy", + "status": "completed", + "startedAt": "2026-05-15T12:47:36.508Z", + "completedAt": "2026-05-15T12:50:14.358Z", + "path": ".trajectories/completed/2026-05/traj_wzzboitm85ee.json" + }, + "traj_x37bhga2j5ph": { + "title": "Deepen broker runtime refactor for PR 906", + "status": "completed", + "startedAt": "2026-05-19T01:42:10.602Z", + "completedAt": "2026-05-19T01:50:40.359Z", + "path": ".trajectories/completed/2026-05/traj_x37bhga2j5ph.json" + }, + "traj_ybcrij9wg8m1": { + "title": "Implement agent-relay view read-only stream client (#864 sub-1)", + "status": "completed", + "startedAt": "2026-05-18T02:02:07.524Z", + "completedAt": "2026-05-18T02:05:41.120Z", + "path": ".trajectories/completed/2026-05/traj_ybcrij9wg8m1.json" + }, + "traj_z171lng2fbbi": { + "title": "Address PR 840 review feedback", + "status": "completed", + "startedAt": "2026-05-11T08:06:37.977Z", + "completedAt": "2026-05-11T08:07:48.097Z", + "path": ".trajectories/completed/2026-05/traj_z171lng2fbbi.json" + }, + "traj_zfa6skfr32vy": { + "title": "Implement relay CLI M1 bootstrap commands", + "status": "completed", + "startedAt": "2026-05-11T19:31:44.734Z", + "completedAt": "2026-05-11T19:34:54.971Z", + "path": ".trajectories/completed/2026-05/traj_zfa6skfr32vy.json" + }, + "traj_zqwco4gl76g3": { + "title": "Fix issue 878", + "status": "completed", + "startedAt": "2026-05-19T04:18:25.024Z", + "completedAt": "2026-05-19T04:27:18.903Z", + "path": ".trajectories/completed/2026-05/traj_zqwco4gl76g3.json" + }, + "traj_zu3252hxzoqh": { + "title": "Open PR for reading worker DM replies", + "status": "completed", + "startedAt": "2026-05-16T06:08:22.396Z", + "completedAt": "2026-05-16T06:09:24.599Z", + "path": ".trajectories/completed/2026-05/traj_zu3252hxzoqh.json" + }, + "traj_1775914296101_a4397efe": { + "title": "fix-sdk-build-resolution-workflow", + "status": "completed", + "startedAt": "2026-04-11T13:31:36.101Z", + "completedAt": "2026-04-11T13:39:53.105Z", + "path": ".trajectories/completed/traj_1775914296101_a4397efe.json" + }, + "traj_1776024661304_cfc829b9": { + "title": "fix-workflow-resume-elegant-workflow", + "status": "abandoned", + "startedAt": "2026-04-12T20:11:01.304Z", + "completedAt": "2026-04-12T20:11:16.381Z", + "path": ".trajectories/completed/traj_1776024661304_cfc829b9.json" + }, + "traj_1778873052429_03a4dacb": { + "title": "ricky-reading-worker-dm-replies-design-spec-status-draft-date-2026-05-15-issue-860-hea-workflow", + "status": "abandoned", + "startedAt": "2026-05-15T19:24:12.429Z", + "completedAt": "2026-05-15T20:01:57.036Z", + "path": ".trajectories/completed/traj_1778873052429_03a4dacb.json" + }, + "traj_1778873197540_01102ade": { + "title": "ricky-child-update-messaging-workflow", + "status": "abandoned", + "startedAt": "2026-05-15T19:26:37.540Z", + "completedAt": "2026-05-15T19:43:47.629Z", + "path": ".trajectories/completed/traj_1778873197540_01102ade.json" + }, + "traj_1778873199489_f2ce4060": { + "title": "ricky-child-update-skill-workflow", + "status": "abandoned", + "startedAt": "2026-05-15T19:26:39.489Z", + "completedAt": "2026-05-15T19:43:43.149Z", + "path": ".trajectories/completed/traj_1778873199489_f2ce4060.json" + }, + "traj_1778873201502_0dacf7c5": { + "title": "ricky-child-update-messaging-2-workflow", + "status": "abandoned", + "startedAt": "2026-05-15T19:26:41.502Z", + "completedAt": "2026-05-15T19:43:35.011Z", + "path": ".trajectories/completed/traj_1778873201502_0dacf7c5.json" + }, + "traj_1778873203502_4c225b7e": { + "title": "ricky-child-update-messaging-test-workflow", + "status": "abandoned", + "startedAt": "2026-05-15T19:26:43.502Z", + "completedAt": "2026-05-15T19:44:33.074Z", + "path": ".trajectories/completed/traj_1778873203502_4c225b7e.json" + }, + "traj_1778873205470_a4e5f0cb": { + "title": "ricky-child-update-issue-860-transcript-test-workflow", + "status": "abandoned", + "startedAt": "2026-05-15T19:26:45.470Z", + "completedAt": "2026-05-15T19:43:37.134Z", + "path": ".trajectories/completed/traj_1778873205470_a4e5f0cb.json" + }, + "traj_1778873207471_b7def991": { + "title": "ricky-child-update-workflow", + "status": "abandoned", + "startedAt": "2026-05-15T19:26:47.471Z", + "completedAt": "2026-05-15T19:43:24.329Z", + "path": ".trajectories/completed/traj_1778873207471_b7def991.json" + }, + "traj_1778874205797_81e92307": { + "title": "ricky-child-update-workflow", + "status": "abandoned", + "startedAt": "2026-05-15T19:43:25.797Z", + "completedAt": "2026-05-15T19:43:43.995Z", + "path": ".trajectories/completed/traj_1778874205797_81e92307.json" + }, + "traj_1778874216773_c6b12ab2": { + "title": "ricky-child-update-messaging-2-workflow", + "status": "abandoned", + "startedAt": "2026-05-15T19:43:36.773Z", + "completedAt": "2026-05-15T19:44:08.270Z", + "path": ".trajectories/completed/traj_1778874216773_c6b12ab2.json" + }, + "traj_1778874218579_a0225559": { + "title": "ricky-child-update-issue-860-transcript-test-workflow", + "status": "abandoned", + "startedAt": "2026-05-15T19:43:38.579Z", + "completedAt": "2026-05-15T19:43:58.721Z", + "path": ".trajectories/completed/traj_1778874218579_a0225559.json" + }, + "traj_1778874224855_9c722c4b": { + "title": "ricky-child-update-skill-workflow", + "status": "abandoned", + "startedAt": "2026-05-15T19:43:44.855Z", + "completedAt": "2026-05-15T19:44:16.528Z", + "path": ".trajectories/completed/traj_1778874224855_9c722c4b.json" + }, + "traj_1778874226983_3367d527": { + "title": "ricky-child-update-workflow", + "status": "abandoned", + "startedAt": "2026-05-15T19:43:46.983Z", + "completedAt": "2026-05-15T19:44:05.612Z", + "path": ".trajectories/completed/traj_1778874226983_3367d527.json" + }, + "traj_1778874229373_9cce9465": { + "title": "ricky-child-update-messaging-workflow", + "status": "abandoned", + "startedAt": "2026-05-15T19:43:49.374Z", + "completedAt": "2026-05-15T19:44:20.096Z", + "path": ".trajectories/completed/traj_1778874229373_9cce9465.json" + }, + "traj_1778874240339_51b823cd": { + "title": "ricky-child-update-issue-860-transcript-test-workflow", + "status": "abandoned", + "startedAt": "2026-05-15T19:44:00.339Z", + "completedAt": "2026-05-15T19:44:18.916Z", + "path": ".trajectories/completed/traj_1778874240339_51b823cd.json" + }, + "traj_1778874241076_caa675a9": { + "title": "ricky-child-update-2-workflow", + "status": "abandoned", + "startedAt": "2026-05-15T19:44:01.076Z", + "completedAt": "2026-05-15T19:44:32.521Z", + "path": ".trajectories/completed/traj_1778874241076_caa675a9.json" + }, + "traj_1778874248966_e29c4c54": { + "title": "ricky-child-update-workflow", + "status": "abandoned", + "startedAt": "2026-05-15T19:44:08.966Z", + "completedAt": "2026-05-15T19:44:27.330Z", + "path": ".trajectories/completed/traj_1778874248966_e29c4c54.json" + }, + "traj_1778874249983_12a98df3": { + "title": "ricky-child-update-messaging-2-workflow", + "status": "abandoned", + "startedAt": "2026-05-15T19:44:09.983Z", + "completedAt": "2026-05-15T19:44:41.100Z", + "path": ".trajectories/completed/traj_1778874249983_12a98df3.json" + }, + "traj_1778874258229_0bdc53d8": { + "title": "ricky-child-update-skill-workflow", + "status": "abandoned", + "startedAt": "2026-05-15T19:44:18.229Z", + "completedAt": "2026-05-15T19:44:49.274Z", + "path": ".trajectories/completed/traj_1778874258229_0bdc53d8.json" + }, + "traj_1778874261453_55f49624": { + "title": "ricky-child-update-messaging-workflow", + "status": "abandoned", + "startedAt": "2026-05-15T19:44:21.453Z", + "completedAt": "2026-05-15T19:44:53.643Z", + "path": ".trajectories/completed/traj_1778874261453_55f49624.json" + }, + "traj_1778874261608_48fb9bf5": { + "title": "ricky-child-update-issue-860-transcript-test-workflow", + "status": "abandoned", + "startedAt": "2026-05-15T19:44:21.608Z", + "completedAt": "2026-05-15T19:44:40.761Z", + "path": ".trajectories/completed/traj_1778874261608_48fb9bf5.json" + }, + "traj_1778874269139_d7d7485a": { + "title": "ricky-child-update-workflow", + "status": "abandoned", + "startedAt": "2026-05-15T19:44:29.139Z", + "completedAt": "2026-05-15T19:44:48.083Z", + "path": ".trajectories/completed/traj_1778874269139_d7d7485a.json" + }, + "traj_1778874274412_70843e0e": { + "title": "ricky-child-update-2-workflow", + "status": "abandoned", + "startedAt": "2026-05-15T19:44:34.412Z", + "completedAt": "2026-05-15T19:45:06.798Z", + "path": ".trajectories/completed/traj_1778874274412_70843e0e.json" + }, + "traj_1778874274581_71efa470": { + "title": "ricky-child-update-messaging-test-workflow", + "status": "abandoned", + "startedAt": "2026-05-15T19:44:34.581Z", + "completedAt": "2026-05-15T19:44:54.182Z", + "path": ".trajectories/completed/traj_1778874274581_71efa470.json" + }, + "traj_1778874282200_39ad11db": { + "title": "ricky-child-update-issue-860-transcript-test-workflow", + "status": "abandoned", + "startedAt": "2026-05-15T19:44:42.200Z", + "completedAt": "2026-05-15T19:45:02.477Z", + "path": ".trajectories/completed/traj_1778874282200_39ad11db.json" + }, + "traj_1778874283570_ce3585b8": { + "title": "ricky-child-update-messaging-2-workflow", + "status": "abandoned", + "startedAt": "2026-05-15T19:44:43.570Z", + "completedAt": "2026-05-15T19:45:14.888Z", + "path": ".trajectories/completed/traj_1778874283570_ce3585b8.json" + }, + "traj_1778874289674_e3f868c8": { + "title": "ricky-child-update-workflow", + "status": "abandoned", + "startedAt": "2026-05-15T19:44:49.674Z", + "completedAt": "2026-05-15T19:45:08.337Z", + "path": ".trajectories/completed/traj_1778874289674_e3f868c8.json" + }, + "traj_1778874291950_0b1b5c1f": { + "title": "ricky-child-update-skill-workflow", + "status": "abandoned", + "startedAt": "2026-05-15T19:44:51.950Z", + "completedAt": "2026-05-15T19:45:23.421Z", + "path": ".trajectories/completed/traj_1778874291950_0b1b5c1f.json" + }, + "traj_1778874295927_4083d181": { + "title": "ricky-child-update-messaging-test-workflow", + "status": "abandoned", + "startedAt": "2026-05-15T19:44:55.927Z", + "completedAt": "2026-05-15T19:45:15.333Z", + "path": ".trajectories/completed/traj_1778874295927_4083d181.json" + }, + "traj_1778874296362_bdf727ff": { + "title": "ricky-child-update-messaging-workflow", + "status": "abandoned", + "startedAt": "2026-05-15T19:44:56.362Z", + "completedAt": "2026-05-15T19:45:27.624Z", + "path": ".trajectories/completed/traj_1778874296362_bdf727ff.json" + }, + "traj_l1349adi1g0o": { + "title": "Fix agent relay MCP PR CI failures", + "status": "completed", + "startedAt": "2026-05-25T21:42:41.236Z", + "completedAt": "2026-05-25T21:42:57.292Z", + "path": ".trajectories/completed/2026-05/traj_l1349adi1g0o.json" + }, + "traj_8nhd9lljhbsw": { + "title": "Switch owned MCP tool names to underscores", + "status": "completed", + "startedAt": "2026-05-25T22:05:23.828Z", + "completedAt": "2026-05-25T22:14:25.886Z", + "path": ".trajectories/completed/2026-05/traj_8nhd9lljhbsw.json" + }, + "traj_gkxajksmwoea": { + "title": "Document owned MCP tool table", + "status": "completed", + "startedAt": "2026-05-25T22:17:18.278Z", + "completedAt": "2026-05-25T22:19:29.639Z", + "path": ".trajectories/completed/2026-05/traj_gkxajksmwoea.json" + }, + "traj_t6h534vn0bpg": { + "title": "Resolve PR merge conflicts", + "status": "completed", + "startedAt": "2026-05-26T10:11:15.356Z", + "completedAt": "2026-05-26T10:21:56.502Z", + "path": ".trajectories/completed/2026-05/traj_t6h534vn0bpg.json" + }, + "traj_cszfl2icaj2t": { + "title": "Add Prettier auto-format workflow", + "status": "completed", + "startedAt": "2026-05-26T11:04:15.563Z", + "completedAt": "2026-05-26T11:05:23.716Z", + "path": ".trajectories/completed/2026-05/traj_cszfl2icaj2t.json" + }, + "traj_i2pjnx3dll5b": { + "title": "Fresh harness runtime plan and implementation", + "status": "completed", + "startedAt": "2026-05-25T15:49:27.102Z", + "completedAt": "2026-05-25T16:22:35.339Z", + "path": ".trajectories/completed/2026-05/traj_i2pjnx3dll5b.json" + }, + "traj_7i9tigaejfje": { + "title": "Clarify headless app-server harness terminology", + "status": "completed", + "startedAt": "2026-05-25T16:34:21.397Z", + "completedAt": "2026-05-25T16:34:33.412Z", + "path": ".trajectories/completed/2026-05/traj_7i9tigaejfje.json" + }, + "traj_1fjub7c9rlap": { + "title": "Rewrite harness docs around SDK adapters", + "status": "completed", + "startedAt": "2026-05-25T16:53:04.706Z", + "completedAt": "2026-05-25T16:53:16.077Z", + "path": ".trajectories/completed/2026-05/traj_1fjub7c9rlap.json" + }, + "traj_0d1efjk6aeo2": { + "title": "Respond to harness PR review comments", + "status": "completed", + "startedAt": "2026-05-25T17:14:45.927Z", + "completedAt": "2026-05-25T17:14:53.457Z", + "path": ".trajectories/completed/2026-05/traj_0d1efjk6aeo2.json" + }, + "traj_9dj3qiugt26j": { + "title": "Fix harness runtime review issues", + "status": "completed", + "startedAt": "2026-05-25T17:41:16.384Z", + "completedAt": "2026-05-25T17:53:06.394Z", + "path": ".trajectories/completed/2026-05/traj_9dj3qiugt26j.json" + }, + "traj_q2r3c9dmdep7": { + "title": "Rename harness plans to harness configs", + "status": "completed", + "startedAt": "2026-05-25T18:00:40.591Z", + "completedAt": "2026-05-25T18:06:34.954Z", + "path": ".trajectories/completed/2026-05/traj_q2r3c9dmdep7.json" + }, + "traj_fiygtgr3tfey": { + "title": "Fix harness config clippy issues", + "status": "completed", + "startedAt": "2026-05-25T18:31:39.975Z", + "completedAt": "2026-05-25T18:34:10.562Z", + "path": ".trajectories/completed/2026-05/traj_fiygtgr3tfey.json" + }, + "traj_n0qwpjvmdl2s": { + "title": "Default headless harness driver", + "status": "completed", + "startedAt": "2026-05-25T19:50:47.661Z", + "completedAt": "2026-05-25T19:52:52.791Z", + "path": ".trajectories/completed/2026-05/traj_n0qwpjvmdl2s.json" + }, + "traj_kgl2opmmfvus": { + "title": "Simplify harness config PR around broker-owned configs", + "status": "completed", + "startedAt": "2026-05-25T21:32:14.085Z", + "completedAt": "2026-05-25T21:47:15.455Z", + "path": ".trajectories/completed/2026-05/traj_kgl2opmmfvus.json" + }, + "traj_bd431l65n9lg": { + "title": "Remove broker harness registry footgun", + "status": "completed", + "startedAt": "2026-05-25T21:55:14.197Z", + "completedAt": "2026-05-25T22:02:22.902Z", + "path": ".trajectories/completed/2026-05/traj_bd431l65n9lg.json" + }, + "traj_qbq3laxbvhzf": { + "title": "Resolve harness PR conflicts and comments", + "status": "completed", + "startedAt": "2026-05-25T22:03:51.255Z", + "completedAt": "2026-05-25T22:25:18.889Z", + "path": ".trajectories/completed/2026-05/traj_qbq3laxbvhzf.json" + }, + "traj_l67sex3nkzfq": { + "title": "Fix failing harness PR e2e tests", + "status": "completed", + "startedAt": "2026-05-25T23:22:50.714Z", + "completedAt": "2026-05-25T23:32:19.352Z", + "path": ".trajectories/completed/2026-05/traj_l67sex3nkzfq.json" + }, + "traj_zyluvmlqo5j7": { + "title": "Resolve harness PR merge conflicts", + "status": "completed", + "startedAt": "2026-05-26T11:24:20.682Z", + "completedAt": "2026-05-26T11:26:52.563Z", + "path": ".trajectories/completed/2026-05/traj_zyluvmlqo5j7.json" + } + } +} diff --git a/example.ts b/example.ts deleted file mode 100644 index 8ef9c3f4e..000000000 --- a/example.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { AgentRelay, defaultHarnesses } from '@agent-relay/sdk'; -import { myApi } from '../my-internal-api' - - -const { codex, claude } = defaultHarnesses; - -const piCoding = { - runtime: 'pty', - command: 'pid', - args: [ - '--dangerously-skip-permissions', - '--append-system-prompt', - 'Follow the company review rubric.', - '{modelArgs}', - '{args}', - ], - modelArgs: ['--model', '{model}'], - env: { - FUN_SETTING: '1', - }, - beforeSpawn: async (ctx) => { - const hasCreditsAvailable = await myApi.hasCreditsAvailable() - - if (!hasCreditsAvailable) { - return { error: 'No credits available', status: 402 } - } - - const sessionId = await createPiResumableSessionId(ctx.cwd, ctx.task, ctx.env) - return { sessionId } - } - -} - - - -const relay = new AgentRelay( - harnesses: [ piCoding, codex, claude ] -); diff --git a/package-lock.json b/package-lock.json index 83082b6d8..cb7aeb6b4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1235,7 +1235,6 @@ }, "node_modules/@clack/prompts/node_modules/is-unicode-supported": { "version": "1.3.0", - "extraneous": true, "inBundle": true, "license": "MIT", "engines": { @@ -6703,9 +6702,9 @@ "link": true }, "node_modules/agent-trajectories": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/agent-trajectories/-/agent-trajectories-0.6.0.tgz", - "integrity": "sha512-wCOHGO7gWw6lA/4e794+YMOLWpfRnlCZiLN5i5lHj3oNHzFYEBlSEEBJXLM3moDM9x0UvLEAEsz+bYrlxW80mQ==", + "version": "0.5.8", + "resolved": "https://registry.npmjs.org/agent-trajectories/-/agent-trajectories-0.5.8.tgz", + "integrity": "sha512-Cu/+uyxAy+eNSlpzuOhk62kM/i0BdlfG8Z4avyzfbHbQ3I9EQLqiUikl3WcG75m3v+4MwTbJq9e6YTG8/ykKPw==", "license": "MIT", "dependencies": { "@clack/prompts": "^0.7.0", @@ -16233,7 +16232,7 @@ "@relayfile/local-mount": "^0.2.2", "@relayfile/sdk": "^0.6.0", "@slack/web-api": "^7.16.0", - "agent-trajectories": "^0.6.0", + "agent-trajectories": "^0.5.8", "commander": "^12.1.0", "dotenv": "^17.2.3", "esbuild": "^0.27.2", @@ -17203,7 +17202,7 @@ "@relaycast/sdk": "^1.1.0", "@relayfile/sdk": ">=0.1.2 <1", "@sinclair/typebox": "^0.34.48", - "agent-trajectories": "^0.6.0", + "agent-trajectories": "^0.5.4", "chalk": "^4.1.2", "ignore": "^7.0.5", "listr2": "^10.2.1", diff --git a/packages/cli/package.json b/packages/cli/package.json index 04eb89075..5fec1bac9 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -63,7 +63,7 @@ "@relayfile/local-mount": "^0.2.2", "@relayfile/sdk": "^0.6.0", "@slack/web-api": "^7.16.0", - "agent-trajectories": "^0.6.0", + "agent-trajectories": "^0.5.8", "commander": "^12.1.0", "dotenv": "^17.2.3", "esbuild": "^0.27.2", diff --git a/packages/sdk/package.json b/packages/sdk/package.json index 380fc60c1..7a2173ebf 100644 --- a/packages/sdk/package.json +++ b/packages/sdk/package.json @@ -179,7 +179,7 @@ "@relaycast/sdk": "^1.1.0", "@relayfile/sdk": ">=0.1.2 <1", "@sinclair/typebox": "^0.34.48", - "agent-trajectories": "^0.6.0", + "agent-trajectories": "^0.5.4", "chalk": "^4.1.2", "ignore": "^7.0.5", "listr2": "^10.2.1", From 64df05521bfda759e82a8ec3bec74fc9f8a6d233 Mon Sep 17 00:00:00 2001 From: Will Washburn Date: Tue, 26 May 2026 11:31:43 -0400 Subject: [PATCH 16/19] Move trajectories under agentworkforce --- .../compact_gqmrna24cmm4_2026-05-19.json | 0 .../compact_gqmrna24cmm4_2026-05-19.md | 0 .../compact_j5u7qhaw4q6a_2026-05-08.json | 0 .../compact_j5u7qhaw4q6a_2026-05-08.md | 0 .../compacted/release-6.0.13.json | 0 .../trajectories}/compacted/release-6.0.13.md | 0 .../compacted/release-6.2.3.json | 0 .../trajectories}/compacted/release-6.2.3.md | 0 .../completed/2026-04/traj_05xg7j388bc4.json | 0 .../completed/2026-04/traj_05xg7j388bc4.md | 0 .../completed/2026-04/traj_0t92gxaz6igh.json | 0 .../completed/2026-04/traj_0t92gxaz6igh.md | 0 .../2026-04/traj_1776105620545_9dcebb3d.json | 0 .../2026-04/traj_1776105620545_9dcebb3d.md | 0 .../2026-04/traj_1776105988184_29f1270c.json | 0 .../2026-04/traj_1776105988184_29f1270c.md | 0 .../completed/2026-04/traj_222ha5671idc.json | 0 .../completed/2026-04/traj_222ha5671idc.md | 0 .../completed/2026-04/traj_3b3p1z4y7qlo.json | 0 .../completed/2026-04/traj_3b3p1z4y7qlo.md | 0 .../completed/2026-04/traj_4zqhfqw7g28l.json | 0 .../completed/2026-04/traj_4zqhfqw7g28l.md | 0 .../completed/2026-04/traj_530xmbfeljyb.json | 0 .../completed/2026-04/traj_530xmbfeljyb.md | 0 .../completed/2026-04/traj_703m7sqyq89t.json | 0 .../completed/2026-04/traj_703m7sqyq89t.md | 0 .../completed/2026-04/traj_8oh4r5km5eic.json | 0 .../completed/2026-04/traj_8oh4r5km5eic.md | 0 .../completed/2026-04/traj_9tt55is74dq5.json | 0 .../completed/2026-04/traj_9tt55is74dq5.md | 0 .../completed/2026-04/traj_abjovknvcijv.json | 0 .../completed/2026-04/traj_abjovknvcijv.md | 0 .../completed/2026-04/traj_avmkyoo2s3rt.json | 0 .../completed/2026-04/traj_avmkyoo2s3rt.md | 0 .../completed/2026-04/traj_d48czxmgx4ac.json | 0 .../completed/2026-04/traj_d48czxmgx4ac.md | 0 .../completed/2026-04/traj_dw8ihhdb8ip7.json | 0 .../completed/2026-04/traj_dw8ihhdb8ip7.md | 0 .../completed/2026-04/traj_e5i62wdjx0jd.json | 0 .../completed/2026-04/traj_e5i62wdjx0jd.md | 0 .../completed/2026-04/traj_g3muawdq6bsb.json | 0 .../completed/2026-04/traj_g3muawdq6bsb.md | 0 .../completed/2026-04/traj_mk0t0cgn4ytq.json | 0 .../completed/2026-04/traj_mk0t0cgn4ytq.md | 0 .../completed/2026-04/traj_o8kgzhfu6jth.json | 0 .../completed/2026-04/traj_o8kgzhfu6jth.md | 0 .../completed/2026-04/traj_qb54w47qwod6.json | 0 .../completed/2026-04/traj_qb54w47qwod6.md | 0 .../completed/2026-04/traj_rs2bt3x0fqba.json | 0 .../completed/2026-04/traj_rs2bt3x0fqba.md | 0 .../completed/2026-04/traj_tjadoebpscps.json | 0 .../completed/2026-04/traj_tjadoebpscps.md | 0 .../completed/2026-04/traj_tv1x9pamkqad.json | 0 .../completed/2026-04/traj_tv1x9pamkqad.md | 0 .../completed/2026-04/traj_ui5omrgz819d.json | 0 .../completed/2026-04/traj_ui5omrgz819d.md | 0 .../completed/2026-04/traj_w0xpsaoxuiyw.json | 0 .../completed/2026-04/traj_w0xpsaoxuiyw.md | 0 .../completed/2026-05/traj_0d1efjk6aeo2.json | 0 .../completed/2026-05/traj_0d1efjk6aeo2.md | 0 .../completed/2026-05/traj_0e8i20oitwvz.json | 0 .../completed/2026-05/traj_0e8i20oitwvz.md | 0 .../completed/2026-05/traj_0o6gb2wvk59t.json | 0 .../completed/2026-05/traj_0o6gb2wvk59t.md | 0 .../completed/2026-05/traj_0z98tkaigaxg.json | 0 .../completed/2026-05/traj_0z98tkaigaxg.md | 0 .../2026-05/traj_1775914133873_35667beb.json | 0 .../2026-05/traj_1775914133873_35667beb.md | 0 .../2026-05/traj_1776073106646_1839be2d.json | 0 .../2026-05/traj_1776073106646_1839be2d.md | 0 .../2026-05/traj_1776113772922_bc92f121.json | 0 .../2026-05/traj_1776113772922_bc92f121.md | 0 .../2026-05/traj_1778873209642_c70e32ab.json | 0 .../2026-05/traj_1778873209642_c70e32ab.md | 0 .../2026-05/traj_1778873211616_6db3b2cd.json | 0 .../2026-05/traj_1778873211616_6db3b2cd.md | 0 .../2026-05/traj_17t39ue8exte/summary.md | 0 .../2026-05/traj_17t39ue8exte/trajectory.json | 0 .../completed/2026-05/traj_1fjub7c9rlap.json | 0 .../completed/2026-05/traj_1fjub7c9rlap.md | 0 .../completed/2026-05/traj_1rrpe2r7fyem.json | 0 .../completed/2026-05/traj_1rrpe2r7fyem.md | 0 .../completed/2026-05/traj_2gpglosdsq7s.json | 0 .../completed/2026-05/traj_2gpglosdsq7s.md | 0 .../completed/2026-05/traj_2tqxnib25omk.json | 0 .../completed/2026-05/traj_2tqxnib25omk.md | 0 .../completed/2026-05/traj_2yicjxgajt0a.json | 0 .../completed/2026-05/traj_2yicjxgajt0a.md | 0 .../completed/2026-05/traj_34b1u84b19gz.json | 0 .../completed/2026-05/traj_34b1u84b19gz.md | 0 .../completed/2026-05/traj_3b3p1z4y7qlo.json | 0 .../completed/2026-05/traj_3b3p1z4y7qlo.md | 0 .../completed/2026-05/traj_3gjtcykvybt5.json | 0 .../completed/2026-05/traj_3gjtcykvybt5.md | 0 .../completed/2026-05/traj_47akjihewlow.json | 0 .../completed/2026-05/traj_47akjihewlow.md | 0 .../2026-05/traj_47akjihewlow.trace.json | 0 .../completed/2026-05/traj_4chzkm724ufo.json | 0 .../completed/2026-05/traj_4chzkm724ufo.md | 0 .../completed/2026-05/traj_4t07itef99ug.json | 0 .../completed/2026-05/traj_4t07itef99ug.md | 0 .../completed/2026-05/traj_4vucir4qvqa2.json | 0 .../completed/2026-05/traj_4vucir4qvqa2.md | 0 .../completed/2026-05/traj_5k0jtc1g5l33.json | 0 .../completed/2026-05/traj_5k0jtc1g5l33.md | 0 .../completed/2026-05/traj_5nzj6v56id4z.json | 0 .../completed/2026-05/traj_5q8i0iz4klpo.json | 0 .../completed/2026-05/traj_5q8i0iz4klpo.md | 0 .../completed/2026-05/traj_5qbla7w4kzoi.json | 0 .../completed/2026-05/traj_5qbla7w4kzoi.md | 0 .../completed/2026-05/traj_60qc24ufr96g.json | 0 .../completed/2026-05/traj_60qc24ufr96g.md | 0 .../completed/2026-05/traj_6sjeohtm3php.json | 0 .../completed/2026-05/traj_6sjeohtm3php.md | 0 .../completed/2026-05/traj_6ujzpx82gqs9.json | 0 .../completed/2026-05/traj_6ujzpx82gqs9.md | 0 .../completed/2026-05/traj_78ytpicts778.json | 0 .../completed/2026-05/traj_78ytpicts778.md | 0 .../completed/2026-05/traj_7i9tigaejfje.json | 0 .../completed/2026-05/traj_7i9tigaejfje.md | 0 .../completed/2026-05/traj_7uznwzoxbao6.json | 0 .../completed/2026-05/traj_7uznwzoxbao6.md | 0 .../completed/2026-05/traj_7zu7et53ph3l.json | 0 .../completed/2026-05/traj_7zu7et53ph3l.md | 0 .../completed/2026-05/traj_81kobstnzzwk.json | 0 .../completed/2026-05/traj_8ljgydz61do5.json | 0 .../completed/2026-05/traj_8ljgydz61do5.md | 0 .../completed/2026-05/traj_8nhd9lljhbsw.json | 0 .../completed/2026-05/traj_8nhd9lljhbsw.md | 0 .../completed/2026-05/traj_90jmd9z27oap.json | 0 .../completed/2026-05/traj_90jmd9z27oap.md | 0 .../completed/2026-05/traj_947wzpddsg9j.json | 0 .../completed/2026-05/traj_947wzpddsg9j.md | 0 .../completed/2026-05/traj_9dj3qiugt26j.json | 0 .../completed/2026-05/traj_9dj3qiugt26j.md | 0 .../completed/2026-05/traj_9fdv7hxm0b60.json | 0 .../completed/2026-05/traj_9fdv7hxm0b60.md | 0 .../completed/2026-05/traj_9gq96irkj00s.json | 0 .../completed/2026-05/traj_9gq96irkj00s.md | 0 .../completed/2026-05/traj_aw7stgf4qau0.json | 0 .../completed/2026-05/traj_aw7stgf4qau0.md | 0 .../2026-05/traj_b3g40827t5zh/summary.md | 0 .../2026-05/traj_b3g40827t5zh/trajectory.json | 0 .../completed/2026-05/traj_bd431l65n9lg.json | 0 .../completed/2026-05/traj_bd431l65n9lg.md | 0 .../completed/2026-05/traj_bdrlknyl8twj.json | 0 .../completed/2026-05/traj_bdrlknyl8twj.md | 0 .../completed/2026-05/traj_bz1a1o15p7px.json | 0 .../completed/2026-05/traj_bz1a1o15p7px.md | 0 .../completed/2026-05/traj_cbmwd07phhm2.json | 0 .../completed/2026-05/traj_cbmwd07phhm2.md | 0 .../completed/2026-05/traj_ceo5q9bh2od3.json | 0 .../completed/2026-05/traj_ceo5q9bh2od3.md | 0 .../completed/2026-05/traj_cszfl2icaj2t.json | 0 .../completed/2026-05/traj_cszfl2icaj2t.md | 0 .../completed/2026-05/traj_d89s38ddu7cj.json | 0 .../completed/2026-05/traj_d89s38ddu7cj.md | 0 .../completed/2026-05/traj_dbsnr453nxjw.json | 0 .../completed/2026-05/traj_dbsnr453nxjw.md | 0 .../completed/2026-05/traj_dcl9hgoiuac5.json | 0 .../completed/2026-05/traj_dcl9hgoiuac5.md | 0 .../completed/2026-05/traj_dpgn0am1jq1c.json | 0 .../completed/2026-05/traj_dpgn0am1jq1c.md | 0 .../completed/2026-05/traj_e1b7ww3un1u3.json | 0 .../completed/2026-05/traj_e1b7ww3un1u3.md | 0 .../completed/2026-05/traj_elx0fcwgs37x.json | 0 .../completed/2026-05/traj_elx0fcwgs37x.md | 0 .../completed/2026-05/traj_erzd7j9nto9r.json | 0 .../completed/2026-05/traj_erzd7j9nto9r.md | 0 .../completed/2026-05/traj_f1iac9ngymlj.json | 0 .../completed/2026-05/traj_f1iac9ngymlj.md | 0 .../completed/2026-05/traj_f3arvbmmlomn.json | 0 .../completed/2026-05/traj_f3arvbmmlomn.md | 0 .../completed/2026-05/traj_f9wxa8ujeg78.json | 0 .../completed/2026-05/traj_f9wxa8ujeg78.md | 0 .../completed/2026-05/traj_fh8oosbijpwc.json | 0 .../completed/2026-05/traj_fh8oosbijpwc.md | 0 .../2026-05/traj_fh8oosbijpwc.trace.json | 0 .../completed/2026-05/traj_fiygtgr3tfey.json | 0 .../completed/2026-05/traj_fiygtgr3tfey.md | 0 .../completed/2026-05/traj_gh05rj5gwsap.json | 0 .../completed/2026-05/traj_gh05rj5gwsap.md | 0 .../2026-05/traj_gh05rj5gwsap.trace.json | 0 .../completed/2026-05/traj_gkxajksmwoea.json | 0 .../completed/2026-05/traj_gkxajksmwoea.md | 0 .../completed/2026-05/traj_gnqvtoxtc8dy.json | 0 .../completed/2026-05/traj_gnqvtoxtc8dy.md | 0 .../completed/2026-05/traj_hfkww5z7trxn.json | 0 .../completed/2026-05/traj_hfkww5z7trxn.md | 0 .../completed/2026-05/traj_hrsndfzk0qay.json | 0 .../completed/2026-05/traj_hrsndfzk0qay.md | 0 .../completed/2026-05/traj_hysw5o7idqas.json | 0 .../completed/2026-05/traj_hysw5o7idqas.md | 0 .../completed/2026-05/traj_i2pjnx3dll5b.json | 0 .../completed/2026-05/traj_i2pjnx3dll5b.md | 0 .../2026-05/traj_i2pjnx3dll5b.trace.json | 0 .../completed/2026-05/traj_ij5b3kcatvwn.json | 0 .../completed/2026-05/traj_ij5b3kcatvwn.md | 0 .../completed/2026-05/traj_iole5zdt9orr.json | 0 .../completed/2026-05/traj_iole5zdt9orr.md | 0 .../completed/2026-05/traj_irafiyk6wpw0.json | 0 .../completed/2026-05/traj_itgr2w8qs3xn.json | 0 .../completed/2026-05/traj_itgr2w8qs3xn.md | 0 .../completed/2026-05/traj_j9k10fez3e81.json | 0 .../completed/2026-05/traj_j9k10fez3e81.md | 0 .../completed/2026-05/traj_jbo2x14y7ovt.json | 0 .../completed/2026-05/traj_jbo2x14y7ovt.md | 0 .../completed/2026-05/traj_jmf9pyt3zikn.json | 0 .../completed/2026-05/traj_jmf9pyt3zikn.md | 0 .../completed/2026-05/traj_k7njijv51iq4.json | 0 .../completed/2026-05/traj_k7njijv51iq4.md | 0 .../completed/2026-05/traj_kgl2opmmfvus.json | 0 .../completed/2026-05/traj_kgl2opmmfvus.md | 0 .../completed/2026-05/traj_l1349adi1g0o.json | 0 .../completed/2026-05/traj_l1349adi1g0o.md | 0 .../completed/2026-05/traj_l67sex3nkzfq.json | 0 .../completed/2026-05/traj_l67sex3nkzfq.md | 0 .../completed/2026-05/traj_lhyrcib40kao.json | 0 .../completed/2026-05/traj_lhyrcib40kao.md | 0 .../completed/2026-05/traj_lieyyspidhfj.json | 0 .../completed/2026-05/traj_lieyyspidhfj.md | 0 .../2026-05/traj_lieyyspidhfj.trace.json | 0 .../completed/2026-05/traj_m7mpv7j8n78h.json | 0 .../completed/2026-05/traj_m7mpv7j8n78h.md | 0 .../completed/2026-05/traj_mi9eqd4rjfea.json | 0 .../completed/2026-05/traj_mi9eqd4rjfea.md | 0 .../completed/2026-05/traj_mytnzgfayj3d.json | 0 .../completed/2026-05/traj_mytnzgfayj3d.md | 0 .../completed/2026-05/traj_mz5m5ysjj31e.json | 0 .../completed/2026-05/traj_mz5m5ysjj31e.md | 0 .../completed/2026-05/traj_n0qwpjvmdl2s.json | 0 .../completed/2026-05/traj_n0qwpjvmdl2s.md | 0 .../completed/2026-05/traj_n8duofq5vq1a.json | 0 .../completed/2026-05/traj_n8duofq5vq1a.md | 0 .../completed/2026-05/traj_o251whkvy9rl.json | 0 .../completed/2026-05/traj_o251whkvy9rl.md | 0 .../completed/2026-05/traj_o9cx33xn5u39.json | 0 .../completed/2026-05/traj_o9cx33xn5u39.md | 0 .../completed/2026-05/traj_ootb5rt3tozd.json | 0 .../completed/2026-05/traj_ootb5rt3tozd.md | 0 .../completed/2026-05/traj_oyc528j7suvo.json | 0 .../completed/2026-05/traj_oyc528j7suvo.md | 0 .../completed/2026-05/traj_piik8r6zu3i7.json | 0 .../completed/2026-05/traj_piik8r6zu3i7.md | 0 .../completed/2026-05/traj_pmrcfj6or3pz.json | 0 .../completed/2026-05/traj_pmrcfj6or3pz.md | 0 .../completed/2026-05/traj_q2r3c9dmdep7.json | 0 .../completed/2026-05/traj_q2r3c9dmdep7.md | 0 .../completed/2026-05/traj_qbq3laxbvhzf.json | 0 .../completed/2026-05/traj_qbq3laxbvhzf.md | 0 .../completed/2026-05/traj_qtmid2nzz0kz.json | 0 .../completed/2026-05/traj_qtmid2nzz0kz.md | 0 .../completed/2026-05/traj_ryf5sstno6p3.json | 0 .../completed/2026-05/traj_ryf5sstno6p3.md | 0 .../completed/2026-05/traj_s5ojo1f4srz4.json | 0 .../completed/2026-05/traj_s5ojo1f4srz4.md | 0 .../completed/2026-05/traj_sh2ahp9z2xg6.json | 0 .../completed/2026-05/traj_sh2ahp9z2xg6.md | 0 .../completed/2026-05/traj_sqerp89tc436.json | 0 .../completed/2026-05/traj_sqerp89tc436.md | 0 .../completed/2026-05/traj_t5uknesn2fcw.json | 0 .../completed/2026-05/traj_t5uknesn2fcw.md | 0 .../completed/2026-05/traj_t6h534vn0bpg.json | 0 .../completed/2026-05/traj_t6h534vn0bpg.md | 0 .../completed/2026-05/traj_tavtex0db4b0.json | 0 .../completed/2026-05/traj_tavtex0db4b0.md | 0 .../completed/2026-05/traj_tgism98me5na.json | 0 .../completed/2026-05/traj_tgism98me5na.md | 0 .../completed/2026-05/traj_u33qn99ijbh4.json | 0 .../completed/2026-05/traj_u33qn99ijbh4.md | 0 .../completed/2026-05/traj_u3loicehnwb4.json | 0 .../completed/2026-05/traj_u3loicehnwb4.md | 0 .../completed/2026-05/traj_u4ixmbqqm2y1.json | 0 .../completed/2026-05/traj_u4ixmbqqm2y1.md | 0 .../completed/2026-05/traj_uf8y40ewrfh0.json | 0 .../completed/2026-05/traj_uf8y40ewrfh0.md | 0 .../completed/2026-05/traj_v1wexlfur5zr.json | 0 .../completed/2026-05/traj_v1wexlfur5zr.md | 0 .../completed/2026-05/traj_v87cyrs8dke9.json | 0 .../completed/2026-05/traj_v87cyrs8dke9.md | 0 .../2026-05/traj_v87cyrs8dke9.trace.json | 0 .../completed/2026-05/traj_v9x3o92ag682.json | 0 .../completed/2026-05/traj_v9x3o92ag682.md | 0 .../completed/2026-05/traj_vfa1jr6otnjn.json | 0 .../completed/2026-05/traj_vfa1jr6otnjn.md | 0 .../completed/2026-05/traj_vkozdglobkyg.json | 0 .../completed/2026-05/traj_vkozdglobkyg.md | 0 .../completed/2026-05/traj_wbn62q4cq16h.json | 0 .../completed/2026-05/traj_wbn62q4cq16h.md | 0 .../completed/2026-05/traj_whd40oxptlhn.json | 0 .../completed/2026-05/traj_whd40oxptlhn.md | 0 .../2026-05/traj_whd40oxptlhn.trace.json | 0 .../completed/2026-05/traj_wx00tjvpptvg.json | 0 .../completed/2026-05/traj_wx00tjvpptvg.md | 0 .../completed/2026-05/traj_wzzboitm85ee.json | 0 .../completed/2026-05/traj_wzzboitm85ee.md | 0 .../completed/2026-05/traj_x37bhga2j5ph.json | 0 .../completed/2026-05/traj_x37bhga2j5ph.md | 0 .../completed/2026-05/traj_ybcrij9wg8m1.json | 0 .../completed/2026-05/traj_ybcrij9wg8m1.md | 0 .../completed/2026-05/traj_z171lng2fbbi.json | 0 .../completed/2026-05/traj_z171lng2fbbi.md | 0 .../completed/2026-05/traj_zfa6skfr32vy.json | 0 .../completed/2026-05/traj_zfa6skfr32vy.md | 0 .../completed/2026-05/traj_zqwco4gl76g3.json | 0 .../completed/2026-05/traj_zqwco4gl76g3.md | 0 .../completed/2026-05/traj_zu3252hxzoqh.json | 0 .../completed/2026-05/traj_zu3252hxzoqh.md | 0 .../completed/2026-05/traj_zyluvmlqo5j7.json | 0 .../completed/2026-05/traj_zyluvmlqo5j7.md | 0 .../traj_1775914296101_a4397efe.json | 0 .../traj_1776024661304_cfc829b9.json | 0 .../traj_1776105620545_9dcebb3d.json | 0 .../traj_1778873052429_03a4dacb.json | 0 .../traj_1778873197540_01102ade.json | 0 .../traj_1778873199489_f2ce4060.json | 0 .../traj_1778873201502_0dacf7c5.json | 0 .../traj_1778873203502_4c225b7e.json | 0 .../traj_1778873205470_a4e5f0cb.json | 0 .../traj_1778873207471_b7def991.json | 0 .../traj_1778873209642_c70e32ab.json | 0 .../traj_1778873211616_6db3b2cd.json | 0 .../traj_1778874205797_81e92307.json | 0 .../traj_1778874216773_c6b12ab2.json | 0 .../traj_1778874218579_a0225559.json | 0 .../traj_1778874224855_9c722c4b.json | 0 .../traj_1778874226983_3367d527.json | 0 .../traj_1778874229373_9cce9465.json | 0 .../traj_1778874240339_51b823cd.json | 0 .../traj_1778874241076_caa675a9.json | 0 .../traj_1778874248966_e29c4c54.json | 0 .../traj_1778874249983_12a98df3.json | 0 .../traj_1778874258229_0bdc53d8.json | 0 .../traj_1778874261453_55f49624.json | 0 .../traj_1778874261608_48fb9bf5.json | 0 .../traj_1778874269139_d7d7485a.json | 0 .../traj_1778874274412_70843e0e.json | 0 .../traj_1778874274581_71efa470.json | 0 .../traj_1778874282200_39ad11db.json | 0 .../traj_1778874283570_ce3585b8.json | 0 .../traj_1778874289674_e3f868c8.json | 0 .../traj_1778874291950_0b1b5c1f.json | 0 .../traj_1778874295927_4083d181.json | 0 .../traj_1778874296362_bdf727ff.json | 0 .trajectories/index.json | 1259 ----------------- package-lock.json | 11 +- packages/cli/package.json | 2 +- packages/sdk/package.json | 2 +- 348 files changed, 8 insertions(+), 1266 deletions(-) rename {.trajectories => .agentworkforce/trajectories}/compacted/compact_gqmrna24cmm4_2026-05-19.json (100%) rename {.trajectories => .agentworkforce/trajectories}/compacted/compact_gqmrna24cmm4_2026-05-19.md (100%) rename {.trajectories => .agentworkforce/trajectories}/compacted/compact_j5u7qhaw4q6a_2026-05-08.json (100%) rename {.trajectories => .agentworkforce/trajectories}/compacted/compact_j5u7qhaw4q6a_2026-05-08.md (100%) rename {.trajectories => .agentworkforce/trajectories}/compacted/release-6.0.13.json (100%) rename {.trajectories => .agentworkforce/trajectories}/compacted/release-6.0.13.md (100%) rename {.trajectories => .agentworkforce/trajectories}/compacted/release-6.2.3.json (100%) rename {.trajectories => .agentworkforce/trajectories}/compacted/release-6.2.3.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-04/traj_05xg7j388bc4.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-04/traj_05xg7j388bc4.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-04/traj_0t92gxaz6igh.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-04/traj_0t92gxaz6igh.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-04/traj_1776105620545_9dcebb3d.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-04/traj_1776105620545_9dcebb3d.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-04/traj_1776105988184_29f1270c.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-04/traj_1776105988184_29f1270c.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-04/traj_222ha5671idc.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-04/traj_222ha5671idc.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-04/traj_3b3p1z4y7qlo.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-04/traj_3b3p1z4y7qlo.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-04/traj_4zqhfqw7g28l.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-04/traj_4zqhfqw7g28l.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-04/traj_530xmbfeljyb.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-04/traj_530xmbfeljyb.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-04/traj_703m7sqyq89t.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-04/traj_703m7sqyq89t.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-04/traj_8oh4r5km5eic.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-04/traj_8oh4r5km5eic.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-04/traj_9tt55is74dq5.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-04/traj_9tt55is74dq5.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-04/traj_abjovknvcijv.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-04/traj_abjovknvcijv.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-04/traj_avmkyoo2s3rt.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-04/traj_avmkyoo2s3rt.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-04/traj_d48czxmgx4ac.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-04/traj_d48czxmgx4ac.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-04/traj_dw8ihhdb8ip7.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-04/traj_dw8ihhdb8ip7.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-04/traj_e5i62wdjx0jd.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-04/traj_e5i62wdjx0jd.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-04/traj_g3muawdq6bsb.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-04/traj_g3muawdq6bsb.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-04/traj_mk0t0cgn4ytq.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-04/traj_mk0t0cgn4ytq.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-04/traj_o8kgzhfu6jth.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-04/traj_o8kgzhfu6jth.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-04/traj_qb54w47qwod6.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-04/traj_qb54w47qwod6.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-04/traj_rs2bt3x0fqba.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-04/traj_rs2bt3x0fqba.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-04/traj_tjadoebpscps.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-04/traj_tjadoebpscps.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-04/traj_tv1x9pamkqad.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-04/traj_tv1x9pamkqad.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-04/traj_ui5omrgz819d.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-04/traj_ui5omrgz819d.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-04/traj_w0xpsaoxuiyw.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-04/traj_w0xpsaoxuiyw.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_0d1efjk6aeo2.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_0d1efjk6aeo2.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_0e8i20oitwvz.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_0e8i20oitwvz.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_0o6gb2wvk59t.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_0o6gb2wvk59t.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_0z98tkaigaxg.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_0z98tkaigaxg.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_1775914133873_35667beb.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_1775914133873_35667beb.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_1776073106646_1839be2d.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_1776073106646_1839be2d.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_1776113772922_bc92f121.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_1776113772922_bc92f121.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_1778873209642_c70e32ab.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_1778873209642_c70e32ab.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_1778873211616_6db3b2cd.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_1778873211616_6db3b2cd.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_17t39ue8exte/summary.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_17t39ue8exte/trajectory.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_1fjub7c9rlap.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_1fjub7c9rlap.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_1rrpe2r7fyem.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_1rrpe2r7fyem.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_2gpglosdsq7s.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_2gpglosdsq7s.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_2tqxnib25omk.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_2tqxnib25omk.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_2yicjxgajt0a.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_2yicjxgajt0a.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_34b1u84b19gz.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_34b1u84b19gz.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_3b3p1z4y7qlo.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_3b3p1z4y7qlo.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_3gjtcykvybt5.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_3gjtcykvybt5.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_47akjihewlow.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_47akjihewlow.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_47akjihewlow.trace.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_4chzkm724ufo.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_4chzkm724ufo.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_4t07itef99ug.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_4t07itef99ug.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_4vucir4qvqa2.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_4vucir4qvqa2.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_5k0jtc1g5l33.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_5k0jtc1g5l33.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_5nzj6v56id4z.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_5q8i0iz4klpo.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_5q8i0iz4klpo.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_5qbla7w4kzoi.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_5qbla7w4kzoi.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_60qc24ufr96g.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_60qc24ufr96g.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_6sjeohtm3php.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_6sjeohtm3php.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_6ujzpx82gqs9.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_6ujzpx82gqs9.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_78ytpicts778.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_78ytpicts778.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_7i9tigaejfje.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_7i9tigaejfje.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_7uznwzoxbao6.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_7uznwzoxbao6.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_7zu7et53ph3l.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_7zu7et53ph3l.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_81kobstnzzwk.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_8ljgydz61do5.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_8ljgydz61do5.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_8nhd9lljhbsw.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_8nhd9lljhbsw.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_90jmd9z27oap.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_90jmd9z27oap.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_947wzpddsg9j.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_947wzpddsg9j.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_9dj3qiugt26j.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_9dj3qiugt26j.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_9fdv7hxm0b60.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_9fdv7hxm0b60.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_9gq96irkj00s.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_9gq96irkj00s.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_aw7stgf4qau0.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_aw7stgf4qau0.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_b3g40827t5zh/summary.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_b3g40827t5zh/trajectory.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_bd431l65n9lg.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_bd431l65n9lg.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_bdrlknyl8twj.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_bdrlknyl8twj.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_bz1a1o15p7px.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_bz1a1o15p7px.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_cbmwd07phhm2.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_cbmwd07phhm2.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_ceo5q9bh2od3.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_ceo5q9bh2od3.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_cszfl2icaj2t.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_cszfl2icaj2t.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_d89s38ddu7cj.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_d89s38ddu7cj.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_dbsnr453nxjw.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_dbsnr453nxjw.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_dcl9hgoiuac5.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_dcl9hgoiuac5.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_dpgn0am1jq1c.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_dpgn0am1jq1c.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_e1b7ww3un1u3.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_e1b7ww3un1u3.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_elx0fcwgs37x.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_elx0fcwgs37x.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_erzd7j9nto9r.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_erzd7j9nto9r.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_f1iac9ngymlj.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_f1iac9ngymlj.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_f3arvbmmlomn.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_f3arvbmmlomn.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_f9wxa8ujeg78.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_f9wxa8ujeg78.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_fh8oosbijpwc.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_fh8oosbijpwc.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_fh8oosbijpwc.trace.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_fiygtgr3tfey.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_fiygtgr3tfey.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_gh05rj5gwsap.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_gh05rj5gwsap.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_gh05rj5gwsap.trace.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_gkxajksmwoea.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_gkxajksmwoea.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_gnqvtoxtc8dy.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_gnqvtoxtc8dy.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_hfkww5z7trxn.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_hfkww5z7trxn.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_hrsndfzk0qay.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_hrsndfzk0qay.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_hysw5o7idqas.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_hysw5o7idqas.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_i2pjnx3dll5b.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_i2pjnx3dll5b.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_i2pjnx3dll5b.trace.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_ij5b3kcatvwn.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_ij5b3kcatvwn.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_iole5zdt9orr.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_iole5zdt9orr.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_irafiyk6wpw0.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_itgr2w8qs3xn.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_itgr2w8qs3xn.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_j9k10fez3e81.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_j9k10fez3e81.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_jbo2x14y7ovt.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_jbo2x14y7ovt.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_jmf9pyt3zikn.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_jmf9pyt3zikn.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_k7njijv51iq4.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_k7njijv51iq4.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_kgl2opmmfvus.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_kgl2opmmfvus.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_l1349adi1g0o.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_l1349adi1g0o.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_l67sex3nkzfq.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_l67sex3nkzfq.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_lhyrcib40kao.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_lhyrcib40kao.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_lieyyspidhfj.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_lieyyspidhfj.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_lieyyspidhfj.trace.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_m7mpv7j8n78h.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_m7mpv7j8n78h.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_mi9eqd4rjfea.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_mi9eqd4rjfea.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_mytnzgfayj3d.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_mytnzgfayj3d.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_mz5m5ysjj31e.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_mz5m5ysjj31e.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_n0qwpjvmdl2s.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_n0qwpjvmdl2s.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_n8duofq5vq1a.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_n8duofq5vq1a.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_o251whkvy9rl.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_o251whkvy9rl.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_o9cx33xn5u39.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_o9cx33xn5u39.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_ootb5rt3tozd.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_ootb5rt3tozd.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_oyc528j7suvo.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_oyc528j7suvo.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_piik8r6zu3i7.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_piik8r6zu3i7.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_pmrcfj6or3pz.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_pmrcfj6or3pz.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_q2r3c9dmdep7.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_q2r3c9dmdep7.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_qbq3laxbvhzf.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_qbq3laxbvhzf.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_qtmid2nzz0kz.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_qtmid2nzz0kz.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_ryf5sstno6p3.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_ryf5sstno6p3.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_s5ojo1f4srz4.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_s5ojo1f4srz4.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_sh2ahp9z2xg6.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_sh2ahp9z2xg6.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_sqerp89tc436.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_sqerp89tc436.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_t5uknesn2fcw.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_t5uknesn2fcw.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_t6h534vn0bpg.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_t6h534vn0bpg.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_tavtex0db4b0.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_tavtex0db4b0.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_tgism98me5na.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_tgism98me5na.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_u33qn99ijbh4.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_u33qn99ijbh4.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_u3loicehnwb4.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_u3loicehnwb4.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_u4ixmbqqm2y1.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_u4ixmbqqm2y1.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_uf8y40ewrfh0.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_uf8y40ewrfh0.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_v1wexlfur5zr.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_v1wexlfur5zr.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_v87cyrs8dke9.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_v87cyrs8dke9.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_v87cyrs8dke9.trace.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_v9x3o92ag682.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_v9x3o92ag682.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_vfa1jr6otnjn.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_vfa1jr6otnjn.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_vkozdglobkyg.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_vkozdglobkyg.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_wbn62q4cq16h.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_wbn62q4cq16h.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_whd40oxptlhn.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_whd40oxptlhn.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_whd40oxptlhn.trace.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_wx00tjvpptvg.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_wx00tjvpptvg.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_wzzboitm85ee.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_wzzboitm85ee.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_x37bhga2j5ph.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_x37bhga2j5ph.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_ybcrij9wg8m1.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_ybcrij9wg8m1.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_z171lng2fbbi.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_z171lng2fbbi.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_zfa6skfr32vy.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_zfa6skfr32vy.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_zqwco4gl76g3.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_zqwco4gl76g3.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_zu3252hxzoqh.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_zu3252hxzoqh.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_zyluvmlqo5j7.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/2026-05/traj_zyluvmlqo5j7.md (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/traj_1775914296101_a4397efe.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/traj_1776024661304_cfc829b9.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/traj_1776105620545_9dcebb3d.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/traj_1778873052429_03a4dacb.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/traj_1778873197540_01102ade.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/traj_1778873199489_f2ce4060.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/traj_1778873201502_0dacf7c5.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/traj_1778873203502_4c225b7e.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/traj_1778873205470_a4e5f0cb.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/traj_1778873207471_b7def991.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/traj_1778873209642_c70e32ab.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/traj_1778873211616_6db3b2cd.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/traj_1778874205797_81e92307.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/traj_1778874216773_c6b12ab2.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/traj_1778874218579_a0225559.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/traj_1778874224855_9c722c4b.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/traj_1778874226983_3367d527.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/traj_1778874229373_9cce9465.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/traj_1778874240339_51b823cd.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/traj_1778874241076_caa675a9.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/traj_1778874248966_e29c4c54.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/traj_1778874249983_12a98df3.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/traj_1778874258229_0bdc53d8.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/traj_1778874261453_55f49624.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/traj_1778874261608_48fb9bf5.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/traj_1778874269139_d7d7485a.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/traj_1778874274412_70843e0e.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/traj_1778874274581_71efa470.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/traj_1778874282200_39ad11db.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/traj_1778874283570_ce3585b8.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/traj_1778874289674_e3f868c8.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/traj_1778874291950_0b1b5c1f.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/traj_1778874295927_4083d181.json (100%) rename {.trajectories => .agentworkforce/trajectories}/completed/traj_1778874296362_bdf727ff.json (100%) delete mode 100644 .trajectories/index.json diff --git a/.trajectories/compacted/compact_gqmrna24cmm4_2026-05-19.json b/.agentworkforce/trajectories/compacted/compact_gqmrna24cmm4_2026-05-19.json similarity index 100% rename from .trajectories/compacted/compact_gqmrna24cmm4_2026-05-19.json rename to .agentworkforce/trajectories/compacted/compact_gqmrna24cmm4_2026-05-19.json diff --git a/.trajectories/compacted/compact_gqmrna24cmm4_2026-05-19.md b/.agentworkforce/trajectories/compacted/compact_gqmrna24cmm4_2026-05-19.md similarity index 100% rename from .trajectories/compacted/compact_gqmrna24cmm4_2026-05-19.md rename to .agentworkforce/trajectories/compacted/compact_gqmrna24cmm4_2026-05-19.md diff --git a/.trajectories/compacted/compact_j5u7qhaw4q6a_2026-05-08.json b/.agentworkforce/trajectories/compacted/compact_j5u7qhaw4q6a_2026-05-08.json similarity index 100% rename from .trajectories/compacted/compact_j5u7qhaw4q6a_2026-05-08.json rename to .agentworkforce/trajectories/compacted/compact_j5u7qhaw4q6a_2026-05-08.json diff --git a/.trajectories/compacted/compact_j5u7qhaw4q6a_2026-05-08.md b/.agentworkforce/trajectories/compacted/compact_j5u7qhaw4q6a_2026-05-08.md similarity index 100% rename from .trajectories/compacted/compact_j5u7qhaw4q6a_2026-05-08.md rename to .agentworkforce/trajectories/compacted/compact_j5u7qhaw4q6a_2026-05-08.md diff --git a/.trajectories/compacted/release-6.0.13.json b/.agentworkforce/trajectories/compacted/release-6.0.13.json similarity index 100% rename from .trajectories/compacted/release-6.0.13.json rename to .agentworkforce/trajectories/compacted/release-6.0.13.json diff --git a/.trajectories/compacted/release-6.0.13.md b/.agentworkforce/trajectories/compacted/release-6.0.13.md similarity index 100% rename from .trajectories/compacted/release-6.0.13.md rename to .agentworkforce/trajectories/compacted/release-6.0.13.md diff --git a/.trajectories/compacted/release-6.2.3.json b/.agentworkforce/trajectories/compacted/release-6.2.3.json similarity index 100% rename from .trajectories/compacted/release-6.2.3.json rename to .agentworkforce/trajectories/compacted/release-6.2.3.json diff --git a/.trajectories/compacted/release-6.2.3.md b/.agentworkforce/trajectories/compacted/release-6.2.3.md similarity index 100% rename from .trajectories/compacted/release-6.2.3.md rename to .agentworkforce/trajectories/compacted/release-6.2.3.md diff --git a/.trajectories/completed/2026-04/traj_05xg7j388bc4.json b/.agentworkforce/trajectories/completed/2026-04/traj_05xg7j388bc4.json similarity index 100% rename from .trajectories/completed/2026-04/traj_05xg7j388bc4.json rename to .agentworkforce/trajectories/completed/2026-04/traj_05xg7j388bc4.json diff --git a/.trajectories/completed/2026-04/traj_05xg7j388bc4.md b/.agentworkforce/trajectories/completed/2026-04/traj_05xg7j388bc4.md similarity index 100% rename from .trajectories/completed/2026-04/traj_05xg7j388bc4.md rename to .agentworkforce/trajectories/completed/2026-04/traj_05xg7j388bc4.md diff --git a/.trajectories/completed/2026-04/traj_0t92gxaz6igh.json b/.agentworkforce/trajectories/completed/2026-04/traj_0t92gxaz6igh.json similarity index 100% rename from .trajectories/completed/2026-04/traj_0t92gxaz6igh.json rename to .agentworkforce/trajectories/completed/2026-04/traj_0t92gxaz6igh.json diff --git a/.trajectories/completed/2026-04/traj_0t92gxaz6igh.md b/.agentworkforce/trajectories/completed/2026-04/traj_0t92gxaz6igh.md similarity index 100% rename from .trajectories/completed/2026-04/traj_0t92gxaz6igh.md rename to .agentworkforce/trajectories/completed/2026-04/traj_0t92gxaz6igh.md diff --git a/.trajectories/completed/2026-04/traj_1776105620545_9dcebb3d.json b/.agentworkforce/trajectories/completed/2026-04/traj_1776105620545_9dcebb3d.json similarity index 100% rename from .trajectories/completed/2026-04/traj_1776105620545_9dcebb3d.json rename to .agentworkforce/trajectories/completed/2026-04/traj_1776105620545_9dcebb3d.json diff --git a/.trajectories/completed/2026-04/traj_1776105620545_9dcebb3d.md b/.agentworkforce/trajectories/completed/2026-04/traj_1776105620545_9dcebb3d.md similarity index 100% rename from .trajectories/completed/2026-04/traj_1776105620545_9dcebb3d.md rename to .agentworkforce/trajectories/completed/2026-04/traj_1776105620545_9dcebb3d.md diff --git a/.trajectories/completed/2026-04/traj_1776105988184_29f1270c.json b/.agentworkforce/trajectories/completed/2026-04/traj_1776105988184_29f1270c.json similarity index 100% rename from .trajectories/completed/2026-04/traj_1776105988184_29f1270c.json rename to .agentworkforce/trajectories/completed/2026-04/traj_1776105988184_29f1270c.json diff --git a/.trajectories/completed/2026-04/traj_1776105988184_29f1270c.md b/.agentworkforce/trajectories/completed/2026-04/traj_1776105988184_29f1270c.md similarity index 100% rename from .trajectories/completed/2026-04/traj_1776105988184_29f1270c.md rename to .agentworkforce/trajectories/completed/2026-04/traj_1776105988184_29f1270c.md diff --git a/.trajectories/completed/2026-04/traj_222ha5671idc.json b/.agentworkforce/trajectories/completed/2026-04/traj_222ha5671idc.json similarity index 100% rename from .trajectories/completed/2026-04/traj_222ha5671idc.json rename to .agentworkforce/trajectories/completed/2026-04/traj_222ha5671idc.json diff --git a/.trajectories/completed/2026-04/traj_222ha5671idc.md b/.agentworkforce/trajectories/completed/2026-04/traj_222ha5671idc.md similarity index 100% rename from .trajectories/completed/2026-04/traj_222ha5671idc.md rename to .agentworkforce/trajectories/completed/2026-04/traj_222ha5671idc.md diff --git a/.trajectories/completed/2026-04/traj_3b3p1z4y7qlo.json b/.agentworkforce/trajectories/completed/2026-04/traj_3b3p1z4y7qlo.json similarity index 100% rename from .trajectories/completed/2026-04/traj_3b3p1z4y7qlo.json rename to .agentworkforce/trajectories/completed/2026-04/traj_3b3p1z4y7qlo.json diff --git a/.trajectories/completed/2026-04/traj_3b3p1z4y7qlo.md b/.agentworkforce/trajectories/completed/2026-04/traj_3b3p1z4y7qlo.md similarity index 100% rename from .trajectories/completed/2026-04/traj_3b3p1z4y7qlo.md rename to .agentworkforce/trajectories/completed/2026-04/traj_3b3p1z4y7qlo.md diff --git a/.trajectories/completed/2026-04/traj_4zqhfqw7g28l.json b/.agentworkforce/trajectories/completed/2026-04/traj_4zqhfqw7g28l.json similarity index 100% rename from .trajectories/completed/2026-04/traj_4zqhfqw7g28l.json rename to .agentworkforce/trajectories/completed/2026-04/traj_4zqhfqw7g28l.json diff --git a/.trajectories/completed/2026-04/traj_4zqhfqw7g28l.md b/.agentworkforce/trajectories/completed/2026-04/traj_4zqhfqw7g28l.md similarity index 100% rename from .trajectories/completed/2026-04/traj_4zqhfqw7g28l.md rename to .agentworkforce/trajectories/completed/2026-04/traj_4zqhfqw7g28l.md diff --git a/.trajectories/completed/2026-04/traj_530xmbfeljyb.json b/.agentworkforce/trajectories/completed/2026-04/traj_530xmbfeljyb.json similarity index 100% rename from .trajectories/completed/2026-04/traj_530xmbfeljyb.json rename to .agentworkforce/trajectories/completed/2026-04/traj_530xmbfeljyb.json diff --git a/.trajectories/completed/2026-04/traj_530xmbfeljyb.md b/.agentworkforce/trajectories/completed/2026-04/traj_530xmbfeljyb.md similarity index 100% rename from .trajectories/completed/2026-04/traj_530xmbfeljyb.md rename to .agentworkforce/trajectories/completed/2026-04/traj_530xmbfeljyb.md diff --git a/.trajectories/completed/2026-04/traj_703m7sqyq89t.json b/.agentworkforce/trajectories/completed/2026-04/traj_703m7sqyq89t.json similarity index 100% rename from .trajectories/completed/2026-04/traj_703m7sqyq89t.json rename to .agentworkforce/trajectories/completed/2026-04/traj_703m7sqyq89t.json diff --git a/.trajectories/completed/2026-04/traj_703m7sqyq89t.md b/.agentworkforce/trajectories/completed/2026-04/traj_703m7sqyq89t.md similarity index 100% rename from .trajectories/completed/2026-04/traj_703m7sqyq89t.md rename to .agentworkforce/trajectories/completed/2026-04/traj_703m7sqyq89t.md diff --git a/.trajectories/completed/2026-04/traj_8oh4r5km5eic.json b/.agentworkforce/trajectories/completed/2026-04/traj_8oh4r5km5eic.json similarity index 100% rename from .trajectories/completed/2026-04/traj_8oh4r5km5eic.json rename to .agentworkforce/trajectories/completed/2026-04/traj_8oh4r5km5eic.json diff --git a/.trajectories/completed/2026-04/traj_8oh4r5km5eic.md b/.agentworkforce/trajectories/completed/2026-04/traj_8oh4r5km5eic.md similarity index 100% rename from .trajectories/completed/2026-04/traj_8oh4r5km5eic.md rename to .agentworkforce/trajectories/completed/2026-04/traj_8oh4r5km5eic.md diff --git a/.trajectories/completed/2026-04/traj_9tt55is74dq5.json b/.agentworkforce/trajectories/completed/2026-04/traj_9tt55is74dq5.json similarity index 100% rename from .trajectories/completed/2026-04/traj_9tt55is74dq5.json rename to .agentworkforce/trajectories/completed/2026-04/traj_9tt55is74dq5.json diff --git a/.trajectories/completed/2026-04/traj_9tt55is74dq5.md b/.agentworkforce/trajectories/completed/2026-04/traj_9tt55is74dq5.md similarity index 100% rename from .trajectories/completed/2026-04/traj_9tt55is74dq5.md rename to .agentworkforce/trajectories/completed/2026-04/traj_9tt55is74dq5.md diff --git a/.trajectories/completed/2026-04/traj_abjovknvcijv.json b/.agentworkforce/trajectories/completed/2026-04/traj_abjovknvcijv.json similarity index 100% rename from .trajectories/completed/2026-04/traj_abjovknvcijv.json rename to .agentworkforce/trajectories/completed/2026-04/traj_abjovknvcijv.json diff --git a/.trajectories/completed/2026-04/traj_abjovknvcijv.md b/.agentworkforce/trajectories/completed/2026-04/traj_abjovknvcijv.md similarity index 100% rename from .trajectories/completed/2026-04/traj_abjovknvcijv.md rename to .agentworkforce/trajectories/completed/2026-04/traj_abjovknvcijv.md diff --git a/.trajectories/completed/2026-04/traj_avmkyoo2s3rt.json b/.agentworkforce/trajectories/completed/2026-04/traj_avmkyoo2s3rt.json similarity index 100% rename from .trajectories/completed/2026-04/traj_avmkyoo2s3rt.json rename to .agentworkforce/trajectories/completed/2026-04/traj_avmkyoo2s3rt.json diff --git a/.trajectories/completed/2026-04/traj_avmkyoo2s3rt.md b/.agentworkforce/trajectories/completed/2026-04/traj_avmkyoo2s3rt.md similarity index 100% rename from .trajectories/completed/2026-04/traj_avmkyoo2s3rt.md rename to .agentworkforce/trajectories/completed/2026-04/traj_avmkyoo2s3rt.md diff --git a/.trajectories/completed/2026-04/traj_d48czxmgx4ac.json b/.agentworkforce/trajectories/completed/2026-04/traj_d48czxmgx4ac.json similarity index 100% rename from .trajectories/completed/2026-04/traj_d48czxmgx4ac.json rename to .agentworkforce/trajectories/completed/2026-04/traj_d48czxmgx4ac.json diff --git a/.trajectories/completed/2026-04/traj_d48czxmgx4ac.md b/.agentworkforce/trajectories/completed/2026-04/traj_d48czxmgx4ac.md similarity index 100% rename from .trajectories/completed/2026-04/traj_d48czxmgx4ac.md rename to .agentworkforce/trajectories/completed/2026-04/traj_d48czxmgx4ac.md diff --git a/.trajectories/completed/2026-04/traj_dw8ihhdb8ip7.json b/.agentworkforce/trajectories/completed/2026-04/traj_dw8ihhdb8ip7.json similarity index 100% rename from .trajectories/completed/2026-04/traj_dw8ihhdb8ip7.json rename to .agentworkforce/trajectories/completed/2026-04/traj_dw8ihhdb8ip7.json diff --git a/.trajectories/completed/2026-04/traj_dw8ihhdb8ip7.md b/.agentworkforce/trajectories/completed/2026-04/traj_dw8ihhdb8ip7.md similarity index 100% rename from .trajectories/completed/2026-04/traj_dw8ihhdb8ip7.md rename to .agentworkforce/trajectories/completed/2026-04/traj_dw8ihhdb8ip7.md diff --git a/.trajectories/completed/2026-04/traj_e5i62wdjx0jd.json b/.agentworkforce/trajectories/completed/2026-04/traj_e5i62wdjx0jd.json similarity index 100% rename from .trajectories/completed/2026-04/traj_e5i62wdjx0jd.json rename to .agentworkforce/trajectories/completed/2026-04/traj_e5i62wdjx0jd.json diff --git a/.trajectories/completed/2026-04/traj_e5i62wdjx0jd.md b/.agentworkforce/trajectories/completed/2026-04/traj_e5i62wdjx0jd.md similarity index 100% rename from .trajectories/completed/2026-04/traj_e5i62wdjx0jd.md rename to .agentworkforce/trajectories/completed/2026-04/traj_e5i62wdjx0jd.md diff --git a/.trajectories/completed/2026-04/traj_g3muawdq6bsb.json b/.agentworkforce/trajectories/completed/2026-04/traj_g3muawdq6bsb.json similarity index 100% rename from .trajectories/completed/2026-04/traj_g3muawdq6bsb.json rename to .agentworkforce/trajectories/completed/2026-04/traj_g3muawdq6bsb.json diff --git a/.trajectories/completed/2026-04/traj_g3muawdq6bsb.md b/.agentworkforce/trajectories/completed/2026-04/traj_g3muawdq6bsb.md similarity index 100% rename from .trajectories/completed/2026-04/traj_g3muawdq6bsb.md rename to .agentworkforce/trajectories/completed/2026-04/traj_g3muawdq6bsb.md diff --git a/.trajectories/completed/2026-04/traj_mk0t0cgn4ytq.json b/.agentworkforce/trajectories/completed/2026-04/traj_mk0t0cgn4ytq.json similarity index 100% rename from .trajectories/completed/2026-04/traj_mk0t0cgn4ytq.json rename to .agentworkforce/trajectories/completed/2026-04/traj_mk0t0cgn4ytq.json diff --git a/.trajectories/completed/2026-04/traj_mk0t0cgn4ytq.md b/.agentworkforce/trajectories/completed/2026-04/traj_mk0t0cgn4ytq.md similarity index 100% rename from .trajectories/completed/2026-04/traj_mk0t0cgn4ytq.md rename to .agentworkforce/trajectories/completed/2026-04/traj_mk0t0cgn4ytq.md diff --git a/.trajectories/completed/2026-04/traj_o8kgzhfu6jth.json b/.agentworkforce/trajectories/completed/2026-04/traj_o8kgzhfu6jth.json similarity index 100% rename from .trajectories/completed/2026-04/traj_o8kgzhfu6jth.json rename to .agentworkforce/trajectories/completed/2026-04/traj_o8kgzhfu6jth.json diff --git a/.trajectories/completed/2026-04/traj_o8kgzhfu6jth.md b/.agentworkforce/trajectories/completed/2026-04/traj_o8kgzhfu6jth.md similarity index 100% rename from .trajectories/completed/2026-04/traj_o8kgzhfu6jth.md rename to .agentworkforce/trajectories/completed/2026-04/traj_o8kgzhfu6jth.md diff --git a/.trajectories/completed/2026-04/traj_qb54w47qwod6.json b/.agentworkforce/trajectories/completed/2026-04/traj_qb54w47qwod6.json similarity index 100% rename from .trajectories/completed/2026-04/traj_qb54w47qwod6.json rename to .agentworkforce/trajectories/completed/2026-04/traj_qb54w47qwod6.json diff --git a/.trajectories/completed/2026-04/traj_qb54w47qwod6.md b/.agentworkforce/trajectories/completed/2026-04/traj_qb54w47qwod6.md similarity index 100% rename from .trajectories/completed/2026-04/traj_qb54w47qwod6.md rename to .agentworkforce/trajectories/completed/2026-04/traj_qb54w47qwod6.md diff --git a/.trajectories/completed/2026-04/traj_rs2bt3x0fqba.json b/.agentworkforce/trajectories/completed/2026-04/traj_rs2bt3x0fqba.json similarity index 100% rename from .trajectories/completed/2026-04/traj_rs2bt3x0fqba.json rename to .agentworkforce/trajectories/completed/2026-04/traj_rs2bt3x0fqba.json diff --git a/.trajectories/completed/2026-04/traj_rs2bt3x0fqba.md b/.agentworkforce/trajectories/completed/2026-04/traj_rs2bt3x0fqba.md similarity index 100% rename from .trajectories/completed/2026-04/traj_rs2bt3x0fqba.md rename to .agentworkforce/trajectories/completed/2026-04/traj_rs2bt3x0fqba.md diff --git a/.trajectories/completed/2026-04/traj_tjadoebpscps.json b/.agentworkforce/trajectories/completed/2026-04/traj_tjadoebpscps.json similarity index 100% rename from .trajectories/completed/2026-04/traj_tjadoebpscps.json rename to .agentworkforce/trajectories/completed/2026-04/traj_tjadoebpscps.json diff --git a/.trajectories/completed/2026-04/traj_tjadoebpscps.md b/.agentworkforce/trajectories/completed/2026-04/traj_tjadoebpscps.md similarity index 100% rename from .trajectories/completed/2026-04/traj_tjadoebpscps.md rename to .agentworkforce/trajectories/completed/2026-04/traj_tjadoebpscps.md diff --git a/.trajectories/completed/2026-04/traj_tv1x9pamkqad.json b/.agentworkforce/trajectories/completed/2026-04/traj_tv1x9pamkqad.json similarity index 100% rename from .trajectories/completed/2026-04/traj_tv1x9pamkqad.json rename to .agentworkforce/trajectories/completed/2026-04/traj_tv1x9pamkqad.json diff --git a/.trajectories/completed/2026-04/traj_tv1x9pamkqad.md b/.agentworkforce/trajectories/completed/2026-04/traj_tv1x9pamkqad.md similarity index 100% rename from .trajectories/completed/2026-04/traj_tv1x9pamkqad.md rename to .agentworkforce/trajectories/completed/2026-04/traj_tv1x9pamkqad.md diff --git a/.trajectories/completed/2026-04/traj_ui5omrgz819d.json b/.agentworkforce/trajectories/completed/2026-04/traj_ui5omrgz819d.json similarity index 100% rename from .trajectories/completed/2026-04/traj_ui5omrgz819d.json rename to .agentworkforce/trajectories/completed/2026-04/traj_ui5omrgz819d.json diff --git a/.trajectories/completed/2026-04/traj_ui5omrgz819d.md b/.agentworkforce/trajectories/completed/2026-04/traj_ui5omrgz819d.md similarity index 100% rename from .trajectories/completed/2026-04/traj_ui5omrgz819d.md rename to .agentworkforce/trajectories/completed/2026-04/traj_ui5omrgz819d.md diff --git a/.trajectories/completed/2026-04/traj_w0xpsaoxuiyw.json b/.agentworkforce/trajectories/completed/2026-04/traj_w0xpsaoxuiyw.json similarity index 100% rename from .trajectories/completed/2026-04/traj_w0xpsaoxuiyw.json rename to .agentworkforce/trajectories/completed/2026-04/traj_w0xpsaoxuiyw.json diff --git a/.trajectories/completed/2026-04/traj_w0xpsaoxuiyw.md b/.agentworkforce/trajectories/completed/2026-04/traj_w0xpsaoxuiyw.md similarity index 100% rename from .trajectories/completed/2026-04/traj_w0xpsaoxuiyw.md rename to .agentworkforce/trajectories/completed/2026-04/traj_w0xpsaoxuiyw.md diff --git a/.trajectories/completed/2026-05/traj_0d1efjk6aeo2.json b/.agentworkforce/trajectories/completed/2026-05/traj_0d1efjk6aeo2.json similarity index 100% rename from .trajectories/completed/2026-05/traj_0d1efjk6aeo2.json rename to .agentworkforce/trajectories/completed/2026-05/traj_0d1efjk6aeo2.json diff --git a/.trajectories/completed/2026-05/traj_0d1efjk6aeo2.md b/.agentworkforce/trajectories/completed/2026-05/traj_0d1efjk6aeo2.md similarity index 100% rename from .trajectories/completed/2026-05/traj_0d1efjk6aeo2.md rename to .agentworkforce/trajectories/completed/2026-05/traj_0d1efjk6aeo2.md diff --git a/.trajectories/completed/2026-05/traj_0e8i20oitwvz.json b/.agentworkforce/trajectories/completed/2026-05/traj_0e8i20oitwvz.json similarity index 100% rename from .trajectories/completed/2026-05/traj_0e8i20oitwvz.json rename to .agentworkforce/trajectories/completed/2026-05/traj_0e8i20oitwvz.json diff --git a/.trajectories/completed/2026-05/traj_0e8i20oitwvz.md b/.agentworkforce/trajectories/completed/2026-05/traj_0e8i20oitwvz.md similarity index 100% rename from .trajectories/completed/2026-05/traj_0e8i20oitwvz.md rename to .agentworkforce/trajectories/completed/2026-05/traj_0e8i20oitwvz.md diff --git a/.trajectories/completed/2026-05/traj_0o6gb2wvk59t.json b/.agentworkforce/trajectories/completed/2026-05/traj_0o6gb2wvk59t.json similarity index 100% rename from .trajectories/completed/2026-05/traj_0o6gb2wvk59t.json rename to .agentworkforce/trajectories/completed/2026-05/traj_0o6gb2wvk59t.json diff --git a/.trajectories/completed/2026-05/traj_0o6gb2wvk59t.md b/.agentworkforce/trajectories/completed/2026-05/traj_0o6gb2wvk59t.md similarity index 100% rename from .trajectories/completed/2026-05/traj_0o6gb2wvk59t.md rename to .agentworkforce/trajectories/completed/2026-05/traj_0o6gb2wvk59t.md diff --git a/.trajectories/completed/2026-05/traj_0z98tkaigaxg.json b/.agentworkforce/trajectories/completed/2026-05/traj_0z98tkaigaxg.json similarity index 100% rename from .trajectories/completed/2026-05/traj_0z98tkaigaxg.json rename to .agentworkforce/trajectories/completed/2026-05/traj_0z98tkaigaxg.json diff --git a/.trajectories/completed/2026-05/traj_0z98tkaigaxg.md b/.agentworkforce/trajectories/completed/2026-05/traj_0z98tkaigaxg.md similarity index 100% rename from .trajectories/completed/2026-05/traj_0z98tkaigaxg.md rename to .agentworkforce/trajectories/completed/2026-05/traj_0z98tkaigaxg.md diff --git a/.trajectories/completed/2026-05/traj_1775914133873_35667beb.json b/.agentworkforce/trajectories/completed/2026-05/traj_1775914133873_35667beb.json similarity index 100% rename from .trajectories/completed/2026-05/traj_1775914133873_35667beb.json rename to .agentworkforce/trajectories/completed/2026-05/traj_1775914133873_35667beb.json diff --git a/.trajectories/completed/2026-05/traj_1775914133873_35667beb.md b/.agentworkforce/trajectories/completed/2026-05/traj_1775914133873_35667beb.md similarity index 100% rename from .trajectories/completed/2026-05/traj_1775914133873_35667beb.md rename to .agentworkforce/trajectories/completed/2026-05/traj_1775914133873_35667beb.md diff --git a/.trajectories/completed/2026-05/traj_1776073106646_1839be2d.json b/.agentworkforce/trajectories/completed/2026-05/traj_1776073106646_1839be2d.json similarity index 100% rename from .trajectories/completed/2026-05/traj_1776073106646_1839be2d.json rename to .agentworkforce/trajectories/completed/2026-05/traj_1776073106646_1839be2d.json diff --git a/.trajectories/completed/2026-05/traj_1776073106646_1839be2d.md b/.agentworkforce/trajectories/completed/2026-05/traj_1776073106646_1839be2d.md similarity index 100% rename from .trajectories/completed/2026-05/traj_1776073106646_1839be2d.md rename to .agentworkforce/trajectories/completed/2026-05/traj_1776073106646_1839be2d.md diff --git a/.trajectories/completed/2026-05/traj_1776113772922_bc92f121.json b/.agentworkforce/trajectories/completed/2026-05/traj_1776113772922_bc92f121.json similarity index 100% rename from .trajectories/completed/2026-05/traj_1776113772922_bc92f121.json rename to .agentworkforce/trajectories/completed/2026-05/traj_1776113772922_bc92f121.json diff --git a/.trajectories/completed/2026-05/traj_1776113772922_bc92f121.md b/.agentworkforce/trajectories/completed/2026-05/traj_1776113772922_bc92f121.md similarity index 100% rename from .trajectories/completed/2026-05/traj_1776113772922_bc92f121.md rename to .agentworkforce/trajectories/completed/2026-05/traj_1776113772922_bc92f121.md diff --git a/.trajectories/completed/2026-05/traj_1778873209642_c70e32ab.json b/.agentworkforce/trajectories/completed/2026-05/traj_1778873209642_c70e32ab.json similarity index 100% rename from .trajectories/completed/2026-05/traj_1778873209642_c70e32ab.json rename to .agentworkforce/trajectories/completed/2026-05/traj_1778873209642_c70e32ab.json diff --git a/.trajectories/completed/2026-05/traj_1778873209642_c70e32ab.md b/.agentworkforce/trajectories/completed/2026-05/traj_1778873209642_c70e32ab.md similarity index 100% rename from .trajectories/completed/2026-05/traj_1778873209642_c70e32ab.md rename to .agentworkforce/trajectories/completed/2026-05/traj_1778873209642_c70e32ab.md diff --git a/.trajectories/completed/2026-05/traj_1778873211616_6db3b2cd.json b/.agentworkforce/trajectories/completed/2026-05/traj_1778873211616_6db3b2cd.json similarity index 100% rename from .trajectories/completed/2026-05/traj_1778873211616_6db3b2cd.json rename to .agentworkforce/trajectories/completed/2026-05/traj_1778873211616_6db3b2cd.json diff --git a/.trajectories/completed/2026-05/traj_1778873211616_6db3b2cd.md b/.agentworkforce/trajectories/completed/2026-05/traj_1778873211616_6db3b2cd.md similarity index 100% rename from .trajectories/completed/2026-05/traj_1778873211616_6db3b2cd.md rename to .agentworkforce/trajectories/completed/2026-05/traj_1778873211616_6db3b2cd.md diff --git a/.trajectories/completed/2026-05/traj_17t39ue8exte/summary.md b/.agentworkforce/trajectories/completed/2026-05/traj_17t39ue8exte/summary.md similarity index 100% rename from .trajectories/completed/2026-05/traj_17t39ue8exte/summary.md rename to .agentworkforce/trajectories/completed/2026-05/traj_17t39ue8exte/summary.md diff --git a/.trajectories/completed/2026-05/traj_17t39ue8exte/trajectory.json b/.agentworkforce/trajectories/completed/2026-05/traj_17t39ue8exte/trajectory.json similarity index 100% rename from .trajectories/completed/2026-05/traj_17t39ue8exte/trajectory.json rename to .agentworkforce/trajectories/completed/2026-05/traj_17t39ue8exte/trajectory.json diff --git a/.trajectories/completed/2026-05/traj_1fjub7c9rlap.json b/.agentworkforce/trajectories/completed/2026-05/traj_1fjub7c9rlap.json similarity index 100% rename from .trajectories/completed/2026-05/traj_1fjub7c9rlap.json rename to .agentworkforce/trajectories/completed/2026-05/traj_1fjub7c9rlap.json diff --git a/.trajectories/completed/2026-05/traj_1fjub7c9rlap.md b/.agentworkforce/trajectories/completed/2026-05/traj_1fjub7c9rlap.md similarity index 100% rename from .trajectories/completed/2026-05/traj_1fjub7c9rlap.md rename to .agentworkforce/trajectories/completed/2026-05/traj_1fjub7c9rlap.md diff --git a/.trajectories/completed/2026-05/traj_1rrpe2r7fyem.json b/.agentworkforce/trajectories/completed/2026-05/traj_1rrpe2r7fyem.json similarity index 100% rename from .trajectories/completed/2026-05/traj_1rrpe2r7fyem.json rename to .agentworkforce/trajectories/completed/2026-05/traj_1rrpe2r7fyem.json diff --git a/.trajectories/completed/2026-05/traj_1rrpe2r7fyem.md b/.agentworkforce/trajectories/completed/2026-05/traj_1rrpe2r7fyem.md similarity index 100% rename from .trajectories/completed/2026-05/traj_1rrpe2r7fyem.md rename to .agentworkforce/trajectories/completed/2026-05/traj_1rrpe2r7fyem.md diff --git a/.trajectories/completed/2026-05/traj_2gpglosdsq7s.json b/.agentworkforce/trajectories/completed/2026-05/traj_2gpglosdsq7s.json similarity index 100% rename from .trajectories/completed/2026-05/traj_2gpglosdsq7s.json rename to .agentworkforce/trajectories/completed/2026-05/traj_2gpglosdsq7s.json diff --git a/.trajectories/completed/2026-05/traj_2gpglosdsq7s.md b/.agentworkforce/trajectories/completed/2026-05/traj_2gpglosdsq7s.md similarity index 100% rename from .trajectories/completed/2026-05/traj_2gpglosdsq7s.md rename to .agentworkforce/trajectories/completed/2026-05/traj_2gpglosdsq7s.md diff --git a/.trajectories/completed/2026-05/traj_2tqxnib25omk.json b/.agentworkforce/trajectories/completed/2026-05/traj_2tqxnib25omk.json similarity index 100% rename from .trajectories/completed/2026-05/traj_2tqxnib25omk.json rename to .agentworkforce/trajectories/completed/2026-05/traj_2tqxnib25omk.json diff --git a/.trajectories/completed/2026-05/traj_2tqxnib25omk.md b/.agentworkforce/trajectories/completed/2026-05/traj_2tqxnib25omk.md similarity index 100% rename from .trajectories/completed/2026-05/traj_2tqxnib25omk.md rename to .agentworkforce/trajectories/completed/2026-05/traj_2tqxnib25omk.md diff --git a/.trajectories/completed/2026-05/traj_2yicjxgajt0a.json b/.agentworkforce/trajectories/completed/2026-05/traj_2yicjxgajt0a.json similarity index 100% rename from .trajectories/completed/2026-05/traj_2yicjxgajt0a.json rename to .agentworkforce/trajectories/completed/2026-05/traj_2yicjxgajt0a.json diff --git a/.trajectories/completed/2026-05/traj_2yicjxgajt0a.md b/.agentworkforce/trajectories/completed/2026-05/traj_2yicjxgajt0a.md similarity index 100% rename from .trajectories/completed/2026-05/traj_2yicjxgajt0a.md rename to .agentworkforce/trajectories/completed/2026-05/traj_2yicjxgajt0a.md diff --git a/.trajectories/completed/2026-05/traj_34b1u84b19gz.json b/.agentworkforce/trajectories/completed/2026-05/traj_34b1u84b19gz.json similarity index 100% rename from .trajectories/completed/2026-05/traj_34b1u84b19gz.json rename to .agentworkforce/trajectories/completed/2026-05/traj_34b1u84b19gz.json diff --git a/.trajectories/completed/2026-05/traj_34b1u84b19gz.md b/.agentworkforce/trajectories/completed/2026-05/traj_34b1u84b19gz.md similarity index 100% rename from .trajectories/completed/2026-05/traj_34b1u84b19gz.md rename to .agentworkforce/trajectories/completed/2026-05/traj_34b1u84b19gz.md diff --git a/.trajectories/completed/2026-05/traj_3b3p1z4y7qlo.json b/.agentworkforce/trajectories/completed/2026-05/traj_3b3p1z4y7qlo.json similarity index 100% rename from .trajectories/completed/2026-05/traj_3b3p1z4y7qlo.json rename to .agentworkforce/trajectories/completed/2026-05/traj_3b3p1z4y7qlo.json diff --git a/.trajectories/completed/2026-05/traj_3b3p1z4y7qlo.md b/.agentworkforce/trajectories/completed/2026-05/traj_3b3p1z4y7qlo.md similarity index 100% rename from .trajectories/completed/2026-05/traj_3b3p1z4y7qlo.md rename to .agentworkforce/trajectories/completed/2026-05/traj_3b3p1z4y7qlo.md diff --git a/.trajectories/completed/2026-05/traj_3gjtcykvybt5.json b/.agentworkforce/trajectories/completed/2026-05/traj_3gjtcykvybt5.json similarity index 100% rename from .trajectories/completed/2026-05/traj_3gjtcykvybt5.json rename to .agentworkforce/trajectories/completed/2026-05/traj_3gjtcykvybt5.json diff --git a/.trajectories/completed/2026-05/traj_3gjtcykvybt5.md b/.agentworkforce/trajectories/completed/2026-05/traj_3gjtcykvybt5.md similarity index 100% rename from .trajectories/completed/2026-05/traj_3gjtcykvybt5.md rename to .agentworkforce/trajectories/completed/2026-05/traj_3gjtcykvybt5.md diff --git a/.trajectories/completed/2026-05/traj_47akjihewlow.json b/.agentworkforce/trajectories/completed/2026-05/traj_47akjihewlow.json similarity index 100% rename from .trajectories/completed/2026-05/traj_47akjihewlow.json rename to .agentworkforce/trajectories/completed/2026-05/traj_47akjihewlow.json diff --git a/.trajectories/completed/2026-05/traj_47akjihewlow.md b/.agentworkforce/trajectories/completed/2026-05/traj_47akjihewlow.md similarity index 100% rename from .trajectories/completed/2026-05/traj_47akjihewlow.md rename to .agentworkforce/trajectories/completed/2026-05/traj_47akjihewlow.md diff --git a/.trajectories/completed/2026-05/traj_47akjihewlow.trace.json b/.agentworkforce/trajectories/completed/2026-05/traj_47akjihewlow.trace.json similarity index 100% rename from .trajectories/completed/2026-05/traj_47akjihewlow.trace.json rename to .agentworkforce/trajectories/completed/2026-05/traj_47akjihewlow.trace.json diff --git a/.trajectories/completed/2026-05/traj_4chzkm724ufo.json b/.agentworkforce/trajectories/completed/2026-05/traj_4chzkm724ufo.json similarity index 100% rename from .trajectories/completed/2026-05/traj_4chzkm724ufo.json rename to .agentworkforce/trajectories/completed/2026-05/traj_4chzkm724ufo.json diff --git a/.trajectories/completed/2026-05/traj_4chzkm724ufo.md b/.agentworkforce/trajectories/completed/2026-05/traj_4chzkm724ufo.md similarity index 100% rename from .trajectories/completed/2026-05/traj_4chzkm724ufo.md rename to .agentworkforce/trajectories/completed/2026-05/traj_4chzkm724ufo.md diff --git a/.trajectories/completed/2026-05/traj_4t07itef99ug.json b/.agentworkforce/trajectories/completed/2026-05/traj_4t07itef99ug.json similarity index 100% rename from .trajectories/completed/2026-05/traj_4t07itef99ug.json rename to .agentworkforce/trajectories/completed/2026-05/traj_4t07itef99ug.json diff --git a/.trajectories/completed/2026-05/traj_4t07itef99ug.md b/.agentworkforce/trajectories/completed/2026-05/traj_4t07itef99ug.md similarity index 100% rename from .trajectories/completed/2026-05/traj_4t07itef99ug.md rename to .agentworkforce/trajectories/completed/2026-05/traj_4t07itef99ug.md diff --git a/.trajectories/completed/2026-05/traj_4vucir4qvqa2.json b/.agentworkforce/trajectories/completed/2026-05/traj_4vucir4qvqa2.json similarity index 100% rename from .trajectories/completed/2026-05/traj_4vucir4qvqa2.json rename to .agentworkforce/trajectories/completed/2026-05/traj_4vucir4qvqa2.json diff --git a/.trajectories/completed/2026-05/traj_4vucir4qvqa2.md b/.agentworkforce/trajectories/completed/2026-05/traj_4vucir4qvqa2.md similarity index 100% rename from .trajectories/completed/2026-05/traj_4vucir4qvqa2.md rename to .agentworkforce/trajectories/completed/2026-05/traj_4vucir4qvqa2.md diff --git a/.trajectories/completed/2026-05/traj_5k0jtc1g5l33.json b/.agentworkforce/trajectories/completed/2026-05/traj_5k0jtc1g5l33.json similarity index 100% rename from .trajectories/completed/2026-05/traj_5k0jtc1g5l33.json rename to .agentworkforce/trajectories/completed/2026-05/traj_5k0jtc1g5l33.json diff --git a/.trajectories/completed/2026-05/traj_5k0jtc1g5l33.md b/.agentworkforce/trajectories/completed/2026-05/traj_5k0jtc1g5l33.md similarity index 100% rename from .trajectories/completed/2026-05/traj_5k0jtc1g5l33.md rename to .agentworkforce/trajectories/completed/2026-05/traj_5k0jtc1g5l33.md diff --git a/.trajectories/completed/2026-05/traj_5nzj6v56id4z.json b/.agentworkforce/trajectories/completed/2026-05/traj_5nzj6v56id4z.json similarity index 100% rename from .trajectories/completed/2026-05/traj_5nzj6v56id4z.json rename to .agentworkforce/trajectories/completed/2026-05/traj_5nzj6v56id4z.json diff --git a/.trajectories/completed/2026-05/traj_5q8i0iz4klpo.json b/.agentworkforce/trajectories/completed/2026-05/traj_5q8i0iz4klpo.json similarity index 100% rename from .trajectories/completed/2026-05/traj_5q8i0iz4klpo.json rename to .agentworkforce/trajectories/completed/2026-05/traj_5q8i0iz4klpo.json diff --git a/.trajectories/completed/2026-05/traj_5q8i0iz4klpo.md b/.agentworkforce/trajectories/completed/2026-05/traj_5q8i0iz4klpo.md similarity index 100% rename from .trajectories/completed/2026-05/traj_5q8i0iz4klpo.md rename to .agentworkforce/trajectories/completed/2026-05/traj_5q8i0iz4klpo.md diff --git a/.trajectories/completed/2026-05/traj_5qbla7w4kzoi.json b/.agentworkforce/trajectories/completed/2026-05/traj_5qbla7w4kzoi.json similarity index 100% rename from .trajectories/completed/2026-05/traj_5qbla7w4kzoi.json rename to .agentworkforce/trajectories/completed/2026-05/traj_5qbla7w4kzoi.json diff --git a/.trajectories/completed/2026-05/traj_5qbla7w4kzoi.md b/.agentworkforce/trajectories/completed/2026-05/traj_5qbla7w4kzoi.md similarity index 100% rename from .trajectories/completed/2026-05/traj_5qbla7w4kzoi.md rename to .agentworkforce/trajectories/completed/2026-05/traj_5qbla7w4kzoi.md diff --git a/.trajectories/completed/2026-05/traj_60qc24ufr96g.json b/.agentworkforce/trajectories/completed/2026-05/traj_60qc24ufr96g.json similarity index 100% rename from .trajectories/completed/2026-05/traj_60qc24ufr96g.json rename to .agentworkforce/trajectories/completed/2026-05/traj_60qc24ufr96g.json diff --git a/.trajectories/completed/2026-05/traj_60qc24ufr96g.md b/.agentworkforce/trajectories/completed/2026-05/traj_60qc24ufr96g.md similarity index 100% rename from .trajectories/completed/2026-05/traj_60qc24ufr96g.md rename to .agentworkforce/trajectories/completed/2026-05/traj_60qc24ufr96g.md diff --git a/.trajectories/completed/2026-05/traj_6sjeohtm3php.json b/.agentworkforce/trajectories/completed/2026-05/traj_6sjeohtm3php.json similarity index 100% rename from .trajectories/completed/2026-05/traj_6sjeohtm3php.json rename to .agentworkforce/trajectories/completed/2026-05/traj_6sjeohtm3php.json diff --git a/.trajectories/completed/2026-05/traj_6sjeohtm3php.md b/.agentworkforce/trajectories/completed/2026-05/traj_6sjeohtm3php.md similarity index 100% rename from .trajectories/completed/2026-05/traj_6sjeohtm3php.md rename to .agentworkforce/trajectories/completed/2026-05/traj_6sjeohtm3php.md diff --git a/.trajectories/completed/2026-05/traj_6ujzpx82gqs9.json b/.agentworkforce/trajectories/completed/2026-05/traj_6ujzpx82gqs9.json similarity index 100% rename from .trajectories/completed/2026-05/traj_6ujzpx82gqs9.json rename to .agentworkforce/trajectories/completed/2026-05/traj_6ujzpx82gqs9.json diff --git a/.trajectories/completed/2026-05/traj_6ujzpx82gqs9.md b/.agentworkforce/trajectories/completed/2026-05/traj_6ujzpx82gqs9.md similarity index 100% rename from .trajectories/completed/2026-05/traj_6ujzpx82gqs9.md rename to .agentworkforce/trajectories/completed/2026-05/traj_6ujzpx82gqs9.md diff --git a/.trajectories/completed/2026-05/traj_78ytpicts778.json b/.agentworkforce/trajectories/completed/2026-05/traj_78ytpicts778.json similarity index 100% rename from .trajectories/completed/2026-05/traj_78ytpicts778.json rename to .agentworkforce/trajectories/completed/2026-05/traj_78ytpicts778.json diff --git a/.trajectories/completed/2026-05/traj_78ytpicts778.md b/.agentworkforce/trajectories/completed/2026-05/traj_78ytpicts778.md similarity index 100% rename from .trajectories/completed/2026-05/traj_78ytpicts778.md rename to .agentworkforce/trajectories/completed/2026-05/traj_78ytpicts778.md diff --git a/.trajectories/completed/2026-05/traj_7i9tigaejfje.json b/.agentworkforce/trajectories/completed/2026-05/traj_7i9tigaejfje.json similarity index 100% rename from .trajectories/completed/2026-05/traj_7i9tigaejfje.json rename to .agentworkforce/trajectories/completed/2026-05/traj_7i9tigaejfje.json diff --git a/.trajectories/completed/2026-05/traj_7i9tigaejfje.md b/.agentworkforce/trajectories/completed/2026-05/traj_7i9tigaejfje.md similarity index 100% rename from .trajectories/completed/2026-05/traj_7i9tigaejfje.md rename to .agentworkforce/trajectories/completed/2026-05/traj_7i9tigaejfje.md diff --git a/.trajectories/completed/2026-05/traj_7uznwzoxbao6.json b/.agentworkforce/trajectories/completed/2026-05/traj_7uznwzoxbao6.json similarity index 100% rename from .trajectories/completed/2026-05/traj_7uznwzoxbao6.json rename to .agentworkforce/trajectories/completed/2026-05/traj_7uznwzoxbao6.json diff --git a/.trajectories/completed/2026-05/traj_7uznwzoxbao6.md b/.agentworkforce/trajectories/completed/2026-05/traj_7uznwzoxbao6.md similarity index 100% rename from .trajectories/completed/2026-05/traj_7uznwzoxbao6.md rename to .agentworkforce/trajectories/completed/2026-05/traj_7uznwzoxbao6.md diff --git a/.trajectories/completed/2026-05/traj_7zu7et53ph3l.json b/.agentworkforce/trajectories/completed/2026-05/traj_7zu7et53ph3l.json similarity index 100% rename from .trajectories/completed/2026-05/traj_7zu7et53ph3l.json rename to .agentworkforce/trajectories/completed/2026-05/traj_7zu7et53ph3l.json diff --git a/.trajectories/completed/2026-05/traj_7zu7et53ph3l.md b/.agentworkforce/trajectories/completed/2026-05/traj_7zu7et53ph3l.md similarity index 100% rename from .trajectories/completed/2026-05/traj_7zu7et53ph3l.md rename to .agentworkforce/trajectories/completed/2026-05/traj_7zu7et53ph3l.md diff --git a/.trajectories/completed/2026-05/traj_81kobstnzzwk.json b/.agentworkforce/trajectories/completed/2026-05/traj_81kobstnzzwk.json similarity index 100% rename from .trajectories/completed/2026-05/traj_81kobstnzzwk.json rename to .agentworkforce/trajectories/completed/2026-05/traj_81kobstnzzwk.json diff --git a/.trajectories/completed/2026-05/traj_8ljgydz61do5.json b/.agentworkforce/trajectories/completed/2026-05/traj_8ljgydz61do5.json similarity index 100% rename from .trajectories/completed/2026-05/traj_8ljgydz61do5.json rename to .agentworkforce/trajectories/completed/2026-05/traj_8ljgydz61do5.json diff --git a/.trajectories/completed/2026-05/traj_8ljgydz61do5.md b/.agentworkforce/trajectories/completed/2026-05/traj_8ljgydz61do5.md similarity index 100% rename from .trajectories/completed/2026-05/traj_8ljgydz61do5.md rename to .agentworkforce/trajectories/completed/2026-05/traj_8ljgydz61do5.md diff --git a/.trajectories/completed/2026-05/traj_8nhd9lljhbsw.json b/.agentworkforce/trajectories/completed/2026-05/traj_8nhd9lljhbsw.json similarity index 100% rename from .trajectories/completed/2026-05/traj_8nhd9lljhbsw.json rename to .agentworkforce/trajectories/completed/2026-05/traj_8nhd9lljhbsw.json diff --git a/.trajectories/completed/2026-05/traj_8nhd9lljhbsw.md b/.agentworkforce/trajectories/completed/2026-05/traj_8nhd9lljhbsw.md similarity index 100% rename from .trajectories/completed/2026-05/traj_8nhd9lljhbsw.md rename to .agentworkforce/trajectories/completed/2026-05/traj_8nhd9lljhbsw.md diff --git a/.trajectories/completed/2026-05/traj_90jmd9z27oap.json b/.agentworkforce/trajectories/completed/2026-05/traj_90jmd9z27oap.json similarity index 100% rename from .trajectories/completed/2026-05/traj_90jmd9z27oap.json rename to .agentworkforce/trajectories/completed/2026-05/traj_90jmd9z27oap.json diff --git a/.trajectories/completed/2026-05/traj_90jmd9z27oap.md b/.agentworkforce/trajectories/completed/2026-05/traj_90jmd9z27oap.md similarity index 100% rename from .trajectories/completed/2026-05/traj_90jmd9z27oap.md rename to .agentworkforce/trajectories/completed/2026-05/traj_90jmd9z27oap.md diff --git a/.trajectories/completed/2026-05/traj_947wzpddsg9j.json b/.agentworkforce/trajectories/completed/2026-05/traj_947wzpddsg9j.json similarity index 100% rename from .trajectories/completed/2026-05/traj_947wzpddsg9j.json rename to .agentworkforce/trajectories/completed/2026-05/traj_947wzpddsg9j.json diff --git a/.trajectories/completed/2026-05/traj_947wzpddsg9j.md b/.agentworkforce/trajectories/completed/2026-05/traj_947wzpddsg9j.md similarity index 100% rename from .trajectories/completed/2026-05/traj_947wzpddsg9j.md rename to .agentworkforce/trajectories/completed/2026-05/traj_947wzpddsg9j.md diff --git a/.trajectories/completed/2026-05/traj_9dj3qiugt26j.json b/.agentworkforce/trajectories/completed/2026-05/traj_9dj3qiugt26j.json similarity index 100% rename from .trajectories/completed/2026-05/traj_9dj3qiugt26j.json rename to .agentworkforce/trajectories/completed/2026-05/traj_9dj3qiugt26j.json diff --git a/.trajectories/completed/2026-05/traj_9dj3qiugt26j.md b/.agentworkforce/trajectories/completed/2026-05/traj_9dj3qiugt26j.md similarity index 100% rename from .trajectories/completed/2026-05/traj_9dj3qiugt26j.md rename to .agentworkforce/trajectories/completed/2026-05/traj_9dj3qiugt26j.md diff --git a/.trajectories/completed/2026-05/traj_9fdv7hxm0b60.json b/.agentworkforce/trajectories/completed/2026-05/traj_9fdv7hxm0b60.json similarity index 100% rename from .trajectories/completed/2026-05/traj_9fdv7hxm0b60.json rename to .agentworkforce/trajectories/completed/2026-05/traj_9fdv7hxm0b60.json diff --git a/.trajectories/completed/2026-05/traj_9fdv7hxm0b60.md b/.agentworkforce/trajectories/completed/2026-05/traj_9fdv7hxm0b60.md similarity index 100% rename from .trajectories/completed/2026-05/traj_9fdv7hxm0b60.md rename to .agentworkforce/trajectories/completed/2026-05/traj_9fdv7hxm0b60.md diff --git a/.trajectories/completed/2026-05/traj_9gq96irkj00s.json b/.agentworkforce/trajectories/completed/2026-05/traj_9gq96irkj00s.json similarity index 100% rename from .trajectories/completed/2026-05/traj_9gq96irkj00s.json rename to .agentworkforce/trajectories/completed/2026-05/traj_9gq96irkj00s.json diff --git a/.trajectories/completed/2026-05/traj_9gq96irkj00s.md b/.agentworkforce/trajectories/completed/2026-05/traj_9gq96irkj00s.md similarity index 100% rename from .trajectories/completed/2026-05/traj_9gq96irkj00s.md rename to .agentworkforce/trajectories/completed/2026-05/traj_9gq96irkj00s.md diff --git a/.trajectories/completed/2026-05/traj_aw7stgf4qau0.json b/.agentworkforce/trajectories/completed/2026-05/traj_aw7stgf4qau0.json similarity index 100% rename from .trajectories/completed/2026-05/traj_aw7stgf4qau0.json rename to .agentworkforce/trajectories/completed/2026-05/traj_aw7stgf4qau0.json diff --git a/.trajectories/completed/2026-05/traj_aw7stgf4qau0.md b/.agentworkforce/trajectories/completed/2026-05/traj_aw7stgf4qau0.md similarity index 100% rename from .trajectories/completed/2026-05/traj_aw7stgf4qau0.md rename to .agentworkforce/trajectories/completed/2026-05/traj_aw7stgf4qau0.md diff --git a/.trajectories/completed/2026-05/traj_b3g40827t5zh/summary.md b/.agentworkforce/trajectories/completed/2026-05/traj_b3g40827t5zh/summary.md similarity index 100% rename from .trajectories/completed/2026-05/traj_b3g40827t5zh/summary.md rename to .agentworkforce/trajectories/completed/2026-05/traj_b3g40827t5zh/summary.md diff --git a/.trajectories/completed/2026-05/traj_b3g40827t5zh/trajectory.json b/.agentworkforce/trajectories/completed/2026-05/traj_b3g40827t5zh/trajectory.json similarity index 100% rename from .trajectories/completed/2026-05/traj_b3g40827t5zh/trajectory.json rename to .agentworkforce/trajectories/completed/2026-05/traj_b3g40827t5zh/trajectory.json diff --git a/.trajectories/completed/2026-05/traj_bd431l65n9lg.json b/.agentworkforce/trajectories/completed/2026-05/traj_bd431l65n9lg.json similarity index 100% rename from .trajectories/completed/2026-05/traj_bd431l65n9lg.json rename to .agentworkforce/trajectories/completed/2026-05/traj_bd431l65n9lg.json diff --git a/.trajectories/completed/2026-05/traj_bd431l65n9lg.md b/.agentworkforce/trajectories/completed/2026-05/traj_bd431l65n9lg.md similarity index 100% rename from .trajectories/completed/2026-05/traj_bd431l65n9lg.md rename to .agentworkforce/trajectories/completed/2026-05/traj_bd431l65n9lg.md diff --git a/.trajectories/completed/2026-05/traj_bdrlknyl8twj.json b/.agentworkforce/trajectories/completed/2026-05/traj_bdrlknyl8twj.json similarity index 100% rename from .trajectories/completed/2026-05/traj_bdrlknyl8twj.json rename to .agentworkforce/trajectories/completed/2026-05/traj_bdrlknyl8twj.json diff --git a/.trajectories/completed/2026-05/traj_bdrlknyl8twj.md b/.agentworkforce/trajectories/completed/2026-05/traj_bdrlknyl8twj.md similarity index 100% rename from .trajectories/completed/2026-05/traj_bdrlknyl8twj.md rename to .agentworkforce/trajectories/completed/2026-05/traj_bdrlknyl8twj.md diff --git a/.trajectories/completed/2026-05/traj_bz1a1o15p7px.json b/.agentworkforce/trajectories/completed/2026-05/traj_bz1a1o15p7px.json similarity index 100% rename from .trajectories/completed/2026-05/traj_bz1a1o15p7px.json rename to .agentworkforce/trajectories/completed/2026-05/traj_bz1a1o15p7px.json diff --git a/.trajectories/completed/2026-05/traj_bz1a1o15p7px.md b/.agentworkforce/trajectories/completed/2026-05/traj_bz1a1o15p7px.md similarity index 100% rename from .trajectories/completed/2026-05/traj_bz1a1o15p7px.md rename to .agentworkforce/trajectories/completed/2026-05/traj_bz1a1o15p7px.md diff --git a/.trajectories/completed/2026-05/traj_cbmwd07phhm2.json b/.agentworkforce/trajectories/completed/2026-05/traj_cbmwd07phhm2.json similarity index 100% rename from .trajectories/completed/2026-05/traj_cbmwd07phhm2.json rename to .agentworkforce/trajectories/completed/2026-05/traj_cbmwd07phhm2.json diff --git a/.trajectories/completed/2026-05/traj_cbmwd07phhm2.md b/.agentworkforce/trajectories/completed/2026-05/traj_cbmwd07phhm2.md similarity index 100% rename from .trajectories/completed/2026-05/traj_cbmwd07phhm2.md rename to .agentworkforce/trajectories/completed/2026-05/traj_cbmwd07phhm2.md diff --git a/.trajectories/completed/2026-05/traj_ceo5q9bh2od3.json b/.agentworkforce/trajectories/completed/2026-05/traj_ceo5q9bh2od3.json similarity index 100% rename from .trajectories/completed/2026-05/traj_ceo5q9bh2od3.json rename to .agentworkforce/trajectories/completed/2026-05/traj_ceo5q9bh2od3.json diff --git a/.trajectories/completed/2026-05/traj_ceo5q9bh2od3.md b/.agentworkforce/trajectories/completed/2026-05/traj_ceo5q9bh2od3.md similarity index 100% rename from .trajectories/completed/2026-05/traj_ceo5q9bh2od3.md rename to .agentworkforce/trajectories/completed/2026-05/traj_ceo5q9bh2od3.md diff --git a/.trajectories/completed/2026-05/traj_cszfl2icaj2t.json b/.agentworkforce/trajectories/completed/2026-05/traj_cszfl2icaj2t.json similarity index 100% rename from .trajectories/completed/2026-05/traj_cszfl2icaj2t.json rename to .agentworkforce/trajectories/completed/2026-05/traj_cszfl2icaj2t.json diff --git a/.trajectories/completed/2026-05/traj_cszfl2icaj2t.md b/.agentworkforce/trajectories/completed/2026-05/traj_cszfl2icaj2t.md similarity index 100% rename from .trajectories/completed/2026-05/traj_cszfl2icaj2t.md rename to .agentworkforce/trajectories/completed/2026-05/traj_cszfl2icaj2t.md diff --git a/.trajectories/completed/2026-05/traj_d89s38ddu7cj.json b/.agentworkforce/trajectories/completed/2026-05/traj_d89s38ddu7cj.json similarity index 100% rename from .trajectories/completed/2026-05/traj_d89s38ddu7cj.json rename to .agentworkforce/trajectories/completed/2026-05/traj_d89s38ddu7cj.json diff --git a/.trajectories/completed/2026-05/traj_d89s38ddu7cj.md b/.agentworkforce/trajectories/completed/2026-05/traj_d89s38ddu7cj.md similarity index 100% rename from .trajectories/completed/2026-05/traj_d89s38ddu7cj.md rename to .agentworkforce/trajectories/completed/2026-05/traj_d89s38ddu7cj.md diff --git a/.trajectories/completed/2026-05/traj_dbsnr453nxjw.json b/.agentworkforce/trajectories/completed/2026-05/traj_dbsnr453nxjw.json similarity index 100% rename from .trajectories/completed/2026-05/traj_dbsnr453nxjw.json rename to .agentworkforce/trajectories/completed/2026-05/traj_dbsnr453nxjw.json diff --git a/.trajectories/completed/2026-05/traj_dbsnr453nxjw.md b/.agentworkforce/trajectories/completed/2026-05/traj_dbsnr453nxjw.md similarity index 100% rename from .trajectories/completed/2026-05/traj_dbsnr453nxjw.md rename to .agentworkforce/trajectories/completed/2026-05/traj_dbsnr453nxjw.md diff --git a/.trajectories/completed/2026-05/traj_dcl9hgoiuac5.json b/.agentworkforce/trajectories/completed/2026-05/traj_dcl9hgoiuac5.json similarity index 100% rename from .trajectories/completed/2026-05/traj_dcl9hgoiuac5.json rename to .agentworkforce/trajectories/completed/2026-05/traj_dcl9hgoiuac5.json diff --git a/.trajectories/completed/2026-05/traj_dcl9hgoiuac5.md b/.agentworkforce/trajectories/completed/2026-05/traj_dcl9hgoiuac5.md similarity index 100% rename from .trajectories/completed/2026-05/traj_dcl9hgoiuac5.md rename to .agentworkforce/trajectories/completed/2026-05/traj_dcl9hgoiuac5.md diff --git a/.trajectories/completed/2026-05/traj_dpgn0am1jq1c.json b/.agentworkforce/trajectories/completed/2026-05/traj_dpgn0am1jq1c.json similarity index 100% rename from .trajectories/completed/2026-05/traj_dpgn0am1jq1c.json rename to .agentworkforce/trajectories/completed/2026-05/traj_dpgn0am1jq1c.json diff --git a/.trajectories/completed/2026-05/traj_dpgn0am1jq1c.md b/.agentworkforce/trajectories/completed/2026-05/traj_dpgn0am1jq1c.md similarity index 100% rename from .trajectories/completed/2026-05/traj_dpgn0am1jq1c.md rename to .agentworkforce/trajectories/completed/2026-05/traj_dpgn0am1jq1c.md diff --git a/.trajectories/completed/2026-05/traj_e1b7ww3un1u3.json b/.agentworkforce/trajectories/completed/2026-05/traj_e1b7ww3un1u3.json similarity index 100% rename from .trajectories/completed/2026-05/traj_e1b7ww3un1u3.json rename to .agentworkforce/trajectories/completed/2026-05/traj_e1b7ww3un1u3.json diff --git a/.trajectories/completed/2026-05/traj_e1b7ww3un1u3.md b/.agentworkforce/trajectories/completed/2026-05/traj_e1b7ww3un1u3.md similarity index 100% rename from .trajectories/completed/2026-05/traj_e1b7ww3un1u3.md rename to .agentworkforce/trajectories/completed/2026-05/traj_e1b7ww3un1u3.md diff --git a/.trajectories/completed/2026-05/traj_elx0fcwgs37x.json b/.agentworkforce/trajectories/completed/2026-05/traj_elx0fcwgs37x.json similarity index 100% rename from .trajectories/completed/2026-05/traj_elx0fcwgs37x.json rename to .agentworkforce/trajectories/completed/2026-05/traj_elx0fcwgs37x.json diff --git a/.trajectories/completed/2026-05/traj_elx0fcwgs37x.md b/.agentworkforce/trajectories/completed/2026-05/traj_elx0fcwgs37x.md similarity index 100% rename from .trajectories/completed/2026-05/traj_elx0fcwgs37x.md rename to .agentworkforce/trajectories/completed/2026-05/traj_elx0fcwgs37x.md diff --git a/.trajectories/completed/2026-05/traj_erzd7j9nto9r.json b/.agentworkforce/trajectories/completed/2026-05/traj_erzd7j9nto9r.json similarity index 100% rename from .trajectories/completed/2026-05/traj_erzd7j9nto9r.json rename to .agentworkforce/trajectories/completed/2026-05/traj_erzd7j9nto9r.json diff --git a/.trajectories/completed/2026-05/traj_erzd7j9nto9r.md b/.agentworkforce/trajectories/completed/2026-05/traj_erzd7j9nto9r.md similarity index 100% rename from .trajectories/completed/2026-05/traj_erzd7j9nto9r.md rename to .agentworkforce/trajectories/completed/2026-05/traj_erzd7j9nto9r.md diff --git a/.trajectories/completed/2026-05/traj_f1iac9ngymlj.json b/.agentworkforce/trajectories/completed/2026-05/traj_f1iac9ngymlj.json similarity index 100% rename from .trajectories/completed/2026-05/traj_f1iac9ngymlj.json rename to .agentworkforce/trajectories/completed/2026-05/traj_f1iac9ngymlj.json diff --git a/.trajectories/completed/2026-05/traj_f1iac9ngymlj.md b/.agentworkforce/trajectories/completed/2026-05/traj_f1iac9ngymlj.md similarity index 100% rename from .trajectories/completed/2026-05/traj_f1iac9ngymlj.md rename to .agentworkforce/trajectories/completed/2026-05/traj_f1iac9ngymlj.md diff --git a/.trajectories/completed/2026-05/traj_f3arvbmmlomn.json b/.agentworkforce/trajectories/completed/2026-05/traj_f3arvbmmlomn.json similarity index 100% rename from .trajectories/completed/2026-05/traj_f3arvbmmlomn.json rename to .agentworkforce/trajectories/completed/2026-05/traj_f3arvbmmlomn.json diff --git a/.trajectories/completed/2026-05/traj_f3arvbmmlomn.md b/.agentworkforce/trajectories/completed/2026-05/traj_f3arvbmmlomn.md similarity index 100% rename from .trajectories/completed/2026-05/traj_f3arvbmmlomn.md rename to .agentworkforce/trajectories/completed/2026-05/traj_f3arvbmmlomn.md diff --git a/.trajectories/completed/2026-05/traj_f9wxa8ujeg78.json b/.agentworkforce/trajectories/completed/2026-05/traj_f9wxa8ujeg78.json similarity index 100% rename from .trajectories/completed/2026-05/traj_f9wxa8ujeg78.json rename to .agentworkforce/trajectories/completed/2026-05/traj_f9wxa8ujeg78.json diff --git a/.trajectories/completed/2026-05/traj_f9wxa8ujeg78.md b/.agentworkforce/trajectories/completed/2026-05/traj_f9wxa8ujeg78.md similarity index 100% rename from .trajectories/completed/2026-05/traj_f9wxa8ujeg78.md rename to .agentworkforce/trajectories/completed/2026-05/traj_f9wxa8ujeg78.md diff --git a/.trajectories/completed/2026-05/traj_fh8oosbijpwc.json b/.agentworkforce/trajectories/completed/2026-05/traj_fh8oosbijpwc.json similarity index 100% rename from .trajectories/completed/2026-05/traj_fh8oosbijpwc.json rename to .agentworkforce/trajectories/completed/2026-05/traj_fh8oosbijpwc.json diff --git a/.trajectories/completed/2026-05/traj_fh8oosbijpwc.md b/.agentworkforce/trajectories/completed/2026-05/traj_fh8oosbijpwc.md similarity index 100% rename from .trajectories/completed/2026-05/traj_fh8oosbijpwc.md rename to .agentworkforce/trajectories/completed/2026-05/traj_fh8oosbijpwc.md diff --git a/.trajectories/completed/2026-05/traj_fh8oosbijpwc.trace.json b/.agentworkforce/trajectories/completed/2026-05/traj_fh8oosbijpwc.trace.json similarity index 100% rename from .trajectories/completed/2026-05/traj_fh8oosbijpwc.trace.json rename to .agentworkforce/trajectories/completed/2026-05/traj_fh8oosbijpwc.trace.json diff --git a/.trajectories/completed/2026-05/traj_fiygtgr3tfey.json b/.agentworkforce/trajectories/completed/2026-05/traj_fiygtgr3tfey.json similarity index 100% rename from .trajectories/completed/2026-05/traj_fiygtgr3tfey.json rename to .agentworkforce/trajectories/completed/2026-05/traj_fiygtgr3tfey.json diff --git a/.trajectories/completed/2026-05/traj_fiygtgr3tfey.md b/.agentworkforce/trajectories/completed/2026-05/traj_fiygtgr3tfey.md similarity index 100% rename from .trajectories/completed/2026-05/traj_fiygtgr3tfey.md rename to .agentworkforce/trajectories/completed/2026-05/traj_fiygtgr3tfey.md diff --git a/.trajectories/completed/2026-05/traj_gh05rj5gwsap.json b/.agentworkforce/trajectories/completed/2026-05/traj_gh05rj5gwsap.json similarity index 100% rename from .trajectories/completed/2026-05/traj_gh05rj5gwsap.json rename to .agentworkforce/trajectories/completed/2026-05/traj_gh05rj5gwsap.json diff --git a/.trajectories/completed/2026-05/traj_gh05rj5gwsap.md b/.agentworkforce/trajectories/completed/2026-05/traj_gh05rj5gwsap.md similarity index 100% rename from .trajectories/completed/2026-05/traj_gh05rj5gwsap.md rename to .agentworkforce/trajectories/completed/2026-05/traj_gh05rj5gwsap.md diff --git a/.trajectories/completed/2026-05/traj_gh05rj5gwsap.trace.json b/.agentworkforce/trajectories/completed/2026-05/traj_gh05rj5gwsap.trace.json similarity index 100% rename from .trajectories/completed/2026-05/traj_gh05rj5gwsap.trace.json rename to .agentworkforce/trajectories/completed/2026-05/traj_gh05rj5gwsap.trace.json diff --git a/.trajectories/completed/2026-05/traj_gkxajksmwoea.json b/.agentworkforce/trajectories/completed/2026-05/traj_gkxajksmwoea.json similarity index 100% rename from .trajectories/completed/2026-05/traj_gkxajksmwoea.json rename to .agentworkforce/trajectories/completed/2026-05/traj_gkxajksmwoea.json diff --git a/.trajectories/completed/2026-05/traj_gkxajksmwoea.md b/.agentworkforce/trajectories/completed/2026-05/traj_gkxajksmwoea.md similarity index 100% rename from .trajectories/completed/2026-05/traj_gkxajksmwoea.md rename to .agentworkforce/trajectories/completed/2026-05/traj_gkxajksmwoea.md diff --git a/.trajectories/completed/2026-05/traj_gnqvtoxtc8dy.json b/.agentworkforce/trajectories/completed/2026-05/traj_gnqvtoxtc8dy.json similarity index 100% rename from .trajectories/completed/2026-05/traj_gnqvtoxtc8dy.json rename to .agentworkforce/trajectories/completed/2026-05/traj_gnqvtoxtc8dy.json diff --git a/.trajectories/completed/2026-05/traj_gnqvtoxtc8dy.md b/.agentworkforce/trajectories/completed/2026-05/traj_gnqvtoxtc8dy.md similarity index 100% rename from .trajectories/completed/2026-05/traj_gnqvtoxtc8dy.md rename to .agentworkforce/trajectories/completed/2026-05/traj_gnqvtoxtc8dy.md diff --git a/.trajectories/completed/2026-05/traj_hfkww5z7trxn.json b/.agentworkforce/trajectories/completed/2026-05/traj_hfkww5z7trxn.json similarity index 100% rename from .trajectories/completed/2026-05/traj_hfkww5z7trxn.json rename to .agentworkforce/trajectories/completed/2026-05/traj_hfkww5z7trxn.json diff --git a/.trajectories/completed/2026-05/traj_hfkww5z7trxn.md b/.agentworkforce/trajectories/completed/2026-05/traj_hfkww5z7trxn.md similarity index 100% rename from .trajectories/completed/2026-05/traj_hfkww5z7trxn.md rename to .agentworkforce/trajectories/completed/2026-05/traj_hfkww5z7trxn.md diff --git a/.trajectories/completed/2026-05/traj_hrsndfzk0qay.json b/.agentworkforce/trajectories/completed/2026-05/traj_hrsndfzk0qay.json similarity index 100% rename from .trajectories/completed/2026-05/traj_hrsndfzk0qay.json rename to .agentworkforce/trajectories/completed/2026-05/traj_hrsndfzk0qay.json diff --git a/.trajectories/completed/2026-05/traj_hrsndfzk0qay.md b/.agentworkforce/trajectories/completed/2026-05/traj_hrsndfzk0qay.md similarity index 100% rename from .trajectories/completed/2026-05/traj_hrsndfzk0qay.md rename to .agentworkforce/trajectories/completed/2026-05/traj_hrsndfzk0qay.md diff --git a/.trajectories/completed/2026-05/traj_hysw5o7idqas.json b/.agentworkforce/trajectories/completed/2026-05/traj_hysw5o7idqas.json similarity index 100% rename from .trajectories/completed/2026-05/traj_hysw5o7idqas.json rename to .agentworkforce/trajectories/completed/2026-05/traj_hysw5o7idqas.json diff --git a/.trajectories/completed/2026-05/traj_hysw5o7idqas.md b/.agentworkforce/trajectories/completed/2026-05/traj_hysw5o7idqas.md similarity index 100% rename from .trajectories/completed/2026-05/traj_hysw5o7idqas.md rename to .agentworkforce/trajectories/completed/2026-05/traj_hysw5o7idqas.md diff --git a/.trajectories/completed/2026-05/traj_i2pjnx3dll5b.json b/.agentworkforce/trajectories/completed/2026-05/traj_i2pjnx3dll5b.json similarity index 100% rename from .trajectories/completed/2026-05/traj_i2pjnx3dll5b.json rename to .agentworkforce/trajectories/completed/2026-05/traj_i2pjnx3dll5b.json diff --git a/.trajectories/completed/2026-05/traj_i2pjnx3dll5b.md b/.agentworkforce/trajectories/completed/2026-05/traj_i2pjnx3dll5b.md similarity index 100% rename from .trajectories/completed/2026-05/traj_i2pjnx3dll5b.md rename to .agentworkforce/trajectories/completed/2026-05/traj_i2pjnx3dll5b.md diff --git a/.trajectories/completed/2026-05/traj_i2pjnx3dll5b.trace.json b/.agentworkforce/trajectories/completed/2026-05/traj_i2pjnx3dll5b.trace.json similarity index 100% rename from .trajectories/completed/2026-05/traj_i2pjnx3dll5b.trace.json rename to .agentworkforce/trajectories/completed/2026-05/traj_i2pjnx3dll5b.trace.json diff --git a/.trajectories/completed/2026-05/traj_ij5b3kcatvwn.json b/.agentworkforce/trajectories/completed/2026-05/traj_ij5b3kcatvwn.json similarity index 100% rename from .trajectories/completed/2026-05/traj_ij5b3kcatvwn.json rename to .agentworkforce/trajectories/completed/2026-05/traj_ij5b3kcatvwn.json diff --git a/.trajectories/completed/2026-05/traj_ij5b3kcatvwn.md b/.agentworkforce/trajectories/completed/2026-05/traj_ij5b3kcatvwn.md similarity index 100% rename from .trajectories/completed/2026-05/traj_ij5b3kcatvwn.md rename to .agentworkforce/trajectories/completed/2026-05/traj_ij5b3kcatvwn.md diff --git a/.trajectories/completed/2026-05/traj_iole5zdt9orr.json b/.agentworkforce/trajectories/completed/2026-05/traj_iole5zdt9orr.json similarity index 100% rename from .trajectories/completed/2026-05/traj_iole5zdt9orr.json rename to .agentworkforce/trajectories/completed/2026-05/traj_iole5zdt9orr.json diff --git a/.trajectories/completed/2026-05/traj_iole5zdt9orr.md b/.agentworkforce/trajectories/completed/2026-05/traj_iole5zdt9orr.md similarity index 100% rename from .trajectories/completed/2026-05/traj_iole5zdt9orr.md rename to .agentworkforce/trajectories/completed/2026-05/traj_iole5zdt9orr.md diff --git a/.trajectories/completed/2026-05/traj_irafiyk6wpw0.json b/.agentworkforce/trajectories/completed/2026-05/traj_irafiyk6wpw0.json similarity index 100% rename from .trajectories/completed/2026-05/traj_irafiyk6wpw0.json rename to .agentworkforce/trajectories/completed/2026-05/traj_irafiyk6wpw0.json diff --git a/.trajectories/completed/2026-05/traj_itgr2w8qs3xn.json b/.agentworkforce/trajectories/completed/2026-05/traj_itgr2w8qs3xn.json similarity index 100% rename from .trajectories/completed/2026-05/traj_itgr2w8qs3xn.json rename to .agentworkforce/trajectories/completed/2026-05/traj_itgr2w8qs3xn.json diff --git a/.trajectories/completed/2026-05/traj_itgr2w8qs3xn.md b/.agentworkforce/trajectories/completed/2026-05/traj_itgr2w8qs3xn.md similarity index 100% rename from .trajectories/completed/2026-05/traj_itgr2w8qs3xn.md rename to .agentworkforce/trajectories/completed/2026-05/traj_itgr2w8qs3xn.md diff --git a/.trajectories/completed/2026-05/traj_j9k10fez3e81.json b/.agentworkforce/trajectories/completed/2026-05/traj_j9k10fez3e81.json similarity index 100% rename from .trajectories/completed/2026-05/traj_j9k10fez3e81.json rename to .agentworkforce/trajectories/completed/2026-05/traj_j9k10fez3e81.json diff --git a/.trajectories/completed/2026-05/traj_j9k10fez3e81.md b/.agentworkforce/trajectories/completed/2026-05/traj_j9k10fez3e81.md similarity index 100% rename from .trajectories/completed/2026-05/traj_j9k10fez3e81.md rename to .agentworkforce/trajectories/completed/2026-05/traj_j9k10fez3e81.md diff --git a/.trajectories/completed/2026-05/traj_jbo2x14y7ovt.json b/.agentworkforce/trajectories/completed/2026-05/traj_jbo2x14y7ovt.json similarity index 100% rename from .trajectories/completed/2026-05/traj_jbo2x14y7ovt.json rename to .agentworkforce/trajectories/completed/2026-05/traj_jbo2x14y7ovt.json diff --git a/.trajectories/completed/2026-05/traj_jbo2x14y7ovt.md b/.agentworkforce/trajectories/completed/2026-05/traj_jbo2x14y7ovt.md similarity index 100% rename from .trajectories/completed/2026-05/traj_jbo2x14y7ovt.md rename to .agentworkforce/trajectories/completed/2026-05/traj_jbo2x14y7ovt.md diff --git a/.trajectories/completed/2026-05/traj_jmf9pyt3zikn.json b/.agentworkforce/trajectories/completed/2026-05/traj_jmf9pyt3zikn.json similarity index 100% rename from .trajectories/completed/2026-05/traj_jmf9pyt3zikn.json rename to .agentworkforce/trajectories/completed/2026-05/traj_jmf9pyt3zikn.json diff --git a/.trajectories/completed/2026-05/traj_jmf9pyt3zikn.md b/.agentworkforce/trajectories/completed/2026-05/traj_jmf9pyt3zikn.md similarity index 100% rename from .trajectories/completed/2026-05/traj_jmf9pyt3zikn.md rename to .agentworkforce/trajectories/completed/2026-05/traj_jmf9pyt3zikn.md diff --git a/.trajectories/completed/2026-05/traj_k7njijv51iq4.json b/.agentworkforce/trajectories/completed/2026-05/traj_k7njijv51iq4.json similarity index 100% rename from .trajectories/completed/2026-05/traj_k7njijv51iq4.json rename to .agentworkforce/trajectories/completed/2026-05/traj_k7njijv51iq4.json diff --git a/.trajectories/completed/2026-05/traj_k7njijv51iq4.md b/.agentworkforce/trajectories/completed/2026-05/traj_k7njijv51iq4.md similarity index 100% rename from .trajectories/completed/2026-05/traj_k7njijv51iq4.md rename to .agentworkforce/trajectories/completed/2026-05/traj_k7njijv51iq4.md diff --git a/.trajectories/completed/2026-05/traj_kgl2opmmfvus.json b/.agentworkforce/trajectories/completed/2026-05/traj_kgl2opmmfvus.json similarity index 100% rename from .trajectories/completed/2026-05/traj_kgl2opmmfvus.json rename to .agentworkforce/trajectories/completed/2026-05/traj_kgl2opmmfvus.json diff --git a/.trajectories/completed/2026-05/traj_kgl2opmmfvus.md b/.agentworkforce/trajectories/completed/2026-05/traj_kgl2opmmfvus.md similarity index 100% rename from .trajectories/completed/2026-05/traj_kgl2opmmfvus.md rename to .agentworkforce/trajectories/completed/2026-05/traj_kgl2opmmfvus.md diff --git a/.trajectories/completed/2026-05/traj_l1349adi1g0o.json b/.agentworkforce/trajectories/completed/2026-05/traj_l1349adi1g0o.json similarity index 100% rename from .trajectories/completed/2026-05/traj_l1349adi1g0o.json rename to .agentworkforce/trajectories/completed/2026-05/traj_l1349adi1g0o.json diff --git a/.trajectories/completed/2026-05/traj_l1349adi1g0o.md b/.agentworkforce/trajectories/completed/2026-05/traj_l1349adi1g0o.md similarity index 100% rename from .trajectories/completed/2026-05/traj_l1349adi1g0o.md rename to .agentworkforce/trajectories/completed/2026-05/traj_l1349adi1g0o.md diff --git a/.trajectories/completed/2026-05/traj_l67sex3nkzfq.json b/.agentworkforce/trajectories/completed/2026-05/traj_l67sex3nkzfq.json similarity index 100% rename from .trajectories/completed/2026-05/traj_l67sex3nkzfq.json rename to .agentworkforce/trajectories/completed/2026-05/traj_l67sex3nkzfq.json diff --git a/.trajectories/completed/2026-05/traj_l67sex3nkzfq.md b/.agentworkforce/trajectories/completed/2026-05/traj_l67sex3nkzfq.md similarity index 100% rename from .trajectories/completed/2026-05/traj_l67sex3nkzfq.md rename to .agentworkforce/trajectories/completed/2026-05/traj_l67sex3nkzfq.md diff --git a/.trajectories/completed/2026-05/traj_lhyrcib40kao.json b/.agentworkforce/trajectories/completed/2026-05/traj_lhyrcib40kao.json similarity index 100% rename from .trajectories/completed/2026-05/traj_lhyrcib40kao.json rename to .agentworkforce/trajectories/completed/2026-05/traj_lhyrcib40kao.json diff --git a/.trajectories/completed/2026-05/traj_lhyrcib40kao.md b/.agentworkforce/trajectories/completed/2026-05/traj_lhyrcib40kao.md similarity index 100% rename from .trajectories/completed/2026-05/traj_lhyrcib40kao.md rename to .agentworkforce/trajectories/completed/2026-05/traj_lhyrcib40kao.md diff --git a/.trajectories/completed/2026-05/traj_lieyyspidhfj.json b/.agentworkforce/trajectories/completed/2026-05/traj_lieyyspidhfj.json similarity index 100% rename from .trajectories/completed/2026-05/traj_lieyyspidhfj.json rename to .agentworkforce/trajectories/completed/2026-05/traj_lieyyspidhfj.json diff --git a/.trajectories/completed/2026-05/traj_lieyyspidhfj.md b/.agentworkforce/trajectories/completed/2026-05/traj_lieyyspidhfj.md similarity index 100% rename from .trajectories/completed/2026-05/traj_lieyyspidhfj.md rename to .agentworkforce/trajectories/completed/2026-05/traj_lieyyspidhfj.md diff --git a/.trajectories/completed/2026-05/traj_lieyyspidhfj.trace.json b/.agentworkforce/trajectories/completed/2026-05/traj_lieyyspidhfj.trace.json similarity index 100% rename from .trajectories/completed/2026-05/traj_lieyyspidhfj.trace.json rename to .agentworkforce/trajectories/completed/2026-05/traj_lieyyspidhfj.trace.json diff --git a/.trajectories/completed/2026-05/traj_m7mpv7j8n78h.json b/.agentworkforce/trajectories/completed/2026-05/traj_m7mpv7j8n78h.json similarity index 100% rename from .trajectories/completed/2026-05/traj_m7mpv7j8n78h.json rename to .agentworkforce/trajectories/completed/2026-05/traj_m7mpv7j8n78h.json diff --git a/.trajectories/completed/2026-05/traj_m7mpv7j8n78h.md b/.agentworkforce/trajectories/completed/2026-05/traj_m7mpv7j8n78h.md similarity index 100% rename from .trajectories/completed/2026-05/traj_m7mpv7j8n78h.md rename to .agentworkforce/trajectories/completed/2026-05/traj_m7mpv7j8n78h.md diff --git a/.trajectories/completed/2026-05/traj_mi9eqd4rjfea.json b/.agentworkforce/trajectories/completed/2026-05/traj_mi9eqd4rjfea.json similarity index 100% rename from .trajectories/completed/2026-05/traj_mi9eqd4rjfea.json rename to .agentworkforce/trajectories/completed/2026-05/traj_mi9eqd4rjfea.json diff --git a/.trajectories/completed/2026-05/traj_mi9eqd4rjfea.md b/.agentworkforce/trajectories/completed/2026-05/traj_mi9eqd4rjfea.md similarity index 100% rename from .trajectories/completed/2026-05/traj_mi9eqd4rjfea.md rename to .agentworkforce/trajectories/completed/2026-05/traj_mi9eqd4rjfea.md diff --git a/.trajectories/completed/2026-05/traj_mytnzgfayj3d.json b/.agentworkforce/trajectories/completed/2026-05/traj_mytnzgfayj3d.json similarity index 100% rename from .trajectories/completed/2026-05/traj_mytnzgfayj3d.json rename to .agentworkforce/trajectories/completed/2026-05/traj_mytnzgfayj3d.json diff --git a/.trajectories/completed/2026-05/traj_mytnzgfayj3d.md b/.agentworkforce/trajectories/completed/2026-05/traj_mytnzgfayj3d.md similarity index 100% rename from .trajectories/completed/2026-05/traj_mytnzgfayj3d.md rename to .agentworkforce/trajectories/completed/2026-05/traj_mytnzgfayj3d.md diff --git a/.trajectories/completed/2026-05/traj_mz5m5ysjj31e.json b/.agentworkforce/trajectories/completed/2026-05/traj_mz5m5ysjj31e.json similarity index 100% rename from .trajectories/completed/2026-05/traj_mz5m5ysjj31e.json rename to .agentworkforce/trajectories/completed/2026-05/traj_mz5m5ysjj31e.json diff --git a/.trajectories/completed/2026-05/traj_mz5m5ysjj31e.md b/.agentworkforce/trajectories/completed/2026-05/traj_mz5m5ysjj31e.md similarity index 100% rename from .trajectories/completed/2026-05/traj_mz5m5ysjj31e.md rename to .agentworkforce/trajectories/completed/2026-05/traj_mz5m5ysjj31e.md diff --git a/.trajectories/completed/2026-05/traj_n0qwpjvmdl2s.json b/.agentworkforce/trajectories/completed/2026-05/traj_n0qwpjvmdl2s.json similarity index 100% rename from .trajectories/completed/2026-05/traj_n0qwpjvmdl2s.json rename to .agentworkforce/trajectories/completed/2026-05/traj_n0qwpjvmdl2s.json diff --git a/.trajectories/completed/2026-05/traj_n0qwpjvmdl2s.md b/.agentworkforce/trajectories/completed/2026-05/traj_n0qwpjvmdl2s.md similarity index 100% rename from .trajectories/completed/2026-05/traj_n0qwpjvmdl2s.md rename to .agentworkforce/trajectories/completed/2026-05/traj_n0qwpjvmdl2s.md diff --git a/.trajectories/completed/2026-05/traj_n8duofq5vq1a.json b/.agentworkforce/trajectories/completed/2026-05/traj_n8duofq5vq1a.json similarity index 100% rename from .trajectories/completed/2026-05/traj_n8duofq5vq1a.json rename to .agentworkforce/trajectories/completed/2026-05/traj_n8duofq5vq1a.json diff --git a/.trajectories/completed/2026-05/traj_n8duofq5vq1a.md b/.agentworkforce/trajectories/completed/2026-05/traj_n8duofq5vq1a.md similarity index 100% rename from .trajectories/completed/2026-05/traj_n8duofq5vq1a.md rename to .agentworkforce/trajectories/completed/2026-05/traj_n8duofq5vq1a.md diff --git a/.trajectories/completed/2026-05/traj_o251whkvy9rl.json b/.agentworkforce/trajectories/completed/2026-05/traj_o251whkvy9rl.json similarity index 100% rename from .trajectories/completed/2026-05/traj_o251whkvy9rl.json rename to .agentworkforce/trajectories/completed/2026-05/traj_o251whkvy9rl.json diff --git a/.trajectories/completed/2026-05/traj_o251whkvy9rl.md b/.agentworkforce/trajectories/completed/2026-05/traj_o251whkvy9rl.md similarity index 100% rename from .trajectories/completed/2026-05/traj_o251whkvy9rl.md rename to .agentworkforce/trajectories/completed/2026-05/traj_o251whkvy9rl.md diff --git a/.trajectories/completed/2026-05/traj_o9cx33xn5u39.json b/.agentworkforce/trajectories/completed/2026-05/traj_o9cx33xn5u39.json similarity index 100% rename from .trajectories/completed/2026-05/traj_o9cx33xn5u39.json rename to .agentworkforce/trajectories/completed/2026-05/traj_o9cx33xn5u39.json diff --git a/.trajectories/completed/2026-05/traj_o9cx33xn5u39.md b/.agentworkforce/trajectories/completed/2026-05/traj_o9cx33xn5u39.md similarity index 100% rename from .trajectories/completed/2026-05/traj_o9cx33xn5u39.md rename to .agentworkforce/trajectories/completed/2026-05/traj_o9cx33xn5u39.md diff --git a/.trajectories/completed/2026-05/traj_ootb5rt3tozd.json b/.agentworkforce/trajectories/completed/2026-05/traj_ootb5rt3tozd.json similarity index 100% rename from .trajectories/completed/2026-05/traj_ootb5rt3tozd.json rename to .agentworkforce/trajectories/completed/2026-05/traj_ootb5rt3tozd.json diff --git a/.trajectories/completed/2026-05/traj_ootb5rt3tozd.md b/.agentworkforce/trajectories/completed/2026-05/traj_ootb5rt3tozd.md similarity index 100% rename from .trajectories/completed/2026-05/traj_ootb5rt3tozd.md rename to .agentworkforce/trajectories/completed/2026-05/traj_ootb5rt3tozd.md diff --git a/.trajectories/completed/2026-05/traj_oyc528j7suvo.json b/.agentworkforce/trajectories/completed/2026-05/traj_oyc528j7suvo.json similarity index 100% rename from .trajectories/completed/2026-05/traj_oyc528j7suvo.json rename to .agentworkforce/trajectories/completed/2026-05/traj_oyc528j7suvo.json diff --git a/.trajectories/completed/2026-05/traj_oyc528j7suvo.md b/.agentworkforce/trajectories/completed/2026-05/traj_oyc528j7suvo.md similarity index 100% rename from .trajectories/completed/2026-05/traj_oyc528j7suvo.md rename to .agentworkforce/trajectories/completed/2026-05/traj_oyc528j7suvo.md diff --git a/.trajectories/completed/2026-05/traj_piik8r6zu3i7.json b/.agentworkforce/trajectories/completed/2026-05/traj_piik8r6zu3i7.json similarity index 100% rename from .trajectories/completed/2026-05/traj_piik8r6zu3i7.json rename to .agentworkforce/trajectories/completed/2026-05/traj_piik8r6zu3i7.json diff --git a/.trajectories/completed/2026-05/traj_piik8r6zu3i7.md b/.agentworkforce/trajectories/completed/2026-05/traj_piik8r6zu3i7.md similarity index 100% rename from .trajectories/completed/2026-05/traj_piik8r6zu3i7.md rename to .agentworkforce/trajectories/completed/2026-05/traj_piik8r6zu3i7.md diff --git a/.trajectories/completed/2026-05/traj_pmrcfj6or3pz.json b/.agentworkforce/trajectories/completed/2026-05/traj_pmrcfj6or3pz.json similarity index 100% rename from .trajectories/completed/2026-05/traj_pmrcfj6or3pz.json rename to .agentworkforce/trajectories/completed/2026-05/traj_pmrcfj6or3pz.json diff --git a/.trajectories/completed/2026-05/traj_pmrcfj6or3pz.md b/.agentworkforce/trajectories/completed/2026-05/traj_pmrcfj6or3pz.md similarity index 100% rename from .trajectories/completed/2026-05/traj_pmrcfj6or3pz.md rename to .agentworkforce/trajectories/completed/2026-05/traj_pmrcfj6or3pz.md diff --git a/.trajectories/completed/2026-05/traj_q2r3c9dmdep7.json b/.agentworkforce/trajectories/completed/2026-05/traj_q2r3c9dmdep7.json similarity index 100% rename from .trajectories/completed/2026-05/traj_q2r3c9dmdep7.json rename to .agentworkforce/trajectories/completed/2026-05/traj_q2r3c9dmdep7.json diff --git a/.trajectories/completed/2026-05/traj_q2r3c9dmdep7.md b/.agentworkforce/trajectories/completed/2026-05/traj_q2r3c9dmdep7.md similarity index 100% rename from .trajectories/completed/2026-05/traj_q2r3c9dmdep7.md rename to .agentworkforce/trajectories/completed/2026-05/traj_q2r3c9dmdep7.md diff --git a/.trajectories/completed/2026-05/traj_qbq3laxbvhzf.json b/.agentworkforce/trajectories/completed/2026-05/traj_qbq3laxbvhzf.json similarity index 100% rename from .trajectories/completed/2026-05/traj_qbq3laxbvhzf.json rename to .agentworkforce/trajectories/completed/2026-05/traj_qbq3laxbvhzf.json diff --git a/.trajectories/completed/2026-05/traj_qbq3laxbvhzf.md b/.agentworkforce/trajectories/completed/2026-05/traj_qbq3laxbvhzf.md similarity index 100% rename from .trajectories/completed/2026-05/traj_qbq3laxbvhzf.md rename to .agentworkforce/trajectories/completed/2026-05/traj_qbq3laxbvhzf.md diff --git a/.trajectories/completed/2026-05/traj_qtmid2nzz0kz.json b/.agentworkforce/trajectories/completed/2026-05/traj_qtmid2nzz0kz.json similarity index 100% rename from .trajectories/completed/2026-05/traj_qtmid2nzz0kz.json rename to .agentworkforce/trajectories/completed/2026-05/traj_qtmid2nzz0kz.json diff --git a/.trajectories/completed/2026-05/traj_qtmid2nzz0kz.md b/.agentworkforce/trajectories/completed/2026-05/traj_qtmid2nzz0kz.md similarity index 100% rename from .trajectories/completed/2026-05/traj_qtmid2nzz0kz.md rename to .agentworkforce/trajectories/completed/2026-05/traj_qtmid2nzz0kz.md diff --git a/.trajectories/completed/2026-05/traj_ryf5sstno6p3.json b/.agentworkforce/trajectories/completed/2026-05/traj_ryf5sstno6p3.json similarity index 100% rename from .trajectories/completed/2026-05/traj_ryf5sstno6p3.json rename to .agentworkforce/trajectories/completed/2026-05/traj_ryf5sstno6p3.json diff --git a/.trajectories/completed/2026-05/traj_ryf5sstno6p3.md b/.agentworkforce/trajectories/completed/2026-05/traj_ryf5sstno6p3.md similarity index 100% rename from .trajectories/completed/2026-05/traj_ryf5sstno6p3.md rename to .agentworkforce/trajectories/completed/2026-05/traj_ryf5sstno6p3.md diff --git a/.trajectories/completed/2026-05/traj_s5ojo1f4srz4.json b/.agentworkforce/trajectories/completed/2026-05/traj_s5ojo1f4srz4.json similarity index 100% rename from .trajectories/completed/2026-05/traj_s5ojo1f4srz4.json rename to .agentworkforce/trajectories/completed/2026-05/traj_s5ojo1f4srz4.json diff --git a/.trajectories/completed/2026-05/traj_s5ojo1f4srz4.md b/.agentworkforce/trajectories/completed/2026-05/traj_s5ojo1f4srz4.md similarity index 100% rename from .trajectories/completed/2026-05/traj_s5ojo1f4srz4.md rename to .agentworkforce/trajectories/completed/2026-05/traj_s5ojo1f4srz4.md diff --git a/.trajectories/completed/2026-05/traj_sh2ahp9z2xg6.json b/.agentworkforce/trajectories/completed/2026-05/traj_sh2ahp9z2xg6.json similarity index 100% rename from .trajectories/completed/2026-05/traj_sh2ahp9z2xg6.json rename to .agentworkforce/trajectories/completed/2026-05/traj_sh2ahp9z2xg6.json diff --git a/.trajectories/completed/2026-05/traj_sh2ahp9z2xg6.md b/.agentworkforce/trajectories/completed/2026-05/traj_sh2ahp9z2xg6.md similarity index 100% rename from .trajectories/completed/2026-05/traj_sh2ahp9z2xg6.md rename to .agentworkforce/trajectories/completed/2026-05/traj_sh2ahp9z2xg6.md diff --git a/.trajectories/completed/2026-05/traj_sqerp89tc436.json b/.agentworkforce/trajectories/completed/2026-05/traj_sqerp89tc436.json similarity index 100% rename from .trajectories/completed/2026-05/traj_sqerp89tc436.json rename to .agentworkforce/trajectories/completed/2026-05/traj_sqerp89tc436.json diff --git a/.trajectories/completed/2026-05/traj_sqerp89tc436.md b/.agentworkforce/trajectories/completed/2026-05/traj_sqerp89tc436.md similarity index 100% rename from .trajectories/completed/2026-05/traj_sqerp89tc436.md rename to .agentworkforce/trajectories/completed/2026-05/traj_sqerp89tc436.md diff --git a/.trajectories/completed/2026-05/traj_t5uknesn2fcw.json b/.agentworkforce/trajectories/completed/2026-05/traj_t5uknesn2fcw.json similarity index 100% rename from .trajectories/completed/2026-05/traj_t5uknesn2fcw.json rename to .agentworkforce/trajectories/completed/2026-05/traj_t5uknesn2fcw.json diff --git a/.trajectories/completed/2026-05/traj_t5uknesn2fcw.md b/.agentworkforce/trajectories/completed/2026-05/traj_t5uknesn2fcw.md similarity index 100% rename from .trajectories/completed/2026-05/traj_t5uknesn2fcw.md rename to .agentworkforce/trajectories/completed/2026-05/traj_t5uknesn2fcw.md diff --git a/.trajectories/completed/2026-05/traj_t6h534vn0bpg.json b/.agentworkforce/trajectories/completed/2026-05/traj_t6h534vn0bpg.json similarity index 100% rename from .trajectories/completed/2026-05/traj_t6h534vn0bpg.json rename to .agentworkforce/trajectories/completed/2026-05/traj_t6h534vn0bpg.json diff --git a/.trajectories/completed/2026-05/traj_t6h534vn0bpg.md b/.agentworkforce/trajectories/completed/2026-05/traj_t6h534vn0bpg.md similarity index 100% rename from .trajectories/completed/2026-05/traj_t6h534vn0bpg.md rename to .agentworkforce/trajectories/completed/2026-05/traj_t6h534vn0bpg.md diff --git a/.trajectories/completed/2026-05/traj_tavtex0db4b0.json b/.agentworkforce/trajectories/completed/2026-05/traj_tavtex0db4b0.json similarity index 100% rename from .trajectories/completed/2026-05/traj_tavtex0db4b0.json rename to .agentworkforce/trajectories/completed/2026-05/traj_tavtex0db4b0.json diff --git a/.trajectories/completed/2026-05/traj_tavtex0db4b0.md b/.agentworkforce/trajectories/completed/2026-05/traj_tavtex0db4b0.md similarity index 100% rename from .trajectories/completed/2026-05/traj_tavtex0db4b0.md rename to .agentworkforce/trajectories/completed/2026-05/traj_tavtex0db4b0.md diff --git a/.trajectories/completed/2026-05/traj_tgism98me5na.json b/.agentworkforce/trajectories/completed/2026-05/traj_tgism98me5na.json similarity index 100% rename from .trajectories/completed/2026-05/traj_tgism98me5na.json rename to .agentworkforce/trajectories/completed/2026-05/traj_tgism98me5na.json diff --git a/.trajectories/completed/2026-05/traj_tgism98me5na.md b/.agentworkforce/trajectories/completed/2026-05/traj_tgism98me5na.md similarity index 100% rename from .trajectories/completed/2026-05/traj_tgism98me5na.md rename to .agentworkforce/trajectories/completed/2026-05/traj_tgism98me5na.md diff --git a/.trajectories/completed/2026-05/traj_u33qn99ijbh4.json b/.agentworkforce/trajectories/completed/2026-05/traj_u33qn99ijbh4.json similarity index 100% rename from .trajectories/completed/2026-05/traj_u33qn99ijbh4.json rename to .agentworkforce/trajectories/completed/2026-05/traj_u33qn99ijbh4.json diff --git a/.trajectories/completed/2026-05/traj_u33qn99ijbh4.md b/.agentworkforce/trajectories/completed/2026-05/traj_u33qn99ijbh4.md similarity index 100% rename from .trajectories/completed/2026-05/traj_u33qn99ijbh4.md rename to .agentworkforce/trajectories/completed/2026-05/traj_u33qn99ijbh4.md diff --git a/.trajectories/completed/2026-05/traj_u3loicehnwb4.json b/.agentworkforce/trajectories/completed/2026-05/traj_u3loicehnwb4.json similarity index 100% rename from .trajectories/completed/2026-05/traj_u3loicehnwb4.json rename to .agentworkforce/trajectories/completed/2026-05/traj_u3loicehnwb4.json diff --git a/.trajectories/completed/2026-05/traj_u3loicehnwb4.md b/.agentworkforce/trajectories/completed/2026-05/traj_u3loicehnwb4.md similarity index 100% rename from .trajectories/completed/2026-05/traj_u3loicehnwb4.md rename to .agentworkforce/trajectories/completed/2026-05/traj_u3loicehnwb4.md diff --git a/.trajectories/completed/2026-05/traj_u4ixmbqqm2y1.json b/.agentworkforce/trajectories/completed/2026-05/traj_u4ixmbqqm2y1.json similarity index 100% rename from .trajectories/completed/2026-05/traj_u4ixmbqqm2y1.json rename to .agentworkforce/trajectories/completed/2026-05/traj_u4ixmbqqm2y1.json diff --git a/.trajectories/completed/2026-05/traj_u4ixmbqqm2y1.md b/.agentworkforce/trajectories/completed/2026-05/traj_u4ixmbqqm2y1.md similarity index 100% rename from .trajectories/completed/2026-05/traj_u4ixmbqqm2y1.md rename to .agentworkforce/trajectories/completed/2026-05/traj_u4ixmbqqm2y1.md diff --git a/.trajectories/completed/2026-05/traj_uf8y40ewrfh0.json b/.agentworkforce/trajectories/completed/2026-05/traj_uf8y40ewrfh0.json similarity index 100% rename from .trajectories/completed/2026-05/traj_uf8y40ewrfh0.json rename to .agentworkforce/trajectories/completed/2026-05/traj_uf8y40ewrfh0.json diff --git a/.trajectories/completed/2026-05/traj_uf8y40ewrfh0.md b/.agentworkforce/trajectories/completed/2026-05/traj_uf8y40ewrfh0.md similarity index 100% rename from .trajectories/completed/2026-05/traj_uf8y40ewrfh0.md rename to .agentworkforce/trajectories/completed/2026-05/traj_uf8y40ewrfh0.md diff --git a/.trajectories/completed/2026-05/traj_v1wexlfur5zr.json b/.agentworkforce/trajectories/completed/2026-05/traj_v1wexlfur5zr.json similarity index 100% rename from .trajectories/completed/2026-05/traj_v1wexlfur5zr.json rename to .agentworkforce/trajectories/completed/2026-05/traj_v1wexlfur5zr.json diff --git a/.trajectories/completed/2026-05/traj_v1wexlfur5zr.md b/.agentworkforce/trajectories/completed/2026-05/traj_v1wexlfur5zr.md similarity index 100% rename from .trajectories/completed/2026-05/traj_v1wexlfur5zr.md rename to .agentworkforce/trajectories/completed/2026-05/traj_v1wexlfur5zr.md diff --git a/.trajectories/completed/2026-05/traj_v87cyrs8dke9.json b/.agentworkforce/trajectories/completed/2026-05/traj_v87cyrs8dke9.json similarity index 100% rename from .trajectories/completed/2026-05/traj_v87cyrs8dke9.json rename to .agentworkforce/trajectories/completed/2026-05/traj_v87cyrs8dke9.json diff --git a/.trajectories/completed/2026-05/traj_v87cyrs8dke9.md b/.agentworkforce/trajectories/completed/2026-05/traj_v87cyrs8dke9.md similarity index 100% rename from .trajectories/completed/2026-05/traj_v87cyrs8dke9.md rename to .agentworkforce/trajectories/completed/2026-05/traj_v87cyrs8dke9.md diff --git a/.trajectories/completed/2026-05/traj_v87cyrs8dke9.trace.json b/.agentworkforce/trajectories/completed/2026-05/traj_v87cyrs8dke9.trace.json similarity index 100% rename from .trajectories/completed/2026-05/traj_v87cyrs8dke9.trace.json rename to .agentworkforce/trajectories/completed/2026-05/traj_v87cyrs8dke9.trace.json diff --git a/.trajectories/completed/2026-05/traj_v9x3o92ag682.json b/.agentworkforce/trajectories/completed/2026-05/traj_v9x3o92ag682.json similarity index 100% rename from .trajectories/completed/2026-05/traj_v9x3o92ag682.json rename to .agentworkforce/trajectories/completed/2026-05/traj_v9x3o92ag682.json diff --git a/.trajectories/completed/2026-05/traj_v9x3o92ag682.md b/.agentworkforce/trajectories/completed/2026-05/traj_v9x3o92ag682.md similarity index 100% rename from .trajectories/completed/2026-05/traj_v9x3o92ag682.md rename to .agentworkforce/trajectories/completed/2026-05/traj_v9x3o92ag682.md diff --git a/.trajectories/completed/2026-05/traj_vfa1jr6otnjn.json b/.agentworkforce/trajectories/completed/2026-05/traj_vfa1jr6otnjn.json similarity index 100% rename from .trajectories/completed/2026-05/traj_vfa1jr6otnjn.json rename to .agentworkforce/trajectories/completed/2026-05/traj_vfa1jr6otnjn.json diff --git a/.trajectories/completed/2026-05/traj_vfa1jr6otnjn.md b/.agentworkforce/trajectories/completed/2026-05/traj_vfa1jr6otnjn.md similarity index 100% rename from .trajectories/completed/2026-05/traj_vfa1jr6otnjn.md rename to .agentworkforce/trajectories/completed/2026-05/traj_vfa1jr6otnjn.md diff --git a/.trajectories/completed/2026-05/traj_vkozdglobkyg.json b/.agentworkforce/trajectories/completed/2026-05/traj_vkozdglobkyg.json similarity index 100% rename from .trajectories/completed/2026-05/traj_vkozdglobkyg.json rename to .agentworkforce/trajectories/completed/2026-05/traj_vkozdglobkyg.json diff --git a/.trajectories/completed/2026-05/traj_vkozdglobkyg.md b/.agentworkforce/trajectories/completed/2026-05/traj_vkozdglobkyg.md similarity index 100% rename from .trajectories/completed/2026-05/traj_vkozdglobkyg.md rename to .agentworkforce/trajectories/completed/2026-05/traj_vkozdglobkyg.md diff --git a/.trajectories/completed/2026-05/traj_wbn62q4cq16h.json b/.agentworkforce/trajectories/completed/2026-05/traj_wbn62q4cq16h.json similarity index 100% rename from .trajectories/completed/2026-05/traj_wbn62q4cq16h.json rename to .agentworkforce/trajectories/completed/2026-05/traj_wbn62q4cq16h.json diff --git a/.trajectories/completed/2026-05/traj_wbn62q4cq16h.md b/.agentworkforce/trajectories/completed/2026-05/traj_wbn62q4cq16h.md similarity index 100% rename from .trajectories/completed/2026-05/traj_wbn62q4cq16h.md rename to .agentworkforce/trajectories/completed/2026-05/traj_wbn62q4cq16h.md diff --git a/.trajectories/completed/2026-05/traj_whd40oxptlhn.json b/.agentworkforce/trajectories/completed/2026-05/traj_whd40oxptlhn.json similarity index 100% rename from .trajectories/completed/2026-05/traj_whd40oxptlhn.json rename to .agentworkforce/trajectories/completed/2026-05/traj_whd40oxptlhn.json diff --git a/.trajectories/completed/2026-05/traj_whd40oxptlhn.md b/.agentworkforce/trajectories/completed/2026-05/traj_whd40oxptlhn.md similarity index 100% rename from .trajectories/completed/2026-05/traj_whd40oxptlhn.md rename to .agentworkforce/trajectories/completed/2026-05/traj_whd40oxptlhn.md diff --git a/.trajectories/completed/2026-05/traj_whd40oxptlhn.trace.json b/.agentworkforce/trajectories/completed/2026-05/traj_whd40oxptlhn.trace.json similarity index 100% rename from .trajectories/completed/2026-05/traj_whd40oxptlhn.trace.json rename to .agentworkforce/trajectories/completed/2026-05/traj_whd40oxptlhn.trace.json diff --git a/.trajectories/completed/2026-05/traj_wx00tjvpptvg.json b/.agentworkforce/trajectories/completed/2026-05/traj_wx00tjvpptvg.json similarity index 100% rename from .trajectories/completed/2026-05/traj_wx00tjvpptvg.json rename to .agentworkforce/trajectories/completed/2026-05/traj_wx00tjvpptvg.json diff --git a/.trajectories/completed/2026-05/traj_wx00tjvpptvg.md b/.agentworkforce/trajectories/completed/2026-05/traj_wx00tjvpptvg.md similarity index 100% rename from .trajectories/completed/2026-05/traj_wx00tjvpptvg.md rename to .agentworkforce/trajectories/completed/2026-05/traj_wx00tjvpptvg.md diff --git a/.trajectories/completed/2026-05/traj_wzzboitm85ee.json b/.agentworkforce/trajectories/completed/2026-05/traj_wzzboitm85ee.json similarity index 100% rename from .trajectories/completed/2026-05/traj_wzzboitm85ee.json rename to .agentworkforce/trajectories/completed/2026-05/traj_wzzboitm85ee.json diff --git a/.trajectories/completed/2026-05/traj_wzzboitm85ee.md b/.agentworkforce/trajectories/completed/2026-05/traj_wzzboitm85ee.md similarity index 100% rename from .trajectories/completed/2026-05/traj_wzzboitm85ee.md rename to .agentworkforce/trajectories/completed/2026-05/traj_wzzboitm85ee.md diff --git a/.trajectories/completed/2026-05/traj_x37bhga2j5ph.json b/.agentworkforce/trajectories/completed/2026-05/traj_x37bhga2j5ph.json similarity index 100% rename from .trajectories/completed/2026-05/traj_x37bhga2j5ph.json rename to .agentworkforce/trajectories/completed/2026-05/traj_x37bhga2j5ph.json diff --git a/.trajectories/completed/2026-05/traj_x37bhga2j5ph.md b/.agentworkforce/trajectories/completed/2026-05/traj_x37bhga2j5ph.md similarity index 100% rename from .trajectories/completed/2026-05/traj_x37bhga2j5ph.md rename to .agentworkforce/trajectories/completed/2026-05/traj_x37bhga2j5ph.md diff --git a/.trajectories/completed/2026-05/traj_ybcrij9wg8m1.json b/.agentworkforce/trajectories/completed/2026-05/traj_ybcrij9wg8m1.json similarity index 100% rename from .trajectories/completed/2026-05/traj_ybcrij9wg8m1.json rename to .agentworkforce/trajectories/completed/2026-05/traj_ybcrij9wg8m1.json diff --git a/.trajectories/completed/2026-05/traj_ybcrij9wg8m1.md b/.agentworkforce/trajectories/completed/2026-05/traj_ybcrij9wg8m1.md similarity index 100% rename from .trajectories/completed/2026-05/traj_ybcrij9wg8m1.md rename to .agentworkforce/trajectories/completed/2026-05/traj_ybcrij9wg8m1.md diff --git a/.trajectories/completed/2026-05/traj_z171lng2fbbi.json b/.agentworkforce/trajectories/completed/2026-05/traj_z171lng2fbbi.json similarity index 100% rename from .trajectories/completed/2026-05/traj_z171lng2fbbi.json rename to .agentworkforce/trajectories/completed/2026-05/traj_z171lng2fbbi.json diff --git a/.trajectories/completed/2026-05/traj_z171lng2fbbi.md b/.agentworkforce/trajectories/completed/2026-05/traj_z171lng2fbbi.md similarity index 100% rename from .trajectories/completed/2026-05/traj_z171lng2fbbi.md rename to .agentworkforce/trajectories/completed/2026-05/traj_z171lng2fbbi.md diff --git a/.trajectories/completed/2026-05/traj_zfa6skfr32vy.json b/.agentworkforce/trajectories/completed/2026-05/traj_zfa6skfr32vy.json similarity index 100% rename from .trajectories/completed/2026-05/traj_zfa6skfr32vy.json rename to .agentworkforce/trajectories/completed/2026-05/traj_zfa6skfr32vy.json diff --git a/.trajectories/completed/2026-05/traj_zfa6skfr32vy.md b/.agentworkforce/trajectories/completed/2026-05/traj_zfa6skfr32vy.md similarity index 100% rename from .trajectories/completed/2026-05/traj_zfa6skfr32vy.md rename to .agentworkforce/trajectories/completed/2026-05/traj_zfa6skfr32vy.md diff --git a/.trajectories/completed/2026-05/traj_zqwco4gl76g3.json b/.agentworkforce/trajectories/completed/2026-05/traj_zqwco4gl76g3.json similarity index 100% rename from .trajectories/completed/2026-05/traj_zqwco4gl76g3.json rename to .agentworkforce/trajectories/completed/2026-05/traj_zqwco4gl76g3.json diff --git a/.trajectories/completed/2026-05/traj_zqwco4gl76g3.md b/.agentworkforce/trajectories/completed/2026-05/traj_zqwco4gl76g3.md similarity index 100% rename from .trajectories/completed/2026-05/traj_zqwco4gl76g3.md rename to .agentworkforce/trajectories/completed/2026-05/traj_zqwco4gl76g3.md diff --git a/.trajectories/completed/2026-05/traj_zu3252hxzoqh.json b/.agentworkforce/trajectories/completed/2026-05/traj_zu3252hxzoqh.json similarity index 100% rename from .trajectories/completed/2026-05/traj_zu3252hxzoqh.json rename to .agentworkforce/trajectories/completed/2026-05/traj_zu3252hxzoqh.json diff --git a/.trajectories/completed/2026-05/traj_zu3252hxzoqh.md b/.agentworkforce/trajectories/completed/2026-05/traj_zu3252hxzoqh.md similarity index 100% rename from .trajectories/completed/2026-05/traj_zu3252hxzoqh.md rename to .agentworkforce/trajectories/completed/2026-05/traj_zu3252hxzoqh.md diff --git a/.trajectories/completed/2026-05/traj_zyluvmlqo5j7.json b/.agentworkforce/trajectories/completed/2026-05/traj_zyluvmlqo5j7.json similarity index 100% rename from .trajectories/completed/2026-05/traj_zyluvmlqo5j7.json rename to .agentworkforce/trajectories/completed/2026-05/traj_zyluvmlqo5j7.json diff --git a/.trajectories/completed/2026-05/traj_zyluvmlqo5j7.md b/.agentworkforce/trajectories/completed/2026-05/traj_zyluvmlqo5j7.md similarity index 100% rename from .trajectories/completed/2026-05/traj_zyluvmlqo5j7.md rename to .agentworkforce/trajectories/completed/2026-05/traj_zyluvmlqo5j7.md diff --git a/.trajectories/completed/traj_1775914296101_a4397efe.json b/.agentworkforce/trajectories/completed/traj_1775914296101_a4397efe.json similarity index 100% rename from .trajectories/completed/traj_1775914296101_a4397efe.json rename to .agentworkforce/trajectories/completed/traj_1775914296101_a4397efe.json diff --git a/.trajectories/completed/traj_1776024661304_cfc829b9.json b/.agentworkforce/trajectories/completed/traj_1776024661304_cfc829b9.json similarity index 100% rename from .trajectories/completed/traj_1776024661304_cfc829b9.json rename to .agentworkforce/trajectories/completed/traj_1776024661304_cfc829b9.json diff --git a/.trajectories/completed/traj_1776105620545_9dcebb3d.json b/.agentworkforce/trajectories/completed/traj_1776105620545_9dcebb3d.json similarity index 100% rename from .trajectories/completed/traj_1776105620545_9dcebb3d.json rename to .agentworkforce/trajectories/completed/traj_1776105620545_9dcebb3d.json diff --git a/.trajectories/completed/traj_1778873052429_03a4dacb.json b/.agentworkforce/trajectories/completed/traj_1778873052429_03a4dacb.json similarity index 100% rename from .trajectories/completed/traj_1778873052429_03a4dacb.json rename to .agentworkforce/trajectories/completed/traj_1778873052429_03a4dacb.json diff --git a/.trajectories/completed/traj_1778873197540_01102ade.json b/.agentworkforce/trajectories/completed/traj_1778873197540_01102ade.json similarity index 100% rename from .trajectories/completed/traj_1778873197540_01102ade.json rename to .agentworkforce/trajectories/completed/traj_1778873197540_01102ade.json diff --git a/.trajectories/completed/traj_1778873199489_f2ce4060.json b/.agentworkforce/trajectories/completed/traj_1778873199489_f2ce4060.json similarity index 100% rename from .trajectories/completed/traj_1778873199489_f2ce4060.json rename to .agentworkforce/trajectories/completed/traj_1778873199489_f2ce4060.json diff --git a/.trajectories/completed/traj_1778873201502_0dacf7c5.json b/.agentworkforce/trajectories/completed/traj_1778873201502_0dacf7c5.json similarity index 100% rename from .trajectories/completed/traj_1778873201502_0dacf7c5.json rename to .agentworkforce/trajectories/completed/traj_1778873201502_0dacf7c5.json diff --git a/.trajectories/completed/traj_1778873203502_4c225b7e.json b/.agentworkforce/trajectories/completed/traj_1778873203502_4c225b7e.json similarity index 100% rename from .trajectories/completed/traj_1778873203502_4c225b7e.json rename to .agentworkforce/trajectories/completed/traj_1778873203502_4c225b7e.json diff --git a/.trajectories/completed/traj_1778873205470_a4e5f0cb.json b/.agentworkforce/trajectories/completed/traj_1778873205470_a4e5f0cb.json similarity index 100% rename from .trajectories/completed/traj_1778873205470_a4e5f0cb.json rename to .agentworkforce/trajectories/completed/traj_1778873205470_a4e5f0cb.json diff --git a/.trajectories/completed/traj_1778873207471_b7def991.json b/.agentworkforce/trajectories/completed/traj_1778873207471_b7def991.json similarity index 100% rename from .trajectories/completed/traj_1778873207471_b7def991.json rename to .agentworkforce/trajectories/completed/traj_1778873207471_b7def991.json diff --git a/.trajectories/completed/traj_1778873209642_c70e32ab.json b/.agentworkforce/trajectories/completed/traj_1778873209642_c70e32ab.json similarity index 100% rename from .trajectories/completed/traj_1778873209642_c70e32ab.json rename to .agentworkforce/trajectories/completed/traj_1778873209642_c70e32ab.json diff --git a/.trajectories/completed/traj_1778873211616_6db3b2cd.json b/.agentworkforce/trajectories/completed/traj_1778873211616_6db3b2cd.json similarity index 100% rename from .trajectories/completed/traj_1778873211616_6db3b2cd.json rename to .agentworkforce/trajectories/completed/traj_1778873211616_6db3b2cd.json diff --git a/.trajectories/completed/traj_1778874205797_81e92307.json b/.agentworkforce/trajectories/completed/traj_1778874205797_81e92307.json similarity index 100% rename from .trajectories/completed/traj_1778874205797_81e92307.json rename to .agentworkforce/trajectories/completed/traj_1778874205797_81e92307.json diff --git a/.trajectories/completed/traj_1778874216773_c6b12ab2.json b/.agentworkforce/trajectories/completed/traj_1778874216773_c6b12ab2.json similarity index 100% rename from .trajectories/completed/traj_1778874216773_c6b12ab2.json rename to .agentworkforce/trajectories/completed/traj_1778874216773_c6b12ab2.json diff --git a/.trajectories/completed/traj_1778874218579_a0225559.json b/.agentworkforce/trajectories/completed/traj_1778874218579_a0225559.json similarity index 100% rename from .trajectories/completed/traj_1778874218579_a0225559.json rename to .agentworkforce/trajectories/completed/traj_1778874218579_a0225559.json diff --git a/.trajectories/completed/traj_1778874224855_9c722c4b.json b/.agentworkforce/trajectories/completed/traj_1778874224855_9c722c4b.json similarity index 100% rename from .trajectories/completed/traj_1778874224855_9c722c4b.json rename to .agentworkforce/trajectories/completed/traj_1778874224855_9c722c4b.json diff --git a/.trajectories/completed/traj_1778874226983_3367d527.json b/.agentworkforce/trajectories/completed/traj_1778874226983_3367d527.json similarity index 100% rename from .trajectories/completed/traj_1778874226983_3367d527.json rename to .agentworkforce/trajectories/completed/traj_1778874226983_3367d527.json diff --git a/.trajectories/completed/traj_1778874229373_9cce9465.json b/.agentworkforce/trajectories/completed/traj_1778874229373_9cce9465.json similarity index 100% rename from .trajectories/completed/traj_1778874229373_9cce9465.json rename to .agentworkforce/trajectories/completed/traj_1778874229373_9cce9465.json diff --git a/.trajectories/completed/traj_1778874240339_51b823cd.json b/.agentworkforce/trajectories/completed/traj_1778874240339_51b823cd.json similarity index 100% rename from .trajectories/completed/traj_1778874240339_51b823cd.json rename to .agentworkforce/trajectories/completed/traj_1778874240339_51b823cd.json diff --git a/.trajectories/completed/traj_1778874241076_caa675a9.json b/.agentworkforce/trajectories/completed/traj_1778874241076_caa675a9.json similarity index 100% rename from .trajectories/completed/traj_1778874241076_caa675a9.json rename to .agentworkforce/trajectories/completed/traj_1778874241076_caa675a9.json diff --git a/.trajectories/completed/traj_1778874248966_e29c4c54.json b/.agentworkforce/trajectories/completed/traj_1778874248966_e29c4c54.json similarity index 100% rename from .trajectories/completed/traj_1778874248966_e29c4c54.json rename to .agentworkforce/trajectories/completed/traj_1778874248966_e29c4c54.json diff --git a/.trajectories/completed/traj_1778874249983_12a98df3.json b/.agentworkforce/trajectories/completed/traj_1778874249983_12a98df3.json similarity index 100% rename from .trajectories/completed/traj_1778874249983_12a98df3.json rename to .agentworkforce/trajectories/completed/traj_1778874249983_12a98df3.json diff --git a/.trajectories/completed/traj_1778874258229_0bdc53d8.json b/.agentworkforce/trajectories/completed/traj_1778874258229_0bdc53d8.json similarity index 100% rename from .trajectories/completed/traj_1778874258229_0bdc53d8.json rename to .agentworkforce/trajectories/completed/traj_1778874258229_0bdc53d8.json diff --git a/.trajectories/completed/traj_1778874261453_55f49624.json b/.agentworkforce/trajectories/completed/traj_1778874261453_55f49624.json similarity index 100% rename from .trajectories/completed/traj_1778874261453_55f49624.json rename to .agentworkforce/trajectories/completed/traj_1778874261453_55f49624.json diff --git a/.trajectories/completed/traj_1778874261608_48fb9bf5.json b/.agentworkforce/trajectories/completed/traj_1778874261608_48fb9bf5.json similarity index 100% rename from .trajectories/completed/traj_1778874261608_48fb9bf5.json rename to .agentworkforce/trajectories/completed/traj_1778874261608_48fb9bf5.json diff --git a/.trajectories/completed/traj_1778874269139_d7d7485a.json b/.agentworkforce/trajectories/completed/traj_1778874269139_d7d7485a.json similarity index 100% rename from .trajectories/completed/traj_1778874269139_d7d7485a.json rename to .agentworkforce/trajectories/completed/traj_1778874269139_d7d7485a.json diff --git a/.trajectories/completed/traj_1778874274412_70843e0e.json b/.agentworkforce/trajectories/completed/traj_1778874274412_70843e0e.json similarity index 100% rename from .trajectories/completed/traj_1778874274412_70843e0e.json rename to .agentworkforce/trajectories/completed/traj_1778874274412_70843e0e.json diff --git a/.trajectories/completed/traj_1778874274581_71efa470.json b/.agentworkforce/trajectories/completed/traj_1778874274581_71efa470.json similarity index 100% rename from .trajectories/completed/traj_1778874274581_71efa470.json rename to .agentworkforce/trajectories/completed/traj_1778874274581_71efa470.json diff --git a/.trajectories/completed/traj_1778874282200_39ad11db.json b/.agentworkforce/trajectories/completed/traj_1778874282200_39ad11db.json similarity index 100% rename from .trajectories/completed/traj_1778874282200_39ad11db.json rename to .agentworkforce/trajectories/completed/traj_1778874282200_39ad11db.json diff --git a/.trajectories/completed/traj_1778874283570_ce3585b8.json b/.agentworkforce/trajectories/completed/traj_1778874283570_ce3585b8.json similarity index 100% rename from .trajectories/completed/traj_1778874283570_ce3585b8.json rename to .agentworkforce/trajectories/completed/traj_1778874283570_ce3585b8.json diff --git a/.trajectories/completed/traj_1778874289674_e3f868c8.json b/.agentworkforce/trajectories/completed/traj_1778874289674_e3f868c8.json similarity index 100% rename from .trajectories/completed/traj_1778874289674_e3f868c8.json rename to .agentworkforce/trajectories/completed/traj_1778874289674_e3f868c8.json diff --git a/.trajectories/completed/traj_1778874291950_0b1b5c1f.json b/.agentworkforce/trajectories/completed/traj_1778874291950_0b1b5c1f.json similarity index 100% rename from .trajectories/completed/traj_1778874291950_0b1b5c1f.json rename to .agentworkforce/trajectories/completed/traj_1778874291950_0b1b5c1f.json diff --git a/.trajectories/completed/traj_1778874295927_4083d181.json b/.agentworkforce/trajectories/completed/traj_1778874295927_4083d181.json similarity index 100% rename from .trajectories/completed/traj_1778874295927_4083d181.json rename to .agentworkforce/trajectories/completed/traj_1778874295927_4083d181.json diff --git a/.trajectories/completed/traj_1778874296362_bdf727ff.json b/.agentworkforce/trajectories/completed/traj_1778874296362_bdf727ff.json similarity index 100% rename from .trajectories/completed/traj_1778874296362_bdf727ff.json rename to .agentworkforce/trajectories/completed/traj_1778874296362_bdf727ff.json diff --git a/.trajectories/index.json b/.trajectories/index.json deleted file mode 100644 index 2d9fd8926..000000000 --- a/.trajectories/index.json +++ /dev/null @@ -1,1259 +0,0 @@ -{ - "version": 1, - "lastUpdated": "2026-05-26T15:01:56.618Z", - "trajectories": { - "traj_05xg7j388bc4": { - "title": "Add browser workflow step integration", - "status": "completed", - "startedAt": "2026-04-10T14:56:33.229Z", - "completedAt": "2026-04-10T15:05:14.660Z", - "path": ".trajectories/completed/2026-04/traj_05xg7j388bc4.json" - }, - "traj_0t92gxaz6igh": { - "title": "Move docs sidebar into the mobile hamburger menu", - "status": "completed", - "startedAt": "2026-04-10T16:29:40.674Z", - "completedAt": "2026-04-10T16:32:14.544Z", - "path": ".trajectories/completed/2026-04/traj_0t92gxaz6igh.json" - }, - "traj_1776105620545_9dcebb3d": { - "title": "fix-inbox-agent-flag-workflow", - "status": "completed", - "startedAt": "2026-04-13T18:40:20.545Z", - "completedAt": "2026-04-13T18:41:52.831Z", - "path": ".trajectories/completed/2026-04/traj_1776105620545_9dcebb3d.json" - }, - "traj_1776105988184_29f1270c": { - "title": "fix-inbox-agent-flag-workflow", - "status": "completed", - "startedAt": "2026-04-13T18:46:28.184Z", - "completedAt": "2026-04-13T20:23:54.308Z", - "path": ".trajectories/completed/2026-04/traj_1776105988184_29f1270c.json" - }, - "traj_222ha5671idc": { - "title": "validate-cloud-connect-e2e-workflow", - "status": "completed", - "startedAt": "2026-04-15T21:32:51.980Z", - "completedAt": "2026-04-15T21:45:41.024Z", - "path": ".trajectories/completed/2026-04/traj_222ha5671idc.json" - }, - "traj_3b3p1z4y7qlo": { - "title": "add-mcp-args-subcommand-workflow", - "status": "completed", - "startedAt": "2026-04-20T13:16:22.009Z", - "completedAt": "2026-04-20T13:26:35.142Z", - "path": ".trajectories/completed/2026-04/traj_3b3p1z4y7qlo.json" - }, - "traj_4zqhfqw7g28l": { - "title": "Investigate GitHub Actions failure for run 24255758219 job 70826792063", - "status": "completed", - "startedAt": "2026-04-10T17:48:33.502Z", - "completedAt": "2026-04-10T17:49:14.485Z", - "path": ".trajectories/completed/2026-04/traj_4zqhfqw7g28l.json" - }, - "traj_530xmbfeljyb": { - "title": "Implement GitHub primitive adapter base layer", - "status": "completed", - "startedAt": "2026-04-10T15:16:25.682Z", - "completedAt": "2026-04-10T15:25:16.937Z", - "path": ".trajectories/completed/2026-04/traj_530xmbfeljyb.json" - }, - "traj_703m7sqyq89t": { - "title": "Fix production docs loader using build-machine absolute MDX paths", - "status": "completed", - "startedAt": "2026-04-10T16:33:10.601Z", - "completedAt": "2026-04-10T16:35:33.660Z", - "path": ".trajectories/completed/2026-04/traj_703m7sqyq89t.json" - }, - "traj_8oh4r5km5eic": { - "title": "Implement GitHub primitive actions", - "status": "completed", - "startedAt": "2026-04-10T15:26:11.355Z", - "completedAt": "2026-04-10T15:33:35.150Z", - "path": ".trajectories/completed/2026-04/traj_8oh4r5km5eic.json" - }, - "traj_9tt55is74dq5": { - "title": "Pin TypeScript build resolution for acp-bridge, memory, trajectory, and cloud", - "status": "completed", - "startedAt": "2026-04-11T13:34:46.304Z", - "completedAt": "2026-04-11T13:35:22.677Z", - "path": ".trajectories/completed/2026-04/traj_9tt55is74dq5.json" - }, - "traj_abjovknvcijv": { - "title": "Scope CI so web-only changes do not run unrelated relay and SDK tests", - "status": "completed", - "startedAt": "2026-04-10T16:08:30.070Z", - "completedAt": "2026-04-10T16:11:08.673Z", - "path": ".trajectories/completed/2026-04/traj_abjovknvcijv.json" - }, - "traj_avmkyoo2s3rt": { - "title": "Implement Browser primitive client", - "status": "completed", - "startedAt": "2026-04-10T14:42:17.242Z", - "completedAt": "2026-04-10T14:55:45.196Z", - "path": ".trajectories/completed/2026-04/traj_avmkyoo2s3rt.json" - }, - "traj_d48czxmgx4ac": { - "title": "Shift dark-mode footer from black to Relay blue", - "status": "completed", - "startedAt": "2026-04-10T16:12:27.477Z", - "completedAt": "2026-04-10T16:13:14.348Z", - "path": ".trajectories/completed/2026-04/traj_d48czxmgx4ac.json" - }, - "traj_dw8ihhdb8ip7": { - "title": "fix-dm-history-workflow", - "status": "abandoned", - "startedAt": "2026-04-13T19:51:57.984Z", - "completedAt": "2026-04-13T19:57:27.195Z", - "path": ".trajectories/completed/2026-04/traj_dw8ihhdb8ip7.json" - }, - "traj_e5i62wdjx0jd": { - "title": "Plan autofix finding groups", - "status": "completed", - "startedAt": "2026-04-13T09:40:42.044Z", - "completedAt": "2026-04-13T09:41:07.789Z", - "path": ".trajectories/completed/2026-04/traj_e5i62wdjx0jd.json" - }, - "traj_g3muawdq6bsb": { - "title": "Invert dark footer gradient so the lighter blue is at the top", - "status": "completed", - "startedAt": "2026-04-10T16:13:19.744Z", - "completedAt": "2026-04-10T16:13:43.289Z", - "path": ".trajectories/completed/2026-04/traj_g3muawdq6bsb.json" - }, - "traj_mk0t0cgn4ytq": { - "title": "Merge origin/main into better-nav and resolve trajectory conflicts", - "status": "completed", - "startedAt": "2026-04-10T15:10:03.877Z", - "completedAt": "2026-04-10T15:10:29.410Z", - "path": ".trajectories/completed/2026-04/traj_mk0t0cgn4ytq.json" - }, - "traj_o8kgzhfu6jth": { - "title": "Add /cloud link to footer", - "status": "completed", - "startedAt": "2026-04-10T16:07:15.131Z", - "completedAt": "2026-04-10T16:07:42.930Z", - "path": ".trajectories/completed/2026-04/traj_o8kgzhfu6jth.json" - }, - "traj_qb54w47qwod6": { - "title": "fix-history-from-workflow", - "status": "completed", - "startedAt": "2026-04-13T20:16:10.459Z", - "completedAt": "2026-04-13T20:25:09.219Z", - "path": ".trajectories/completed/2026-04/traj_qb54w47qwod6.json" - }, - "traj_rs2bt3x0fqba": { - "title": "Compare failed web deploy to prior deploys and identify no-downtime fix", - "status": "completed", - "startedAt": "2026-04-10T17:50:43.088Z", - "completedAt": "2026-04-10T18:00:44.095Z", - "path": ".trajectories/completed/2026-04/traj_rs2bt3x0fqba.json" - }, - "traj_tjadoebpscps": { - "title": "fix-dm-history-workflow", - "status": "completed", - "startedAt": "2026-04-13T20:02:27.719Z", - "completedAt": "2026-04-13T20:02:35.662Z", - "path": ".trajectories/completed/2026-04/traj_tjadoebpscps.json" - }, - "traj_tv1x9pamkqad": { - "title": "Add GitHub primitive workflow step integration", - "status": "completed", - "startedAt": "2026-04-10T15:34:36.611Z", - "completedAt": "2026-04-10T15:42:17.590Z", - "path": ".trajectories/completed/2026-04/traj_tv1x9pamkqad.json" - }, - "traj_ui5omrgz819d": { - "title": "cloud-run-start-from-workflow", - "status": "completed", - "startedAt": "2026-04-27T20:00:33.269Z", - "completedAt": "2026-04-27T20:08:46.379Z", - "path": ".trajectories/completed/2026-04/traj_ui5omrgz819d.json" - }, - "traj_w0xpsaoxuiyw": { - "title": "Pin TypeScript compiler version and build invocation in selected packages", - "status": "completed", - "startedAt": "2026-04-11T13:35:52.600Z", - "completedAt": "2026-04-11T13:36:48.341Z", - "path": ".trajectories/completed/2026-04/traj_w0xpsaoxuiyw.json" - }, - "traj_0e8i20oitwvz": { - "title": "Final fresh-eyes review Codex GPT-5.5 fix", - "status": "completed", - "startedAt": "2026-05-15T12:46:11.342Z", - "completedAt": "2026-05-15T12:46:11.500Z", - "path": ".trajectories/completed/2026-05/traj_0e8i20oitwvz.json" - }, - "traj_0o6gb2wvk59t": { - "title": "Fresh end-to-end validation for headless readiness", - "status": "completed", - "startedAt": "2026-05-15T10:55:49.188Z", - "completedAt": "2026-05-15T11:11:52.324Z", - "path": ".trajectories/completed/2026-05/traj_0o6gb2wvk59t.json" - }, - "traj_0z98tkaigaxg": { - "title": "ricky-child-update-issue-860-transcript-test-workflow", - "status": "completed", - "startedAt": "2026-05-15T21:06:58.558Z", - "completedAt": "2026-05-15T21:35:56.724Z", - "path": ".trajectories/completed/2026-05/traj_0z98tkaigaxg.json" - }, - "traj_1775914133873_35667beb": { - "title": "fix-sdk-build-resolution-workflow", - "status": "completed", - "startedAt": "2026-04-11T13:28:53.873Z", - "completedAt": "2026-05-08T13:33:48.161Z", - "path": ".trajectories/completed/2026-05/traj_1775914133873_35667beb.json" - }, - "traj_1776073106646_1839be2d": { - "title": "autofix-swarm-Agentworkforce-relay-workflow", - "status": "completed", - "startedAt": "2026-04-13T09:38:26.646Z", - "completedAt": "2026-05-08T13:33:45.944Z", - "path": ".trajectories/completed/2026-05/traj_1776073106646_1839be2d.json" - }, - "traj_1776113772922_bc92f121": { - "title": "autofix-swarm-Agentworkforce-relay-workflow", - "status": "completed", - "startedAt": "2026-04-13T20:56:12.922Z", - "completedAt": "2026-05-08T13:33:43.489Z", - "path": ".trajectories/completed/2026-05/traj_1776113772922_bc92f121.json" - }, - "traj_1778873209642_c70e32ab": { - "title": "ricky-child-update-2-workflow", - "status": "completed", - "startedAt": "2026-05-15T19:26:49.642Z", - "completedAt": "2026-05-15T19:36:18.257Z", - "path": ".trajectories/completed/2026-05/traj_1778873209642_c70e32ab.json" - }, - "traj_1778873211616_6db3b2cd": { - "title": "ricky-child-update-docs-sync-workflow", - "status": "completed", - "startedAt": "2026-05-15T19:26:51.616Z", - "completedAt": "2026-05-15T19:35:07.059Z", - "path": ".trajectories/completed/2026-05/traj_1778873211616_6db3b2cd.json" - }, - "traj_1rrpe2r7fyem": { - "title": "Use streaming PTY input in CLI drive", - "status": "completed", - "startedAt": "2026-05-20T07:20:33.009Z", - "completedAt": "2026-05-20T07:26:17.567Z", - "path": ".trajectories/completed/2026-05/traj_1rrpe2r7fyem.json" - }, - "traj_2gpglosdsq7s": { - "title": "Fix broker session read paths and agent listing errors", - "status": "completed", - "startedAt": "2026-05-19T12:37:18.367Z", - "completedAt": "2026-05-19T12:48:50.116Z", - "path": ".trajectories/completed/2026-05/traj_2gpglosdsq7s.json" - }, - "traj_2tqxnib25omk": { - "title": "Add workflow reliability contract coverage", - "status": "completed", - "startedAt": "2026-05-08T15:27:50.875Z", - "completedAt": "2026-05-08T15:28:02.639Z", - "path": ".trajectories/completed/2026-05/traj_2tqxnib25omk.json" - }, - "traj_2yicjxgajt0a": { - "title": "Review GPT-5.5 hardening", - "status": "completed", - "startedAt": "2026-05-15T10:54:19.300Z", - "completedAt": "2026-05-15T10:54:19.476Z", - "path": ".trajectories/completed/2026-05/traj_2yicjxgajt0a.json" - }, - "traj_34b1u84b19gz": { - "title": "Address PR 827 review feedback", - "status": "completed", - "startedAt": "2026-05-08T18:29:34.717Z", - "completedAt": "2026-05-08T18:33:55.607Z", - "path": ".trajectories/completed/2026-05/traj_34b1u84b19gz.json" - }, - "traj_3gjtcykvybt5": { - "title": "Fix PR CI failures", - "status": "completed", - "startedAt": "2026-05-15T11:24:06.054Z", - "completedAt": "2026-05-15T11:25:49.087Z", - "path": ".trajectories/completed/2026-05/traj_3gjtcykvybt5.json" - }, - "traj_47akjihewlow": { - "title": "Further split broker runtime module for issue 875", - "status": "completed", - "startedAt": "2026-05-19T01:28:35.746Z", - "completedAt": "2026-05-19T01:38:29.105Z", - "path": ".trajectories/completed/2026-05/traj_47akjihewlow.json" - }, - "traj_4chzkm724ufo": { - "title": "Fix headless orchestrator worktree CLI E2E issues", - "status": "completed", - "startedAt": "2026-05-15T11:44:28.338Z", - "completedAt": "2026-05-15T11:51:05.319Z", - "path": ".trajectories/completed/2026-05/traj_4chzkm724ufo.json" - }, - "traj_4t07itef99ug": { - "title": "Implement relay CLI bootstrap commands for proactive runtime M1", - "status": "completed", - "startedAt": "2026-05-11T21:47:37.805Z", - "completedAt": "2026-05-11T21:49:49.859Z", - "path": ".trajectories/completed/2026-05/traj_4t07itef99ug.json" - }, - "traj_4vucir4qvqa2": { - "title": "Harden headless broker readiness semantics", - "status": "completed", - "startedAt": "2026-05-15T09:46:07.617Z", - "completedAt": "2026-05-15T09:59:00.460Z", - "path": ".trajectories/completed/2026-05/traj_4vucir4qvqa2.json" - }, - "traj_5k0jtc1g5l33": { - "title": "Resolve PR 932 conflicts and review comments", - "status": "completed", - "startedAt": "2026-05-22T19:13:09.359Z", - "completedAt": "2026-05-22T19:13:16.971Z", - "path": ".trajectories/completed/2026-05/traj_5k0jtc1g5l33.json" - }, - "traj_5nzj6v56id4z": { - "title": "Fix PR914 review comments", - "status": "completed", - "startedAt": "2026-05-19T13:20:42.407Z", - "completedAt": "2026-05-19T13:26:28.697Z", - "path": ".trajectories/completed/2026-05/traj_5nzj6v56id4z.json" - }, - "traj_5q8i0iz4klpo": { - "title": "ricky-child-update-2-workflow", - "status": "completed", - "startedAt": "2026-05-15T21:07:02.452Z", - "completedAt": "2026-05-15T21:36:03.688Z", - "path": ".trajectories/completed/2026-05/traj_5q8i0iz4klpo.json" - }, - "traj_5qbla7w4kzoi": { - "title": "Fix issue 877", - "status": "completed", - "startedAt": "2026-05-19T03:40:40.798Z", - "completedAt": "2026-05-19T03:54:06.889Z", - "path": ".trajectories/completed/2026-05/traj_5qbla7w4kzoi.json" - }, - "traj_60qc24ufr96g": { - "title": "Expand workflow reliability contract matrix", - "status": "completed", - "startedAt": "2026-05-08T15:40:11.699Z", - "completedAt": "2026-05-08T15:40:22.521Z", - "path": ".trajectories/completed/2026-05/traj_60qc24ufr96g.json" - }, - "traj_6sjeohtm3php": { - "title": "Address broker headless reliability review findings", - "status": "completed", - "startedAt": "2026-05-15T09:30:56.316Z", - "completedAt": "2026-05-15T09:32:47.870Z", - "path": ".trajectories/completed/2026-05/traj_6sjeohtm3php.json" - }, - "traj_6ujzpx82gqs9": { - "title": "ricky-slack-primitive-implementation-workflow-status-r-workflow", - "status": "completed", - "startedAt": "2026-05-08T16:06:54.844Z", - "completedAt": "2026-05-08T16:18:16.119Z", - "path": ".trajectories/completed/2026-05/traj_6ujzpx82gqs9.json" - }, - "traj_78ytpicts778": { - "title": "Address PR 932 result callback review findings", - "status": "completed", - "startedAt": "2026-05-22T15:59:25.187Z", - "completedAt": "2026-05-22T16:05:12.320Z", - "path": ".trajectories/completed/2026-05/traj_78ytpicts778.json" - }, - "traj_7uznwzoxbao6": { - "title": "Fix standalone detached headless startup", - "status": "completed", - "startedAt": "2026-05-15T10:18:46.273Z", - "completedAt": "2026-05-15T10:25:00.598Z", - "path": ".trajectories/completed/2026-05/traj_7uznwzoxbao6.json" - }, - "traj_7zu7et53ph3l": { - "title": "Harden Codex GPT-5.5 local CLI compatibility", - "status": "completed", - "startedAt": "2026-05-15T10:35:25.212Z", - "completedAt": "2026-05-15T10:40:53.355Z", - "path": ".trajectories/completed/2026-05/traj_7zu7et53ph3l.json" - }, - "traj_81kobstnzzwk": { - "title": "Orchestrate team review cycle for #892 #893 #894 #895", - "status": "completed", - "startedAt": "2026-05-19T08:16:32.762Z", - "completedAt": "2026-05-19T08:37:32.966Z", - "path": ".trajectories/completed/2026-05/traj_81kobstnzzwk.json" - }, - "traj_8ljgydz61do5": { - "title": "ricky-child-update-messaging-2-workflow", - "status": "completed", - "startedAt": "2026-05-15T21:06:54.217Z", - "completedAt": "2026-05-15T21:41:56.478Z", - "path": ".trajectories/completed/2026-05/traj_8ljgydz61do5.json" - }, - "traj_90jmd9z27oap": { - "title": "Resolve PR 948 merge conflicts", - "status": "completed", - "startedAt": "2026-05-22T19:49:08.797Z", - "completedAt": "2026-05-22T20:45:01.262Z", - "path": ".trajectories/completed/2026-05/traj_90jmd9z27oap.json" - }, - "traj_947wzpddsg9j": { - "title": "Implement relay CLI bootstrap commands for proactive runtime M1", - "status": "completed", - "startedAt": "2026-05-11T23:11:57.326Z", - "completedAt": "2026-05-11T23:14:23.136Z", - "path": ".trajectories/completed/2026-05/traj_947wzpddsg9j.json" - }, - "traj_9fdv7hxm0b60": { - "title": "Strict standalone smoke follow-up", - "status": "completed", - "startedAt": "2026-05-15T10:37:17.693Z", - "completedAt": "2026-05-15T10:43:11.587Z", - "path": ".trajectories/completed/2026-05/traj_9fdv7hxm0b60.json" - }, - "traj_9gq96irkj00s": { - "title": "Update relay to use published relaycast Rust reclaim fix", - "status": "completed", - "startedAt": "2026-05-10T18:45:02.118Z", - "completedAt": "2026-05-10T18:48:11.532Z", - "path": ".trajectories/completed/2026-05/traj_9gq96irkj00s.json" - }, - "traj_aw7stgf4qau0": { - "title": "Fix publish smoke cloud tarball dependency", - "status": "completed", - "startedAt": "2026-05-11T07:49:42.778Z", - "completedAt": "2026-05-11T07:50:37.848Z", - "path": ".trajectories/completed/2026-05/traj_aw7stgf4qau0.json" - }, - "traj_bdrlknyl8twj": { - "title": "Add workflow reliability defaults and E2E matrix", - "status": "completed", - "startedAt": "2026-05-08T17:54:45.069Z", - "completedAt": "2026-05-08T18:05:37.305Z", - "path": ".trajectories/completed/2026-05/traj_bdrlknyl8twj.json" - }, - "traj_bz1a1o15p7px": { - "title": "Fix PR 949 CI failure", - "status": "completed", - "startedAt": "2026-05-22T16:56:55.021Z", - "completedAt": "2026-05-22T16:57:55.372Z", - "path": ".trajectories/completed/2026-05/traj_bz1a1o15p7px.json" - }, - "traj_cbmwd07phhm2": { - "title": "Implement #869 snapshot module + dump-pty command", - "status": "completed", - "startedAt": "2026-05-17T14:19:10.603Z", - "completedAt": "2026-05-17T14:33:32.293Z", - "path": ".trajectories/completed/2026-05/traj_cbmwd07phhm2.json" - }, - "traj_ceo5q9bh2od3": { - "title": "Add structured spawned-agent results", - "status": "completed", - "startedAt": "2026-05-20T21:24:17.929Z", - "completedAt": "2026-05-20T21:43:51.936Z", - "path": ".trajectories/completed/2026-05/traj_ceo5q9bh2od3.json" - }, - "traj_d89s38ddu7cj": { - "title": "Review Codex GPT-5.5 spawn fix", - "status": "completed", - "startedAt": "2026-05-15T12:25:39.946Z", - "completedAt": "2026-05-15T12:25:40.708Z", - "path": ".trajectories/completed/2026-05/traj_d89s38ddu7cj.json" - }, - "traj_dbsnr453nxjw": { - "title": "Confirm and remove unused package dependencies", - "status": "completed", - "startedAt": "2026-05-22T16:01:11.967Z", - "completedAt": "2026-05-22T16:12:01.466Z", - "path": ".trajectories/completed/2026-05/traj_dbsnr453nxjw.json" - }, - "traj_dcl9hgoiuac5": { - "title": "Verify --broker-name override for agent-relay up", - "status": "completed", - "startedAt": "2026-05-21T18:56:55.532Z", - "completedAt": "2026-05-21T19:00:06.831Z", - "path": ".trajectories/completed/2026-05/traj_dcl9hgoiuac5.json" - }, - "traj_dpgn0am1jq1c": { - "title": "Implement M1 relay CLI bootstrap commands", - "status": "completed", - "startedAt": "2026-05-11T18:43:20.429Z", - "completedAt": "2026-05-11T18:43:20.733Z", - "path": ".trajectories/completed/2026-05/traj_dpgn0am1jq1c.json" - }, - "traj_e1b7ww3un1u3": { - "title": "Harden agents logs raw and follow output", - "status": "completed", - "startedAt": "2026-05-19T10:59:00.118Z", - "completedAt": "2026-05-19T11:04:44.466Z", - "path": ".trajectories/completed/2026-05/traj_e1b7ww3un1u3.json" - }, - "traj_elx0fcwgs37x": { - "title": "ricky-child-update-messaging-workflow", - "status": "completed", - "startedAt": "2026-05-15T21:06:50.250Z", - "completedAt": "2026-05-15T21:46:46.167Z", - "path": ".trajectories/completed/2026-05/traj_elx0fcwgs37x.json" - }, - "traj_erzd7j9nto9r": { - "title": "Strict review and PR prep for headless broker readiness", - "status": "completed", - "startedAt": "2026-05-15T10:02:10.164Z", - "completedAt": "2026-05-15T10:06:38.127Z", - "path": ".trajectories/completed/2026-05/traj_erzd7j9nto9r.json" - }, - "traj_f1iac9ngymlj": { - "title": "Fix reliability review findings 892-895", - "status": "completed", - "startedAt": "2026-05-19T09:52:54.932Z", - "completedAt": "2026-05-19T10:01:19.068Z", - "path": ".trajectories/completed/2026-05/traj_f1iac9ngymlj.json" - }, - "traj_f3arvbmmlomn": { - "title": "Address PR feedback for headless broker reliability", - "status": "completed", - "startedAt": "2026-05-15T12:09:02.122Z", - "completedAt": "2026-05-15T12:15:11.435Z", - "path": ".trajectories/completed/2026-05/traj_f3arvbmmlomn.json" - }, - "traj_f9wxa8ujeg78": { - "title": "Refactor broker main for issue 875", - "status": "completed", - "startedAt": "2026-05-19T00:54:40.328Z", - "completedAt": "2026-05-19T00:55:57.506Z", - "path": ".trajectories/completed/2026-05/traj_f9wxa8ujeg78.json" - }, - "traj_fh8oosbijpwc": { - "title": "Track A: relaycast subscribe + @self DM routing", - "status": "completed", - "startedAt": "2026-05-12T06:28:56.427Z", - "completedAt": "2026-05-12T11:21:33.352Z", - "path": ".trajectories/completed/2026-05/traj_fh8oosbijpwc.json" - }, - "traj_gh05rj5gwsap": { - "title": "Bump relaycast Rust SDK in relay", - "status": "completed", - "startedAt": "2026-05-14T16:41:17.430Z", - "completedAt": "2026-05-14T16:42:32.485Z", - "path": ".trajectories/completed/2026-05/traj_gh05rj5gwsap.json" - }, - "traj_gnqvtoxtc8dy": { - "title": "Fix broker half-start recovery", - "status": "completed", - "startedAt": "2026-05-19T12:34:36.057Z", - "completedAt": "2026-05-19T12:47:18.115Z", - "path": ".trajectories/completed/2026-05/traj_gnqvtoxtc8dy.json" - }, - "traj_hfkww5z7trxn": { - "title": "Fresh comprehensive review of PR 856", - "status": "completed", - "startedAt": "2026-05-15T12:56:14.439Z", - "completedAt": "2026-05-15T13:00:15.366Z", - "path": ".trajectories/completed/2026-05/traj_hfkww5z7trxn.json" - }, - "traj_hrsndfzk0qay": { - "title": "Tighten Codex 5.5 fallback coverage", - "status": "completed", - "startedAt": "2026-05-15T10:57:41.681Z", - "completedAt": "2026-05-15T10:57:41.827Z", - "path": ".trajectories/completed/2026-05/traj_hrsndfzk0qay.json" - }, - "traj_hysw5o7idqas": { - "title": "Fix issue 924", - "status": "completed", - "startedAt": "2026-05-20T05:35:07.262Z", - "completedAt": "2026-05-20T05:47:54.189Z", - "path": ".trajectories/completed/2026-05/traj_hysw5o7idqas.json" - }, - "traj_ij5b3kcatvwn": { - "title": "ricky-reading-worker-dm-replies-design-spec-status-draft-date-2026-05-15-issue-860-hea-workflow", - "status": "completed", - "startedAt": "2026-05-15T21:06:45.545Z", - "completedAt": "2026-05-15T21:50:07.842Z", - "path": ".trajectories/completed/2026-05/traj_ij5b3kcatvwn.json" - }, - "traj_iole5zdt9orr": { - "title": "Fix PR 831 CI conflicts", - "status": "completed", - "startedAt": "2026-05-10T15:18:12.326Z", - "completedAt": "2026-05-10T15:29:41.840Z", - "path": ".trajectories/completed/2026-05/traj_iole5zdt9orr.json" - }, - "traj_irafiyk6wpw0": { - "title": "Fix agents:logs near-unparseable TTY redraw garbage (codex implement, claude review)", - "status": "completed", - "startedAt": "2026-05-19T10:30:38.222Z", - "completedAt": "2026-05-19T10:44:24.757Z", - "path": ".trajectories/completed/2026-05/traj_irafiyk6wpw0.json" - }, - "traj_itgr2w8qs3xn": { - "title": "Make workflow deterministic failures repairable by agents", - "status": "completed", - "startedAt": "2026-05-08T14:44:45.732Z", - "completedAt": "2026-05-08T14:44:45.984Z", - "path": ".trajectories/completed/2026-05/traj_itgr2w8qs3xn.json" - }, - "traj_j9k10fez3e81": { - "title": "review-loop-mpb2bvnf-1-workflow", - "status": "completed", - "startedAt": "2026-05-18T10:30:09.927Z", - "completedAt": "2026-05-18T14:53:04.092Z", - "path": ".trajectories/completed/2026-05/traj_j9k10fez3e81.json" - }, - "traj_jbo2x14y7ovt": { - "title": "Fix issue 876", - "status": "completed", - "startedAt": "2026-05-19T02:48:10.768Z", - "completedAt": "2026-05-19T02:56:24.584Z", - "path": ".trajectories/completed/2026-05/traj_jbo2x14y7ovt.json" - }, - "traj_jmf9pyt3zikn": { - "title": "Fix issue 874", - "status": "completed", - "startedAt": "2026-05-19T00:07:13.993Z", - "completedAt": "2026-05-19T00:17:27.680Z", - "path": ".trajectories/completed/2026-05/traj_jmf9pyt3zikn.json" - }, - "traj_k7njijv51iq4": { - "title": "ricky-slack-primitive-implementation-workflow-status-r-workflow", - "status": "completed", - "startedAt": "2026-05-08T16:18:55.300Z", - "completedAt": "2026-05-08T16:26:03.266Z", - "path": ".trajectories/completed/2026-05/traj_k7njijv51iq4.json" - }, - "traj_lhyrcib40kao": { - "title": "Address PR #914 CodeRabbit reliability review findings", - "status": "completed", - "startedAt": "2026-05-19T11:52:46.110Z", - "completedAt": "2026-05-19T12:07:22.401Z", - "path": ".trajectories/completed/2026-05/traj_lhyrcib40kao.json" - }, - "traj_lieyyspidhfj": { - "title": "Fix PR 823 conflicts checks and comments", - "status": "completed", - "startedAt": "2026-05-09T08:37:17.563Z", - "completedAt": "2026-05-09T08:47:54.686Z", - "path": ".trajectories/completed/2026-05/traj_lieyyspidhfj.json" - }, - "traj_m7mpv7j8n78h": { - "title": "Address Relay PR 826 review feedback", - "status": "completed", - "startedAt": "2026-05-08T15:17:53.113Z", - "completedAt": "2026-05-08T15:24:32.409Z", - "path": ".trajectories/completed/2026-05/traj_m7mpv7j8n78h.json" - }, - "traj_mi9eqd4rjfea": { - "title": "Address stdio fresh review findings", - "status": "abandoned", - "startedAt": "2026-05-11T18:25:24.626Z", - "completedAt": "2026-05-11T18:37:05.318Z", - "path": ".trajectories/completed/2026-05/traj_mi9eqd4rjfea.json" - }, - "traj_mytnzgfayj3d": { - "title": "Fix PR 948 telemetry package validation failure", - "status": "completed", - "startedAt": "2026-05-22T23:34:27.422Z", - "completedAt": "2026-05-22T23:36:15.152Z", - "path": ".trajectories/completed/2026-05/traj_mytnzgfayj3d.json" - }, - "traj_mz5m5ysjj31e": { - "title": "Fix Relay SDK broker stdout drain", - "status": "completed", - "startedAt": "2026-05-10T20:24:43.831Z", - "completedAt": "2026-05-10T20:35:47.359Z", - "path": ".trajectories/completed/2026-05/traj_mz5m5ysjj31e.json" - }, - "traj_n8duofq5vq1a": { - "title": "Update Codex registry for GPT-5.5", - "status": "completed", - "startedAt": "2026-05-15T10:27:57.532Z", - "completedAt": "2026-05-15T10:33:19.705Z", - "path": ".trajectories/completed/2026-05/traj_n8duofq5vq1a.json" - }, - "traj_o251whkvy9rl": { - "title": "Fix Codex GPT-5.5 E2E rough edges", - "status": "completed", - "startedAt": "2026-05-15T11:59:26.764Z", - "completedAt": "2026-05-15T12:12:25.515Z", - "path": ".trajectories/completed/2026-05/traj_o251whkvy9rl.json" - }, - "traj_o9cx33xn5u39": { - "title": "add-mcp-args-register-flag-workflow", - "status": "completed", - "startedAt": "2026-04-20T15:06:23.387Z", - "completedAt": "2026-05-08T13:33:35.341Z", - "path": ".trajectories/completed/2026-05/traj_o9cx33xn5u39.json" - }, - "traj_ootb5rt3tozd": { - "title": "ricky-child-update-docs-sync-workflow", - "status": "completed", - "startedAt": "2026-05-15T21:07:04.494Z", - "completedAt": "2026-05-15T21:45:20.368Z", - "path": ".trajectories/completed/2026-05/traj_ootb5rt3tozd.json" - }, - "traj_oyc528j7suvo": { - "title": "Expose cloud workflow scheduling through Relay SDK", - "status": "completed", - "startedAt": "2026-05-09T19:43:34.805Z", - "completedAt": "2026-05-09T19:44:00.107Z", - "path": ".trajectories/completed/2026-05/traj_oyc528j7suvo.json" - }, - "traj_piik8r6zu3i7": { - "title": "Issue 867: RelayEventListener", - "status": "completed", - "startedAt": "2026-05-18T01:56:18.236Z", - "completedAt": "2026-05-18T02:01:49.991Z", - "path": ".trajectories/completed/2026-05/traj_piik8r6zu3i7.json" - }, - "traj_pmrcfj6or3pz": { - "title": "Address runtime split review comments", - "status": "completed", - "startedAt": "2026-05-19T02:03:43.962Z", - "completedAt": "2026-05-19T02:09:31.002Z", - "path": ".trajectories/completed/2026-05/traj_pmrcfj6or3pz.json" - }, - "traj_qtmid2nzz0kz": { - "title": "Address PR 929 review comments", - "status": "completed", - "startedAt": "2026-05-20T06:21:54.721Z", - "completedAt": "2026-05-20T06:26:56.700Z", - "path": ".trajectories/completed/2026-05/traj_qtmid2nzz0kz.json" - }, - "traj_ryf5sstno6p3": { - "title": "Telemetry key from env (P0.5 of #881)", - "status": "completed", - "startedAt": "2026-05-18T02:56:55.314Z", - "completedAt": "2026-05-18T03:02:35.202Z", - "path": ".trajectories/completed/2026-05/traj_ryf5sstno6p3.json" - }, - "traj_s5ojo1f4srz4": { - "title": "Remove unused user-directory package", - "status": "completed", - "startedAt": "2026-05-22T16:27:44.927Z", - "completedAt": "2026-05-22T16:36:20.545Z", - "path": ".trajectories/completed/2026-05/traj_s5ojo1f4srz4.json" - }, - "traj_sh2ahp9z2xg6": { - "title": "Fix uuid install deprecation warning", - "status": "completed", - "startedAt": "2026-05-19T17:21:40.756Z", - "completedAt": "2026-05-19T17:21:49.702Z", - "path": ".trajectories/completed/2026-05/traj_sh2ahp9z2xg6.json" - }, - "traj_sqerp89tc436": { - "title": "Remove legacy root bin fallback", - "status": "completed", - "startedAt": "2026-05-19T00:45:33.159Z", - "completedAt": "2026-05-19T00:50:03.857Z", - "path": ".trajectories/completed/2026-05/traj_sqerp89tc436.json" - }, - "traj_t5uknesn2fcw": { - "title": "ricky-child-update-skill-workflow", - "status": "completed", - "startedAt": "2026-05-15T21:06:52.453Z", - "completedAt": "2026-05-15T21:40:04.209Z", - "path": ".trajectories/completed/2026-05/traj_t5uknesn2fcw.json" - }, - "traj_tavtex0db4b0": { - "title": "Make workflow failures repairable by agents", - "status": "completed", - "startedAt": "2026-05-08T14:34:19.969Z", - "completedAt": "2026-05-08T14:44:45.719Z", - "path": ".trajectories/completed/2026-05/traj_tavtex0db4b0.json" - }, - "traj_tgism98me5na": { - "title": "Implement relay CLI proactive runtime bootstrap commands", - "status": "completed", - "startedAt": "2026-05-11T20:04:48.053Z", - "completedAt": "2026-05-11T20:05:54.956Z", - "path": ".trajectories/completed/2026-05/traj_tgism98me5na.json" - }, - "traj_u33qn99ijbh4": { - "title": "ricky-child-update-workflow", - "status": "completed", - "startedAt": "2026-05-15T21:07:00.444Z", - "completedAt": "2026-05-15T21:30:50.445Z", - "path": ".trajectories/completed/2026-05/traj_u33qn99ijbh4.json" - }, - "traj_u3loicehnwb4": { - "title": "Gate broker diagnostic logs behind env flag", - "status": "completed", - "startedAt": "2026-05-21T04:14:44.815Z", - "completedAt": "2026-05-21T04:14:45.063Z", - "path": ".trajectories/completed/2026-05/traj_u3loicehnwb4.json" - }, - "traj_u4ixmbqqm2y1": { - "title": "Add cloud workflow schedule CLI", - "status": "completed", - "startedAt": "2026-05-09T19:26:42.106Z", - "completedAt": "2026-05-09T19:29:18.024Z", - "path": ".trajectories/completed/2026-05/traj_u4ixmbqqm2y1.json" - }, - "traj_uf8y40ewrfh0": { - "title": "Address PR 831 review feedback and conflicts", - "status": "completed", - "startedAt": "2026-05-09T19:59:24.197Z", - "completedAt": "2026-05-09T19:59:24.403Z", - "path": ".trajectories/completed/2026-05/traj_uf8y40ewrfh0.json" - }, - "traj_v1wexlfur5zr": { - "title": "Fix broker headless reliability doc", - "status": "completed", - "startedAt": "2026-05-15T09:04:51.316Z", - "completedAt": "2026-05-15T09:13:50.970Z", - "path": ".trajectories/completed/2026-05/traj_v1wexlfur5zr.json" - }, - "traj_v87cyrs8dke9": { - "title": "Refactor runDriveSession below complexity 15 (#897)", - "status": "completed", - "startedAt": "2026-05-14T14:28:34.155Z", - "completedAt": "2026-05-18T18:06:04.950Z", - "path": ".trajectories/completed/2026-05/traj_v87cyrs8dke9.json" - }, - "traj_v9x3o92ag682": { - "title": "ricky-child-update-messaging-test-workflow", - "status": "completed", - "startedAt": "2026-05-15T21:06:56.418Z", - "completedAt": "2026-05-15T21:34:35.623Z", - "path": ".trajectories/completed/2026-05/traj_v9x3o92ag682.json" - }, - "traj_vfa1jr6otnjn": { - "title": "Refresh PR 948 after main advanced", - "status": "completed", - "startedAt": "2026-05-22T23:23:16.807Z", - "completedAt": "2026-05-22T23:23:26.380Z", - "path": ".trajectories/completed/2026-05/traj_vfa1jr6otnjn.json" - }, - "traj_vkozdglobkyg": { - "title": "Address Relay PR 826 review comments", - "status": "completed", - "startedAt": "2026-05-08T15:50:35.978Z", - "completedAt": "2026-05-08T15:51:38.854Z", - "path": ".trajectories/completed/2026-05/traj_vkozdglobkyg.json" - }, - "traj_wbn62q4cq16h": { - "title": "Update generated workflow to Codex agents only", - "status": "completed", - "startedAt": "2026-05-15T21:03:02.671Z", - "completedAt": "2026-05-15T21:06:00.384Z", - "path": ".trajectories/completed/2026-05/traj_wbn62q4cq16h.json" - }, - "traj_whd40oxptlhn": { - "title": "Review spawn persistence fix and open PR", - "status": "completed", - "startedAt": "2026-05-13T10:57:02.796Z", - "completedAt": "2026-05-13T11:00:43.100Z", - "path": ".trajectories/completed/2026-05/traj_whd40oxptlhn.json" - }, - "traj_wx00tjvpptvg": { - "title": "Investigate agent-relay spawn persistence", - "status": "completed", - "startedAt": "2026-05-13T10:49:12.464Z", - "completedAt": "2026-05-13T10:53:03.748Z", - "path": ".trajectories/completed/2026-05/traj_wx00tjvpptvg.json" - }, - "traj_wzzboitm85ee": { - "title": "Resolve PR conflicts around platform tradeoff copy", - "status": "completed", - "startedAt": "2026-05-15T12:47:36.508Z", - "completedAt": "2026-05-15T12:50:14.358Z", - "path": ".trajectories/completed/2026-05/traj_wzzboitm85ee.json" - }, - "traj_x37bhga2j5ph": { - "title": "Deepen broker runtime refactor for PR 906", - "status": "completed", - "startedAt": "2026-05-19T01:42:10.602Z", - "completedAt": "2026-05-19T01:50:40.359Z", - "path": ".trajectories/completed/2026-05/traj_x37bhga2j5ph.json" - }, - "traj_ybcrij9wg8m1": { - "title": "Implement agent-relay view read-only stream client (#864 sub-1)", - "status": "completed", - "startedAt": "2026-05-18T02:02:07.524Z", - "completedAt": "2026-05-18T02:05:41.120Z", - "path": ".trajectories/completed/2026-05/traj_ybcrij9wg8m1.json" - }, - "traj_z171lng2fbbi": { - "title": "Address PR 840 review feedback", - "status": "completed", - "startedAt": "2026-05-11T08:06:37.977Z", - "completedAt": "2026-05-11T08:07:48.097Z", - "path": ".trajectories/completed/2026-05/traj_z171lng2fbbi.json" - }, - "traj_zfa6skfr32vy": { - "title": "Implement relay CLI M1 bootstrap commands", - "status": "completed", - "startedAt": "2026-05-11T19:31:44.734Z", - "completedAt": "2026-05-11T19:34:54.971Z", - "path": ".trajectories/completed/2026-05/traj_zfa6skfr32vy.json" - }, - "traj_zqwco4gl76g3": { - "title": "Fix issue 878", - "status": "completed", - "startedAt": "2026-05-19T04:18:25.024Z", - "completedAt": "2026-05-19T04:27:18.903Z", - "path": ".trajectories/completed/2026-05/traj_zqwco4gl76g3.json" - }, - "traj_zu3252hxzoqh": { - "title": "Open PR for reading worker DM replies", - "status": "completed", - "startedAt": "2026-05-16T06:08:22.396Z", - "completedAt": "2026-05-16T06:09:24.599Z", - "path": ".trajectories/completed/2026-05/traj_zu3252hxzoqh.json" - }, - "traj_1775914296101_a4397efe": { - "title": "fix-sdk-build-resolution-workflow", - "status": "completed", - "startedAt": "2026-04-11T13:31:36.101Z", - "completedAt": "2026-04-11T13:39:53.105Z", - "path": ".trajectories/completed/traj_1775914296101_a4397efe.json" - }, - "traj_1776024661304_cfc829b9": { - "title": "fix-workflow-resume-elegant-workflow", - "status": "abandoned", - "startedAt": "2026-04-12T20:11:01.304Z", - "completedAt": "2026-04-12T20:11:16.381Z", - "path": ".trajectories/completed/traj_1776024661304_cfc829b9.json" - }, - "traj_1778873052429_03a4dacb": { - "title": "ricky-reading-worker-dm-replies-design-spec-status-draft-date-2026-05-15-issue-860-hea-workflow", - "status": "abandoned", - "startedAt": "2026-05-15T19:24:12.429Z", - "completedAt": "2026-05-15T20:01:57.036Z", - "path": ".trajectories/completed/traj_1778873052429_03a4dacb.json" - }, - "traj_1778873197540_01102ade": { - "title": "ricky-child-update-messaging-workflow", - "status": "abandoned", - "startedAt": "2026-05-15T19:26:37.540Z", - "completedAt": "2026-05-15T19:43:47.629Z", - "path": ".trajectories/completed/traj_1778873197540_01102ade.json" - }, - "traj_1778873199489_f2ce4060": { - "title": "ricky-child-update-skill-workflow", - "status": "abandoned", - "startedAt": "2026-05-15T19:26:39.489Z", - "completedAt": "2026-05-15T19:43:43.149Z", - "path": ".trajectories/completed/traj_1778873199489_f2ce4060.json" - }, - "traj_1778873201502_0dacf7c5": { - "title": "ricky-child-update-messaging-2-workflow", - "status": "abandoned", - "startedAt": "2026-05-15T19:26:41.502Z", - "completedAt": "2026-05-15T19:43:35.011Z", - "path": ".trajectories/completed/traj_1778873201502_0dacf7c5.json" - }, - "traj_1778873203502_4c225b7e": { - "title": "ricky-child-update-messaging-test-workflow", - "status": "abandoned", - "startedAt": "2026-05-15T19:26:43.502Z", - "completedAt": "2026-05-15T19:44:33.074Z", - "path": ".trajectories/completed/traj_1778873203502_4c225b7e.json" - }, - "traj_1778873205470_a4e5f0cb": { - "title": "ricky-child-update-issue-860-transcript-test-workflow", - "status": "abandoned", - "startedAt": "2026-05-15T19:26:45.470Z", - "completedAt": "2026-05-15T19:43:37.134Z", - "path": ".trajectories/completed/traj_1778873205470_a4e5f0cb.json" - }, - "traj_1778873207471_b7def991": { - "title": "ricky-child-update-workflow", - "status": "abandoned", - "startedAt": "2026-05-15T19:26:47.471Z", - "completedAt": "2026-05-15T19:43:24.329Z", - "path": ".trajectories/completed/traj_1778873207471_b7def991.json" - }, - "traj_1778874205797_81e92307": { - "title": "ricky-child-update-workflow", - "status": "abandoned", - "startedAt": "2026-05-15T19:43:25.797Z", - "completedAt": "2026-05-15T19:43:43.995Z", - "path": ".trajectories/completed/traj_1778874205797_81e92307.json" - }, - "traj_1778874216773_c6b12ab2": { - "title": "ricky-child-update-messaging-2-workflow", - "status": "abandoned", - "startedAt": "2026-05-15T19:43:36.773Z", - "completedAt": "2026-05-15T19:44:08.270Z", - "path": ".trajectories/completed/traj_1778874216773_c6b12ab2.json" - }, - "traj_1778874218579_a0225559": { - "title": "ricky-child-update-issue-860-transcript-test-workflow", - "status": "abandoned", - "startedAt": "2026-05-15T19:43:38.579Z", - "completedAt": "2026-05-15T19:43:58.721Z", - "path": ".trajectories/completed/traj_1778874218579_a0225559.json" - }, - "traj_1778874224855_9c722c4b": { - "title": "ricky-child-update-skill-workflow", - "status": "abandoned", - "startedAt": "2026-05-15T19:43:44.855Z", - "completedAt": "2026-05-15T19:44:16.528Z", - "path": ".trajectories/completed/traj_1778874224855_9c722c4b.json" - }, - "traj_1778874226983_3367d527": { - "title": "ricky-child-update-workflow", - "status": "abandoned", - "startedAt": "2026-05-15T19:43:46.983Z", - "completedAt": "2026-05-15T19:44:05.612Z", - "path": ".trajectories/completed/traj_1778874226983_3367d527.json" - }, - "traj_1778874229373_9cce9465": { - "title": "ricky-child-update-messaging-workflow", - "status": "abandoned", - "startedAt": "2026-05-15T19:43:49.374Z", - "completedAt": "2026-05-15T19:44:20.096Z", - "path": ".trajectories/completed/traj_1778874229373_9cce9465.json" - }, - "traj_1778874240339_51b823cd": { - "title": "ricky-child-update-issue-860-transcript-test-workflow", - "status": "abandoned", - "startedAt": "2026-05-15T19:44:00.339Z", - "completedAt": "2026-05-15T19:44:18.916Z", - "path": ".trajectories/completed/traj_1778874240339_51b823cd.json" - }, - "traj_1778874241076_caa675a9": { - "title": "ricky-child-update-2-workflow", - "status": "abandoned", - "startedAt": "2026-05-15T19:44:01.076Z", - "completedAt": "2026-05-15T19:44:32.521Z", - "path": ".trajectories/completed/traj_1778874241076_caa675a9.json" - }, - "traj_1778874248966_e29c4c54": { - "title": "ricky-child-update-workflow", - "status": "abandoned", - "startedAt": "2026-05-15T19:44:08.966Z", - "completedAt": "2026-05-15T19:44:27.330Z", - "path": ".trajectories/completed/traj_1778874248966_e29c4c54.json" - }, - "traj_1778874249983_12a98df3": { - "title": "ricky-child-update-messaging-2-workflow", - "status": "abandoned", - "startedAt": "2026-05-15T19:44:09.983Z", - "completedAt": "2026-05-15T19:44:41.100Z", - "path": ".trajectories/completed/traj_1778874249983_12a98df3.json" - }, - "traj_1778874258229_0bdc53d8": { - "title": "ricky-child-update-skill-workflow", - "status": "abandoned", - "startedAt": "2026-05-15T19:44:18.229Z", - "completedAt": "2026-05-15T19:44:49.274Z", - "path": ".trajectories/completed/traj_1778874258229_0bdc53d8.json" - }, - "traj_1778874261453_55f49624": { - "title": "ricky-child-update-messaging-workflow", - "status": "abandoned", - "startedAt": "2026-05-15T19:44:21.453Z", - "completedAt": "2026-05-15T19:44:53.643Z", - "path": ".trajectories/completed/traj_1778874261453_55f49624.json" - }, - "traj_1778874261608_48fb9bf5": { - "title": "ricky-child-update-issue-860-transcript-test-workflow", - "status": "abandoned", - "startedAt": "2026-05-15T19:44:21.608Z", - "completedAt": "2026-05-15T19:44:40.761Z", - "path": ".trajectories/completed/traj_1778874261608_48fb9bf5.json" - }, - "traj_1778874269139_d7d7485a": { - "title": "ricky-child-update-workflow", - "status": "abandoned", - "startedAt": "2026-05-15T19:44:29.139Z", - "completedAt": "2026-05-15T19:44:48.083Z", - "path": ".trajectories/completed/traj_1778874269139_d7d7485a.json" - }, - "traj_1778874274412_70843e0e": { - "title": "ricky-child-update-2-workflow", - "status": "abandoned", - "startedAt": "2026-05-15T19:44:34.412Z", - "completedAt": "2026-05-15T19:45:06.798Z", - "path": ".trajectories/completed/traj_1778874274412_70843e0e.json" - }, - "traj_1778874274581_71efa470": { - "title": "ricky-child-update-messaging-test-workflow", - "status": "abandoned", - "startedAt": "2026-05-15T19:44:34.581Z", - "completedAt": "2026-05-15T19:44:54.182Z", - "path": ".trajectories/completed/traj_1778874274581_71efa470.json" - }, - "traj_1778874282200_39ad11db": { - "title": "ricky-child-update-issue-860-transcript-test-workflow", - "status": "abandoned", - "startedAt": "2026-05-15T19:44:42.200Z", - "completedAt": "2026-05-15T19:45:02.477Z", - "path": ".trajectories/completed/traj_1778874282200_39ad11db.json" - }, - "traj_1778874283570_ce3585b8": { - "title": "ricky-child-update-messaging-2-workflow", - "status": "abandoned", - "startedAt": "2026-05-15T19:44:43.570Z", - "completedAt": "2026-05-15T19:45:14.888Z", - "path": ".trajectories/completed/traj_1778874283570_ce3585b8.json" - }, - "traj_1778874289674_e3f868c8": { - "title": "ricky-child-update-workflow", - "status": "abandoned", - "startedAt": "2026-05-15T19:44:49.674Z", - "completedAt": "2026-05-15T19:45:08.337Z", - "path": ".trajectories/completed/traj_1778874289674_e3f868c8.json" - }, - "traj_1778874291950_0b1b5c1f": { - "title": "ricky-child-update-skill-workflow", - "status": "abandoned", - "startedAt": "2026-05-15T19:44:51.950Z", - "completedAt": "2026-05-15T19:45:23.421Z", - "path": ".trajectories/completed/traj_1778874291950_0b1b5c1f.json" - }, - "traj_1778874295927_4083d181": { - "title": "ricky-child-update-messaging-test-workflow", - "status": "abandoned", - "startedAt": "2026-05-15T19:44:55.927Z", - "completedAt": "2026-05-15T19:45:15.333Z", - "path": ".trajectories/completed/traj_1778874295927_4083d181.json" - }, - "traj_1778874296362_bdf727ff": { - "title": "ricky-child-update-messaging-workflow", - "status": "abandoned", - "startedAt": "2026-05-15T19:44:56.362Z", - "completedAt": "2026-05-15T19:45:27.624Z", - "path": ".trajectories/completed/traj_1778874296362_bdf727ff.json" - }, - "traj_l1349adi1g0o": { - "title": "Fix agent relay MCP PR CI failures", - "status": "completed", - "startedAt": "2026-05-25T21:42:41.236Z", - "completedAt": "2026-05-25T21:42:57.292Z", - "path": ".trajectories/completed/2026-05/traj_l1349adi1g0o.json" - }, - "traj_8nhd9lljhbsw": { - "title": "Switch owned MCP tool names to underscores", - "status": "completed", - "startedAt": "2026-05-25T22:05:23.828Z", - "completedAt": "2026-05-25T22:14:25.886Z", - "path": ".trajectories/completed/2026-05/traj_8nhd9lljhbsw.json" - }, - "traj_gkxajksmwoea": { - "title": "Document owned MCP tool table", - "status": "completed", - "startedAt": "2026-05-25T22:17:18.278Z", - "completedAt": "2026-05-25T22:19:29.639Z", - "path": ".trajectories/completed/2026-05/traj_gkxajksmwoea.json" - }, - "traj_t6h534vn0bpg": { - "title": "Resolve PR merge conflicts", - "status": "completed", - "startedAt": "2026-05-26T10:11:15.356Z", - "completedAt": "2026-05-26T10:21:56.502Z", - "path": ".trajectories/completed/2026-05/traj_t6h534vn0bpg.json" - }, - "traj_cszfl2icaj2t": { - "title": "Add Prettier auto-format workflow", - "status": "completed", - "startedAt": "2026-05-26T11:04:15.563Z", - "completedAt": "2026-05-26T11:05:23.716Z", - "path": ".trajectories/completed/2026-05/traj_cszfl2icaj2t.json" - }, - "traj_17t39ue8exte": { - "title": "Add GitHub traffic to PostHog sync", - "status": "completed", - "startedAt": "2026-05-26T13:16:29.926Z", - "completedAt": "2026-05-26T13:17:08.417Z", - "path": ".trajectories/completed/2026-05/traj_17t39ue8exte/trajectory.json" - }, - "traj_b3g40827t5zh": { - "title": "Address GitHub traffic PostHog PR review comments", - "status": "completed", - "startedAt": "2026-05-26T13:42:50.509Z", - "completedAt": "2026-05-26T13:44:38.186Z", - "path": ".trajectories/completed/2026-05/traj_b3g40827t5zh/trajectory.json" - }, - "traj_i2pjnx3dll5b": { - "title": "Fresh harness runtime plan and implementation", - "status": "completed", - "startedAt": "2026-05-25T15:49:27.102Z", - "completedAt": "2026-05-25T16:22:35.339Z", - "path": ".trajectories/completed/2026-05/traj_i2pjnx3dll5b.json" - }, - "traj_7i9tigaejfje": { - "title": "Clarify headless app-server harness terminology", - "status": "completed", - "startedAt": "2026-05-25T16:34:21.397Z", - "completedAt": "2026-05-25T16:34:33.412Z", - "path": ".trajectories/completed/2026-05/traj_7i9tigaejfje.json" - }, - "traj_1fjub7c9rlap": { - "title": "Rewrite harness docs around SDK adapters", - "status": "completed", - "startedAt": "2026-05-25T16:53:04.706Z", - "completedAt": "2026-05-25T16:53:16.077Z", - "path": ".trajectories/completed/2026-05/traj_1fjub7c9rlap.json" - }, - "traj_0d1efjk6aeo2": { - "title": "Respond to harness PR review comments", - "status": "completed", - "startedAt": "2026-05-25T17:14:45.927Z", - "completedAt": "2026-05-25T17:14:53.457Z", - "path": ".trajectories/completed/2026-05/traj_0d1efjk6aeo2.json" - }, - "traj_9dj3qiugt26j": { - "title": "Fix harness runtime review issues", - "status": "completed", - "startedAt": "2026-05-25T17:41:16.384Z", - "completedAt": "2026-05-25T17:53:06.394Z", - "path": ".trajectories/completed/2026-05/traj_9dj3qiugt26j.json" - }, - "traj_q2r3c9dmdep7": { - "title": "Rename harness plans to harness configs", - "status": "completed", - "startedAt": "2026-05-25T18:00:40.591Z", - "completedAt": "2026-05-25T18:06:34.954Z", - "path": ".trajectories/completed/2026-05/traj_q2r3c9dmdep7.json" - }, - "traj_fiygtgr3tfey": { - "title": "Fix harness config clippy issues", - "status": "completed", - "startedAt": "2026-05-25T18:31:39.975Z", - "completedAt": "2026-05-25T18:34:10.562Z", - "path": ".trajectories/completed/2026-05/traj_fiygtgr3tfey.json" - }, - "traj_n0qwpjvmdl2s": { - "title": "Default headless harness driver", - "status": "completed", - "startedAt": "2026-05-25T19:50:47.661Z", - "completedAt": "2026-05-25T19:52:52.791Z", - "path": ".trajectories/completed/2026-05/traj_n0qwpjvmdl2s.json" - }, - "traj_kgl2opmmfvus": { - "title": "Simplify harness config PR around broker-owned configs", - "status": "completed", - "startedAt": "2026-05-25T21:32:14.085Z", - "completedAt": "2026-05-25T21:47:15.455Z", - "path": ".trajectories/completed/2026-05/traj_kgl2opmmfvus.json" - }, - "traj_bd431l65n9lg": { - "title": "Remove broker harness registry footgun", - "status": "completed", - "startedAt": "2026-05-25T21:55:14.197Z", - "completedAt": "2026-05-25T22:02:22.902Z", - "path": ".trajectories/completed/2026-05/traj_bd431l65n9lg.json" - }, - "traj_qbq3laxbvhzf": { - "title": "Resolve harness PR conflicts and comments", - "status": "completed", - "startedAt": "2026-05-25T22:03:51.255Z", - "completedAt": "2026-05-25T22:25:18.889Z", - "path": ".trajectories/completed/2026-05/traj_qbq3laxbvhzf.json" - }, - "traj_l67sex3nkzfq": { - "title": "Fix failing harness PR e2e tests", - "status": "completed", - "startedAt": "2026-05-25T23:22:50.714Z", - "completedAt": "2026-05-25T23:32:19.352Z", - "path": ".trajectories/completed/2026-05/traj_l67sex3nkzfq.json" - }, - "traj_zyluvmlqo5j7": { - "title": "Resolve harness PR merge conflicts", - "status": "completed", - "startedAt": "2026-05-26T11:24:20.682Z", - "completedAt": "2026-05-26T11:26:52.563Z", - "path": ".trajectories/completed/2026-05/traj_zyluvmlqo5j7.json" - } - } -} diff --git a/package-lock.json b/package-lock.json index cb7aeb6b4..83082b6d8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1235,6 +1235,7 @@ }, "node_modules/@clack/prompts/node_modules/is-unicode-supported": { "version": "1.3.0", + "extraneous": true, "inBundle": true, "license": "MIT", "engines": { @@ -6702,9 +6703,9 @@ "link": true }, "node_modules/agent-trajectories": { - "version": "0.5.8", - "resolved": "https://registry.npmjs.org/agent-trajectories/-/agent-trajectories-0.5.8.tgz", - "integrity": "sha512-Cu/+uyxAy+eNSlpzuOhk62kM/i0BdlfG8Z4avyzfbHbQ3I9EQLqiUikl3WcG75m3v+4MwTbJq9e6YTG8/ykKPw==", + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/agent-trajectories/-/agent-trajectories-0.6.0.tgz", + "integrity": "sha512-wCOHGO7gWw6lA/4e794+YMOLWpfRnlCZiLN5i5lHj3oNHzFYEBlSEEBJXLM3moDM9x0UvLEAEsz+bYrlxW80mQ==", "license": "MIT", "dependencies": { "@clack/prompts": "^0.7.0", @@ -16232,7 +16233,7 @@ "@relayfile/local-mount": "^0.2.2", "@relayfile/sdk": "^0.6.0", "@slack/web-api": "^7.16.0", - "agent-trajectories": "^0.5.8", + "agent-trajectories": "^0.6.0", "commander": "^12.1.0", "dotenv": "^17.2.3", "esbuild": "^0.27.2", @@ -17202,7 +17203,7 @@ "@relaycast/sdk": "^1.1.0", "@relayfile/sdk": ">=0.1.2 <1", "@sinclair/typebox": "^0.34.48", - "agent-trajectories": "^0.5.4", + "agent-trajectories": "^0.6.0", "chalk": "^4.1.2", "ignore": "^7.0.5", "listr2": "^10.2.1", diff --git a/packages/cli/package.json b/packages/cli/package.json index 5fec1bac9..04eb89075 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -63,7 +63,7 @@ "@relayfile/local-mount": "^0.2.2", "@relayfile/sdk": "^0.6.0", "@slack/web-api": "^7.16.0", - "agent-trajectories": "^0.5.8", + "agent-trajectories": "^0.6.0", "commander": "^12.1.0", "dotenv": "^17.2.3", "esbuild": "^0.27.2", diff --git a/packages/sdk/package.json b/packages/sdk/package.json index 7a2173ebf..380fc60c1 100644 --- a/packages/sdk/package.json +++ b/packages/sdk/package.json @@ -179,7 +179,7 @@ "@relaycast/sdk": "^1.1.0", "@relayfile/sdk": ">=0.1.2 <1", "@sinclair/typebox": "^0.34.48", - "agent-trajectories": "^0.5.4", + "agent-trajectories": "^0.6.0", "chalk": "^4.1.2", "ignore": "^7.0.5", "listr2": "^10.2.1", From c223ca85f565aeae9d4353908a832316ca69fcb3 Mon Sep 17 00:00:00 2001 From: Will Washburn Date: Tue, 26 May 2026 11:43:05 -0400 Subject: [PATCH 17/19] Clarify headless app-server worker naming --- crates/broker/src/cli/mod.rs | 14 ++++++++------ crates/broker/src/runtime/app_server.rs | 2 +- crates/broker/src/runtime/mod.rs | 4 +++- 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/crates/broker/src/cli/mod.rs b/crates/broker/src/cli/mod.rs index d9deeee49..97c0aba2a 100644 --- a/crates/broker/src/cli/mod.rs +++ b/crates/broker/src/cli/mod.rs @@ -25,7 +25,9 @@ enum Commands { Init(InitCommand), Pty(PtyCommand), Headless(HeadlessCommand), - AppServer(AppServerCommand), + /// Internal: headless worker shim for app-server-backed harnesses. + #[command(name = "app-server", hide = true)] + HeadlessAppServer(HeadlessAppServerCommand), /// Compute MCP injection args and side-effect config file paths for a CLI /// without spawning it. Outputs JSON to stdout. McpArgs(McpArgsCommand), @@ -53,7 +55,7 @@ impl Commands { Commands::Init(_) => "init", Commands::Pty(_) => "pty", Commands::Headless(_) => "headless", - Commands::AppServer(_) => "app_server", + Commands::HeadlessAppServer(_) => "app_server", Commands::McpArgs(_) => "mcp_args", Commands::Swarm(_) => "swarm", Commands::DumpPty(_) => "dump_pty", @@ -88,8 +90,8 @@ impl Commands { } Commands::Headless(cmd) => non_empty_name(cmd.agent_name.as_deref()) .unwrap_or_else(|| format!("headless-{pid}")), - Commands::AppServer(cmd) => non_empty_name(cmd.agent_name.as_deref()) - .unwrap_or_else(|| format!("app_server-{pid}")), + Commands::HeadlessAppServer(cmd) => non_empty_name(cmd.agent_name.as_deref()) + .unwrap_or_else(|| format!("headless-app-server-{pid}")), Commands::Wrap { cli, .. } => format!("wrap-{cli}-{pid}"), Commands::McpArgs(_) => format!("mcp_args-{pid}"), Commands::DumpPty(cmd) => format!("dump_pty-{}-{}", cmd.name, pid), @@ -118,7 +120,7 @@ pub(crate) async fn run() -> Result<()> { Commands::Init(cmd) => runtime::run_init(cmd, telemetry).await, Commands::Pty(cmd) => pty_worker::run_pty_worker(cmd).await, Commands::Headless(cmd) => runtime::run_headless_worker(cmd).await, - Commands::AppServer(cmd) => runtime::run_app_server_worker(cmd).await, + Commands::HeadlessAppServer(cmd) => runtime::run_headless_app_server_worker(cmd).await, Commands::McpArgs(cmd) => cli_mcp_args::run_mcp_args(cmd).await, Commands::Swarm(args) => swarm::run_swarm(args).await, Commands::DumpPty(cmd) => runtime::run_dump_pty(cmd).await, @@ -277,7 +279,7 @@ pub(crate) struct HeadlessCommand { } #[derive(Debug, clap::Args, Clone)] -pub(crate) struct AppServerCommand { +pub(crate) struct HeadlessAppServerCommand { #[arg(long)] pub(crate) protocol: String, diff --git a/crates/broker/src/runtime/app_server.rs b/crates/broker/src/runtime/app_server.rs index 81bff8f41..c41fd2ed9 100644 --- a/crates/broker/src/runtime/app_server.rs +++ b/crates/broker/src/runtime/app_server.rs @@ -10,7 +10,7 @@ struct AppServerAuthConfig { const APP_SERVER_HTTP_TIMEOUT: Duration = Duration::from_secs(30); -pub(crate) async fn run_app_server_worker(cmd: AppServerCommand) -> Result<()> { +pub(crate) async fn run_headless_app_server_worker(cmd: HeadlessAppServerCommand) -> Result<()> { let protocol = cmd.protocol.trim().to_ascii_lowercase(); let endpoint = cmd.endpoint.trim().trim_end_matches('/').to_string(); let session_id = cmd.session_id.clone(); diff --git a/crates/broker/src/runtime/mod.rs b/crates/broker/src/runtime/mod.rs index d0646d04f..55081d8f0 100644 --- a/crates/broker/src/runtime/mod.rs +++ b/crates/broker/src/runtime/mod.rs @@ -49,7 +49,9 @@ use crate::{ }, }; -use crate::cli::{AppServerCommand, DumpPtyCommand, DumpPtyFormat, HeadlessCommand, InitCommand}; +use crate::cli::{ + DumpPtyCommand, DumpPtyFormat, HeadlessAppServerCommand, HeadlessCommand, InitCommand, +}; use crate::worker::{WorkerEvent, WorkerHandle, WorkerRegistry}; use crate::{broker, listen_api, routing, worker_request}; From 514e1751361eece4ab5b3b3b0dfc9afb16d66056 Mon Sep 17 00:00:00 2001 From: Will Washburn Date: Tue, 26 May 2026 12:06:25 -0400 Subject: [PATCH 18/19] Move harness runtime docs into web --- docs/harness-runtime-config.md | 202 -------------------- web/content/docs/harness-runtime-config.mdx | 188 ++++++++++++++++++ web/content/docs/harnesses.mdx | 1 + web/lib/docs-nav.ts | 1 + 4 files changed, 190 insertions(+), 202 deletions(-) delete mode 100644 docs/harness-runtime-config.md create mode 100644 web/content/docs/harness-runtime-config.mdx diff --git a/docs/harness-runtime-config.md b/docs/harness-runtime-config.md deleted file mode 100644 index 369bf8787..000000000 --- a/docs/harness-runtime-config.md +++ /dev/null @@ -1,202 +0,0 @@ -# Harness Runtime Config - -## Goal - -Harnesses should be user-extensible without requiring Rust changes for normal -agent CLIs. The durable boundary is data: the Rust broker validates and executes -`HarnessConfig` objects. SDKs may help users build those objects, but the broker -does not call back into SDK functions and does not depend on broker-local named -config state. - -## Core Model - -The broker has two public runtime categories: - -- `pty`: runs a command inside a PTY and manages terminal-oriented delivery. -- `headless`: controls a non-terminal agent through a driver. - -The first headless driver is `app_server`, used for session-backed HTTP agents -such as OpenCode. `driver` defaults to `app_server` when `runtime` is -`headless`. - -Names in this design: - -- A harness config is the concrete `pty` or `headless` object the broker runs. -- A harness adapter is SDK/userland code that returns a harness config. -- A named harness is an SDK-side shortcut in `new AgentRelay({ harnesses })`. -- `harnessConfig` is the spawn field that carries concrete config to the broker. - -## Config Shapes - -PTY configs are process and terminal backed: - -```ts -type PtyHarnessConfig = { - runtime: 'pty'; - command: string; - args: string[]; - cwd?: string; - env?: Record; - sessionId?: string; - delivery?: { - mode?: 'pty-injection'; - format?: 'relay-block'; - }; - metadata?: Record; -}; -``` - -Headless app-server configs are session backed: - -```ts -type HeadlessAppServerHarnessConfig = { - runtime: 'headless'; - driver?: 'app_server'; - protocol: 'opencode' | string; - endpoint: string; - sessionId: string; - auth?: { - type: 'bearer' | 'basic' | 'none'; - token?: string; - username?: string; - password?: string; - }; - host?: { - ownership?: 'broker-owned' | 'attached'; - pid?: number; - }; - release?: 'abort' | 'detach' | 'delete'; - metadata?: Record; -}; -``` - -For now, `app_server` configs are attach-only. `host.ownership: -'broker-owned'` is reserved and rejected until the broker owns app-server -lifecycle supervision. When `host.pid` is provided, the broker reports that as -the harness PID. - -Config `env` and `auth` values are visible to the broker. Adapters should return -explicit allowlists instead of copying whole process environments. - -## SDK Adapters - -An SDK adapter is a helper that returns data: - -```ts -function companyClaude(): ResolvedHarnessConfig { - return { - runtime: 'pty', - command: 'claude', - args: ['--dangerously-skip-permissions', '--append-system-prompt', 'Follow the company review rubric.'], - }; -} -``` - -Register stable configs by name in the SDK: - -```ts -const relay = new AgentRelay({ - harnesses: { - 'company-claude': companyClaude(), - }, -}); -``` - -This name is local SDK ergonomics. Before spawn, the SDK resolves it to a -concrete `harnessConfig` and sends that config to the broker. The broker does -not keep an in-memory harness registry, because broker-local names become a -multi-broker footgun. - -Use inline configs for per-spawn setup: - -```ts -const sessionId = await createCodexSession({ cwd, task }); - -await relay.spawn('CodexReviewer', 'codex', task, { - harnessConfig: { - runtime: 'pty', - command: 'codex', - args: ['resume', sessionId], - cwd, - sessionId, - }, -}); -``` - -This avoids pretending SDK callbacks are durable. If the SDK process exits, the -broker can still execute the agent because it already received the concrete -config. - -## Broker API - -`POST /api/spawn` accepts optional `harnessConfig`. - -Resolution rules: - -- `harnessConfig` is concrete and runs as supplied after validation. -- SDK names are resolved before this API call. -- Relaycast spawns that need custom behavior send full `harnessConfig`. -- `harnessId` is not accepted in broker or Relaycast spawn payloads. - -That keeps every spawn request self-contained. It avoids bugs where behavior -depends on registration order, stale broker process memory, or whether two -brokers agree on what a mutable name means. - -## Relaycast Spawns - -Agent-crafted Relaycast spawns should send a portable inline config: - -```json -{ - "agent": { - "name": "CodexReviewer", - "cli": "codex", - "task": "Review the current diff.", - "harnessConfig": { - "runtime": "pty", - "command": "codex", - "args": ["resume", "session_123"], - "sessionId": "session_123" - } - } -} -``` - -The broker validates the config and then uses the same spawn path as -SDK-submitted configs. - -## Broker Responsibilities - -The broker owns: - -- Agent registry and name uniqueness. -- Spawn, release, and future fork lifecycle. -- Relay routing and local-vs-remote delivery. -- Delivery queues, retry, ack, failure, and manual flush semantics. -- Process and server supervision for broker-owned runtimes. -- Capability checks for PTY-only routes. -- Event emission, metrics, logs, and replay buffers. - -The broker does not own arbitrary user logic unless that logic is built into -Rust or represented as validated config data. - -## Runtime Notes - -The PTY executor consumes a concrete PTY config. It handles process spawn, -terminal streaming, raw input, resize, snapshot, release, and PTY message -injection. - -The headless runtime covers non-PTY workers. Provider-command headless workers -remain the built-in path for existing providers. App-server headless workers -attach to a session server instead. Headless runtimes do not expose PTY input, -resize, or snapshot capabilities. - -## Implementation Phases - -1. Add shared config schema and SDK types. -2. Teach the broker to accept and execute resolved PTY configs. -3. Add a headless app-server config path with an OpenCode protocol driver. -4. Resolve named SDK harnesses to inline `harnessConfig` before spawn. -5. Allow Relaycast spawn events to carry inline `harnessConfig`. -6. Add capability-aware runtime checks for PTY-only operations. -7. Document Claude PTY, Codex inline PTY, and OpenCode headless examples. diff --git a/web/content/docs/harness-runtime-config.mdx b/web/content/docs/harness-runtime-config.mdx new file mode 100644 index 000000000..e8b91aee8 --- /dev/null +++ b/web/content/docs/harness-runtime-config.mdx @@ -0,0 +1,188 @@ +--- +title: Harness runtime config +description: Reference for the concrete HarnessConfig objects that SDK adapters send to the broker. +--- + +Use this page when you need the exact `HarnessConfig` shape. For a shorter +guide with Codex, Claude, and OpenCode examples, start with +[Harnesses](/docs/harnesses). + +The broker only executes serializable config data. SDK adapters can help you +build that data, but the broker does not call SDK functions after spawn and does +not keep a named harness registry. + +## Runtime Categories + +| Runtime | Use for | Broker capabilities | +| --- | --- | --- | +| `pty` | Terminal-backed CLIs such as Codex or Claude Code | process spawn, PTY stream, input, resize, snapshot, delivery, release | +| `headless` | Non-terminal sessions such as OpenCode app-server | session delivery, release | + +When `runtime` is `headless`, `driver` defaults to `app_server`. + +## Terms + +| Term | Meaning | +| --- | --- | +| Harness config | Concrete `pty` or `headless` JSON the broker can validate and run | +| Harness adapter | SDK or userland helper that returns a harness config | +| Named harness | SDK-side shortcut in `new AgentRelay({ harnesses })` | +| `harnessConfig` | Spawn field carrying the concrete config to the broker | + +Named harnesses are local SDK ergonomics. The SDK resolves them to an inline +`harnessConfig` before the spawn request reaches the broker. + +## PTY Config + +Use `pty` for terminal-backed coding harnesses: + +```typescript +type PtyHarnessConfig = { + runtime: 'pty'; + command: string; + args: string[]; + cwd?: string; + env?: Record; + sessionId?: string; + delivery?: { + mode?: 'pty-injection'; + format?: 'relay-block'; + }; + metadata?: Record; +}; +``` + +Example: + +```typescript +const harnessConfig = { + runtime: 'pty', + command: 'codex', + args: ['resume', sessionId], + cwd, + env: { + PATH: process.env.PATH ?? '', + CODEX_HOME: process.env.CODEX_HOME ?? '', + }, + sessionId, +} satisfies ResolvedHarnessConfig; +``` + +The broker owns the spawned process, PTY stream, raw input, resize, snapshots, +message injection, and release behavior for this runtime. + +## Headless App-Server Config + +Use `headless` for a non-terminal agent session controlled through an app +server. OpenCode is the first supported protocol: + +```typescript +type HeadlessAppServerHarnessConfig = { + runtime: 'headless'; + driver?: 'app_server'; + protocol: 'opencode' | string; + endpoint: string; + sessionId: string; + auth?: { + type: 'bearer' | 'basic' | 'none'; + token?: string; + username?: string; + password?: string; + }; + host?: { + ownership?: 'broker-owned' | 'attached'; + pid?: number; + }; + release?: 'abort' | 'detach' | 'delete'; + metadata?: Record; +}; +``` + +Example: + +```typescript +const harnessConfig = { + runtime: 'headless', + protocol: 'opencode', + endpoint: 'http://127.0.0.1:4096', + sessionId: 'ses_123', + host: { ownership: 'attached', pid: 34567 }, + release: 'abort', +} satisfies ResolvedHarnessConfig; +``` + +For now, app-server configs are attach-only. `host.ownership: 'broker-owned'` +is reserved until the broker owns app-server lifecycle supervision. If +`host.pid` is provided, the broker reports that PID as the harness process ID. + +## Adapter Pattern + +An adapter should return config data: + +```typescript +function companyClaude(): ResolvedHarnessConfig { + return { + runtime: 'pty', + command: 'claude', + args: [ + '--dangerously-skip-permissions', + '--append-system-prompt', + 'Follow the company review rubric.', + ], + }; +} +``` + +Register stable configs by name: + +```typescript +const relay = new AgentRelay({ + harnesses: { + 'company-claude': companyClaude(), + }, +}); +``` + +Use an inline `harnessConfig` when setup changes per spawn, such as creating a +Codex session: + +```typescript +const sessionId = await createCodexSession({ cwd, task }); + +await relay.spawn('CodexReviewer', 'codex', task, { + harnessConfig: { + runtime: 'pty', + command: 'codex', + args: ['resume', sessionId], + cwd, + sessionId, + }, +}); +``` + +Do not copy the whole process environment into `env`, and do not put secrets in +`metadata`. `env` and `auth` are visible to the broker, so pass explicit +allowlists. + +## Spawn Payloads + +`POST /api/spawn` accepts `harnessConfig`: + +```json +{ + "name": "CodexReviewer", + "cli": "codex", + "task": "Review the current diff.", + "harnessConfig": { + "runtime": "pty", + "command": "codex", + "args": ["resume", "session_123"], + "sessionId": "session_123" + } +} +``` + +The broker rejects `harnessId`. Relaycast spawns that need custom behavior +should also send a full inline `harnessConfig`, which keeps each spawn +self-contained across local, remote, and multi-broker deployments. + diff --git a/web/content/docs/harnesses.mdx b/web/content/docs/harnesses.mdx index 86bffdff8..cf18bafb6 100644 --- a/web/content/docs/harnesses.mdx +++ b/web/content/docs/harnesses.mdx @@ -166,6 +166,7 @@ state or which broker receives it. ## See Also +- [Harness runtime config](/docs/harness-runtime-config) - Exact config shapes - [Spawning an agent](/docs/spawning-an-agent) - High-level spawn APIs - [Event handlers](/docs/event-handlers) - SDK event subscriptions - [Broker HTTP / WS API](/docs/reference-broker-api) - Broker API routes diff --git a/web/lib/docs-nav.ts b/web/lib/docs-nav.ts index 35f822c9b..3964f52c4 100644 --- a/web/lib/docs-nav.ts +++ b/web/lib/docs-nav.ts @@ -95,6 +95,7 @@ const ALL_SLUGS = [ 'communicate-openai-agents', 'communicate-swarms', 'communicate-crewai', + 'harness-runtime-config', 'local-mode', 'reference-openclaw', 'reference-workflows', From 57af0b507a52283e26b54ebb66452024857d2719 Mon Sep 17 00:00:00 2001 From: Will Washburn Date: Tue, 26 May 2026 12:15:48 -0400 Subject: [PATCH 19/19] Move doctor repro docs into web --- docs/doctor-orchestration-repros.md | 140 ------------- .../docs/doctor-orchestration-repros.mdx | 184 ++++++++++++++++++ web/lib/docs-nav.ts | 1 + 3 files changed, 185 insertions(+), 140 deletions(-) delete mode 100644 docs/doctor-orchestration-repros.md create mode 100644 web/content/docs/doctor-orchestration-repros.mdx diff --git a/docs/doctor-orchestration-repros.md b/docs/doctor-orchestration-repros.md deleted file mode 100644 index cfba04850..000000000 --- a/docs/doctor-orchestration-repros.md +++ /dev/null @@ -1,140 +0,0 @@ -# Doctor Orchestration Repros - -These are deterministic local repros for orchestration states that previously -required comparing `status`, `who`, and messaging command output by hand. -Credential values in observed output are redacted. - -## Stale or Wrong Broker Connection - -Run from a temporary project with the built CLI: - -```bash -CLI=/Users/khaliqgant/Projects/AgentWorkforce/relay/dist/src/cli/index.js -TMP=$(mktemp -d /tmp/relay-repro-A-C-XXXXXX) -cd "$TMP" -node "$CLI" up --no-dashboard --port 49200 -cat .agent-relay/connection.json -node "$CLI" status -node "$CLI" who --json -kill -9 11078 -node "$CLI" up --no-dashboard --port 49300 -node -e 'const fs=require("fs"); const old=JSON.parse(process.argv[1]); const next=JSON.parse(process.argv[2]); old.pid=next.pid; fs.writeFileSync(".agent-relay/connection.json", JSON.stringify(old,null,2));' "$CONN1" "$CONN2" -cat .agent-relay/connection.json -node "$CLI" status -node "$CLI" status --wait-for=1 -node "$CLI" who --json -``` - -Observed output: - -```text -Broker started. -Broker PID: 11078 -Stop with: agent-relay down - -{ - "api_key": "br_", - "pid": 11078, - "port": 49201, - "url": "http://127.0.0.1:49201" -} - -Status: RUNNING -Mode: broker (stdio) -PID: 11078 -Project: /private/tmp/relay-repro-A-C-HuYoNc -Agents: 0 -Workspace Key: rk_live_ -Observer: https://agentrelay.com/observer?key=rk_live_ - -[] - -Broker started. -Broker PID: 11410 -Stop with: agent-relay down - -{ - "api_key": "br_", - "pid": 11410, - "port": 49201, - "url": "http://127.0.0.1:49201" -} - -Status: RUNNING -Mode: broker (stdio) -PID: 11410 -Project: /private/tmp/relay-repro-A-C-HuYoNc - -Status: STARTING -Mode: broker (stdio) -PID: 11410 -Project: /private/tmp/relay-repro-A-C-HuYoNc -Broker process is running, but the API did not become ready before timeout. - -[] -``` - -## Unresolved API Key Template - -With the same temporary project, the correctly resolved broker session key -allowed an orchestrator read to reach Relaycast: - -```bash -node "$CLI" replies WorkerA --json -``` - -Observed output: - -```text -No DM conversation with WorkerA. -``` - -The literal unresolved template fails before a meaningful orchestrator read: - -```bash -RELAY_API_KEY='${RELAY_API_KEY}' node "$CLI" replies WorkerA --json -``` - -Observed output: - -```text -Failed to initialize relaycast client: Workspace key required (rk_live_...) -``` - -## Half-Started Broker With Missing Metadata - -Run with Relaycast environment variables unset so messaging commands must rely -on local broker metadata: - -```bash -CLI=/Users/khaliqgant/Projects/AgentWorkforce/relay/dist/src/cli/index.js -RUN=(env -u RELAY_API_KEY -u RELAY_AGENT_TOKEN -u RELAY_WORKSPACES_JSON -u RELAY_DEFAULT_WORKSPACE -u RELAY_WORKSPACE_ID -u RELAY_BASE_URL -u RELAY_BROKER_URL -u RELAY_BROKER_API_KEY -u RELAY_AGENT_NAME -u RELAY_AGENT_TYPE -u RELAY_STRICT_AGENT_NAME node "$CLI") -TMP=$(mktemp -d /tmp/relay-repro-half2-XXXXXX) -cd "$TMP" -"${RUN[@]}" up --no-dashboard --port 49600 -rm .agent-relay/connection.json -ps -p 15596 -o pid=,comm= -"${RUN[@]}" status -"${RUN[@]}" history -"${RUN[@]}" replies WorkerA --json -"${RUN[@]}" up --no-dashboard --port 49700 -``` - -Observed output: - -```text -Broker started. -Broker PID: 15596 -Stop with: agent-relay down - -15596 /Users/khaliqgant/Projects/AgentWorkforce/relay/target/release/agent-relay-broker - -Status: STOPPED - -Failed to initialize relaycast client: Failed to read broker connection metadata. Start the broker with `agent-relay up` or set RELAY_API_KEY. - -Failed to initialize relaycast client: Failed to read broker connection metadata. Start the broker with `agent-relay up` or set RELAY_API_KEY. - -Broker background start did not become ready within 10s (pid: 16245). -Run `agent-relay status --wait-for=10` for details, or `agent-relay down --force` to clean up. -``` diff --git a/web/content/docs/doctor-orchestration-repros.mdx b/web/content/docs/doctor-orchestration-repros.mdx new file mode 100644 index 000000000..5a4d723c4 --- /dev/null +++ b/web/content/docs/doctor-orchestration-repros.mdx @@ -0,0 +1,184 @@ +--- +title: Doctor orchestration repros +description: Local repro steps for broker connection and orchestration diagnostics. +--- + +Use these local repros when `agent-relay status`, `agent-relay who`, or +messaging commands disagree about broker state. They intentionally create broken +broker metadata so you can verify diagnostics without comparing command output +by hand. + +Credential values shown by your local commands should be treated as secrets. +Do not paste unredacted workspace keys, broker API keys, or agent tokens into +issues or shared logs. + +## Stale Broker Connection + +This repro simulates a connection file that points at an old broker URL while +recording the PID of a newer broker process. + +```bash +TMP=$(mktemp -d "${TMPDIR:-/tmp}/relay-repro-stale-XXXXXX") +cd "$TMP" + +agent-relay up --no-dashboard --port 49200 +CONN1=$(cat .agent-relay/connection.json) +PID1=$(node -e 'console.log(JSON.parse(process.argv[1]).pid)' "$CONN1") + +kill -9 "$PID1" + +agent-relay up --no-dashboard --port 49300 +CONN2=$(cat .agent-relay/connection.json) + +node -e ' +const fs = require("node:fs"); +const oldConn = JSON.parse(process.argv[1]); +const nextConn = JSON.parse(process.argv[2]); +oldConn.pid = nextConn.pid; +fs.writeFileSync(".agent-relay/connection.json", JSON.stringify(oldConn, null, 2)); +' "$CONN1" "$CONN2" + +agent-relay status +agent-relay status --wait-for=1 +agent-relay who --json +``` + +Expected result: + +```text +Status: STARTING +Broker process is running, but the API did not become ready before timeout. + +[] +``` + +The broker process exists, but the recorded API URL is stale. Diagnostic +commands should report the mismatch instead of treating the workspace as a +healthy broker session. + +## Unresolved API Key Template + +This repro checks that a literal unresolved environment template fails before a +messaging command attempts a Relaycast read. + +First confirm that the correctly resolved local broker context reaches +Relaycast: + +```bash +agent-relay replies WorkerA --json +``` + +Expected result when there is no conversation: + +```text +No DM conversation with WorkerA. +``` + +Then run the same command with a literal unresolved template: + +```bash +RELAY_API_KEY='${RELAY_API_KEY}' agent-relay replies WorkerA --json +``` + +Expected result: + +```text +Failed to initialize relaycast client: Workspace key required (rk_live_...) +``` + +The command should reject the unresolved template as invalid credential input +instead of treating it as a real workspace key. + +## Half-Started Broker Metadata + +This repro simulates a broker process that is still running after its local +connection metadata has disappeared. + +```bash +TMP=$(mktemp -d "${TMPDIR:-/tmp}/relay-repro-half-started-XXXXXX") +cd "$TMP" + +env \ + -u RELAY_API_KEY \ + -u RELAY_AGENT_TOKEN \ + -u RELAY_WORKSPACES_JSON \ + -u RELAY_DEFAULT_WORKSPACE \ + -u RELAY_WORKSPACE_ID \ + -u RELAY_BASE_URL \ + -u RELAY_BROKER_URL \ + -u RELAY_BROKER_API_KEY \ + -u RELAY_AGENT_NAME \ + -u RELAY_AGENT_TYPE \ + -u RELAY_STRICT_AGENT_NAME \ + agent-relay up --no-dashboard --port 49600 + +CONN=$(cat .agent-relay/connection.json) +PID=$(node -e 'console.log(JSON.parse(process.argv[1]).pid)' "$CONN") +rm .agent-relay/connection.json + +ps -p "$PID" -o pid=,comm= + +env \ + -u RELAY_API_KEY \ + -u RELAY_AGENT_TOKEN \ + -u RELAY_WORKSPACES_JSON \ + -u RELAY_DEFAULT_WORKSPACE \ + -u RELAY_WORKSPACE_ID \ + -u RELAY_BASE_URL \ + -u RELAY_BROKER_URL \ + -u RELAY_BROKER_API_KEY \ + -u RELAY_AGENT_NAME \ + -u RELAY_AGENT_TYPE \ + -u RELAY_STRICT_AGENT_NAME \ + agent-relay status + +env \ + -u RELAY_API_KEY \ + -u RELAY_AGENT_TOKEN \ + -u RELAY_WORKSPACES_JSON \ + -u RELAY_DEFAULT_WORKSPACE \ + -u RELAY_WORKSPACE_ID \ + -u RELAY_BASE_URL \ + -u RELAY_BROKER_URL \ + -u RELAY_BROKER_API_KEY \ + -u RELAY_AGENT_NAME \ + -u RELAY_AGENT_TYPE \ + -u RELAY_STRICT_AGENT_NAME \ + agent-relay history + +env \ + -u RELAY_API_KEY \ + -u RELAY_AGENT_TOKEN \ + -u RELAY_WORKSPACES_JSON \ + -u RELAY_DEFAULT_WORKSPACE \ + -u RELAY_WORKSPACE_ID \ + -u RELAY_BASE_URL \ + -u RELAY_BROKER_URL \ + -u RELAY_BROKER_API_KEY \ + -u RELAY_AGENT_NAME \ + -u RELAY_AGENT_TYPE \ + -u RELAY_STRICT_AGENT_NAME \ + agent-relay replies WorkerA --json +``` + +Expected result: + +```text +Status: STOPPED + +Failed to initialize relaycast client: Failed to read broker connection metadata. Start the broker with `agent-relay up` or set RELAY_API_KEY. +``` + +The process table can still contain the broker PID, but the workspace is missing +the metadata needed for broker-backed messaging. Diagnostic commands should +surface that missing metadata directly. + +## Cleanup + +Each repro creates a temporary project directory and may leave a broker process +behind. Clean up with: + +```bash +agent-relay down --force --all +``` + diff --git a/web/lib/docs-nav.ts b/web/lib/docs-nav.ts index 3964f52c4..bd4ed913d 100644 --- a/web/lib/docs-nav.ts +++ b/web/lib/docs-nav.ts @@ -95,6 +95,7 @@ const ALL_SLUGS = [ 'communicate-openai-agents', 'communicate-swarms', 'communicate-crewai', + 'doctor-orchestration-repros', 'harness-runtime-config', 'local-mode', 'reference-openclaw',