taskchef 7.22.4 → 7.23.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/README.md +43 -31
- package/docs/dashboard-lifecycle.md +177 -0
- package/docs/images/dashboard-token-pending.jpg +0 -0
- package/docs/spec.md +117 -61
- package/docs/workflows.md +30 -18
- package/mcp/dashboard-session.js +51 -0
- package/package.json +3 -1
- package/src/dashboard/app.js +207 -32
- package/src/dashboard/index.html +10 -8
- package/src/dashboard/styles.css +20 -5
- package/src/dashboard-manager.js +633 -157
- package/src/dashboard-ownership.js +124 -13
- package/src/dashboard-session-process.js +179 -0
- package/src/dashboard-session.js +91 -0
- package/src/dashboard.js +288 -8
- package/src/mcp.js +2 -2
- package/src/version.js +1 -1
package/README.md
CHANGED
|
@@ -16,6 +16,7 @@ request -> recorded TaskChef task -> Codex executor -> request/result turn timel
|
|
|
16
16
|
| --- | --- |
|
|
17
17
|
| Install, configure, dispatch, inspect, and recover | This README |
|
|
18
18
|
| Follow the normative agent contract and MCP interfaces | [Specification](docs/spec.md) |
|
|
19
|
+
| Understand dashboard start, upgrade, and shutdown | [Dashboard lifecycle](docs/dashboard-lifecycle.md) |
|
|
19
20
|
| Understand implementation flows and trust boundaries | [Workflows](docs/workflows.md) |
|
|
20
21
|
| Compare TaskChef with FirstMate | [FirstMate comparison research](docs/firstmate-taskchef-comparison.md) |
|
|
21
22
|
| Review deferred ideas | [Backlog](BACKLOG.md) |
|
|
@@ -61,6 +62,8 @@ AGENTS.md managed dispatcher instructions plus user additions
|
|
|
61
62
|
taskchef.json schema-2 Codex project index, dashboard preference, and delegation metadata
|
|
62
63
|
tasks.jsonl one task snapshot per line (schema 10; schema 4-9 migration supported)
|
|
63
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
|
|
64
67
|
```
|
|
65
68
|
|
|
66
69
|
Index or inspect Codex projects conversationally:
|
|
@@ -238,28 +241,36 @@ $taskchef-dashboard Ensure and open the TaskChef dashboard.
|
|
|
238
241
|
```
|
|
239
242
|
|
|
240
243
|
MCP activation and `$taskchef-dashboard` call the input-free `ensure_dashboard`
|
|
241
|
-
MCP tool. It starts at
|
|
242
|
-
|
|
243
|
-
`
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
that canonical workspace. A nonce-bound
|
|
260
|
-
the matching secret before TaskChef
|
|
261
|
-
|
|
262
|
-
|
|
244
|
+
MCP tool. It starts at most one loopback dashboard scoped to the running Codex
|
|
245
|
+
session on `127.0.0.1:3210`, or reuses a listener only when its bounded
|
|
246
|
+
`/api/health` identity proves the exact TaskChef/dashboard-server version,
|
|
247
|
+
canonical workspace, and `session` launcher. The response says `started` or
|
|
248
|
+
`reused` and includes the stable URL, canonical workspace, and versions.
|
|
249
|
+
|
|
250
|
+
The dashboard is launched by MCP but is not hosted by one MCP transport. It
|
|
251
|
+
therefore survives an individual MCP close, stdin EOF, signal, or plugin reload.
|
|
252
|
+
Each MCP securely registers its original Codex parent PID; after every
|
|
253
|
+
registered Codex session PID disappears for a grace period, the dashboard
|
|
254
|
+
closes and exits. Activating an installed newer TaskChef MCP authenticates and
|
|
255
|
+
retires a compatible older `mcp`- or `session`-owned dashboard for the same
|
|
256
|
+
canonical workspace, then starts the installed version. These are best-effort
|
|
257
|
+
local guards, not a claim that Codex supplies a restart guarantee. TaskChef adds
|
|
258
|
+
no daemon or OS-persistent component. See the complete
|
|
259
|
+
[dashboard lifecycle](docs/dashboard-lifecycle.md).
|
|
260
|
+
|
|
261
|
+
Authenticated handoff requires the older listener to have written TaskChef's
|
|
262
|
+
private mode-0600 ownership record in that canonical workspace. A nonce-bound
|
|
263
|
+
HMAC challenge proves the listener has the matching secret before TaskChef
|
|
264
|
+
sends an authenticated two-phase handoff. A session listener prepares by
|
|
265
|
+
fencing ordinary joins, adding the activating Codex PID, and returning a signed
|
|
266
|
+
bounded lease snapshot while remaining live. A separate authenticated commit
|
|
267
|
+
allows a short concurrent-activator grace, returns the signed final immutable
|
|
268
|
+
lease set, and then schedules graceful shutdown after a bounded response-retry
|
|
269
|
+
window. A mode-`0600`, secret-free, signed final-snapshot record permits exact
|
|
270
|
+
lease recovery if every commit response is lost; a prior MCP-owned listener
|
|
271
|
+
receives a separately authenticated graceful shutdown request. The secret is never
|
|
272
|
+
returned by `/api/health`, sent in a request, or logged. Standalone,
|
|
273
|
+
different-workspace, newer, malformed,
|
|
263
274
|
unverified, and spoofed listeners are left untouched. Versions predating this
|
|
264
275
|
protocol cannot be taken over safely and may require one final manual cleanup.
|
|
265
276
|
The ownership record is durable metadata: shutdown retains it, and the next
|
|
@@ -316,10 +327,10 @@ app-callable archive interface or guarantees CLI compatibility. The dormant
|
|
|
316
327
|
server path also rejects requests before discovering or invoking the CLI.
|
|
317
328
|
|
|
318
329
|
Task details also show whole-task and per-turn token usage when `ccusage` can
|
|
319
|
-
map the linked Codex thread. A completed turn briefly shows “
|
|
320
|
-
|
|
330
|
+
map the linked Codex thread. A completed turn briefly shows “Calculating token
|
|
331
|
+
usage…” while TaskChef performs bounded deferred reconciliation, because
|
|
321
332
|
the terminal lifecycle callback precedes Codex's final output write. Historical
|
|
322
|
-
tasks may show a trustworthy task total while older turns remain “
|
|
333
|
+
tasks may show a trustworthy task total while older turns remain “Token usage
|
|
323
334
|
unavailable” when no cumulative turn boundaries were recorded. Input, cached
|
|
324
335
|
input, output, reasoning, and total counts retain ccusage's categories. Dollar
|
|
325
336
|
figures are labeled API-equivalent estimates; provenance identifies the online
|
|
@@ -330,9 +341,10 @@ pricing modes. ccusage 20.0.20 may omit GPT-5.6 cache-write charges, so TaskChef
|
|
|
330
341
|
labels that analyzer limitation instead of presenting the estimate as complete.
|
|
331
342
|
The header shows the running TaskChef package version reported by the same
|
|
332
343
|
bounded health identity used for compatible-listener checks.
|
|
333
|
-
The canonical port is owned by a dashboard initialized
|
|
334
|
-
before its tool transport connects. Health identity records
|
|
335
|
-
and MCP recovery reuses only another exact-compatible
|
|
344
|
+
The canonical port is owned by a dashboard session process initialized by the
|
|
345
|
+
TaskChef MCP before its tool transport connects. Health identity records a
|
|
346
|
+
`session` launcher, and MCP recovery reuses only another exact-compatible,
|
|
347
|
+
authenticated session dashboard;
|
|
336
348
|
a foreground `taskchef dashboard` process is intentionally standalone so its
|
|
337
349
|
child commands cannot silently inherit an agent-shell sandbox.
|
|
338
350
|
Task and result times are relative through 29 days (with minute detail for the
|
|
@@ -419,14 +431,14 @@ does not necessarily reload Codex. Then run `$taskchef-dashboard` (or call
|
|
|
419
431
|
|
|
420
432
|
- the expected released TaskChef version;
|
|
421
433
|
- the expected dashboard protocol `serverVersion`;
|
|
422
|
-
- the `
|
|
434
|
+
- the `session` dashboard launcher;
|
|
423
435
|
- the canonical TaskChef workspace path;
|
|
424
436
|
- the canonical `http://127.0.0.1:3210/` URL.
|
|
425
437
|
|
|
426
438
|
The release-install sequence is therefore: install plugin, activate or reload
|
|
427
439
|
the new MCP process, ensure the dashboard, then verify TaskChef version,
|
|
428
|
-
protocol `serverVersion`, `
|
|
429
|
-
Exact-compatible
|
|
440
|
+
protocol `serverVersion`, `session` launcher, canonical workspace, and URL.
|
|
441
|
+
Exact-compatible session servers may be reused; standalone and unknown listeners
|
|
430
442
|
remain untouched.
|
|
431
443
|
|
|
432
444
|
If autostart reports a **verified older TaskChef** listener, the port occupant
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
# Dashboard lifecycle
|
|
2
|
+
|
|
3
|
+
This document defines how the canonical TaskChef dashboard starts, survives MCP
|
|
4
|
+
reloads, changes version, and stops. The [specification](spec.md) is normative;
|
|
5
|
+
the [README](../README.md) covers user operation, and
|
|
6
|
+
[workflows](workflows.md) maps these guarantees to implementation.
|
|
7
|
+
|
|
8
|
+
## Ownership model
|
|
9
|
+
|
|
10
|
+
The canonical dashboard is a loopback-only process scoped to a running Codex
|
|
11
|
+
application session. It is launched and maintained by TaskChef MCP activation,
|
|
12
|
+
but it is not hosted by one MCP transport. This distinction lets the dashboard
|
|
13
|
+
survive an individual MCP EOF, signal, transport close, or plugin reload while
|
|
14
|
+
other TaskChef MCP transports in the same Codex session continue using it.
|
|
15
|
+
|
|
16
|
+
TaskChef does not install a daemon, login item, lifecycle hook, or privileged
|
|
17
|
+
service. A foreground `taskchef dashboard` process remains a separate
|
|
18
|
+
`standalone` launcher and is never adopted as the canonical session dashboard.
|
|
19
|
+
|
|
20
|
+
The dashboard was originally moved into the MCP runtime so the experimental
|
|
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; an available cumulative value
|
|
33
|
+
shown during a newer active turn is labeled as known so far.
|
|
34
|
+
|
|
35
|
+

|
|
36
|
+
|
|
37
|
+
## Start and reuse
|
|
38
|
+
|
|
39
|
+
Unless `dashboard.autostart` is explicitly `false`, MCP activation runs the
|
|
40
|
+
same serialized ensure operation exposed by `ensure_dashboard` before the MCP
|
|
41
|
+
transport connects. An explicit ensure remains available when autostart is
|
|
42
|
+
disabled. Failure is isolated from MCP tool startup and emits only a bounded,
|
|
43
|
+
non-sensitive diagnostic.
|
|
44
|
+
|
|
45
|
+
The canonical session manager requires an explicit nonzero port and normally
|
|
46
|
+
binds `127.0.0.1:3210`; ephemeral port zero remains available only to direct
|
|
47
|
+
foreground/server callers that own the returned listener. Reuse requires an
|
|
48
|
+
exact bounded health identity:
|
|
49
|
+
|
|
50
|
+
- TaskChef dashboard service and health schema;
|
|
51
|
+
- installed TaskChef version;
|
|
52
|
+
- dashboard protocol version;
|
|
53
|
+
- canonical workspace;
|
|
54
|
+
- `session` launcher.
|
|
55
|
+
|
|
56
|
+
The MCP then authenticates the listener with the private ownership credential
|
|
57
|
+
and registers its original Codex parent PID as a session lease. Registration
|
|
58
|
+
success and transferred lease sets carry response HMACs bound to their fresh
|
|
59
|
+
request nonce and complete result, so a different process appearing between
|
|
60
|
+
the challenge and control request cannot be adopted. Concurrent starts
|
|
61
|
+
serialize locally and converge across processes by authenticating the single
|
|
62
|
+
listener that wins the port race.
|
|
63
|
+
|
|
64
|
+
A detached child reports readiness over a private inherited IPC channel only
|
|
65
|
+
after the listener is bound and the new owner record is durably published.
|
|
66
|
+
Startup errors use the same channel. A bounded timeout sends a cooperative
|
|
67
|
+
cancellation message, so slow or failed initialization cannot be mistaken for
|
|
68
|
+
success or silently strand a late or partially constructed listener. Owner
|
|
69
|
+
publication checks cancellation before atomic replacement; while publication
|
|
70
|
+
is in flight, every close path retains the port until publication settles, so
|
|
71
|
+
an older credential writer cannot race and overwrite a succeeding session's
|
|
72
|
+
owner record.
|
|
73
|
+
|
|
74
|
+
## MCP reload and plugin upgrade
|
|
75
|
+
|
|
76
|
+
Closing one MCP transport does not close the session dashboard. EOF, SIGINT,
|
|
77
|
+
SIGTERM, protocol close, failed transport startup, and detected MCP-parent loss
|
|
78
|
+
still close that MCP process promptly, but the independently hosted dashboard
|
|
79
|
+
remains while a registered Codex session PID is alive.
|
|
80
|
+
|
|
81
|
+
After a plugin upgrade, installing files alone cannot execute new code. When
|
|
82
|
+
the newly installed MCP activates, it compares the live identity with its own
|
|
83
|
+
version. An exact current listener is reused. A verified older TaskChef
|
|
84
|
+
`mcp`- or `session`-launched listener for the same canonical workspace receives
|
|
85
|
+
an authenticated graceful handoff request. A session listener prepares an
|
|
86
|
+
idempotent handoff by fencing new registrations, adding the activating Codex
|
|
87
|
+
PID, and snapshotting its bounded live leases while it remains running. Only
|
|
88
|
+
after the MCP receives and verifies that signed result does it send a separate
|
|
89
|
+
authenticated commit that schedules graceful shutdown. A lost prepare response
|
|
90
|
+
is safely retried; an abandoned preparation expires and reopens registration.
|
|
91
|
+
A commit begins a short bounded finalization grace during which concurrent
|
|
92
|
+
authenticated activators can join. The commit response then returns the final
|
|
93
|
+
immutable lease snapshot with a credential-bound proof. The listener remains
|
|
94
|
+
available for a bounded commit-response retry window before graceful shutdown,
|
|
95
|
+
so a surviving activator can replace an elected peer that exits before launch
|
|
96
|
+
without discarding the older live sessions. The replacement starts with the
|
|
97
|
+
verified final leases. A full lease set refuses a distinct activating PID
|
|
98
|
+
without stopping the old listener. Finalization also reserves one of the 64
|
|
99
|
+
bounded lease slots for a distinct recovery activator; a 64-lease snapshot
|
|
100
|
+
cannot commit retirement and leaves the old listener running. The new MCP then
|
|
101
|
+
starts the current `session` version. A newer listener is never downgraded,
|
|
102
|
+
including during the brief old-to-new listener gap. If different newer versions
|
|
103
|
+
race, a higher contender authenticates and replaces a lower winner until the
|
|
104
|
+
highest active version remains.
|
|
105
|
+
|
|
106
|
+
Before acknowledging commit, the retiring session atomically records that
|
|
107
|
+
signed final snapshot in the mode-`0600` workspace file
|
|
108
|
+
`.taskchef-dashboard-handoff.json`. The record
|
|
109
|
+
contains no control secret. It exists only so an activator that loses every
|
|
110
|
+
commit response can authenticate and recover the exact finalized leases after
|
|
111
|
+
the old listener closes. The single record is retained and atomically
|
|
112
|
+
overwritten by the next finalized handoff; it cannot authenticate against a
|
|
113
|
+
new owner identity and secret. Avoiding post-publication deletion prevents one
|
|
114
|
+
replacement from removing a newer handoff generation. Invalid, permissively
|
|
115
|
+
readable, foreign-workspace, or incorrectly signed records are ignored and
|
|
116
|
+
never authorize takeover.
|
|
117
|
+
|
|
118
|
+
Both private metadata writers sync the completed file, atomically rename it,
|
|
119
|
+
and sync the canonical workspace directory before reporting publication. Final
|
|
120
|
+
lease joins are fenced before the immutable snapshot and durable write begin.
|
|
121
|
+
|
|
122
|
+
Versions predating authenticated ownership cannot be retired safely. Such a
|
|
123
|
+
legacy listener may require one final manual cleanup. This limitation is
|
|
124
|
+
intentional; TaskChef does not weaken listener safety to automate migration.
|
|
125
|
+
|
|
126
|
+
## Codex session end
|
|
127
|
+
|
|
128
|
+
Each MCP registers the exact PID of the Codex process that launched it. The
|
|
129
|
+
dashboard checks only those registered PIDs with a non-signalling existence
|
|
130
|
+
probe. When none remains alive for the configured grace period, the dashboard
|
|
131
|
+
gracefully closes its HTTP listener and exits. Registering another live Codex
|
|
132
|
+
session during the grace period cancels expiry.
|
|
133
|
+
|
|
134
|
+
This is a best-effort local lifecycle guard, not a claim that Codex documents
|
|
135
|
+
or guarantees restart cleanup. PID existence cannot prove application identity
|
|
136
|
+
after an unlikely PID reuse, and abrupt operating-system termination can always
|
|
137
|
+
interrupt graceful cleanup. A later MCP activation still performs authenticated
|
|
138
|
+
version handoff, which is the recovery boundary for a recognized stale
|
|
139
|
+
TaskChef listener.
|
|
140
|
+
|
|
141
|
+
## Security boundary
|
|
142
|
+
|
|
143
|
+
TaskChef writes ownership to `.taskchef-dashboard-owner.json` and finalized
|
|
144
|
+
handoff metadata to `.taskchef-dashboard-handoff.json` as private regular
|
|
145
|
+
mode-0600 files in the canonical workspace. The credential never appears in health responses,
|
|
146
|
+
diagnostics, URLs, or logs. A fresh nonce-bound HMAC challenge proves that the
|
|
147
|
+
listener and owner record share the credential. Shutdown and session
|
|
148
|
+
registration use separate action-bound proofs; successful registration and
|
|
149
|
+
handoff responses are also nonce- and result-bound. Nonces are single-use within
|
|
150
|
+
a bounded five-minute replay window. The replay cache has a fixed capacity and
|
|
151
|
+
refuses overflow while entries remain valid.
|
|
152
|
+
|
|
153
|
+
TaskChef sends control requests only after all public identity and private
|
|
154
|
+
ownership fields match. It never discovers or kills a port owner, sends OS
|
|
155
|
+
signals to a listener, uses `kill -9`, searches broadly for processes, or
|
|
156
|
+
requires elevated permission. These listeners remain untouched:
|
|
157
|
+
|
|
158
|
+
- standalone dashboards;
|
|
159
|
+
- unknown or spoofed services;
|
|
160
|
+
- different canonical workspaces;
|
|
161
|
+
- newer TaskChef versions;
|
|
162
|
+
- malformed or mismatched ownership records;
|
|
163
|
+
- listeners that fail the authenticated challenge;
|
|
164
|
+
- uncooperative legacy listeners without the handoff protocol.
|
|
165
|
+
|
|
166
|
+
## Lifecycle matrix
|
|
167
|
+
|
|
168
|
+
| Event | MCP transport | Canonical dashboard |
|
|
169
|
+
| --- | --- | --- |
|
|
170
|
+
| MCP activation, no listener | Starts | Starts current session version |
|
|
171
|
+
| MCP activation, exact listener | Starts | Authenticated reuse and lease registration |
|
|
172
|
+
| One MCP EOF, signal, or reload | Closes | Remains while a Codex session PID is alive |
|
|
173
|
+
| Plugin upgrade activates newer MCP | Starts current version | Verified older version retires; current version starts |
|
|
174
|
+
| All registered Codex session PIDs disappear | May already be closed | Graceful close after the grace period |
|
|
175
|
+
| `dashboard.autostart: false` | Starts normally | No activation-time ensure; explicit ensure still works |
|
|
176
|
+
| Foreground `taskchef dashboard` | Unrelated | Standalone process follows its foreground CLI lifetime |
|
|
177
|
+
| Unknown or unverified port occupant | Starts normally | Occupant is untouched; ensure reports a bounded conflict |
|
|
Binary file
|
package/docs/spec.md
CHANGED
|
@@ -57,9 +57,15 @@ is dated research, not contract.
|
|
|
57
57
|
|
|
58
58
|
## Workspace contract
|
|
59
59
|
|
|
60
|
-
TaskChef MUST manage only `AGENTS.md`, `taskchef.json`, `tasks.jsonl`,
|
|
61
|
-
optional `.taskchef-usage.json` cache
|
|
62
|
-
|
|
60
|
+
TaskChef MUST manage only `AGENTS.md`, `taskchef.json`, `tasks.jsonl`, the
|
|
61
|
+
optional `.taskchef-usage.json` cache, and the optional dashboard lifecycle
|
|
62
|
+
records `.taskchef-dashboard-owner.json` and
|
|
63
|
+
`.taskchef-dashboard-handoff.json` inside the dispatcher workspace. It MUST
|
|
64
|
+
preserve unrelated paths. The owner record MUST be a retained mode-`0600`
|
|
65
|
+
current-listener identity and control credential that is atomically replaced by
|
|
66
|
+
a new owner. The handoff record MUST be a retained mode-`0600`, secret-free,
|
|
67
|
+
credential-signed final lease snapshot that is atomically overwritten by the
|
|
68
|
+
next finalized handoff.
|
|
63
69
|
|
|
64
70
|
`taskchef.json` MUST have schema version 2, the following required fields, and
|
|
65
71
|
an optional exact `dashboard` object:
|
|
@@ -191,8 +197,9 @@ port conflicts, and dashboard errors MUST NOT prevent tool registration or MCP
|
|
|
191
197
|
availability. They MUST emit only a bounded non-sensitive diagnostic through
|
|
192
198
|
the MCP process logging channel. MCP initialization MUST NOT open a browser.
|
|
193
199
|
If transport connection fails after dashboard startup, the MCP server MUST
|
|
194
|
-
best-effort close
|
|
195
|
-
|
|
200
|
+
best-effort close its manager and partially attached transport, then propagate
|
|
201
|
+
the original connection failure even when cleanup also fails. Closing that
|
|
202
|
+
individual MCP MUST NOT directly close a valid Codex-session dashboard.
|
|
196
203
|
|
|
197
204
|
At the start of every dispatcher turn, the dispatcher SHOULD call
|
|
198
205
|
`ensure_dashboard` best-effort. Failure MUST NOT block direct TaskChef answers,
|
|
@@ -282,12 +289,11 @@ object. Validation, marker, identity, uniqueness, freshness, or filesystem
|
|
|
282
289
|
failures are surfaced as tool errors and MUST NOT partially mutate the log.
|
|
283
290
|
|
|
284
291
|
### `ensure_dashboard`
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
Exact-compatible reuse does not write it.
|
|
292
|
+
**Caller:** dispatcher. **Mutation:** starts or reuses the authenticated
|
|
293
|
+
Codex-session-scoped loopback dashboard. The first start writes a private
|
|
294
|
+
dashboard ownership record in the canonical workspace. The record remains
|
|
295
|
+
after shutdown and the next owner atomically replaces it before reporting
|
|
296
|
+
startup success.
|
|
291
297
|
|
|
292
298
|
**Input:** empty object.
|
|
293
299
|
|
|
@@ -296,7 +302,7 @@ Exact-compatible reuse does not write it.
|
|
|
296
302
|
```text
|
|
297
303
|
{ dashboard: {
|
|
298
304
|
action: "started" | "reused",
|
|
299
|
-
launcher: "
|
|
305
|
+
launcher: "session",
|
|
300
306
|
url: "http://127.0.0.1:3210/",
|
|
301
307
|
workspace: string,
|
|
302
308
|
taskchefVersion: string,
|
|
@@ -304,51 +310,98 @@ Exact-compatible reuse does not write it.
|
|
|
304
310
|
} }
|
|
305
311
|
```
|
|
306
312
|
|
|
307
|
-
MCP initialization MUST complete its best-effort
|
|
308
|
-
|
|
309
|
-
starts
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
listener
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
313
|
+
MCP initialization MUST complete its best-effort ensure before exposing the
|
|
314
|
+
MCP transport. Calls MUST serialize within one MCP process. The first call
|
|
315
|
+
starts a dashboard session process or reuses the exact current listener; later
|
|
316
|
+
and concurrent calls are idempotent. The stable default MUST bind only to
|
|
317
|
+
`127.0.0.1:3210` and MUST NOT accept a model-supplied workspace, host, port,
|
|
318
|
+
session PID, or credential.
|
|
319
|
+
|
|
320
|
+
Exact reuse MUST require the fixed service/schema, TaskChef version,
|
|
321
|
+
dashboard-server version, canonical workspace, and `session` launcher identity.
|
|
322
|
+
It MUST additionally prove the private owner credential and use a fresh,
|
|
323
|
+
single-use, action-bound HMAC to register the MCP's original Codex parent PID.
|
|
324
|
+
The registration acknowledgement and every transferred lease set MUST carry a
|
|
325
|
+
separate response HMAC bound to the request nonce and complete accepted result.
|
|
326
|
+
The independent dashboard MUST survive closure of an individual MCP transport.
|
|
327
|
+
The session manager MUST require an explicit nonzero port because a detached
|
|
328
|
+
child cannot safely return an ephemeral bound port without an additional IPC
|
|
329
|
+
ownership channel. Direct foreground server callers MAY continue to bind port
|
|
330
|
+
zero when they retain the returned listener.
|
|
331
|
+
|
|
332
|
+
The dashboard MUST track only explicitly registered PIDs using non-signalling
|
|
333
|
+
existence probes. Once every registered PID is absent for the grace period, it
|
|
334
|
+
MUST gracefully close its HTTP listener and exit. A new authenticated live
|
|
335
|
+
registration during the grace period MUST cancel expiry. This is a local
|
|
336
|
+
best-effort session guard, not a Codex restart guarantee.
|
|
337
|
+
|
|
338
|
+
An older TaskChef version MAY be retired only when its exact health identity
|
|
339
|
+
reports the same canonical workspace and an `mcp` or `session` launcher; a
|
|
340
|
+
private regular mode-0600 owner record exactly matches that listener; and a
|
|
341
|
+
fresh nonce-bound HMAC challenge proves control of the record's secret. Only
|
|
342
|
+
then MAY the new MCP send an action- and nonce-bound authenticated loopback
|
|
343
|
+
handoff. Before retiring a prior `session` listener, an idempotent prepare
|
|
344
|
+
action MUST fence new registrations, register the activating Codex PID,
|
|
345
|
+
validate and return the bounded live PID lease set while the old listener
|
|
346
|
+
remains running. Only a separate authenticated commit after the caller verifies
|
|
347
|
+
that result MAY schedule shutdown. A lost prepare response MUST be retryable,
|
|
348
|
+
and an abandoned preparation MUST expire without shutting down the listener. A
|
|
349
|
+
full, failed, or malformed transfer MUST leave the
|
|
350
|
+
listener running and MUST NOT acknowledge a concurrent registration that will
|
|
351
|
+
be absent from the returned set. A prior `mcp` listener MAY instead receive a
|
|
352
|
+
separately authenticated graceful shutdown request.
|
|
353
|
+
A commit MUST begin a short bounded finalization grace that allows concurrent
|
|
354
|
+
authenticated activators to join. Its response MUST contain a credential-bound
|
|
355
|
+
proof of the final immutable complete lease snapshot. The listener MUST remain
|
|
356
|
+
available for a bounded commit-response retry window before shutdown, so a
|
|
357
|
+
surviving activator can recover if the elected one exits before launch. An
|
|
358
|
+
activator observing the authenticated old-owner listener gap MUST wait for the
|
|
359
|
+
elected replacement and MUST NOT bind an older version into that gap.
|
|
360
|
+
The finalized transferable snapshot MUST reserve one bounded lease slot for a
|
|
361
|
+
distinct recovery activator. If that complete union cannot fit, commit MUST fail
|
|
362
|
+
without stopping the old listener. When different compatible newer versions
|
|
363
|
+
race, a higher version that loses the bind MUST authenticate and replace the
|
|
364
|
+
lower winner rather than accepting it as final.
|
|
365
|
+
Before acknowledging commit, the retiring session MUST atomically persist the
|
|
366
|
+
credential-bound final snapshot in a private mode-`0600` same-workspace record
|
|
367
|
+
that contains no secret. A replacement MAY use that record only after verifying
|
|
368
|
+
its exact workspace, listener identity, handoff identifier when known, bounded
|
|
369
|
+
PID set, and HMAC with the private owner credential. It MUST ignore the record
|
|
370
|
+
once replacement ownership is published, but MUST NOT unlink it after that
|
|
371
|
+
transition because a newer handoff may already have atomically replaced it. The
|
|
372
|
+
single retained record MUST be overwritten only by a newer finalized handoff
|
|
373
|
+
and MUST remain unusable against a different owner identity or credential.
|
|
374
|
+
Owner and handoff publication MUST sync the completed private file, atomically
|
|
375
|
+
rename it, and sync the containing canonical workspace directory before
|
|
376
|
+
reporting success. Finalization MUST fence further handoff joins before taking
|
|
377
|
+
and persisting the immutable snapshot.
|
|
378
|
+
The new MCP MAY then start its current `session` version and MUST NOT downgrade
|
|
379
|
+
a newer listener. Concurrent startup and handoff MUST converge on one
|
|
380
|
+
authenticated listener. Single-use control nonces MUST be retained in a fixed,
|
|
381
|
+
time-bounded replay cache that refuses overflow while entries remain valid.
|
|
382
|
+
|
|
383
|
+
The credential MUST NOT appear in health responses, requests, diagnostics, or
|
|
384
|
+
logs. A standalone, unknown, malformed, different-workspace, newer, unproven,
|
|
385
|
+
spoofed, or legacy listener without valid ownership metadata MUST produce a
|
|
386
|
+
concise actionable conflict and MUST NOT receive a shutdown request, signal,
|
|
387
|
+
or process-level termination attempt. TaskChef MUST NOT discover or kill port
|
|
388
|
+
owners. An invalid workspace, initial task log, or ownership write MUST leave
|
|
389
|
+
no newly owned listener.
|
|
390
|
+
|
|
391
|
+
Detached session startup MUST use a private child readiness acknowledgement
|
|
392
|
+
sent only after listener bind and atomic ownership publication. Startup errors
|
|
393
|
+
MUST propagate through that channel. A bounded readiness timeout MUST
|
|
394
|
+
cooperatively cancel the exact child so late initialization cannot strand an
|
|
395
|
+
unreported listener. Ownership publication MUST check cancellation before its
|
|
396
|
+
atomic replacement, and the listener MUST retain the port until that write
|
|
397
|
+
commits or aborts on every shutdown path so an older writer cannot overwrite a
|
|
398
|
+
successor's credential.
|
|
399
|
+
|
|
400
|
+
MCP EOF, explicit close, protocol close, SIGINT, SIGTERM, transport-start
|
|
401
|
+
failure, and MCP-parent loss MUST still bound MCP shutdown. They MUST close the
|
|
402
|
+
MCP manager and transport without directly closing the independently hosted
|
|
403
|
+
session dashboard. Foreground `taskchef dashboard` remains `standalone`, is
|
|
404
|
+
never adopted by MCP, and follows its foreground process lifetime.
|
|
352
405
|
|
|
353
406
|
The packaged `$taskchef-dashboard` skill MUST call this tool, report `started`
|
|
354
407
|
or `reused`, and return the canonical clickable URL. It MAY use an available
|
|
@@ -358,6 +411,9 @@ back to the link without failing. It MUST NOT inspect task outcomes or dispatch.
|
|
|
358
411
|
**Annotations:** `readOnlyHint: false`, `destructiveHint: false`,
|
|
359
412
|
`openWorldHint: false`.
|
|
360
413
|
|
|
414
|
+
The complete operational rationale and limits are documented in
|
|
415
|
+
[Dashboard lifecycle](dashboard-lifecycle.md).
|
|
416
|
+
|
|
361
417
|
### `prepare_dispatch`
|
|
362
418
|
|
|
363
419
|
**Caller:** dispatcher. **Mutation:** none.
|
|
@@ -643,8 +699,8 @@ identity or infer semantic results.
|
|
|
643
699
|
|
|
644
700
|
TaskChef MUST NOT install or require daemons, launchd agents, login items,
|
|
645
701
|
system services, cron jobs, hooks, privileged components, or elevated/system
|
|
646
|
-
permissions for dashboard availability. Availability is best-effort while
|
|
647
|
-
|
|
702
|
+
permissions for dashboard availability. Availability is best-effort while a
|
|
703
|
+
registered Codex session process is alive and is not guaranteed while Codex is
|
|
648
704
|
closed.
|
|
649
705
|
|
|
650
706
|
Releases predating authenticated dashboard handoff are legacy listeners. A
|
|
@@ -656,6 +712,6 @@ protocol, compatible prior-version handoff is automatic.
|
|
|
656
712
|
Installing or replacing plugin files MUST NOT be described as activating the
|
|
657
713
|
new MCP code. Release verification MUST install the plugin, activate or reload
|
|
658
714
|
the new MCP process, ensure the dashboard, and verify the expected TaskChef
|
|
659
|
-
version, dashboard protocol `serverVersion`, `
|
|
660
|
-
and canonical URL. Exact-compatible
|
|
715
|
+
version, dashboard protocol `serverVersion`, `session` launcher, canonical workspace,
|
|
716
|
+
and canonical URL. Exact-compatible session-listener reuse remains valid; installation MUST NOT be
|
|
661
717
|
claimed to reload Codex automatically.
|