taskchef 6.1.3 → 7.1.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/SPEC.md DELETED
@@ -1,107 +0,0 @@
1
- # TaskChef specification
2
-
3
- ## Purpose
4
-
5
- TaskChef routes work from a data-only dispatcher workspace to visible Codex
6
- project tasks, stores exact child links, and caches explicit semantic results.
7
-
8
- ## Workspace
9
-
10
- The canonical workspace contains only:
11
-
12
- - `AGENTS.md`: managed dispatcher instructions plus user instructions.
13
- - `taskchef.json`: schema-versioned configured projects.
14
- - `tasks.jsonl`: append-on-create, atomic-rewrite-on-update task snapshots.
15
-
16
- All workspace writes use one lock and atomic replacement. Task IDs and non-null
17
- thread IDs are globally unique.
18
-
19
- ## Task schema
20
-
21
- New records use schema version 4 and contain:
22
-
23
- - immutable `id`, project snapshot, title, instruction, and `createdAt`;
24
- - nullable `threadId` until executor self-linking succeeds;
25
- - `status`, nullable bounded `summary`, nullable `turnId`, `updatedAt`, and
26
- `updatedBy`.
27
-
28
- New unresolved records require the exact first-line HTML marker followed by a
29
- blank line. Schema 1-3 records and historical `updatedBy: hook` values remain
30
- readable without eager migration, and task read/list APIs expose their persisted
31
- schema version so reporting can distinguish legacy recovery from schema 4
32
- executor link-pending state.
33
-
34
- ## Dispatch workflow
35
-
36
- 1. `prepare_dispatch` validates the workspace and returns one fresh lowercase
37
- UUID, exact marker, timestamp, and routing targets.
38
- 2. The marked instruction contains the executor ownership paragraph, mandatory
39
- first-action `link_task` paragraph, result callback paragraph, and task body.
40
- 3. `record_task` writes schema 4 with `threadId: null` before creation.
41
- 4. Native task creation runs once.
42
- 5. The dispatcher returns immediately, including for a provisional worktree
43
- client ID. It does not list or read tasks, search markers, wait, poll, or
44
- link the record.
45
- 6. Creation failure writes a terminal `failed` result with null identities and
46
- a concise bounded summary.
47
-
48
- ## Executor self-linking
49
-
50
- The executor obtains its own durable native thread ID and calls
51
- `link_task(taskId, threadId)` before substantive work. The operation:
52
-
53
- - accepts only schema 4 records;
54
- - rejects unknown task IDs, malformed/provisional IDs, exact-marker mismatch,
55
- thread reuse, and conflicting retries;
56
- - atomically changes only `null` to one durable ID under the workspace lock;
57
- - is idempotent for the same task and ID;
58
- - leaves rejected, unavailable, interrupted, or cancelled links visibly
59
- pending and retryable.
60
-
61
- The executor must never use a parent/delegator ID, inherited session identity,
62
- title match, or provisional client ID. This is a cooperative local assertion,
63
- not transport-authenticated caller identity.
64
-
65
- ## Semantic results
66
-
67
- `report_result` accepts `completed`, `needs_input`, or `failed` with a concise
68
- summary. Linked tasks require an exact stored thread-ID match and a non-null
69
- current turn ID. Self-linked schema 4 journeys require canonical, time-ordered
70
- Codex UUID turn IDs; each changed semantic result must use an ID newer than the
71
- stored turn, while an identical same-turn retry is idempotent. Creation failure
72
- is the sole null-identity result. Follow-up turns must self-read the exact
73
- thread and submit the new turn ID. Atomic writes preserve one JSONL line per
74
- task.
75
-
76
- ## Legacy resolver
77
-
78
- The CLI-only `taskchef task resolve` command accepts unresolved schema 1-3
79
- records after an operator establishes one exact marker match. It rejects schema
80
- 4 records. There is no public `resolve_task` MCP tool.
81
-
82
- ## Dashboard and reports
83
-
84
- The existing file watcher observes `link_task` and result rewrites in real
85
- time. "Open task in Codex" uses only the self-linked child ID. Reports treat
86
- `updatedBy: mcp` terminal or needs-input snapshots as semantic cache and may
87
- compare them with one native metadata snapshot. Reporting never mutates task
88
- history or infers completion from hooks.
89
-
90
- ## Packaging
91
-
92
- The plugin ships its skills, MCP server, CLI, dashboard, and source modules. It
93
- contains no hooks configuration, hook executable, hook runtime, or hook trust
94
- requirement.
95
-
96
- ## Acceptance
97
-
98
- - Record-before-create and exact-marker guarantees remain mandatory.
99
- - Creation returns without post-create waiting, polling, task search, or reads.
100
- - A provisional-path executor self-links its exact durable child ID before
101
- substantive work.
102
- - Parent/delegator and provisional IDs cannot be accidentally substituted.
103
- - Link and result retries are idempotent; conflicts cannot corrupt JSONL.
104
- - Link failures remain visible and retryable; creation failures are terminal.
105
- - Current-turn freshness is retained across needs-input, follow-up, and final
106
- completion.
107
- - The plugin installs and runs without hook configuration or approval.
@@ -1,227 +0,0 @@
1
- # Delegation and result design
2
-
3
- TaskChef stores a durable local task history while Codex owns execution. The
4
- dispatcher records intent, the executor registers its own identity, and only
5
- the executor reports semantic outcomes.
6
-
7
- ## Key terminology
8
-
9
- The central identity rule is: **the executor child links itself**. The
10
- dispatcher may create the child, but it never treats its own thread, a parent
11
- thread, or a provisional creation handle as the executor's durable identity.
12
-
13
- | Term | Meaning |
14
- | --- | --- |
15
- | TaskChef task ID | Stable UUID allocated by `prepare_dispatch`; it identifies the durable TaskChef record. |
16
- | Exact marker | First-line correlation marker copied into the executor instruction; it binds that instruction to the pre-recorded TaskChef task. |
17
- | Source or parent thread ID | The dispatcher/delegator context; never valid as the executor identity. |
18
- | Executor thread ID | The child's own durable `CODEX_THREAD_ID`; the executor supplies it to `link_task`. |
19
- | Provisional client thread ID | Temporary native creation handle; useful for creation UI, but never identity authority. |
20
- | Turn ID | Current native turn UUIDv7 read from the exact executor thread; it proves result freshness. |
21
- | `tasks.jsonl` | Durable append/rewrite history whose latest snapshot is shown by TaskChef. |
22
-
23
- The diagrams below are intentionally small. Calls into **TaskChef MCP** name
24
- the MCP function being invoked. Notes beside `tasks.jsonl` name the fields that
25
- step populates or replaces.
26
-
27
- ## Workflow 1: Prepare and record intent
28
-
29
- The dispatcher first asks TaskChef to allocate routing and correlation values.
30
- `prepare_dispatch` does not write a record. The dispatcher then embeds the exact
31
- marker in the instruction and calls `record_task` **before** native creation, so
32
- an executor can self-link as soon as its first turn starts.
33
-
34
- ```mermaid
35
- sequenceDiagram
36
- autonumber
37
- actor U as User
38
- participant D as Dispatcher
39
- participant M as TaskChef MCP
40
- participant W as tasks.jsonl
41
-
42
- U->>D: Delegation request
43
- D->>M: prepare_dispatch()
44
- M-->>D: taskId, marker, preparedAt, projects
45
- Note over D,M: Allocate identity and routing only#59; no record written
46
- D->>M: record_task(id, project, title, marked instruction, threadId=null)
47
- M->>W: Append schema 4 snapshot
48
- Note right of W: id, project, title, instruction, createdAt<br>threadId=null, status=working, summary=null, turnId=null<br>updatedAt=createdAt, updatedBy=dispatcher
49
- M-->>D: Recorded task snapshot
50
- ```
51
-
52
- ## Workflow 2: Create and self-link the executor
53
-
54
- After recording, the dispatcher creates the native Codex task and returns
55
- immediately. A durable or provisional ID returned to the dispatcher is not
56
- trusted as executor identity. The child reads its own `CODEX_THREAD_ID` and
57
- uses `link_task` as its first TaskChef action.
58
-
59
- The exact marker correlates the child instruction with the pre-created record.
60
- `link_task` atomically permits one `null`-to-durable transition, rejects a
61
- malformed or reused ID, and makes the dashboard deep link target the child—not
62
- the source, parent, or dispatcher thread.
63
-
64
- ```mermaid
65
- sequenceDiagram
66
- autonumber
67
- actor U as User
68
- participant D as Dispatcher
69
- participant C as Codex native tasks
70
- participant E as Executor child
71
- participant M as TaskChef MCP
72
- participant W as tasks.jsonl
73
- participant V as Dashboard
74
-
75
- D->>C: Create task with marked instruction
76
- C-->>D: Durable threadId or provisional clientThreadId
77
- Note over D,C: Creation result is not executor identity authority
78
- D-->>U: Created-task directive#59; dispatcher returns immediately
79
- C->>E: Start initial executor turn
80
- E->>E: Read own CODEX_THREAD_ID
81
- E->>M: link_task(taskId, child threadId)
82
- M->>W: Atomic identity registration
83
- Note right of W: Set threadId=child UUIDv7<br>Set updatedAt and updatedBy=mcp<br>Keep status=working, summary=null, turnId=null
84
- M-->>E: Self-linked task snapshot
85
- W-->>V: Filesystem watcher refresh
86
- Note right of V: Deep link targets the exact executor child
87
- ```
88
-
89
- ## Workflow 3: Report the current turn
90
-
91
- Before ending with a semantic outcome, the executor reads its exact native
92
- thread and obtains that turn's current UUIDv7. It then calls `report_result`
93
- with its matching self-linked thread ID. The status is `completed`, `failed`,
94
- or `needs_input`; the summary is concise and bounded.
95
-
96
- Changed results must use a strictly newer turn ID. An identical same-turn retry
97
- is idempotent, but reusing an old turn ID for a changed result cannot establish
98
- freshness.
99
-
100
- ```mermaid
101
- sequenceDiagram
102
- autonumber
103
- participant E as Executor child
104
- participant C as Codex native tasks
105
- participant M as TaskChef MCP
106
- participant W as tasks.jsonl
107
- participant V as Dashboard
108
-
109
- E->>C: Exact read of this executor thread
110
- C-->>E: Current turnId UUIDv7
111
- E->>M: report_result(taskId, threadId, turnId, status, summary)
112
- M->>W: Store semantic result
113
- Note right of W: Replace status, summary, turnId<br>Set updatedAt and updatedBy=mcp
114
- M-->>E: Updated task snapshot
115
- W-->>V: Filesystem watcher refresh
116
- ```
117
-
118
- ## Workflow 4: Resume after `needs_input`
119
-
120
- `needs_input` is a semantic pause, not a native approval prompt. After the user
121
- responds or resumes the task, the executor reads the exact task again. The new
122
- turn ID, rather than the initial one, accompanies the updated result.
123
-
124
- ```mermaid
125
- sequenceDiagram
126
- autonumber
127
- actor U as User
128
- participant E as Executor child
129
- participant C as Codex native tasks
130
- participant M as TaskChef MCP
131
- participant W as tasks.jsonl
132
- participant V as Dashboard
133
-
134
- E-->>U: Request decision or information
135
- U->>E: Follow up or resume
136
- E->>C: Exact native read after follow-up
137
- C-->>E: Newer current turnId UUIDv7
138
- E->>M: report_result(taskId, threadId, newer turnId, completed, summary)
139
- M->>W: Replace latest semantic result
140
- Note right of W: status=completed, new summary, newer turnId<br>updatedAt refreshed, updatedBy=mcp
141
- M-->>E: Completed task snapshot
142
- W-->>V: Filesystem watcher refresh
143
- ```
144
-
145
- ## Workflow 5: Creation and linking failures
146
-
147
- Because `record_task` happens first, native creation failure remains visible:
148
- the dispatcher reports one terminal failure while both identity fields stay
149
- null. The dispatcher makes exactly one native creation call and never retries
150
- it. TaskChef never guesses an executor identity from recent tasks, titles,
151
- transcripts, or dashboard activity.
152
-
153
- For linking, outcome depends on where interruption occurs. Before commit, an
154
- eligible record remains link-pending. If the atomic write commits but its reply
155
- is lost, the record is already linked and an identical retry returns that
156
- snapshot. Inspect rejections before retrying; identity conflicts and terminal
157
- records must not be blindly retried.
158
-
159
- ```mermaid
160
- sequenceDiagram
161
- autonumber
162
- actor U as User
163
- participant D as Dispatcher
164
- participant C as Codex native tasks
165
- participant E as Executor child
166
- participant M as TaskChef MCP
167
- participant W as tasks.jsonl
168
-
169
- alt Native creation fails after record_task
170
- D->>C: Create task with marked instruction
171
- C--xD: Creation error
172
- D->>M: report_result(taskId, null, null, failed, bounded summary)
173
- M->>W: Store terminal creation failure
174
- Note right of W: Keep threadId=null and turnId=null<br>Set status=failed, summary, updatedAt, updatedBy=mcp
175
- M-->>D: Failed task snapshot
176
- D-->>U: Creation failure with preserved TaskChef taskId
177
- else Initial link stops before commit
178
- E--xM: link_task(taskId, child threadId)
179
- Note right of W: Remains threadId=null, status=working<br>Eligible link-pending record may retry later
180
- else Link commits but response is lost
181
- E->>M: link_task(taskId, child threadId)
182
- M->>W: Commit child threadId
183
- M--xE: Response lost
184
- E->>M: Identical link_task retry
185
- M-->>E: Return existing linked snapshot
186
- end
187
- ```
188
-
189
- ## MCP calls and field transitions
190
-
191
- | Step | Caller | Operation | Key input | Task record effect |
192
- | --- | --- | --- | --- | --- |
193
- | 1 | Dispatcher | `prepare_dispatch` | No task identity supplied | Returns `taskId`, exact `marker`, `preparedAt`, and configured `projects`; does not write `tasks.jsonl`. |
194
- | 2 | Dispatcher | `record_task` | `id`, `project`, `title`, marked `instruction`, `threadId: null` | Appends schema 4 with `createdAt`; sets `status: working`, `summary: null`, `turnId: null`, `updatedAt: createdAt`, `updatedBy: dispatcher`. |
195
- | 3 | Dispatcher | Native Codex task creation—not MCP | Target project plus marked instruction | Does not change the TaskChef record. A returned durable or provisional ID is not identity authority. |
196
- | 4 | Executor | `link_task` | Marked `taskId` plus its own `CODEX_THREAD_ID` | Atomically changes `threadId` from `null` to the canonical child UUIDv7; refreshes `updatedAt` and sets `updatedBy: mcp`. |
197
- | 5 | Executor | `report_result` | Exact `taskId`, self-linked `threadId`, current `turnId`, semantic `status`, concise `summary` | Replaces the latest `status`, `summary`, and `turnId`; refreshes `updatedAt` and sets `updatedBy: mcp`. Changed follow-up results require a newer UUIDv7 `turnId`. |
198
- | Failure | Dispatcher | `report_result` after native creation error | `taskId`, `threadId: null`, `turnId: null`, `status: failed`, bounded `summary` | Preserves the pre-created record and null identity while storing a terminal creation failure. |
199
-
200
- ## Design boundaries
201
-
202
- There is no task listing, candidate read, marker search, wait, polling loop,
203
- native creation retry, transcript read, or hook in the dispatch path. The
204
- filesystem watcher notices atomic TaskChef writes and refreshes only the
205
- dashboard; reports read current state on demand.
206
-
207
- Custom MCP does not authenticate the calling Codex task. The executor thread ID
208
- is therefore a cooperative assertion inside TaskChef's local single-user trust
209
- boundary. The design prevents accidental parent/child confusion but does not
210
- claim resistance to a deliberately forged local MCP call.
211
-
212
- Historical `updatedBy: hook` values remain readable, but new installations
213
- contain no hook and new writes use `dispatcher` or `mcp`.
214
-
215
- ## Legacy recovery
216
-
217
- `taskchef task resolve` is retained only for unresolved schema 1-3 records.
218
- Operators must establish one exact marker match and one unique durable child
219
- ID. Schema 4 self-linking records reject manual resolution. History is read
220
- compatibly and is not eagerly rewritten.
221
-
222
- ## Dashboard and reports
223
-
224
- The dashboard deep link uses only the stored self-linked child ID. File watcher
225
- events surface linking and results without user interaction. Reporting may
226
- compare current native metadata with cached semantic results, but it never
227
- writes inferred lifecycle state.