taskchef 8.2.2 → 8.3.1
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/README.md +53 -56
- package/docs/dashboard-lifecycle.md +108 -194
- package/docs/spec.md +75 -89
- package/docs/workflows.md +39 -22
- package/package.json +1 -1
- package/scripts/roles/resolve_roles.py +2 -2
- package/skills/taskchef-delegate/SKILL.md +11 -11
- package/skills/taskchef-delegate/references/model-roles.md +21 -44
- package/skills/taskchef-executor/SKILL.md +34 -0
- package/src/dashboard/dist/app.js +1 -1
- package/src/dashboard/dist/app.js.map +1 -1
- package/src/dashboard/react/components/ModelSettings.tsx +1 -1
- package/src/dashboard-control.js +34 -0
- package/src/dashboard-manager.js +183 -842
- package/src/dashboard-session-process.js +35 -126
- package/src/dashboard-session.js +0 -5
- package/src/dashboard.js +29 -282
- package/src/mcp.js +3 -3
- package/src/model-roles.js +3 -3
- package/src/dashboard-ownership.js +0 -251
package/README.md
CHANGED
|
@@ -62,8 +62,6 @@ AGENTS.md managed dispatcher instructions plus user additions
|
|
|
62
62
|
taskchef.json schema-2 Codex project index, dashboard preference, and delegation metadata
|
|
63
63
|
tasks.jsonl one task snapshot per line (schema 10; schema 4-9 migration supported)
|
|
64
64
|
.taskchef-usage.json optional mode-0600 ccusage snapshot and turn-boundary cache
|
|
65
|
-
.taskchef-dashboard-owner.json optional mode-0600 current dashboard identity and control credential; retained and atomically replaced
|
|
66
|
-
.taskchef-dashboard-handoff.json optional mode-0600 secret-free signed final lease snapshot; retained and atomically overwritten
|
|
67
65
|
```
|
|
68
66
|
|
|
69
67
|
Index or inspect Codex projects conversationally:
|
|
@@ -179,13 +177,14 @@ Use $taskchef-executor to execute and report this delegated TaskChef assignment.
|
|
|
179
177
|
|
|
180
178
|
### Model roles
|
|
181
179
|
|
|
182
|
-
TaskChef can apply personal Planner, Implementer, and Reviewer
|
|
183
|
-
from `~/.codex/agents/`.
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
180
|
+
TaskChef can apply personal Orchestrator, Planner, Implementer, and Reviewer
|
|
181
|
+
model preferences from `~/.codex/agents/`. Every delegated task uses the
|
|
182
|
+
Orchestrator preference for its visible parent. For repository work, a combined
|
|
183
|
+
investigate-or-plan-and-implement request runs fresh Planner, Implementer, and
|
|
184
|
+
Reviewer subagents in that order. A direct implementation, or a later request
|
|
185
|
+
to implement prior investigation, skips the Planner and runs a fresh Implementer
|
|
186
|
+
and Reviewer in the same visible task. Explicit model choices take precedence
|
|
187
|
+
for the role they target.
|
|
189
188
|
|
|
190
189
|
## Work with and report executors
|
|
191
190
|
|
|
@@ -271,40 +270,36 @@ $taskchef-dashboard Ensure and open the TaskChef dashboard.
|
|
|
271
270
|
MCP activation and `$taskchef-dashboard` call the input-free `ensure_dashboard`
|
|
272
271
|
MCP tool. It starts at most one loopback dashboard scoped to the running Codex
|
|
273
272
|
session on `127.0.0.1:3210`, or reuses a listener only when its bounded
|
|
274
|
-
`/api/health` identity
|
|
275
|
-
canonical workspace, and
|
|
276
|
-
`reused` and includes the stable URL, canonical workspace, and
|
|
273
|
+
`/api/health` identity reports the exact TaskChef/dashboard-server version,
|
|
274
|
+
canonical workspace, and recognized launcher. The response says `started` or
|
|
275
|
+
`reused` and includes the stable URL, canonical workspace, versions, and actual
|
|
276
|
+
launcher.
|
|
277
277
|
|
|
278
278
|
The dashboard is launched by MCP but is not hosted by one MCP transport. It
|
|
279
279
|
therefore survives an individual MCP close, stdin EOF, signal, or plugin reload.
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
280
|
+
Only a listener launched as `session` registers each same-version MCP's original
|
|
281
|
+
Codex parent PID in its in-memory lease. After every registered Codex session
|
|
282
|
+
PID disappears for a grace period, the dashboard closes and exits. Activating
|
|
283
|
+
an installed newer TaskChef MCP recognizes and
|
|
284
|
+
gracefully stops an older TaskChef dashboard for the same canonical workspace,
|
|
285
|
+
waits boundedly for the port, then starts the installed version in that ensure.
|
|
286
|
+
Lease state is not transferred across versions; the replacement initially knows
|
|
287
|
+
only the activating session. These are best-effort
|
|
285
288
|
local guards, not a claim that Codex supplies a restart guarantee. TaskChef adds
|
|
286
289
|
no daemon or OS-persistent component. See the complete
|
|
287
290
|
[dashboard lifecycle](docs/dashboard-lifecycle.md).
|
|
288
291
|
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
returned by `/api/health`, sent in a request, or logged. Standalone,
|
|
301
|
-
different-workspace, newer, malformed,
|
|
302
|
-
unverified, and spoofed listeners are left untouched. Versions predating this
|
|
303
|
-
protocol cannot be taken over safely and may require one final manual cleanup.
|
|
304
|
-
The ownership record is durable metadata: shutdown retains it, and the next
|
|
305
|
-
MCP owner atomically replaces it after binding. This avoids both a live
|
|
306
|
-
credentialless retirement window and an old process deleting its replacement's
|
|
307
|
-
proof.
|
|
292
|
+
TaskChef uses a trusted, single-user localhost model. Exact structured health is
|
|
293
|
+
sufficient service recognition; it is not cryptographic authentication. Simple
|
|
294
|
+
session and shutdown controls require exact Host and Origin, JSON content, a
|
|
295
|
+
non-simple request header, and an exact bounded body to block ordinary
|
|
296
|
+
cross-site browser requests. Each control names the exact health identity the
|
|
297
|
+
caller observed; the listener refuses a stale identity and the caller probes the
|
|
298
|
+
port again before deciding what to do. Unknown, malformed, different-workspace,
|
|
299
|
+
unrelated, and newer listeners remain untouched. A release using the former HMAC control
|
|
300
|
+
protocol refuses the new simple shutdown request, so the first upgrade across
|
|
301
|
+
that boundary may require stopping that verified legacy TaskChef listener once
|
|
302
|
+
before ensuring again.
|
|
308
303
|
|
|
309
304
|
Autostart is enabled when `dashboard` is absent and in new workspaces. To opt
|
|
310
305
|
out, add this optional exact object to `taskchef.json` while retaining its other
|
|
@@ -381,10 +376,9 @@ The header shows the running TaskChef package version reported by the same
|
|
|
381
376
|
bounded health identity used for compatible-listener checks.
|
|
382
377
|
The Settings page shows the ccusage version reported by the executable that
|
|
383
378
|
TaskChef resolves at runtime.
|
|
384
|
-
The canonical port is owned by a dashboard session process initialized
|
|
385
|
-
TaskChef MCP before its tool transport connects.
|
|
386
|
-
|
|
387
|
-
authenticated session dashboard;
|
|
379
|
+
The canonical port is normally owned by a dashboard session process initialized
|
|
380
|
+
by the TaskChef MCP before its tool transport connects. MCP recovery reuses an
|
|
381
|
+
exact-compatible same-workspace dashboard and reports its actual launcher;
|
|
388
382
|
a foreground `taskchef dashboard` process is intentionally standalone so its
|
|
389
383
|
child commands cannot silently inherit an agent-shell sandbox.
|
|
390
384
|
Task and result times are relative through 29 days (with minute detail for the
|
|
@@ -399,11 +393,16 @@ its task disappears; selecting it then explains that current details are no
|
|
|
399
393
|
longer available.
|
|
400
394
|
Apart from an explicit manual state selection from the task-detail menu, it does not mutate
|
|
401
395
|
TaskChef data and prints its local URL. A foreground dashboard identifies
|
|
402
|
-
itself as standalone
|
|
403
|
-
standalone
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
396
|
+
itself as `standalone`. An exact-current, healthy same-workspace listener with a
|
|
397
|
+
recognized `standalone`, `mcp`, or `session` launcher may be reused on the
|
|
398
|
+
canonical MCP port; ensure reports its actual launcher, and only `session`
|
|
399
|
+
listeners register Codex PID leases. If an unknown, malformed, or
|
|
400
|
+
different-workspace process owns port 3210, TaskChef reports a concise conflict
|
|
401
|
+
and never kills that process. A recognized older same-workspace TaskChef
|
|
402
|
+
listener receives a simple guarded graceful shutdown request. If it lacks the
|
|
403
|
+
compatible callback or refuses the request, it remains running and ensure
|
|
404
|
+
reports a conflict. The foreground CLI similarly asks you to stop a conflicting
|
|
405
|
+
listener or choose another `--port`.
|
|
407
406
|
|
|
408
407
|
The health endpoint contains only a fixed service marker, health schema,
|
|
409
408
|
TaskChef version, dashboard-server version, canonical workspace, and launcher.
|
|
@@ -471,24 +470,22 @@ does not necessarily reload Codex. Then run `$taskchef-dashboard` (or call
|
|
|
471
470
|
|
|
472
471
|
- the expected released TaskChef version;
|
|
473
472
|
- the expected dashboard protocol `serverVersion`;
|
|
474
|
-
- the `session` dashboard
|
|
473
|
+
- the reported dashboard launcher (`session` for a newly started canonical dashboard);
|
|
475
474
|
- the canonical TaskChef workspace path;
|
|
476
475
|
- the canonical `http://127.0.0.1:3210/` URL.
|
|
477
476
|
|
|
478
477
|
The release-install sequence is therefore: install plugin, activate or reload
|
|
479
478
|
the new MCP process, ensure the dashboard, then verify TaskChef version,
|
|
480
|
-
protocol `serverVersion`,
|
|
481
|
-
Exact-compatible
|
|
482
|
-
remain untouched.
|
|
479
|
+
protocol `serverVersion`, reported launcher, canonical workspace, and URL.
|
|
480
|
+
Exact-compatible same-workspace servers with a recognized launcher may be
|
|
481
|
+
reused; unknown listeners remain untouched.
|
|
483
482
|
|
|
484
483
|
If autostart reports a **verified older TaskChef** listener, the port occupant
|
|
485
|
-
passed the bounded TaskChef identity check but
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
it does not, retain it for diagnosis because TaskChef deliberately refuses to
|
|
491
|
-
weaken the ownership proof.
|
|
484
|
+
passed the bounded TaskChef identity check but refused the simple graceful
|
|
485
|
+
shutdown request. Releases using the former HMAC control protocol form a
|
|
486
|
+
one-time compatibility boundary: stop that verified legacy TaskChef listener
|
|
487
|
+
through the application/session that launched it, then activate the installed
|
|
488
|
+
plugin and ensure again. Do not kill an arbitrary port owner.
|
|
492
489
|
|
|
493
490
|
## Development
|
|
494
491
|
|
|
@@ -5,214 +5,128 @@ reloads, changes version, and stops. The [specification](spec.md) is normative;
|
|
|
5
5
|
the [README](../README.md) covers user operation, and
|
|
6
6
|
[workflows](workflows.md) maps these guarantees to implementation.
|
|
7
7
|
|
|
8
|
-
##
|
|
8
|
+
## Process model
|
|
9
9
|
|
|
10
10
|
The canonical dashboard is a loopback-only process scoped to a running Codex
|
|
11
|
-
application session.
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
11
|
+
application session. TaskChef MCP activation launches it, but one MCP transport
|
|
12
|
+
does not own it. It can therefore survive an individual MCP EOF, signal,
|
|
13
|
+
transport close, or plugin reload while another TaskChef MCP transport in the
|
|
14
|
+
same Codex session remains active.
|
|
15
15
|
|
|
16
16
|
TaskChef does not install a daemon, login item, lifecycle hook, or privileged
|
|
17
|
-
service. A foreground `taskchef dashboard`
|
|
18
|
-
|
|
17
|
+
service. A foreground `taskchef dashboard` remains a separate `standalone`
|
|
18
|
+
launcher.
|
|
19
19
|
|
|
20
|
-
|
|
21
|
-
chat-archive action could inherit the MCP host environment. That action is now
|
|
22
|
-
disabled because Codex does not expose a reliable supported app-callable
|
|
23
|
-
archive interface. The dashboard still benefits from MCP activation,
|
|
24
|
-
workspace resolution, and startup isolation, but none of those requires the
|
|
25
|
-
HTTP listener to share one MCP transport's lifetime. The session process keeps
|
|
26
|
-
those benefits without retaining the obsolete per-transport ownership.
|
|
27
|
-
|
|
28
|
-
## Token usage presentation
|
|
29
|
-
|
|
30
|
-
The detail view distinguishes an active turn whose final usage is pending from
|
|
31
|
-
a terminal turn whose usage is being calculated. Available usage keeps both
|
|
32
|
-
the token total and API-equivalent USD estimate. Task cards keep the latest
|
|
33
|
-
cumulative value visible during a newer active turn and label it as updating;
|
|
34
|
-
pending is reserved for tasks that do not have a usage snapshot yet.
|
|
35
|
-
|
|
36
|
-
The dashboard owns a small background recovery queue for derived usage. It
|
|
37
|
-
deduplicates tasks, limits concurrent ccusage reads, preserves successful cache
|
|
38
|
-
records, and revisits missing, interrupted, or cooldown-expired records without
|
|
39
|
-
requiring a detail request. The queue starts with the dashboard, reacts to task
|
|
40
|
-
log revisions, performs periodic recovery passes, and stops with the dashboard.
|
|
41
|
-
Settings reports the version returned by the resolved ccusage executable.
|
|
42
|
-
|
|
43
|
-

|
|
44
|
-
|
|
45
|
-
## Reported work presentation
|
|
46
|
-
|
|
47
|
-
The task detail view reports wall-clock elapsed time from TaskChef lifecycle
|
|
48
|
-
timestamps. Each terminal turn's **Elapsed** value is `result.updatedAt` minus
|
|
49
|
-
`startedAt`. **Total reported work** is the sum of valid terminal-turn elapsed
|
|
50
|
-
times, so idle gaps between follow-up turns and the unfinished portion of an
|
|
51
|
-
active turn are excluded. A working turn shows a live **Elapsed so far** value
|
|
52
|
-
from `startedAt` to the current time without adding it to the task total.
|
|
53
|
-
|
|
54
|
-
Durations below one minute use whole seconds; durations below one hour use
|
|
55
|
-
minutes and seconds; durations below one day use hours and minutes; longer
|
|
56
|
-
durations use days and hours. Each displayed unit is floored, and positive
|
|
57
|
-
sub-second durations display as `<1s`. Missing, malformed, reversed, or
|
|
58
|
-
unsupported timestamp ranges display an explicit unavailable state. Zero-width
|
|
59
|
-
terminal ranges are also unavailable because existing records cannot reliably
|
|
60
|
-
distinguish synthesized boundaries from same-millisecond measured work. Timing
|
|
61
|
-
is derived independently of `.taskchef-usage.json` and is reported wall-clock
|
|
62
|
-
elapsed time, not model compute time.
|
|
63
|
-
|
|
64
|
-

|
|
20
|
+
## Start and reuse
|
|
65
21
|
|
|
66
|
-
|
|
22
|
+
Unless `dashboard.autostart` is explicitly `false`, MCP activation runs the same
|
|
23
|
+
serialized ensure operation exposed by `ensure_dashboard`. Failure is isolated
|
|
24
|
+
from MCP startup and emits a bounded diagnostic.
|
|
67
25
|
|
|
68
|
-
|
|
26
|
+
The canonical session manager requires an explicit nonzero port and normally
|
|
27
|
+
binds `127.0.0.1:3210`. Its deterministic lifecycle is:
|
|
28
|
+
|
|
29
|
+
1. No listener: start the installed dashboard and wait until its health endpoint
|
|
30
|
+
is reachable.
|
|
31
|
+
2. Exact current identity for the canonical workspace: reuse it after another
|
|
32
|
+
health probe. A `session` listener first registers the activating Codex PID
|
|
33
|
+
in its in-memory lease.
|
|
34
|
+
3. Exact older TaskChef identity for the canonical workspace: request graceful
|
|
35
|
+
shutdown, wait a bounded time for port release, then start the installed
|
|
36
|
+
version within the same ensure operation.
|
|
37
|
+
4. Recognized newer TaskChef identity: refuse to downgrade it.
|
|
38
|
+
5. Unknown, malformed, different-workspace, or unrelated listener: report a
|
|
39
|
+
clear conflict without sending a control request or process signal.
|
|
40
|
+
|
|
41
|
+
Health is an exact bounded structured identity containing the service marker,
|
|
42
|
+
schema, TaskChef version, dashboard server version, canonical workspace, and
|
|
43
|
+
launcher. It is sufficient service recognition in TaskChef's trusted,
|
|
44
|
+
single-user localhost model. It is not cryptographic authentication.
|
|
45
|
+
|
|
46
|
+
Concurrent activations can all observe a free port. Only one detached process
|
|
47
|
+
can bind it; other activators inspect and reuse or replace the winner according
|
|
48
|
+
to the same rules. A detached child reports readiness over inherited IPC after
|
|
49
|
+
the server has bound, completed initialization, and created its first in-memory
|
|
50
|
+
lease. A bounded timeout cancels failed or slow startup.
|
|
69
51
|
|
|
70
|
-
|
|
71
|
-
snapshot before monitors or derived-state writers start. Reusing an existing
|
|
72
|
-
listener does not create another startup snapshot. Snapshot failure aborts the
|
|
73
|
-
new server start and does not weaken MCP reporting isolation.
|
|
52
|
+
## MCP reload and plugin upgrade
|
|
74
53
|
|
|
75
|
-
|
|
76
|
-
|
|
54
|
+
Closing an MCP transport does not close the dashboard. Each exact same-version
|
|
55
|
+
reuse registers the activating Codex PID. The dashboard checks these in-memory
|
|
56
|
+
leases with non-signalling existence probes and closes after all registered PIDs
|
|
57
|
+
are gone for the configured grace period.
|
|
58
|
+
|
|
59
|
+
Lease state is deliberately not transferred across versions. A replacement
|
|
60
|
+
dashboard initially knows only the activating session. A later ensure from
|
|
61
|
+
another session registers that session, and can restart the dashboard if the
|
|
62
|
+
first lease has already expired. This accepted consequence keeps upgrade
|
|
63
|
+
behavior deterministic and avoids durable or cross-version ownership state.
|
|
64
|
+
|
|
65
|
+
Releases using the former HMAC control protocol do not understand the simple
|
|
66
|
+
shutdown request. The first upgrade from such a release reports that the
|
|
67
|
+
recognized older listener refused graceful shutdown and leaves it running. Stop
|
|
68
|
+
that verified TaskChef listener through its existing lifecycle, then activate
|
|
69
|
+
or ensure the newly installed plugin again. TaskChef never adds a generic
|
|
70
|
+
process-kill fallback to cross this one-time compatibility boundary.
|
|
71
|
+
|
|
72
|
+
## Local control boundary
|
|
73
|
+
|
|
74
|
+
The dashboard listens only on `127.0.0.1` or `::1` and has no browser login.
|
|
75
|
+
Its health identity contains no task data, credentials, environment variables,
|
|
76
|
+
or process-control details.
|
|
77
|
+
|
|
78
|
+
The session-registration and graceful-shutdown endpoints are intentionally
|
|
79
|
+
small localhost controls. They require the exact listener Host and Origin,
|
|
80
|
+
JSON content type, a non-simple `X-TaskChef-Control` header, and an exact bounded
|
|
81
|
+
body. Each body includes the exact structured health identity observed by the
|
|
82
|
+
caller. The receiver compares it with its own identity before registering a
|
|
83
|
+
session or accepting shutdown. On a mismatch the caller probes the listener
|
|
84
|
+
again and applies the normal lifecycle rules to the current occupant. These
|
|
85
|
+
checks block ordinary cross-site browser requests and DNS rebinding to a
|
|
86
|
+
different Host. They are request-shape checks, not authentication or an
|
|
87
|
+
ownership protocol.
|
|
88
|
+
|
|
89
|
+
Future LAN access is outside this model. It must be a separate opt-in feature
|
|
90
|
+
with password-backed user authentication and suitable transport protection.
|
|
91
|
+
|
|
92
|
+
TaskChef sends graceful shutdown only after exact recognized TaskChef health for
|
|
93
|
+
the same canonical workspace. It never discovers or kills a port owner, sends
|
|
94
|
+
OS signals to an unknown process, uses forceful termination, searches broadly
|
|
95
|
+
for processes, or requires elevated permission.
|
|
96
|
+
|
|
97
|
+
## Dashboard state and presentation
|
|
98
|
+
|
|
99
|
+
A newly started server creates or deduplicates a verified private workspace
|
|
100
|
+
snapshot before monitors or derived-state writers start. Reuse does not create
|
|
101
|
+
another startup snapshot. Snapshot failure aborts the new server.
|
|
102
|
+
|
|
103
|
+
The dashboard watches task history and the project index. It warns when
|
|
104
|
+
historical task snapshots reference paths absent from the current index and
|
|
77
105
|
offers recovery-oriented read-only commands. It never mutates or restores
|
|
78
106
|
configuration.
|
|
79
107
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
non-sensitive diagnostic.
|
|
85
|
-
|
|
86
|
-
The canonical session manager requires an explicit nonzero port and normally
|
|
87
|
-
binds `127.0.0.1:3210`; ephemeral port zero remains available only to direct
|
|
88
|
-
foreground/server callers that own the returned listener. Reuse requires an
|
|
89
|
-
exact bounded health identity:
|
|
90
|
-
|
|
91
|
-
- TaskChef dashboard service and health schema;
|
|
92
|
-
- installed TaskChef version;
|
|
93
|
-
- dashboard protocol version;
|
|
94
|
-
- canonical workspace;
|
|
95
|
-
- `session` launcher.
|
|
96
|
-
|
|
97
|
-
The MCP then authenticates the listener with the private ownership credential
|
|
98
|
-
and registers its original Codex parent PID as a session lease. Registration
|
|
99
|
-
success and transferred lease sets carry response HMACs bound to their fresh
|
|
100
|
-
request nonce and complete result, so a different process appearing between
|
|
101
|
-
the challenge and control request cannot be adopted. Concurrent starts
|
|
102
|
-
serialize locally and converge across processes by authenticating the single
|
|
103
|
-
listener that wins the port race.
|
|
104
|
-
|
|
105
|
-
A detached child reports readiness over a private inherited IPC channel only
|
|
106
|
-
after the listener is bound and the new owner record is durably published.
|
|
107
|
-
Startup errors use the same channel. A bounded timeout sends a cooperative
|
|
108
|
-
cancellation message, so slow or failed initialization cannot be mistaken for
|
|
109
|
-
success or silently strand a late or partially constructed listener. Owner
|
|
110
|
-
publication checks cancellation before atomic replacement; while publication
|
|
111
|
-
is in flight, every close path retains the port until publication settles, so
|
|
112
|
-
an older credential writer cannot race and overwrite a succeeding session's
|
|
113
|
-
owner record.
|
|
108
|
+
The detail view distinguishes an active turn whose final usage is pending from
|
|
109
|
+
a terminal turn whose usage is being calculated. Available usage keeps both the
|
|
110
|
+
token total and API-equivalent USD estimate. The dashboard owns a bounded
|
|
111
|
+
background queue for derived usage and stops that queue with the server.
|
|
114
112
|
|
|
115
|
-
|
|
113
|
+

|
|
116
114
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
After a plugin upgrade, installing files alone cannot execute new code. When
|
|
123
|
-
the newly installed MCP activates, it compares the live identity with its own
|
|
124
|
-
version. An exact current listener is reused. A verified older TaskChef
|
|
125
|
-
`mcp`- or `session`-launched listener for the same canonical workspace receives
|
|
126
|
-
an authenticated graceful handoff request. A session listener prepares an
|
|
127
|
-
idempotent handoff by fencing new registrations, adding the activating Codex
|
|
128
|
-
PID, and snapshotting its bounded live leases while it remains running. Only
|
|
129
|
-
after the MCP receives and verifies that signed result does it send a separate
|
|
130
|
-
authenticated commit that schedules graceful shutdown. A lost prepare response
|
|
131
|
-
is safely retried; an abandoned preparation expires and reopens registration.
|
|
132
|
-
A commit begins a short bounded finalization grace during which concurrent
|
|
133
|
-
authenticated activators can join. The commit response then returns the final
|
|
134
|
-
immutable lease snapshot with a credential-bound proof. The listener remains
|
|
135
|
-
available for a bounded commit-response retry window before graceful shutdown,
|
|
136
|
-
so a surviving activator can replace an elected peer that exits before launch
|
|
137
|
-
without discarding the older live sessions. The replacement starts with the
|
|
138
|
-
verified final leases. A full lease set refuses a distinct activating PID
|
|
139
|
-
without stopping the old listener. Finalization also reserves one of the 64
|
|
140
|
-
bounded lease slots for a distinct recovery activator; a 64-lease snapshot
|
|
141
|
-
cannot commit retirement and leaves the old listener running. The new MCP then
|
|
142
|
-
starts the current `session` version. A newer listener is never downgraded,
|
|
143
|
-
including during the brief old-to-new listener gap. If different newer versions
|
|
144
|
-
race, a higher contender authenticates and replaces a lower winner until the
|
|
145
|
-
highest active version remains.
|
|
146
|
-
|
|
147
|
-
Before acknowledging commit, the retiring session atomically records that
|
|
148
|
-
signed final snapshot in the mode-`0600` workspace file
|
|
149
|
-
`.taskchef-dashboard-handoff.json`. The record
|
|
150
|
-
contains no control secret. It exists only so an activator that loses every
|
|
151
|
-
commit response can authenticate and recover the exact finalized leases after
|
|
152
|
-
the old listener closes. The single record is retained and atomically
|
|
153
|
-
overwritten by the next finalized handoff; it cannot authenticate against a
|
|
154
|
-
new owner identity and secret. Avoiding post-publication deletion prevents one
|
|
155
|
-
replacement from removing a newer handoff generation. Invalid, permissively
|
|
156
|
-
readable, foreign-workspace, or incorrectly signed records are ignored and
|
|
157
|
-
never authorize takeover.
|
|
158
|
-
|
|
159
|
-
Both private metadata writers sync the completed file, atomically rename it,
|
|
160
|
-
and sync the canonical workspace directory before reporting publication. Final
|
|
161
|
-
lease joins are fenced before the immutable snapshot and durable write begin.
|
|
162
|
-
|
|
163
|
-
Versions predating authenticated ownership cannot be retired safely. Such a
|
|
164
|
-
legacy listener may require one final manual cleanup. This limitation is
|
|
165
|
-
intentional; TaskChef does not weaken listener safety to automate migration.
|
|
166
|
-
|
|
167
|
-
## Codex session end
|
|
168
|
-
|
|
169
|
-
Each MCP registers the exact PID of the Codex process that launched it. The
|
|
170
|
-
dashboard checks only those registered PIDs with a non-signalling existence
|
|
171
|
-
probe. When none remains alive for the configured grace period, the dashboard
|
|
172
|
-
gracefully closes its HTTP listener and exits. Registering another live Codex
|
|
173
|
-
session during the grace period cancels expiry.
|
|
174
|
-
|
|
175
|
-
This is a best-effort local lifecycle guard, not a claim that Codex documents
|
|
176
|
-
or guarantees restart cleanup. PID existence cannot prove application identity
|
|
177
|
-
after an unlikely PID reuse, and abrupt operating-system termination can always
|
|
178
|
-
interrupt graceful cleanup. A later MCP activation still performs authenticated
|
|
179
|
-
version handoff, which is the recovery boundary for a recognized stale
|
|
180
|
-
TaskChef listener.
|
|
181
|
-
|
|
182
|
-
## Security boundary
|
|
183
|
-
|
|
184
|
-
TaskChef writes ownership to `.taskchef-dashboard-owner.json` and finalized
|
|
185
|
-
handoff metadata to `.taskchef-dashboard-handoff.json` as private regular
|
|
186
|
-
mode-0600 files in the canonical workspace. The credential never appears in health responses,
|
|
187
|
-
diagnostics, URLs, or logs. A fresh nonce-bound HMAC challenge proves that the
|
|
188
|
-
listener and owner record share the credential. Shutdown and session
|
|
189
|
-
registration use separate action-bound proofs; successful registration and
|
|
190
|
-
handoff responses are also nonce- and result-bound. Nonces are single-use within
|
|
191
|
-
a bounded five-minute replay window. The replay cache has a fixed capacity and
|
|
192
|
-
refuses overflow while entries remain valid.
|
|
193
|
-
|
|
194
|
-
TaskChef sends control requests only after all public identity and private
|
|
195
|
-
ownership fields match. It never discovers or kills a port owner, sends OS
|
|
196
|
-
signals to a listener, uses `kill -9`, searches broadly for processes, or
|
|
197
|
-
requires elevated permission. These listeners remain untouched:
|
|
198
|
-
|
|
199
|
-
- standalone dashboards;
|
|
200
|
-
- unknown or spoofed services;
|
|
201
|
-
- different canonical workspaces;
|
|
202
|
-
- newer TaskChef versions;
|
|
203
|
-
- malformed or mismatched ownership records;
|
|
204
|
-
- listeners that fail the authenticated challenge;
|
|
205
|
-
- uncooperative legacy listeners without the handoff protocol.
|
|
115
|
+
Reported work is wall-clock elapsed time derived from TaskChef lifecycle
|
|
116
|
+
timestamps. It excludes idle gaps and unfinished portions of active turns from
|
|
117
|
+
the terminal total. Missing, malformed, reversed, zero-width, or unsupported
|
|
118
|
+
timestamp ranges display an unavailable state.
|
|
206
119
|
|
|
207
120
|
## Lifecycle matrix
|
|
208
121
|
|
|
209
|
-
| Event |
|
|
210
|
-
| --- | --- |
|
|
211
|
-
|
|
|
212
|
-
|
|
|
213
|
-
|
|
|
214
|
-
|
|
|
215
|
-
|
|
|
216
|
-
|
|
|
217
|
-
|
|
|
218
|
-
|
|
|
122
|
+
| Event | Result |
|
|
123
|
+
| --- | --- |
|
|
124
|
+
| Activation with no listener | Start installed session dashboard |
|
|
125
|
+
| Activation with exact current listener | Register a session lease when supported, verify health again, reuse |
|
|
126
|
+
| Activation with recognized older listener | Request graceful shutdown, wait boundedly, start installed version |
|
|
127
|
+
| Activation with recognized newer listener | Refuse downgrade and leave it running |
|
|
128
|
+
| Activation with unknown or different-workspace listener | Report conflict and leave it untouched |
|
|
129
|
+
| One MCP EOF, signal, or reload | Dashboard remains while a registered Codex PID is alive |
|
|
130
|
+
| All registered Codex PIDs disappear | Dashboard closes after the grace period |
|
|
131
|
+
| `dashboard.autostart: false` | Explicit ensure remains available |
|
|
132
|
+
| Foreground `taskchef dashboard` | Standalone process follows foreground CLI lifetime |
|