taskchef 5.3.0 → 5.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.codex-plugin/plugin.json +1 -1
- package/SPEC.md +18 -11
- package/package.json +1 -1
- package/skills/taskchef-delegate/SKILL.md +19 -9
- package/src/delegation.js +5 -0
package/SPEC.md
CHANGED
|
@@ -179,9 +179,11 @@ cases.
|
|
|
179
179
|
For each assignment, `$taskchef-delegate`:
|
|
180
180
|
|
|
181
181
|
1. runs `dispatch prepare` and native Codex project discovery concurrently;
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
182
|
+
only when neither a native provisional-ID resolver nor programmatic tool
|
|
183
|
+
orchestration is available, it also takes one recent-thread baseline
|
|
184
|
+
snapshot in that parallel group. The preparation command resolves the
|
|
185
|
+
canonical workspace, loads and validates configured projects, and generates
|
|
186
|
+
the full UUID, preparation timestamp, and exact marker in one process
|
|
185
187
|
2. selects one unambiguous configured target and matches its exact path against
|
|
186
188
|
the already-loaded native projects
|
|
187
189
|
3. prefixes the instruction with the prepared exact
|
|
@@ -195,22 +197,27 @@ For each assignment, `$taskchef-delegate`:
|
|
|
195
197
|
6. when creation returns only a provisional client ID, immediately appends the
|
|
196
198
|
marked entry with `threadId: null`, then prefers one native client-ID wait or
|
|
197
199
|
resolution call with a 30-second timeout when Codex exposes one
|
|
198
|
-
7. when no native operation is available,
|
|
200
|
+
7. when no native operation is available, excludes durable Codex IDs from the
|
|
201
|
+
successful pre-creation baseline, then takes at most two recent-thread
|
|
199
202
|
snapshots on a nominal 10- and 30-second schedule after the provisional
|
|
200
203
|
result; a late first checkpoint runs immediately, and the second starts at
|
|
201
204
|
least 20 seconds after the first actually started. It filters candidates by
|
|
202
205
|
available host/project/time/worktree metadata, uses title only as an advisory
|
|
203
|
-
ordering hint,
|
|
204
|
-
starts with the
|
|
206
|
+
ordering hint, batches independent reads programmatically when supported,
|
|
207
|
+
and accepts only one thread whose structured delegated input starts with the
|
|
208
|
+
exact marker
|
|
205
209
|
8. atomically fills the nullable thread ID after an exact match
|
|
206
210
|
9. returns after recording or after reporting that bounded resolution was
|
|
207
211
|
unresolved, without waiting for executor work completion.
|
|
208
212
|
|
|
209
|
-
The exact random marker
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
213
|
+
The exact random marker remains the sole correlation proof. A successful
|
|
214
|
+
pre-creation snapshot is only a candidate-elimination baseline; its failure
|
|
215
|
+
does not block creation or weaken the marker check. Creation-time filtering
|
|
216
|
+
allows five seconds of clock skew. Candidate reads run concurrently where the
|
|
217
|
+
host permits, use one programmatic batch when available, and inspect only
|
|
218
|
+
structured `codexDelegation.input`, never untrusted title, summary, preview, or
|
|
219
|
+
plain-text marker echoes. A native resolver result is verified against the same
|
|
220
|
+
structured
|
|
214
221
|
marker before persistence. Zero exact matches remain unresolved; multiple exact
|
|
215
222
|
matches are ambiguous. Snapshot, candidate-read, native-resolution, or
|
|
216
223
|
task-resolution errors leave the already-recorded nullable entry intact. The
|
package/package.json
CHANGED
|
@@ -27,15 +27,21 @@ for all deterministic workspace and task-record operations.
|
|
|
27
27
|
|
|
28
28
|
## Dispatch
|
|
29
29
|
|
|
30
|
-
1. In parallel, run `<plugin-root>/bin/taskchef.js dispatch prepare --json
|
|
31
|
-
|
|
30
|
+
1. In parallel, run `<plugin-root>/bin/taskchef.js dispatch prepare --json`,
|
|
31
|
+
list the native Codex projects once, and, only when neither a dedicated
|
|
32
|
+
provisional-ID resolver nor programmatic tool orchestration is available,
|
|
33
|
+
take one pre-creation `list_threads` snapshot with limit 50. Do not add this
|
|
34
|
+
snapshot when candidate reads can be issued in one programmatic batch. The
|
|
35
|
+
prepare command resolves the
|
|
32
36
|
canonical workspace, loads and validates the configured routing targets,
|
|
33
37
|
generates the lowercase full UUID task ID, and returns `preparedAt` plus the
|
|
34
38
|
exact first-line marker. Use
|
|
35
39
|
`$taskchef-bootstrap` if the workspace is missing or unhealthy.
|
|
36
40
|
The CLI resolves `--workspace`, then `TASKCHEF_WORKSPACE`, then
|
|
37
41
|
`~/.agents/taskchef`; do not substitute the current project. Reject the
|
|
38
|
-
dispatcher workspace itself as a target.
|
|
42
|
+
dispatcher workspace itself as a target. From the pre-creation snapshot,
|
|
43
|
+
retain only durable Codex thread IDs as a candidate-elimination baseline.
|
|
44
|
+
Snapshot failure must not block creation; continue without a baseline.
|
|
39
45
|
2. Split the request into the smallest independently useful outcomes. Include
|
|
40
46
|
constraints, expected testing, and reporting in every instruction.
|
|
41
47
|
3. Classify against configured `name`, every URL in the `githubRepos` list, and
|
|
@@ -54,9 +60,9 @@ for all deterministic workspace and task-record operations.
|
|
|
54
60
|
Prefix the complete executor instruction with
|
|
55
61
|
exactly `<!-- taskchef_id=<full UUID> -->` as the first line, followed by a
|
|
56
62
|
blank line and the instruction body. Preserve this
|
|
57
|
-
marked instruction for recording, and note the creation time.
|
|
58
|
-
|
|
59
|
-
|
|
63
|
+
marked instruction for recording, and note the creation time. The exact
|
|
64
|
+
random marker remains the sole correlation proof; the pre-creation IDs only
|
|
65
|
+
eliminate threads that already existed.
|
|
60
66
|
6. Create one real Codex task using the exact configured project, a local
|
|
61
67
|
environment on its executor host, the marked instruction, and a short title.
|
|
62
68
|
7. When `create_thread` returns a durable `threadId`, immediately run
|
|
@@ -81,8 +87,10 @@ for all deterministic workspace and task-record operations.
|
|
|
81
87
|
accepts the provisional ID and waits for or resolves its durable thread
|
|
82
88
|
ID, call it exactly once with a timeout of at most 30 seconds. Do not invent
|
|
83
89
|
an operation or pass the provisional ID to tools that require `threadId`.
|
|
84
|
-
- When no native operation is available, take at most two
|
|
85
|
-
snapshots with limit 50.
|
|
90
|
+
- When no native operation is available, take at most two post-creation
|
|
91
|
+
`list_threads` snapshots with limit 50. Exclude every durable Codex ID from
|
|
92
|
+
the successful pre-creation baseline before reading candidates. The
|
|
93
|
+
nominal schedule is 10 and 30 seconds after
|
|
86
94
|
the provisional result. Treat the first checkpoint as due, not expired: if
|
|
87
95
|
nullable recording or other required work finishes after 10 seconds, take
|
|
88
96
|
the first snapshot immediately. Start the second snapshot no sooner than
|
|
@@ -96,7 +104,9 @@ for all deterministic workspace and task-record operations.
|
|
|
96
104
|
may normalize it, so never exclude a candidate because its title differs.
|
|
97
105
|
- Read every remaining candidate with `read_thread`, requesting one turn and
|
|
98
106
|
no command output. Read candidates concurrently when the tool surface
|
|
99
|
-
permits
|
|
107
|
+
permits; when programmatic tool orchestration is available, issue the
|
|
108
|
+
independent reads together in one programmatic batch. Inspect only the
|
|
109
|
+
structured
|
|
100
110
|
`userMessage.content[].codexDelegation.input`; do not trust titles,
|
|
101
111
|
summaries, previews, plain-text echoes, or assistant output as proof.
|
|
102
112
|
- Accept a candidate only when the structured input's first line is exactly
|
package/src/delegation.js
CHANGED
|
@@ -250,6 +250,7 @@ export async function createAndRecordDelegation({
|
|
|
250
250
|
recordTask,
|
|
251
251
|
resolveRecordedTask = null,
|
|
252
252
|
resolveProvisionalThread = null,
|
|
253
|
+
baselineThreadIds = new Set(),
|
|
253
254
|
taskId = randomUUID(),
|
|
254
255
|
checkpointsMs = THREAD_RESOLUTION_CHECKPOINTS_MS,
|
|
255
256
|
timeoutMs = THREAD_RESOLUTION_TIMEOUT_MS,
|
|
@@ -274,6 +275,9 @@ export async function createAndRecordDelegation({
|
|
|
274
275
|
if (resolveRecordedTask !== null && typeof resolveRecordedTask !== "function") {
|
|
275
276
|
throw new Error("resolveRecordedTask must be a function or null");
|
|
276
277
|
}
|
|
278
|
+
if (!(baselineThreadIds instanceof Set)) {
|
|
279
|
+
throw new Error("baselineThreadIds must be a Set");
|
|
280
|
+
}
|
|
277
281
|
validateResolutionSchedule(checkpointsMs, timeoutMs);
|
|
278
282
|
|
|
279
283
|
const prepared = prepareDelegation(instruction, { taskId });
|
|
@@ -507,6 +511,7 @@ export async function createAndRecordDelegation({
|
|
|
507
511
|
try {
|
|
508
512
|
const snapshot = await listThreads({ limit: recentLimit });
|
|
509
513
|
candidates = filterThreadCandidates(snapshot, {
|
|
514
|
+
baselineThreadIds,
|
|
510
515
|
excludedThreadIds: provisionalIds,
|
|
511
516
|
hostId: expected.hostId ?? null,
|
|
512
517
|
projectId: expected.projectId ?? target.projectId ?? null,
|