taskchef 8.3.0 → 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.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "taskchef",
3
- "version": "8.3.0",
3
+ "version": "8.3.1",
4
4
  "description": "Dispatch work from a data-only workspace to visible Codex project tasks.",
5
5
  "author": {
6
6
  "name": "Favo Yang",
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:
@@ -272,40 +270,36 @@ $taskchef-dashboard Ensure and open the TaskChef dashboard.
272
270
  MCP activation and `$taskchef-dashboard` call the input-free `ensure_dashboard`
273
271
  MCP tool. It starts at most one loopback dashboard scoped to the running Codex
274
272
  session on `127.0.0.1:3210`, or reuses a listener only when its bounded
275
- `/api/health` identity proves the exact TaskChef/dashboard-server version,
276
- canonical workspace, and `session` launcher. The response says `started` or
277
- `reused` and includes the stable URL, canonical workspace, and versions.
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.
278
277
 
279
278
  The dashboard is launched by MCP but is not hosted by one MCP transport. It
280
279
  therefore survives an individual MCP close, stdin EOF, signal, or plugin reload.
281
- Each MCP securely registers its original Codex parent PID; after every
282
- registered Codex session PID disappears for a grace period, the dashboard
283
- closes and exits. Activating an installed newer TaskChef MCP authenticates and
284
- retires a compatible older `mcp`- or `session`-owned dashboard for the same
285
- canonical workspace, then starts the installed version. These are best-effort
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
286
288
  local guards, not a claim that Codex supplies a restart guarantee. TaskChef adds
287
289
  no daemon or OS-persistent component. See the complete
288
290
  [dashboard lifecycle](docs/dashboard-lifecycle.md).
289
291
 
290
- Authenticated handoff requires the older listener to have written TaskChef's
291
- private mode-0600 ownership record in that canonical workspace. A nonce-bound
292
- HMAC challenge proves the listener has the matching secret before TaskChef
293
- sends an authenticated two-phase handoff. A session listener prepares by
294
- fencing ordinary joins, adding the activating Codex PID, and returning a signed
295
- bounded lease snapshot while remaining live. A separate authenticated commit
296
- allows a short concurrent-activator grace, returns the signed final immutable
297
- lease set, and then schedules graceful shutdown after a bounded response-retry
298
- window. A mode-`0600`, secret-free, signed final-snapshot record permits exact
299
- lease recovery if every commit response is lost; a prior MCP-owned listener
300
- receives a separately authenticated graceful shutdown request. The secret is never
301
- returned by `/api/health`, sent in a request, or logged. Standalone,
302
- different-workspace, newer, malformed,
303
- unverified, and spoofed listeners are left untouched. Versions predating this
304
- protocol cannot be taken over safely and may require one final manual cleanup.
305
- The ownership record is durable metadata: shutdown retains it, and the next
306
- MCP owner atomically replaces it after binding. This avoids both a live
307
- credentialless retirement window and an old process deleting its replacement's
308
- 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.
309
303
 
310
304
  Autostart is enabled when `dashboard` is absent and in new workspaces. To opt
311
305
  out, add this optional exact object to `taskchef.json` while retaining its other
@@ -382,10 +376,9 @@ The header shows the running TaskChef package version reported by the same
382
376
  bounded health identity used for compatible-listener checks.
383
377
  The Settings page shows the ccusage version reported by the executable that
384
378
  TaskChef resolves at runtime.
385
- The canonical port is owned by a dashboard session process initialized by the
386
- TaskChef MCP before its tool transport connects. Health identity records a
387
- `session` launcher, and MCP recovery reuses only another exact-compatible,
388
- 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;
389
382
  a foreground `taskchef dashboard` process is intentionally standalone so its
390
383
  child commands cannot silently inherit an agent-shell sandbox.
391
384
  Task and result times are relative through 29 days (with minute detail for the
@@ -400,11 +393,16 @@ its task disappears; selecting it then explains that current details are no
400
393
  longer available.
401
394
  Apart from an explicit manual state selection from the task-detail menu, it does not mutate
402
395
  TaskChef data and prints its local URL. A foreground dashboard identifies
403
- itself as standalone and is never reused on the canonical MCP port. If a
404
- standalone, unknown, different-workspace, or stale-version process owns port
405
- 3210, TaskChef reports a concise conflict and never kills or replaces that
406
- process. The foreground CLI similarly asks you to stop the listener or choose
407
- another `--port`.
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`.
408
406
 
409
407
  The health endpoint contains only a fixed service marker, health schema,
410
408
  TaskChef version, dashboard-server version, canonical workspace, and launcher.
@@ -472,24 +470,22 @@ does not necessarily reload Codex. Then run `$taskchef-dashboard` (or call
472
470
 
473
471
  - the expected released TaskChef version;
474
472
  - the expected dashboard protocol `serverVersion`;
475
- - the `session` dashboard launcher;
473
+ - the reported dashboard launcher (`session` for a newly started canonical dashboard);
476
474
  - the canonical TaskChef workspace path;
477
475
  - the canonical `http://127.0.0.1:3210/` URL.
478
476
 
479
477
  The release-install sequence is therefore: install plugin, activate or reload
480
478
  the new MCP process, ensure the dashboard, then verify TaskChef version,
481
- protocol `serverVersion`, `session` launcher, canonical workspace, and URL.
482
- Exact-compatible session servers may be reused; standalone and unknown listeners
483
- 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.
484
482
 
485
483
  If autostart reports a **verified older TaskChef** listener, the port occupant
486
- passed the bounded TaskChef identity check but could not complete authenticated
487
- handoff. For a release older than the ownership protocol, stop that one known
488
- legacy MCP process once through the application/session that launched it, then
489
- activate the installed plugin again. Do not kill an arbitrary port owner. A
490
- listener from a handoff-capable prior release should retire automatically; if
491
- it does not, retain it for diagnosis because TaskChef deliberately refuses to
492
- 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.
493
489
 
494
490
  ## Development
495
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
- ## Ownership model
8
+ ## Process model
9
9
 
10
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.
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` process remains a separate
18
- `standalone` launcher and is never adopted as the canonical session dashboard.
17
+ service. A foreground `taskchef dashboard` remains a separate `standalone`
18
+ launcher.
19
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. 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
- ![Pending token usage in the task detail view](images/dashboard-token-pending.jpg)
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
- ![Reported work across a multi-turn task](images/reported-work-duration-desktop.jpg)
20
+ ## Start and reuse
65
21
 
66
- ![Unavailable reported work on a narrow layout](images/reported-work-duration-mobile.jpg)
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
- ## Start and reuse
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
- An actual new dashboard server creates or deduplicates a verified private state
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
- The dashboard watches both task history and the project index. It warns when
76
- historical task snapshots reference paths absent from the current index, and
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
- Unless `dashboard.autostart` is explicitly `false`, MCP activation runs the
81
- same serialized ensure operation exposed by `ensure_dashboard` before the MCP
82
- transport connects. An explicit ensure remains available when autostart is
83
- disabled. Failure is isolated from MCP tool startup and emits only a bounded,
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
- ## MCP reload and plugin upgrade
113
+ ![Pending token usage in the task detail view](images/dashboard-token-pending.jpg)
116
114
 
117
- Closing one MCP transport does not close the session dashboard. EOF, SIGINT,
118
- SIGTERM, protocol close, failed transport startup, and detected MCP-parent loss
119
- still close that MCP process promptly, but the independently hosted dashboard
120
- remains while a registered Codex session PID is alive.
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 | MCP transport | Canonical dashboard |
210
- | --- | --- | --- |
211
- | MCP activation, no listener | Starts | Starts current session version |
212
- | MCP activation, exact listener | Starts | Authenticated reuse and lease registration |
213
- | One MCP EOF, signal, or reload | Closes | Remains while a Codex session PID is alive |
214
- | Plugin upgrade activates newer MCP | Starts current version | Verified older version retires; current version starts |
215
- | All registered Codex session PIDs disappear | May already be closed | Graceful close after the grace period |
216
- | `dashboard.autostart: false` | Starts normally | No activation-time ensure; explicit ensure still works |
217
- | Foreground `taskchef dashboard` | Unrelated | Standalone process follows its foreground CLI lifetime |
218
- | Unknown or unverified port occupant | Starts normally | Occupant is untouched; ensure reports a bounded conflict |
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 |