taskchef 5.5.0 → 5.5.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "taskchef",
3
- "version": "5.5.0",
3
+ "version": "5.5.2",
4
4
  "description": "Dispatch work from a data-only workspace to visible Codex project tasks.",
5
5
  "author": {
6
6
  "name": "Favo Yang",
package/README.md CHANGED
@@ -32,6 +32,10 @@ TaskChef does not copy executor results into its workspace. When you ask for a
32
32
  report, it reads the recorded task IDs, checks those Codex tasks once, and
33
33
  shows their current state without saving another snapshot.
34
34
 
35
+ See [Delegation design](docs/delegation-design.md) for the complete illustrated
36
+ workflow, durable and provisional-ID examples, safety invariants, and measured
37
+ CLI-versus-MCP latency comparison.
38
+
35
39
  ## Quickstart
36
40
 
37
41
  ### 1. Install the plugin
@@ -91,7 +95,7 @@ TaskChef replies with a link to the new Codex task. Open it to follow progress
91
95
  or give the executor more instructions. The dispatcher is ready for another
92
96
  request immediately.
93
97
 
94
- The plugin's focused local tools prepare and record delegations directly in the
98
+ The plugin's focused MCP tools prepare and record delegations directly in the
95
99
  canonical workspace. They preserve TaskChef's lock and atomic-write guarantees
96
100
  without shell quoting, stdin handling, temporary record files, or a separate
97
101
  command-sandbox permission round trip.
@@ -201,8 +205,11 @@ The plugin has three skills:
201
205
  - `$taskchef-delegate` routes requests and creates executor tasks
202
206
  - `$taskchef-report` reads the task history and reports live executor state once
203
207
 
204
- The CLI underneath these skills manages workspace data. Run it once with `npx`
205
- if you do not want a global installation:
208
+ Normal delegation uses the plugin's bundled MCP tools. The bootstrap and report
209
+ skills continue to call the CLI for deterministic workspace administration,
210
+ task-history reads, and later recovery. The same CLI is also available for
211
+ direct inspection, benchmarking, and manual operations over the shared
212
+ workspace logic. Run it once with `npx` if you do not want a global installation:
206
213
 
207
214
  ```sh
208
215
  npx taskchef help
@@ -214,9 +221,9 @@ For the shorter command used below, install it globally:
214
221
  npm install --global taskchef
215
222
  ```
216
223
 
217
- The npm package provides the data CLI. The Codex plugin provides the skills
218
- that create and inspect executor tasks. From a source checkout, use
219
- `node bin/taskchef.js`.
224
+ The npm package provides the data CLI. The Codex plugin provides the skills and
225
+ focused MCP tools used during delegation; native Codex tools still create and
226
+ inspect executor tasks. From a source checkout, use `node bin/taskchef.js`.
220
227
 
221
228
  ```text
222
229
  taskchef help
@@ -240,11 +247,14 @@ Workspace resolution is deterministic: `--workspace <path>`, then the
240
247
  current directory is never an implicit workspace. Data commands accept
241
248
  `--json` for machine-readable output. Run `taskchef help` for every option.
242
249
 
243
- `taskchef dispatch prepare --json` performs the read-only preparation used by
244
- the delegation skill in one process: it resolves the canonical workspace,
245
- loads and validates configured projects, and returns a generated task UUID,
246
- preparation timestamp, and exact correlation marker. `task record` accepts one
247
- JSON value only from closed, non-interactive standard input.
250
+ `taskchef dispatch prepare --json` is the CLI equivalent of the MCP
251
+ `prepare_dispatch` operation: it resolves the canonical workspace, loads and
252
+ validates configured projects, and returns a generated task UUID, preparation
253
+ timestamp, and exact correlation marker. Normal delegation calls the MCP tool;
254
+ the CLI command remains useful for diagnostics and benchmarks. `task record`
255
+ accepts one JSON value only from closed, non-interactive standard input and is
256
+ intended for manual recovery or direct CLI use, not the skill's normal
257
+ recording path.
248
258
 
249
259
  For repeatable live delegation measurements, run
250
260
  `npm run benchmark:e2e -- write`. It reads one non-interactive JSON value,
@@ -345,8 +355,11 @@ printf '%s\n' '{"id":"c0f010ff-84f2-4838-a69d-0ff1f5d721d7","project":"/workspac
345
355
  taskchef task record --json
346
356
  ```
347
357
 
348
- If a task has `threadId: null`, Codex can later find its exact marker and pass
349
- the verified durable ID to the CLI. Resolution is atomic and only permits the
358
+ If a task has `threadId: null`, a later Codex workflow can find its exact
359
+ marker and pass the verified durable ID through its prescribed interface. The
360
+ delegate skill uses the MCP `resolve_task` tool during bounded post-creation
361
+ recovery; the report skill and direct manual recovery use the equivalent CLI
362
+ operation below. Both reach the same atomic logic, which permits only the
350
363
  one-way transition from null to one unique thread ID:
351
364
 
352
365
  ```sh
@@ -378,7 +391,9 @@ TITLE PROJECT CREATED ID THREAD ID
378
391
  Add retry logs payments 2026-08-12T10:00:00.000Z c0f010ff 019f9d46
379
392
  ```
380
393
 
381
- The complete data contract is in [SPEC.md](SPEC.md). Deferred ideas are in
394
+ The complete data contract is in [SPEC.md](SPEC.md). The illustrated runtime
395
+ workflow and latency analysis are in
396
+ [Delegation design](docs/delegation-design.md). Deferred ideas are in
382
397
  [BACKLOG.md](BACKLOG.md).
383
398
 
384
399
  ## Development and release
@@ -0,0 +1,268 @@
1
+ # Delegation design
2
+
3
+ This document explains how TaskChef 5.5 delegates a request, records the new
4
+ Codex task, and safely recovers a durable task ID when creation initially
5
+ returns only a provisional ID.
6
+
7
+ ## Mental model
8
+
9
+ TaskChef is the dispatcher and Codex tasks are the executors. TaskChef chooses
10
+ where work belongs, creates a normal Codex task there, and appends one entry to
11
+ the canonical `~/.agents/taskchef/tasks.jsonl` history. It returns after the
12
+ task is recorded; it does not wait for executor completion.
13
+
14
+ ```mermaid
15
+ flowchart LR
16
+ U["User request"] --> D["TaskChef dispatcher"]
17
+ D --> P["Choose configured project"]
18
+ P --> C["Create Codex executor"]
19
+ C --> R["Record task atomically"]
20
+ R --> U2["Return executor link"]
21
+ ```
22
+
23
+ Three focused local tools handle TaskChef-owned data operations:
24
+
25
+ | Tool | Responsibility | Mutates history? |
26
+ | --- | --- | --- |
27
+ | `prepare_dispatch` | Load routes and generate the UUID, timestamp, and exact marker | No |
28
+ | `record_task` | Append the created task with a durable ID or `null` | Yes, one atomic append |
29
+ | `resolve_task` | Fill a recorded `null` ID after one exact marker match | Yes, one-way and atomic |
30
+
31
+ The tools never create Codex tasks. Task creation and thread discovery remain
32
+ native Codex operations.
33
+
34
+ ## Before and after structured tools
35
+
36
+ The following values come from separate real traces. The MCP record calls used
37
+ an existing record and therefore measured duplicate validation, locking, tool
38
+ transport, and permission overhead rather than a new append. The resolve calls
39
+ were idempotent. Treat the operation comparison as strong evidence about
40
+ orchestration overhead, not as a complete post-release delegation benchmark.
41
+
42
+ | Stage | Earlier CLI path | TaskChef 5.5 MCP path | What changed |
43
+ | --- | ---: | ---: | --- |
44
+ | Prepare routing data and correlation values | Several operations; roughly 0.4–1.0 s in the original trace | `prepare_dispatch`: 79 ms | One call now loads routes and generates UUID, timestamp, and marker internally |
45
+ | Native Codex project list | About 0.6–0.7 s | Still about 0.6–0.7 s | Runs concurrently with preparation |
46
+ | Create Codex task | About 0.3 s | Fundamentally unchanged | Still a native Codex operation |
47
+ | Record permission-aware operation | 7.167 s | 62 ms, then 58 ms | Removed shell, stdin, temporary-file, sandbox-failure, and approval paths |
48
+ | Resolve permission-aware operation | 8.982 s | 11 ms, then 8 ms | Uses a structured atomic call instead of a new shell command |
49
+ | Approval prompts | Required in the failing trace | None in the MCP benchmark | The installed local tool process has the appropriate tool authorization |
50
+
51
+ Combining measurements from different runs suggests a durable fast path near
52
+ 1.0–1.2 seconds, compared with roughly 8–9 seconds for the later CLI benchmark.
53
+ This is an estimate until another full post-release delegation benchmark
54
+ measures every stage in one run.
55
+
56
+ ### Where the time was saved
57
+
58
+ MCP is not inherently thousands of times faster than invoking a CLI. Both
59
+ paths ultimately call the same TaskChef validation, lock, and atomic-write
60
+ code. The large difference came from work surrounding that code:
61
+
62
+ | Removed overhead | Evidence from the original trace |
63
+ | --- | --- |
64
+ | Interactive stdin and EOF handling | The first TTY attempt consumed several tool round trips and did not terminate cleanly |
65
+ | Temporary-file/redirection orchestration | A second invocation was needed to pass one exact JSON value non-interactively |
66
+ | Late sandbox failure | The redirected attempt waited about 7.3 seconds before `EPERM` on the canonical workspace lock |
67
+ | Approval and retry | The escalated retry took about 11 seconds including review and then succeeded |
68
+ | Separate UUID/timestamp shell work | Those values are now generated inside `prepare_dispatch` |
69
+ | Repeated process/tool boundaries | Preparation and both writes are focused structured calls with validated schemas |
70
+
71
+ The actual TaskChef write is small. The MCP benchmark reached duplicate-record
72
+ validation in tens of milliseconds. The improvement comes mainly from avoiding
73
+ a known-to-fail sandboxed command followed by an approved retry, not from
74
+ weakening locking, atomicity, or validation.
75
+
76
+ ## Durable-ID fast path
77
+
78
+ ```mermaid
79
+ sequenceDiagram
80
+ participant U as User
81
+ participant S as Delegate skill
82
+ participant M as TaskChef MCP
83
+ participant C as Codex
84
+ participant W as Canonical workspace
85
+
86
+ U->>S: Delegate request
87
+ par Independent preparation
88
+ S->>M: prepare_dispatch()
89
+ M->>W: Load and validate routes
90
+ M-->>S: UUID, timestamp, marker, projects
91
+ and
92
+ S->>C: List native projects once
93
+ C-->>S: Native projects
94
+ end
95
+ S->>S: Select one exact configured project
96
+ S->>C: Create task with marked instruction
97
+ C-->>S: durable threadId
98
+ S->>M: record_task(..., threadId)
99
+ M->>W: Lock, validate, append atomically
100
+ M-->>S: Recorded task
101
+ S-->>U: Return created task immediately
102
+ ```
103
+
104
+ ### Example
105
+
106
+ Preparation returns:
107
+
108
+ ```json
109
+ {
110
+ "schemaVersion": 1,
111
+ "workspace": "/home/example/.agents/taskchef",
112
+ "taskId": "c0f010ff-84f2-4838-a69d-0ff1f5d721d7",
113
+ "preparedAt": "2026-08-14T09:30:00.000Z",
114
+ "marker": "<!-- taskchef_id=c0f010ff-84f2-4838-a69d-0ff1f5d721d7 -->",
115
+ "projectCount": 1,
116
+ "projects": [
117
+ {
118
+ "name": "t2",
119
+ "path": "/projects/t2",
120
+ "isGitRepository": true,
121
+ "githubRepos": [],
122
+ "description": "Small Python fixture project"
123
+ }
124
+ ]
125
+ }
126
+ ```
127
+
128
+ The exact executor instruction becomes:
129
+
130
+ ```text
131
+ <!-- taskchef_id=c0f010ff-84f2-4838-a69d-0ff1f5d721d7 -->
132
+
133
+ Return exactly the integers 1 through 10, one per line.
134
+ Do not modify files.
135
+ ```
136
+
137
+ If Codex returns a durable ID such as
138
+ `019ffbd4-5d96-79c0-9364-130d58156b76`, TaskChef sends the same marked
139
+ instruction and durable ID to `record_task`. The tool rejects a mismatched
140
+ marker, duplicate task ID, or duplicate durable thread ID before appending.
141
+
142
+ ## Provisional-ID recovery path
143
+
144
+ Codex can sometimes return a `clientThreadId` or `pendingWorktreeId` before the
145
+ durable task is discoverable. TaskChef never writes that provisional value into
146
+ the canonical `threadId` field.
147
+
148
+ ```mermaid
149
+ flowchart TD
150
+ C["Creation returns provisional ID"] --> N["Record task with threadId: null"]
151
+ N --> S1["First recent-task snapshot around 10 seconds"]
152
+ S1 --> B1["Filter candidates and batch-read structured inputs"]
153
+ B1 --> M1{"Exactly one exact marker match?"}
154
+ M1 -->|Yes| R["resolve_task: null to durable ID"]
155
+ M1 -->|No| S2["Second snapshot at least 20 seconds after first start"]
156
+ S2 --> B2["Filter candidates and batch-read structured inputs"]
157
+ B2 --> M2{"Exactly one exact marker match?"}
158
+ M2 -->|Yes| R
159
+ M2 -->|Zero, multiple, or error| U["Keep null and report unresolved"]
160
+ ```
161
+
162
+ The nominal snapshot starts are 10 and 30 seconds after the provisional
163
+ result. They are catch-up checkpoints rather than expiration deadlines. If
164
+ mandatory recording finishes at 14 seconds, the first snapshot starts
165
+ immediately at 14 seconds, and the second cannot start before 34 seconds. Work
166
+ spent filtering and reading candidates counts toward that 20-second interval.
167
+ TaskChef never takes a third snapshot.
168
+
169
+ ### Example
170
+
171
+ Suppose task creation initially returns only:
172
+
173
+ ```json
174
+ {
175
+ "clientThreadId": "local:pending-123"
176
+ }
177
+ ```
178
+
179
+ TaskChef keeps that value for diagnostics only and records the complete task
180
+ with `threadId: null`:
181
+
182
+ ```json
183
+ {
184
+ "id": "c0f010ff-84f2-4838-a69d-0ff1f5d721d7",
185
+ "project": "/projects/t2",
186
+ "title": "Count from 1 to 10",
187
+ "instruction": "<!-- taskchef_id=c0f010ff-84f2-4838-a69d-0ff1f5d721d7 -->\n\nReturn exactly the integers 1 through 10, one per line.\nDo not modify files.",
188
+ "threadId": null
189
+ }
190
+ ```
191
+
192
+ A later candidate read might contain this structured delegated input:
193
+
194
+ ```json
195
+ {
196
+ "userMessage": {
197
+ "content": [
198
+ {
199
+ "codexDelegation": {
200
+ "input": "<!-- taskchef_id=c0f010ff-84f2-4838-a69d-0ff1f5d721d7 -->\n\nReturn exactly the integers 1 through 10, one per line.\nDo not modify files."
201
+ }
202
+ }
203
+ ]
204
+ },
205
+ "threadId": "019ffbd4-5d96-79c0-9364-130d58156b76"
206
+ }
207
+ ```
208
+
209
+ If this is the only exact marker match, TaskChef calls:
210
+
211
+ ```json
212
+ {
213
+ "tool": "resolve_task",
214
+ "arguments": {
215
+ "taskId": "c0f010ff-84f2-4838-a69d-0ff1f5d721d7",
216
+ "threadId": "019ffbd4-5d96-79c0-9364-130d58156b76"
217
+ }
218
+ }
219
+ ```
220
+
221
+ The stored value changes atomically from `null` to that durable ID. If neither
222
+ snapshot finds exactly one match, the stored value remains `null`; TaskChef
223
+ reports `local:pending-123` only as provisional diagnostic context.
224
+
225
+ For each snapshot TaskChef:
226
+
227
+ 1. Lists at most 50 recent tasks.
228
+ 2. Filters by available host, project, creation time, and worktree metadata.
229
+ 3. Uses title only to prioritize reads, never as correlation proof.
230
+ 4. Reads every remaining candidate together in one programmatic batch.
231
+ 5. Examines only structured `codexDelegation.input`.
232
+ 6. Accepts only one input beginning with the exact marker and blank line.
233
+ 7. Calls `resolve_task` once to atomically change `null` to the durable ID.
234
+
235
+ Zero matches, multiple matches, read errors, or resolution-write errors leave
236
+ the existing nullable record intact. TaskChef reports that state and never
237
+ guesses.
238
+
239
+ ## Correctness and safety invariants
240
+
241
+ | Invariant | Enforcement |
242
+ | --- | --- |
243
+ | Canonical workspace | The MCP server resolves `TASKCHEF_WORKSPACE` or `~/.agents/taskchef`; the model cannot pass a workspace path |
244
+ | Exact marked instruction | The full UUID marker is generated before creation and must be the first line followed by a blank line |
245
+ | Durable correlation | Only the exact marker inside structured delegated input proves a discovery match |
246
+ | No provisional persistence | A provisional ID is diagnostic only; the record receives `null` |
247
+ | Atomic history | Record and resolve reuse TaskChef's existing locks and atomic file replacement |
248
+ | One-way resolution | Resolution permits only `null` to one unique durable ID and is idempotent for that same ID |
249
+ | Bounded discovery | At most two snapshots, with at least 20 seconds between their actual start times |
250
+ | Immediate handoff | The dispatcher returns after recording or bounded recovery and never waits for executor completion |
251
+
252
+ ## Stable capability assumptions
253
+
254
+ TaskChef 5.5 does not probe the tool surface after creation. The supported Codex
255
+ surface has no native provisional-ID resolver, so the skill always uses the
256
+ fixed two-snapshot recovery workflow when creation is provisional. A future
257
+ native resolver should be adopted through a versioned TaskChef change and
258
+ tests, rather than adding capability-detection latency and variable behavior to
259
+ every dispatch.
260
+
261
+ ## Validation references
262
+
263
+ - The normative data and workflow contract is in [`../SPEC.md`](../SPEC.md).
264
+ - The executable skill instructions are in
265
+ [`../skills/taskchef-delegate/SKILL.md`](../skills/taskchef-delegate/SKILL.md).
266
+ - Structured tool definitions are in [`../src/mcp.js`](../src/mcp.js).
267
+ - Timestamped local benchmark artifacts are written under
268
+ `reports/e2e-benchmarks/` and intentionally remain outside release packages.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "taskchef",
3
- "version": "5.5.0",
3
+ "version": "5.5.2",
4
4
  "description": "A non-blocking interactive dispatcher for visible Codex tasks.",
5
5
  "license": "MIT",
6
6
  "author": "Favo Yang",
@@ -23,6 +23,7 @@
23
23
  "assets",
24
24
  "BACKLOG.md",
25
25
  "bin",
26
+ "docs/delegation-design.md",
26
27
  "index.js",
27
28
  "mcp",
28
29
  "SPEC.md",