taskchef 5.7.2 → 5.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.codex-plugin/plugin.json +2 -2
- package/BACKLOG.md +4 -4
- package/README.md +78 -45
- package/SPEC.md +106 -89
- package/docs/delegation-design.md +158 -254
- package/hooks/hooks.json +18 -0
- package/hooks/taskchef-initial-prompt.js +17 -0
- package/index.js +6 -1
- package/package.json +2 -1
- package/skills/taskchef-bootstrap/SKILL.md +6 -3
- package/skills/taskchef-delegate/SKILL.md +49 -91
- package/skills/taskchef-report/SKILL.md +60 -27
- package/src/cli.js +8 -2
- package/src/delegation.js +109 -359
- package/src/hook.js +60 -0
- package/src/mcp.js +35 -2
- package/src/workspace-path.js +5 -1
- package/src/workspace.js +211 -14
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "taskchef",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.8.0",
|
|
4
4
|
"description": "Dispatch work from a data-only workspace to visible Codex project tasks.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Favo Yang",
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
"interface": {
|
|
21
21
|
"displayName": "TaskChef",
|
|
22
22
|
"shortDescription": "Dispatch work to the right Codex project task.",
|
|
23
|
-
"longDescription": "Route
|
|
23
|
+
"longDescription": "Route work to visible Codex project tasks, cache their latest semantic result, and query fresh reports on demand.",
|
|
24
24
|
"developerName": "Favo Yang",
|
|
25
25
|
"category": "Productivity",
|
|
26
26
|
"capabilities": [
|
package/BACKLOG.md
CHANGED
|
@@ -50,7 +50,7 @@ clear data model before implementation.
|
|
|
50
50
|
`resolve_client_thread(clientThreadId) -> { status, threadId? }`. Returning a
|
|
51
51
|
reserved durable ID from `create_thread`, or emitting a materialization event
|
|
52
52
|
containing it, would also close the lifecycle gap.
|
|
53
|
-
- Re-evaluate
|
|
54
|
-
one of these APIs. Keep exact
|
|
55
|
-
|
|
56
|
-
|
|
53
|
+
- Re-evaluate whether the initial-hook identity link and exact-marker manual
|
|
54
|
+
recovery can be simplified when Codex exposes one of these APIs. Keep exact
|
|
55
|
+
correlation verification before persisting the returned durable ID unless
|
|
56
|
+
the official contract provides equivalent guarantees.
|
package/README.md
CHANGED
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
Bring work for all your local Codex projects to one inbox. TaskChef reads each
|
|
4
4
|
request, chooses the right project, and opens a normal Codex task there. It
|
|
5
|
-
keeps a task history
|
|
6
|
-
|
|
5
|
+
keeps a task history plus the executor's latest semantic result so you can find
|
|
6
|
+
the work later. Codex task state remains authoritative for current activity.
|
|
7
7
|
|
|
8
8
|
If a request contains independent work for different projects, TaskChef can
|
|
9
9
|
open several tasks. It returns as soon as they are created, so you can send the
|
|
@@ -28,13 +28,15 @@ request in dispatcher
|
|
|
28
28
|
+-- task entry --> executor in project B
|
|
29
29
|
```
|
|
30
30
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
31
|
+
Executors report a compact `completed`, `needs_input`, or `failed` result into
|
|
32
|
+
their existing task entry. When you ask for a report, TaskChef filters old
|
|
33
|
+
terminal work and checks cheap live metadata once for every selected task.
|
|
34
|
+
Active or approval-waiting metadata overrides the cache immediately; idle MCP
|
|
35
|
+
results are trusted by default, with detailed reads reserved for anomalies. It
|
|
36
|
+
never infers completion from hook events.
|
|
34
37
|
|
|
35
|
-
See [Delegation design](docs/delegation-design.md) for the
|
|
36
|
-
|
|
37
|
-
CLI-versus-MCP latency comparison.
|
|
38
|
+
See [Delegation design](docs/delegation-design.md) for the illustrated workflow,
|
|
39
|
+
writer boundaries, locking, trust model, freshness rules, and follow-up example.
|
|
38
40
|
|
|
39
41
|
## Quickstart
|
|
40
42
|
|
|
@@ -50,6 +52,12 @@ codex plugin marketplace add favoyang/codex-plugins
|
|
|
50
52
|
codex plugin add taskchef@favoyang-plugins
|
|
51
53
|
```
|
|
52
54
|
|
|
55
|
+
In a new Codex task, run `/hooks`, review the TaskChef hook, and trust it. Codex
|
|
56
|
+
skips new or changed plugin hooks until you approve their current definition,
|
|
57
|
+
so repeat this review after an update changes the hook. TaskChef uses this hook
|
|
58
|
+
to link the marked initial executor prompt and to provide read-only current-turn
|
|
59
|
+
identity on later prompts in that same executor. It never writes task outcomes.
|
|
60
|
+
|
|
53
61
|
### 2. Bootstrap the dispatcher workspace
|
|
54
62
|
|
|
55
63
|
Invoke the bootstrap skill from any Codex project:
|
|
@@ -122,21 +130,19 @@ the same project.
|
|
|
122
130
|
Open an executor and prompt it like any other Codex task. Its thread is the
|
|
123
131
|
live source of truth for progress, questions, and results.
|
|
124
132
|
|
|
125
|
-
The dispatcher workspace keeps `tasks.jsonl`,
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
work.
|
|
133
|
+
The dispatcher workspace keeps `tasks.jsonl`, one line per submitted
|
|
134
|
+
delegation. New tasks are appended. Later locked atomic updates may fill the
|
|
135
|
+
nullable thread ID and replace the task's latest status, summary, turn ID,
|
|
136
|
+
timestamp, and writer. There is no transition-event log.
|
|
130
137
|
|
|
131
138
|
Every delegated instruction begins with a unique
|
|
132
139
|
`<!-- taskchef_id=<UUID> -->` marker followed by a blank line, an
|
|
133
|
-
executor-ownership paragraph,
|
|
140
|
+
executor-ownership paragraph, a result-callback paragraph, and the assignment. The
|
|
134
141
|
valid HTML comment stays invisible in rendered Markdown.
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
task, the recorded marker remains available for recovery.
|
|
142
|
+
TaskChef records the marked delegation before executor creation. If creation
|
|
143
|
+
does not return a durable thread ID, the trusted initial-prompt hook receives
|
|
144
|
+
the root session ID and atomically links it to the existing entry. Delegation
|
|
145
|
+
does not wait, poll, list tasks, or retry discovery.
|
|
140
146
|
|
|
141
147
|
### Ask for a live report
|
|
142
148
|
|
|
@@ -146,9 +152,15 @@ Ask the dispatcher when you want a current overview:
|
|
|
146
152
|
Report on the work TaskChef has dispatched.
|
|
147
153
|
```
|
|
148
154
|
|
|
149
|
-
This runs `$taskchef-report`.
|
|
150
|
-
|
|
151
|
-
|
|
155
|
+
This runs `$taskchef-report`. Overviews always consider working, needs-input,
|
|
156
|
+
unresolved, legacy, and terminal tasks changed in the last seven days. Older
|
|
157
|
+
terminal tasks are skipped unless requested or live metadata shows that they
|
|
158
|
+
are active or awaiting approval. Cached MCP results are trusted for idle tasks
|
|
159
|
+
in broad overviews. Active or approval-waiting tasks are reported directly from
|
|
160
|
+
the one broad metadata snapshot. Focused reports read a selected idle task once
|
|
161
|
+
when its metadata is newer than the callback; missing callbacks and other
|
|
162
|
+
anomalies also receive at most one targeted read. Reporting writes nothing and
|
|
163
|
+
never polls.
|
|
152
164
|
|
|
153
165
|
### Manage configured projects
|
|
154
166
|
|
|
@@ -177,17 +189,19 @@ project metadata that TaskChef used when it delegated the work.
|
|
|
177
189
|
|
|
178
190
|
## Important boundaries
|
|
179
191
|
|
|
180
|
-
- TaskChef is an interactive dispatcher
|
|
181
|
-
|
|
182
|
-
-
|
|
183
|
-
|
|
184
|
-
them to finish.
|
|
192
|
+
- TaskChef is an interactive dispatcher, not a scheduler, daemon, or background
|
|
193
|
+
worker. Its single lifecycle hook writes initial executor identity, then only
|
|
194
|
+
provides read-only current-turn context on follow-up prompts.
|
|
195
|
+
- Executors are visible Codex tasks. The dispatcher does not supervise them or
|
|
196
|
+
wait for them to finish.
|
|
185
197
|
- TaskChef routes only to projects on the same local execution host.
|
|
186
|
-
-
|
|
187
|
-
|
|
198
|
+
- Each task line contains the latest reported semantic result, not a complete
|
|
199
|
+
lifecycle or event history.
|
|
188
200
|
- TaskChef does not store executor transcripts, hidden reasoning, or `hostId`.
|
|
189
|
-
- A live report
|
|
190
|
-
|
|
201
|
+
- A live report uses one metadata snapshot for all selected tasks and
|
|
202
|
+
immediately overrides active or approval-waiting state. Broad overviews stay
|
|
203
|
+
cache-first; focused reports read selected idle tasks once when metadata is
|
|
204
|
+
newer than the callback. Reporting never persists inferred live state.
|
|
191
205
|
|
|
192
206
|
## Updating
|
|
193
207
|
|
|
@@ -245,7 +259,9 @@ taskchef task summary
|
|
|
245
259
|
|
|
246
260
|
Workspace resolution is deterministic: `--workspace <path>`, then the
|
|
247
261
|
`TASKCHEF_WORKSPACE` environment variable, then `~/.agents/taskchef`. The
|
|
248
|
-
|
|
262
|
+
environment override must be absolute (or start with `~/`) so plugin processes
|
|
263
|
+
with different working directories resolve the same workspace. The current
|
|
264
|
+
directory is never an implicit workspace. Data commands use concise
|
|
249
265
|
human-readable output by default and accept `--json` for machine-readable
|
|
250
266
|
output. Run `taskchef help` for every option.
|
|
251
267
|
|
|
@@ -345,7 +361,7 @@ The current configuration schema is version 2. Version 1 remains readable:
|
|
|
345
361
|
legacy `githubRepo: null` normalizes to `githubRepos: []`, and a legacy string
|
|
346
362
|
normalizes to a one-item `githubRepos` list. `workspace init` persists this
|
|
347
363
|
migration atomically; other configuration writes also emit version 2. Legacy
|
|
348
|
-
task lines remain readable without an eager rewrite of the
|
|
364
|
+
task lines remain readable without an eager rewrite of the JSONL history.
|
|
349
365
|
|
|
350
366
|
### Task history
|
|
351
367
|
|
|
@@ -353,16 +369,15 @@ task lines remain readable without an eager rewrite of the append-only history.
|
|
|
353
369
|
`project` value is the exact configured project path:
|
|
354
370
|
|
|
355
371
|
```sh
|
|
356
|
-
printf '%s\n' '{"id":"c0f010ff-84f2-4838-a69d-0ff1f5d721d7","project":"/workspace/payments","title":"Add retry logs","instruction":"<!-- taskchef_id=c0f010ff-84f2-4838-a69d-0ff1f5d721d7 -->\n\nThis task owns the delegated assignment. Execute it in this task; do not re-dispatch it merely because it concerns TaskChef or a configured project. Explicit requests to delegate separate work remain valid.\n\nAdd structured logs for failed retries and test them.","threadId":"019f..."}' |
|
|
372
|
+
printf '%s\n' '{"id":"c0f010ff-84f2-4838-a69d-0ff1f5d721d7","project":"/workspace/payments","title":"Add retry logs","instruction":"<!-- taskchef_id=c0f010ff-84f2-4838-a69d-0ff1f5d721d7 -->\n\nThis task owns the delegated assignment. Execute it in this task; do not re-dispatch it merely because it concerns TaskChef or a configured project. Explicit requests to delegate separate work remain valid.\n\nBefore ending, call the TaskChef report_result MCP tool with completed, needs_input, or failed and a concise summary. Use needs_input only for a semantic decision or information the user must provide; a native approval prompt is live Codex state, not a TaskChef result. Do not include secrets, transcripts, or raw command output.\n\nAdd structured logs for failed retries and test them.","threadId":"019f..."}' |
|
|
357
373
|
taskchef task record --json
|
|
358
374
|
```
|
|
359
375
|
|
|
360
|
-
If a task has `threadId: null`,
|
|
361
|
-
marker
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
one-way transition from null to one unique thread ID:
|
|
376
|
+
If a task has `threadId: null`, the initial plugin hook normally resolves its
|
|
377
|
+
exact marker to the root session ID. Direct manual recovery may use the
|
|
378
|
+
equivalent CLI operation below after verifying one exact structured marker
|
|
379
|
+
match. Both hook and CLI reach the same locked atomic logic, which permits only
|
|
380
|
+
the one-way transition from null to one unique thread ID:
|
|
366
381
|
|
|
367
382
|
```sh
|
|
368
383
|
taskchef task resolve c0f010ff-84f2-4838-a69d-0ff1f5d721d7 \
|
|
@@ -392,8 +407,8 @@ the complete values in `--json` output, and the selected order applies to its
|
|
|
392
407
|
`task show` accepts either the full task ID or the exact eight-character task
|
|
393
408
|
ID printed by the default human-readable list. A short ID must identify exactly
|
|
394
409
|
one recorded task; use `task list --full-id` when a short ID is missing or
|
|
395
|
-
ambiguous. Its default output labels the title, project
|
|
396
|
-
|
|
410
|
+
ambiguous. Its default output labels the title, project, latest result fields,
|
|
411
|
+
creation and update times, task/thread/turn IDs, and instruction. A null thread ID appears as
|
|
397
412
|
`-`. Line breaks in labeled values are escaped as `\\r` and `\\n`, while
|
|
398
413
|
multiline instructions retain their original line breaks and indentation. Pass
|
|
399
414
|
`--json` to receive the unchanged complete task object.
|
|
@@ -401,32 +416,50 @@ multiline instructions retain their original line breaks and indentation. Pass
|
|
|
401
416
|
```text
|
|
402
417
|
Title: Add retry logs
|
|
403
418
|
Project: payments
|
|
419
|
+
Status: completed
|
|
420
|
+
Summary: Added structured retry logs and regression coverage.
|
|
404
421
|
Project path: /workspace/payments
|
|
405
422
|
Created: 2026-08-12T10:00:00.000Z
|
|
423
|
+
Updated: 2026-08-12T10:08:00.000Z
|
|
424
|
+
Updated by: mcp
|
|
406
425
|
Task ID: c0f010ff-84f2-4838-a69d-0ff1f5d721d7
|
|
407
426
|
Thread ID: 019f9d46-f42c-7482-9707-3c107bf241ee
|
|
427
|
+
Turn ID: 019f9d47-result-turn
|
|
408
428
|
Instruction:
|
|
409
429
|
<!-- taskchef_id=c0f010ff-84f2-4838-a69d-0ff1f5d721d7 -->
|
|
410
430
|
|
|
411
431
|
This task owns the delegated assignment. Execute it in this task; do not re-dispatch it merely because it concerns TaskChef or a configured project. Explicit requests to delegate separate work remain valid.
|
|
412
432
|
|
|
433
|
+
Before ending, call the TaskChef report_result MCP tool with completed, needs_input, or failed and a concise summary. Use needs_input only for a semantic decision or information the user must provide; a native approval prompt is live Codex state, not a TaskChef result. Do not include secrets, transcripts, or raw command output.
|
|
434
|
+
|
|
413
435
|
Add structured logs for failed payment retries and test them.
|
|
414
436
|
```
|
|
415
437
|
|
|
416
438
|
The list remains a compact table:
|
|
417
439
|
|
|
418
440
|
```text
|
|
419
|
-
TITLE PROJECT
|
|
420
|
-
Add retry logs payments 2026-08-12T10:
|
|
441
|
+
TITLE PROJECT STATUS UPDATED ID THREAD ID
|
|
442
|
+
Add retry logs payments completed 2026-08-12T10:08:00.000Z c0f010ff 019f9d46
|
|
421
443
|
```
|
|
422
444
|
|
|
423
445
|
The complete data contract is in [SPEC.md](SPEC.md). The illustrated runtime
|
|
424
|
-
workflow and
|
|
446
|
+
workflow, writer boundaries, and freshness rules are in
|
|
425
447
|
[Delegation design](docs/delegation-design.md). Deferred ideas are in
|
|
426
448
|
[BACKLOG.md](BACKLOG.md).
|
|
427
449
|
|
|
428
450
|
## Development and release
|
|
429
451
|
|
|
452
|
+
This result-callback redesign changes the public
|
|
453
|
+
`createAndRecordDelegation` contract from post-creation thread discovery to
|
|
454
|
+
record-before-create plus hook resolution. Release it as a new major version.
|
|
455
|
+
Library callers migrating from TaskChef 5.x should remove `listThreads`,
|
|
456
|
+
`readThread`, checkpoint, and timeout arguments; provide `recordTask` before
|
|
457
|
+
creation and optional `resolveRecordedTask` and `reportRecordedResult`
|
|
458
|
+
callbacks instead. The old pure thread-inspection exports remain temporarily
|
|
459
|
+
available as deprecated compatibility helpers, but TaskChef no longer calls
|
|
460
|
+
them. Creation errors expose `taskChefTaskId` and `taskChefResultReporting` so
|
|
461
|
+
library callers can recover a record when the failure callback was unavailable.
|
|
462
|
+
|
|
430
463
|
```sh
|
|
431
464
|
npm test
|
|
432
465
|
npm pack --dry-run
|
package/SPEC.md
CHANGED
|
@@ -4,11 +4,11 @@
|
|
|
4
4
|
|
|
5
5
|
TaskChef is an interactive Codex dispatcher. It routes independent assignments
|
|
6
6
|
to real Codex tasks in configured local projects, records each submitted
|
|
7
|
-
delegation in a task history, and returns immediately. New tasks append;
|
|
8
|
-
|
|
7
|
+
delegation in a task history, and returns immediately. New tasks append; locked
|
|
8
|
+
atomic updates may later resolve identity and replace the latest semantic result.
|
|
9
9
|
|
|
10
|
-
Codex tasks remain authoritative for
|
|
11
|
-
not
|
|
10
|
+
Codex tasks remain authoritative for current activity. TaskChef stores only the
|
|
11
|
+
latest useful semantic result, not a second lifecycle or event database.
|
|
12
12
|
|
|
13
13
|
## Core behavior
|
|
14
14
|
|
|
@@ -19,14 +19,15 @@ not maintain a second lifecycle database.
|
|
|
19
19
|
2. TaskChef separates only outcomes that can proceed independently.
|
|
20
20
|
3. It selects each target using configured project metadata and validates the
|
|
21
21
|
selected local path.
|
|
22
|
-
4. It
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
22
|
+
4. It embeds a generated TaskChef UUID marker, executor-ownership sentence, and
|
|
23
|
+
result-callback instruction, then records the task with `threadId: null`.
|
|
24
|
+
5. It creates an independently openable Codex task. A durable returned ID is
|
|
25
|
+
resolved immediately; otherwise the initial-prompt hook links the root
|
|
26
|
+
session ID without polling.
|
|
27
27
|
6. It returns without waiting for executor work to complete.
|
|
28
|
-
7.
|
|
29
|
-
|
|
28
|
+
7. Executors report `completed`, `needs_input`, or `failed` through MCP. Reports
|
|
29
|
+
filter old terminal entries, use one live metadata snapshot, and read only
|
|
30
|
+
tasks whose cached result may be stale.
|
|
30
31
|
|
|
31
32
|
A task created by TaskChef owns its delegated initial assignment. It executes
|
|
32
33
|
that assignment in the current task and does not re-dispatch it merely because
|
|
@@ -60,7 +61,10 @@ Every command resolves one workspace in this precedence order:
|
|
|
60
61
|
2. `TASKCHEF_WORKSPACE`
|
|
61
62
|
3. `~/.agents/taskchef`
|
|
62
63
|
|
|
63
|
-
|
|
64
|
+
`TASKCHEF_WORKSPACE` must be absolute or start with `~/`; this prevents the
|
|
65
|
+
hook, MCP server, and CLI from resolving one relative override against
|
|
66
|
+
different process directories. The current directory is never an implicit
|
|
67
|
+
workspace. `workspace path` exposes
|
|
64
68
|
the resolved absolute path and its source. Bootstrap compares this canonical
|
|
65
69
|
path with native Codex projects, and when absent invokes the validated
|
|
66
70
|
`codex app <path>` command before verifying the native list again. It never
|
|
@@ -136,14 +140,14 @@ legacy `null` to `[]`; `workspace init` persists the migration atomically, and
|
|
|
136
140
|
any later configuration write emits version 2.
|
|
137
141
|
|
|
138
142
|
The configuration does not store dispatcher identity, execution modes,
|
|
139
|
-
schedules, task
|
|
143
|
+
schedules, task state, host information, or the workspace path.
|
|
140
144
|
|
|
141
145
|
## Task entry
|
|
142
146
|
|
|
143
147
|
`tasks.jsonl` contains one compact JSON object per line, in append order:
|
|
144
148
|
|
|
145
149
|
```json
|
|
146
|
-
{"schemaVersion":
|
|
150
|
+
{"schemaVersion":3,"id":"c0f010ff-84f2-4838-a69d-0ff1f5d721d7","project":{"name":"payments-api","path":"/workspace/payments-api","isGitRepository":true,"githubRepos":["https://github.com/example/payments-api","https://github.com/example/payments-sdk"],"description":"Owns payment authorization, capture, refunds, and provider integrations."},"title":"Add payment retry logs","instruction":"<!-- taskchef_id=c0f010ff-84f2-4838-a69d-0ff1f5d721d7 -->\n\nThis task owns the delegated assignment. Execute it in this task; do not re-dispatch it merely because it concerns TaskChef or a configured project. Explicit requests to delegate separate work remain valid.\n\nBefore ending, call the TaskChef report_result MCP tool with completed, needs_input, or failed and a concise summary. Use needs_input only for a semantic decision or information the user must provide; a native approval prompt is live Codex state, not a TaskChef result. Do not include secrets, transcripts, or raw command output.\n\nAdd structured logs for failed payment retries and test them.","threadId":"019f9d46-f42c-7482-9707-3c107bf241ee","createdAt":"2026-08-08T10:00:00.000Z","status":"completed","summary":"Added structured retry logs and regression coverage.","turnId":"019f9d47-result-turn","updatedAt":"2026-08-08T10:08:00.000Z","updatedBy":"mcp"}
|
|
147
151
|
```
|
|
148
152
|
|
|
149
153
|
- `schemaVersion` identifies the task entry format.
|
|
@@ -154,28 +158,38 @@ schedules, task status, results, host information, or the workspace path.
|
|
|
154
158
|
`<!-- taskchef_id=<full UUID> -->` correlation marker, executor-ownership
|
|
155
159
|
paragraph, and assignment body.
|
|
156
160
|
- `threadId` identifies the created Codex task, or is `null` when creation was
|
|
157
|
-
accepted but
|
|
161
|
+
accepted but its initial identity has not yet been linked.
|
|
158
162
|
- `createdAt` is the dispatch time as an ISO 8601 timestamp.
|
|
159
|
-
|
|
160
|
-
|
|
163
|
+
- `status` is `working`, `needs_input`, `completed`, or `failed`; legacy
|
|
164
|
+
entries normalize it to `null`.
|
|
165
|
+
- `summary` is a nullable, bounded latest-result summary.
|
|
166
|
+
- `turnId` identifies the initial hook turn or latest reported result turn. An
|
|
167
|
+
MCP result for a linked executor requires it; null is allowed only for a
|
|
168
|
+
failed creation before any durable thread exists.
|
|
169
|
+
- `updatedAt` is the server-side update time.
|
|
170
|
+
- `updatedBy` is `dispatcher`, `hook`, or `mcp`.
|
|
171
|
+
|
|
172
|
+
Schema-version-3 entries have exactly these fields. IDs and non-null thread IDs must be
|
|
161
173
|
unique; any number of unresolved entries may have `threadId: null`. The file is
|
|
162
174
|
empty or newline terminated, with no blank lines. TaskChef rejects a malformed
|
|
163
175
|
log instead of skipping bad entries. Writers replace the complete validated
|
|
164
176
|
file atomically under a workspace lock, so an interrupted write leaves either
|
|
165
177
|
the old history or the complete new history.
|
|
166
178
|
|
|
167
|
-
Task creation appends entries.
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
179
|
+
Task creation appends entries. Identity resolution and result callbacks acquire
|
|
180
|
+
the same cross-process lock, reread and validate the complete log, patch one
|
|
181
|
+
matching entry, and atomically replace the file. Resolution is idempotent and
|
|
182
|
+
one-way from null to one unique durable thread ID. Result callbacks must match
|
|
183
|
+
the recorded task/thread and replace only the latest result snapshot; they do
|
|
184
|
+
not append events.
|
|
171
185
|
|
|
172
186
|
The project snapshot preserves the route even if the project is renamed,
|
|
173
|
-
moved, or removed later. Entries never contain
|
|
174
|
-
|
|
187
|
+
moved, or removed later. Entries never contain transcripts, hidden reasoning,
|
|
188
|
+
`hostId`, or an event history.
|
|
175
189
|
|
|
176
|
-
New task entries use schema version
|
|
177
|
-
|
|
178
|
-
|
|
190
|
+
New task entries use schema version 3. Version 1 and 2 entries remain readable
|
|
191
|
+
and normalize to version 3 in API and CLI output with nullable result fields.
|
|
192
|
+
Historical task entries with the
|
|
179
193
|
old heading-style marker also remain readable. New nullable records, candidate
|
|
180
194
|
matching, and resolution require the exact HTML-comment marker; TaskChef never
|
|
181
195
|
uses an old marker to correlate a thread. Direct records that already have a
|
|
@@ -197,49 +211,29 @@ For each assignment, `$taskchef-delegate`:
|
|
|
197
211
|
the already-loaded native projects
|
|
198
212
|
3. prefixes the instruction with the prepared exact
|
|
199
213
|
`<!-- taskchef_id=<UUID> -->` marker as the first line, followed by a blank
|
|
200
|
-
line, the executor-ownership sentence,
|
|
214
|
+
line, the executor-ownership sentence, result-callback sentence, and
|
|
201
215
|
assignment body
|
|
202
|
-
4.
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
serial reads
|
|
220
|
-
8. atomically fills the nullable thread ID with `resolve_task` after an exact
|
|
221
|
-
match
|
|
222
|
-
9. returns after recording or after reporting that bounded resolution was
|
|
223
|
-
unresolved, without waiting for executor work completion.
|
|
224
|
-
|
|
225
|
-
The exact random marker remains the sole correlation proof. Creation-time
|
|
226
|
-
filtering allows five seconds of clock skew. Candidate reads use exactly one
|
|
227
|
-
programmatic batch per snapshot and inspect only
|
|
228
|
-
structured `codexDelegation.input`, never untrusted title, summary, preview, or
|
|
229
|
-
plain-text marker echoes. Zero exact matches remain unresolved; multiple exact
|
|
230
|
-
matches are ambiguous. Snapshot, candidate-read, or task-resolution errors
|
|
231
|
-
leave the already-recorded nullable entry intact. The workflow is bounded by
|
|
232
|
-
two snapshots rather than an absolute wall-clock cutoff:
|
|
233
|
-
mandatory recording or tool latency can shift both attempts later, but cannot
|
|
234
|
-
erase an attempt or reduce the minimum 20-second interval between their start
|
|
235
|
-
times.
|
|
236
|
-
A `clientThreadId`, `pendingWorktreeId`, or ID in the documented provisional
|
|
237
|
-
`local:` namespace remains diagnostic context and is rejected from every path
|
|
238
|
-
that could persist the canonical `threadId` field.
|
|
216
|
+
4. appends a `working` task entry with `threadId: null` through `record_task`
|
|
217
|
+
before executor creation
|
|
218
|
+
5. creates a real Codex task at the exact configured path
|
|
219
|
+
6. calls `resolve_task` when creation returns a durable thread ID; otherwise it
|
|
220
|
+
returns immediately and the initial `UserPromptSubmit` hook resolves the root
|
|
221
|
+
session ID against the exact marker
|
|
222
|
+
7. records executor-creation failure as a `failed` semantic result on the
|
|
223
|
+
already-existing entry
|
|
224
|
+
8. never lists, reads, waits for, or polls threads during delegation.
|
|
225
|
+
|
|
226
|
+
Recording first closes the creation/hook race. On the exact marked prompt, the
|
|
227
|
+
hook receives the root session ID and initial turn ID and writes only identity
|
|
228
|
+
plus `working`. On later prompts whose session ID matches a recorded executor,
|
|
229
|
+
the same `UserPromptSubmit` hook reads the task history and supplies the current
|
|
230
|
+
turn ID as callback context without writing. No permission, tool, stop,
|
|
231
|
+
notification, or session hook writes task lifecycle state. A provisional
|
|
232
|
+
`local:` ID is diagnostic only and can never be persisted as `threadId`.
|
|
239
233
|
|
|
240
234
|
The plugin bundles a local stdio MCP server with focused `prepare_dispatch`,
|
|
241
|
-
`record_task`, and `
|
|
242
|
-
model and resolves only `TASKCHEF_WORKSPACE` or the canonical
|
|
235
|
+
`record_task`, `resolve_task`, and `report_result` tools. It accepts no workspace path from the
|
|
236
|
+
model and resolves only an absolute (or `~/`-prefixed) `TASKCHEF_WORKSPACE` or the canonical
|
|
243
237
|
`~/.agents/taskchef` default. The write tools reuse the public workspace APIs,
|
|
244
238
|
so structured calls cannot bypass exact-field validation, locking, atomic
|
|
245
239
|
replacement, unique IDs, or one-way nullable resolution. They are closed-world
|
|
@@ -247,7 +241,11 @@ local mutations and never create Codex tasks. Desktop thread tools remain
|
|
|
247
241
|
available only to the Codex skill; the standalone CLI remains available for
|
|
248
242
|
bootstrap, manual inspection, and recovery.
|
|
249
243
|
|
|
250
|
-
###
|
|
244
|
+
### Legacy end-to-end benchmark results
|
|
245
|
+
|
|
246
|
+
Schema-v1 benchmark fixtures below validate historical bounded-resolver
|
|
247
|
+
artifacts only. New benchmarks must measure record-before-create, initial-hook
|
|
248
|
+
identity, and result callbacks without using the removed snapshot resolver.
|
|
251
249
|
|
|
252
250
|
An explicitly requested live benchmark writes one ignored, timestamped JSON
|
|
253
251
|
artifact through `scripts/e2e-benchmark.js`. Schema version 1 contains:
|
|
@@ -298,17 +296,20 @@ up to seven seconds, while permanent permission failures such as `EPERM` or
|
|
|
298
296
|
`EACCES` fail immediately so the caller can request the required permission
|
|
299
297
|
without paying the contention retry budget.
|
|
300
298
|
|
|
301
|
-
A failed executor creation
|
|
302
|
-
|
|
303
|
-
|
|
299
|
+
A failed executor creation normally leaves its pre-created entry with `failed`.
|
|
300
|
+
The exported orchestration helper attaches `taskChefTaskId` and
|
|
301
|
+
`taskChefResultReporting` (`recorded`, `failed`, or `unavailable`) to a thrown
|
|
302
|
+
creation error so callers can recover the entry if failure reporting itself was
|
|
303
|
+
not available. A failed pre-creation record stops before executor creation, so
|
|
304
|
+
there is no untracked executor.
|
|
304
305
|
|
|
305
306
|
## Task history and live reports
|
|
306
307
|
|
|
307
308
|
The CLI reads persisted history without contacting Codex:
|
|
308
309
|
|
|
309
310
|
- `task show <id-or-8-character-prefix>` returns one entry. By default it emits
|
|
310
|
-
labeled human-readable lines for title, project
|
|
311
|
-
|
|
311
|
+
labeled human-readable lines for title, project, status, summary, creation and
|
|
312
|
+
update metadata, task/thread/turn IDs, and instruction. A null ID renders as `-`.
|
|
312
313
|
Carriage returns and newlines in labeled values render as `\\r` and `\\n`.
|
|
313
314
|
The instruction starts on the line after `Instruction:` and retains its stored
|
|
314
315
|
line breaks and indentation. `--json` returns the unchanged complete task
|
|
@@ -318,7 +319,7 @@ The CLI reads persisted history without contacting Codex:
|
|
|
318
319
|
wrong-case prefixes fail without selecting a task.
|
|
319
320
|
- `task list` returns entries newest-first by creation time, optionally filtered
|
|
320
321
|
by historical project name or exact path. `--ascending` returns oldest-first.
|
|
321
|
-
Human rows include task and thread ID
|
|
322
|
+
Human rows include status, update time, task ID, and thread ID, abbreviating UUID-shaped IDs
|
|
322
323
|
to their first eight-character section unless `--full-id` is passed. Null
|
|
323
324
|
thread IDs display as `-`. ID formatting does not alter JSON values, and the
|
|
324
325
|
selected order applies to both human rows and the JSON `tasks` array.
|
|
@@ -326,20 +327,35 @@ The CLI reads persisted history without contacting Codex:
|
|
|
326
327
|
- `task resolve <id> --thread-id <thread-id>` atomically fills one nullable
|
|
327
328
|
thread ID after Codex verifies the exact structured marker match.
|
|
328
329
|
|
|
329
|
-
When the user requests
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
330
|
+
When the user requests an overview, `$taskchef-report` includes working,
|
|
331
|
+
needs-input, unresolved, legacy, and terminal tasks updated during the last
|
|
332
|
+
seven days. It omits older terminal entries unless explicitly requested or a
|
|
333
|
+
single recent-thread metadata snapshot shows that they are active or awaiting
|
|
334
|
+
approval. That one snapshot is a broad contradiction check: active or awaiting-
|
|
335
|
+
approval metadata overrides a cached result immediately, without one detailed
|
|
336
|
+
read per task. An inactive state does not prove semantic completion; in a broad
|
|
337
|
+
overview it permits an `updatedBy: mcp` result to stand by default.
|
|
338
|
+
Dispatcher- or hook-written `working` snapshots have no semantic callback and
|
|
339
|
+
trigger a live read when selected; an inactive task without an MCP callback has
|
|
340
|
+
an unknown outcome. An MCP-written `failed` snapshot with null thread/turn IDs
|
|
341
|
+
is a fresh executor-creation failure and requires no live lookup. For a focused
|
|
342
|
+
task, title, or project report, any newer matched metadata timestamp triggers at
|
|
343
|
+
most one targeted read per selected inactive task. This distinguishes normal
|
|
344
|
+
same-turn finalization from a quick newer turn by comparing structured turn IDs
|
|
345
|
+
and native turn state. Missing callbacks, uncertain or contradictory identity
|
|
346
|
+
or metadata, and explicitly fully-live requests also trigger one targeted read.
|
|
347
|
+
Reads are batched in groups of eight. Broad overviews do not fan out reads over
|
|
348
|
+
idle terminal tasks solely because their timestamps are newer. Reporting never
|
|
349
|
+
persists inferred live state and does not poll, wait, or schedule work.
|
|
335
350
|
|
|
336
351
|
## Boundaries
|
|
337
352
|
|
|
338
353
|
TaskChef does not include:
|
|
339
354
|
|
|
340
|
-
- lifecycle
|
|
341
|
-
-
|
|
342
|
-
-
|
|
355
|
+
- lifecycle event history or hook-inferred completion
|
|
356
|
+
- lifecycle event types beyond `UserPromptSubmit`
|
|
357
|
+
- indefinite polling, daemons, heartbeats, dispatcher wakeups, or schedules
|
|
358
|
+
- arbitrary Codex task discovery
|
|
343
359
|
- remote hosts or `hostId` storage
|
|
344
360
|
- transcript or hidden-reasoning collection
|
|
345
361
|
- one-active-task-per-project restrictions
|
|
@@ -351,15 +367,16 @@ TaskChef does not include:
|
|
|
351
367
|
1. Bootstrap creates `AGENTS.md`, `taskchef.json`, and `tasks.jsonl`, then
|
|
352
368
|
remains idempotent.
|
|
353
369
|
2. Project metadata routes an unambiguous request to the correct local project.
|
|
354
|
-
3. A
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
thread ID; zero or multiple matches record `threadId: null` for later
|
|
358
|
-
recovery.
|
|
370
|
+
3. A delegation records `working` before creating a visible Codex task.
|
|
371
|
+
4. A durable creation resolves immediately; a provisional creation is linked
|
|
372
|
+
by the initial exact-marker hook without polling.
|
|
359
373
|
5. The dispatcher returns without waiting for execution.
|
|
360
374
|
6. Several independent assignments can create several entries, including
|
|
361
375
|
multiple entries for the same project.
|
|
362
376
|
7. Task history commands return deterministic entries and project counts.
|
|
363
|
-
8.
|
|
364
|
-
9.
|
|
377
|
+
8. MCP callbacks replace the latest needs-input, completed, or failed snapshot.
|
|
378
|
+
9. A report skips old terminal tasks by default, checks live metadata once,
|
|
379
|
+
overrides active or approval-waiting tasks directly, and reads only anomalous
|
|
380
|
+
candidates without writing inferred state.
|
|
381
|
+
10. Malformed JSONL, duplicate IDs, duplicate thread IDs, and symlinked managed
|
|
365
382
|
files fail safely.
|