taskchef 8.4.2 → 8.5.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.4.2",
3
+ "version": "8.5.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
@@ -100,9 +100,22 @@ malformed, preview an explicit config or state restore, then bind the apply to
100
100
  the preview's raw-state hash and plan with --confirm-unreadable-current.
101
101
 
102
102
  Reindexing catches TaskChef up with newly saved Codex projects by comparing
103
- exact canonical paths and indexing missing requested projects. It preserves
104
- existing curated entries and does not silently remove projects or overwrite
105
- metadata.
103
+ exact same-host canonical paths from one native schema-2 project snapshot.
104
+ Reconciliation adds eligible paths and identity bindings atomically, isolates
105
+ per-project failures, and preserves existing curated names, descriptions, and
106
+ complete repository lists. It does not delete missing projects. Duplicate
107
+ native IDs, duplicate canonical targets, and identity/path moves remain
108
+ diagnostics rather than guesses.
109
+
110
+ Configuration schema 2 accepts an optional strict `projectIndex` containing
111
+ local native identity bindings, explicit exclusions, and bounded routing hints.
112
+ Removing a project records an exclusion so reconciliation cannot silently
113
+ re-add it; `include_project` clears an exact exclusion before a later reconcile.
114
+ Aliases come only from explicit selection or correction. Repository ownership
115
+ requires an inspected exact origin, and report-derived responsibilities retain
116
+ their accepted task/thread/turn provenance. Forgetting keeps bounded suppression
117
+ so an old report retry cannot recreate a removed hint. Older TaskChef releases
118
+ reject this optional field; use a compatible backup before downgrading.
106
119
 
107
120
  Codex CLI resolution follows the same contract as
108
121
  `workspace init --register-codex`: an explicit `--codex-cli` path wins, then
@@ -149,7 +162,8 @@ From another project, invoke the delegation skill explicitly:
149
162
  $taskchef-delegate In payments, add structured logs for failed retries and test them.
150
163
  ```
151
164
 
152
- TaskChef prepares a UUID and marker, persists the task before native creation,
165
+ The dispatcher lists native projects once per batch, reconciles that snapshot,
166
+ then prepares a UUID and marker for each outcome, persists the task before native creation,
153
167
  creates the executor, and returns its task link. New executor instructions keep
154
168
  the assignment visible from the first line, add a concise local reporting
155
169
  authorization paragraph, leave one blank line, then place
@@ -19,6 +19,8 @@ This folder is the canonical per-user TaskChef dispatcher workspace.
19
19
  - For every other actionable request that asks for an independent new outcome,
20
20
  use `$taskchef-delegate` automatically, even when the user does not explicitly
21
21
  say "delegate" or mention TaskChef.
22
+ - Delegation lists native projects once per batch, reconciles that exact
23
+ snapshot once, and routes only to one eligible exact native target.
22
24
  - GitHub issue and pull-request URLs may identify any repository advertised by
23
25
  a configured project, including child repositories of managed workspaces.
24
26
  - Do not perform delegated work directly in the dispatcher thread.
package/docs/spec.md CHANGED
@@ -65,7 +65,7 @@ preserve unrelated paths. Dashboard process identity and Codex-session leases
65
65
  MUST remain in memory and MUST NOT create owner, secret, or handoff files.
66
66
 
67
67
  `taskchef.json` MUST have schema version 2, the following required fields, and
68
- an optional exact `dashboard` object:
68
+ optional exact `dashboard` and `projectIndex` objects:
69
69
 
70
70
  ```json
71
71
  {
@@ -85,6 +85,15 @@ is backward-compatible and means `true`; new workspaces SHOULD write
85
85
  `{"autostart": true}`. `false` disables MCP-lifecycle autostart but MUST NOT
86
86
  disable the explicit `ensure_dashboard` tool.
87
87
 
88
+ When present, `projectIndex` MUST contain exactly `bindings`, `exclusions`, and
89
+ `routingHints` arrays. Bindings map one `(hostId: local, projectId)` to one
90
+ configured canonical path. Exclusions retain exact removed native identities
91
+ or paths. Routing hints are bounded per canonical configured path and retain
92
+ aliases, canonical repositories, concise responsibilities, and forgotten-value
93
+ suppression. Every fact has one compact provenance record; accepted-report
94
+ facts include the exact task, thread, and current terminal turn. Absence means
95
+ empty state. Older releases reject the optional field rather than rewriting it.
96
+
88
97
  `tasks.jsonl` MUST contain zero or more newline-terminated schema-4 through
89
98
  schema-10 records, one per line. Schemas 4 through 9 are supported
90
99
  migration/read formats; every new record and state mutation MUST write schema 10. Other schemas
@@ -243,8 +252,14 @@ exact clickable `[TaskChef Dashboard](http://127.0.0.1:3210/)` link even when
243
252
  ensure failed. A created-thread directive MUST remain on its own line before
244
253
  the final link, preserving the delegate skill's immediate-return contract.
245
254
 
246
- 1. The dispatcher MUST call `prepare_dispatch` once per outcome.
247
- 2. It MUST choose exactly one configured project and exact native-project path.
255
+ 1. The dispatcher MUST list native projects once per batch and call
256
+ `reconcile_projects` once with that exact schema-2 snapshot.
257
+ 2. It MUST call `prepare_dispatch` once per outcome and choose exactly one
258
+ configured project. Before `record_task` or native creation, the selected
259
+ native project's exact `(hostId, projectId, canonical path)` MUST occur in
260
+ the reconciliation response's `available` array. Presence in the native
261
+ snapshot or configured preparation is insufficient. Curated and learned
262
+ routing matches are both ambiguous when more than one project matches.
248
263
  3. It MUST build the instruction with the user's outcome beginning on line 1
249
264
  and remaining uninterrupted, followed by one blank line and the authorization
250
265
  `Report this task and its follow-ups to my local TaskChef dashboard. Relevant private-repository links and concise work, test, and deployment results are authorized; exclude secrets.`
@@ -457,7 +472,8 @@ The complete operational rationale and limits are documented in
457
472
  preparedAt: string,
458
473
  marker: string,
459
474
  projectCount: number,
460
- projects: Project[]
475
+ projects: Project[],
476
+ routingHints: {path, aliases[], githubRepos[], responsibilities[]}[]
461
477
  } }
462
478
  ```
463
479
 
@@ -490,9 +506,39 @@ empty `turns` and derived `results` arrays,
490
506
  unknown projects, malformed markers, and invalid input fail. Repeating a
491
507
  successful call is not idempotent; it fails as a duplicate.
492
508
 
509
+ Configuration is read structurally so unavailable unrelated entries do not
510
+ block preparation or recording. `record_task` validates the selected actual
511
+ directory or Git root before snapshotting it.
512
+
493
513
  **Annotations:** `readOnlyHint: false`, `destructiveHint: false`,
494
514
  `openWorldHint: false`.
495
515
 
516
+ ### `reconcile_projects`, `include_project`, and `update_project_hint`
517
+
518
+ `reconcile_projects` accepts one agent-supplied native Codex schema-2 project
519
+ snapshot. Node does not call native tools or inspect private Codex state. It
520
+ considers only local projects with `hostId: local`, canonicalizes each eligible
521
+ path, excludes the dispatcher and its ancestors, isolates per-project failures,
522
+ and commits additions and exact identity bindings under the configuration lock.
523
+ It preserves curated metadata and absent projects. Repeated identical or empty
524
+ snapshots do not write. Duplicate IDs, canonical targets, or identity/path moves
525
+ produce bounded diagnostics. Its MCP response contains counts, current eligible
526
+ targets, diagnostics, and changed state rather than full configuration copies.
527
+
528
+ Removing a configured project records an exclusion. `include_project` removes
529
+ one exact exclusion by native project ID or canonical path; a later reconcile
530
+ must validate and add the target. A move is handled through exact preview-bound
531
+ removal, explicit inclusion, and reconciliation of the new path.
532
+
533
+ `update_project_hint` remembers, corrects, or forgets one bounded fact. Aliases
534
+ require explicit user evidence; correction is the only operation that removes
535
+ the same alias from another project. Repository ownership requires an inspected
536
+ exact origin from the selected project or a contained Git root. Responsibilities
537
+ require an accepted current terminal task/thread/turn. Forgetting requires
538
+ explicit user evidence and leaves bounded suppression against stale report
539
+ replay. Learning remains separate from terminal reporting and a learning error
540
+ cannot undo an accepted result.
541
+
496
542
  ### `link_task`
497
543
 
498
544
  **Caller:** executor. **Mutation:** one atomic identity transition.
package/docs/workflows.md CHANGED
@@ -127,13 +127,12 @@ sequenceDiagram
127
127
  participant C as Native Codex
128
128
  participant E as Executor
129
129
  U->>D: Request outcome
130
- par Route once
131
- D->>C: List native projects
132
- and Prepare each outcome
130
+ D->>C: List native projects once
131
+ D->>M: reconcile_projects(snapshot)
132
+ M-->>D: Counts, available targets, diagnostics
133
+ par Prepare each outcome
133
134
  D->>M: prepare_dispatch()
134
- M->>W: prepareDispatch()
135
- W-->>M: UUID, marker, projects
136
- M-->>D: preparation
135
+ M-->>D: UUID, marker, projects
137
136
  end
138
137
  D->>D: Choose one configured and native project
139
138
  D->>M: record_task(id, project, title, instruction, null)
@@ -451,6 +450,15 @@ inside the critical section. Writes use temporary files/hard links and atomic
451
450
  rename so readers see complete snapshots. Configuration replacement syncs the
452
451
  new file and workspace directory before its audit transaction is committed.
453
452
 
453
+ Project reconciliation consumes one agent-supplied native schema-2 snapshot;
454
+ the Node process never calls native Codex project tools. It filters to eligible
455
+ local-host targets, canonicalizes paths, preserves curated and missing entries,
456
+ and writes only when projects or identity bindings change. Explicit removal
457
+ stores an exclusion. Learned aliases, repository ownership, and responsibilities
458
+ stay in bounded configuration slots with compact evidence and never alter
459
+ historical task snapshots. Optional learning happens after an accepted terminal
460
+ report, so its failure cannot change that task result.
461
+
454
462
  The dispatcher controls routing and immutable intent. The executor controls its
455
463
  cooperatively asserted identity and semantic result. Neither identity nor
456
464
  summary is cryptographically authenticated; this is a local single-user trust
package/index.js CHANGED
@@ -10,6 +10,7 @@ export {
10
10
  ensureWorkspaceInstructions,
11
11
  filterTasks,
12
12
  importProjects,
13
+ includeProject,
13
14
  initializeWorkspace,
14
15
  linkTask,
15
16
  listProjects,
@@ -20,6 +21,7 @@ export {
20
21
  manuallyTransitionTask,
21
22
  migrateTaskLog,
22
23
  prepareDispatch,
24
+ reconcileProjects,
23
25
  readConfig,
24
26
  listTasks,
25
27
  readTask,
@@ -31,6 +33,7 @@ export {
31
33
  restoreWorkspaceBackup,
32
34
  validateConfig,
33
35
  updateProject,
36
+ updateProjectHint,
34
37
  verifyWorkspaceBackup,
35
38
  } from "./src/workspace.js";
36
39
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "taskchef",
3
- "version": "8.4.2",
3
+ "version": "8.5.1",
4
4
  "description": "A non-blocking interactive dispatcher for visible Codex tasks.",
5
5
  "license": "MIT",
6
6
  "author": "Favo Yang",
@@ -39,14 +39,17 @@ all deterministic workspace operations.
39
39
  invokes the supported `codex app <path>` command through a validated Codex
40
40
  CLI discovered from the current desktop environment; never invoke
41
41
  `codex add` or hard-code an application bundle path.
42
- 3. `workspace init` takes no stdin, creates an empty
42
+ 3. After registration is verified, pass the final native schema-2 snapshot to
43
+ `reconcile_projects` once. Preserve its diagnostics; one unavailable or
44
+ ineligible project does not invalidate eligible additions.
45
+ 4. `workspace init` takes no stdin, creates an empty
43
46
  configuration when missing, creates the one-entry-per-task JSONL log, and
44
47
  refreshes managed instructions. The installed plugin provides all four
45
48
  TaskChef skills outside the dispatcher workspace.
46
- 4. Run `doctor --json` after setup or when the user asks to diagnose the
49
+ 5. Run `doctor --json` after setup or when the user asks to diagnose the
47
50
  workspace. Doctor is read-only. Rerun `workspace init --json` to repair the
48
51
  managed scaffold.
49
- 5. Report the actions or failed checks. A successful initialization with failed
52
+ 6. Report the actions or failed checks. A successful initialization with failed
50
53
  Codex opening remains initialized but not verified as a saved local project.
51
54
  End without dispatching unless the user
52
55
  separately requested work.
@@ -60,6 +63,11 @@ proof of registration. Completion requires verifying the intended index entry
60
63
  and the complete project set. Any operation that removes a project entry
61
64
  requires the user's explicit permission for the exact removed names; removing a
62
65
  repository URL from an entry does not authorize removing the entry.
66
+ Removal records a reconciliation exclusion. Use `include_project` only after an
67
+ explicit request to include that exact native project again, then reconcile a
68
+ fresh native snapshot. An identity/path move remains diagnostic until the old
69
+ exact entry is removed through its preview-bound workflow, its exclusion is
70
+ explicitly cleared, and reconciliation validates the new target.
63
71
 
64
72
  ## Optional model roles
65
73
 
@@ -9,6 +9,14 @@ delegation. It stores canonical paths and routing metadata such as curated
9
9
  names, descriptions, Git status, and GitHub repositories. It does not index
10
10
  repository contents or create a second kind of project.
11
11
 
12
+ For a whole-project refresh, pass the agent's single native schema-2
13
+ `list_projects` snapshot to `reconcile_projects`. TaskChef validates local
14
+ `hostId: local` entries, canonicalizes each path, isolates per-project failures,
15
+ adds new eligible paths, and binds native project IDs only by exact same-host
16
+ canonical path. It preserves curated names, descriptions, and complete
17
+ repository lists. Missing native entries are retained; duplicate identities,
18
+ duplicate canonical targets, and identity/path moves return diagnostics.
19
+
12
20
  Index only Codex projects local to the TaskChef workspace's execution host.
13
21
  Remote connection projects are outside the v1 contract. Never index the
14
22
  TaskChef dispatcher workspace or a directory containing it; the dispatcher is
@@ -69,11 +77,8 @@ the correct workspace rather than guessing from the folder name.
69
77
  ### Reindex after Codex changes
70
78
 
71
79
  When the user asks TaskChef to reindex or catch up after saving more projects in
72
- Codex, list native local Codex projects once and run `project list --json` once
73
- before mutation. Compare exact canonical paths, then index each requested
74
- eligible Codex project that is missing from TaskChef by following the
75
- appropriate path above, sharing the batch verification instead of relisting
76
- after each write. After all additions, run `project list --json` once more and
80
+ Codex, list native projects once and call `reconcile_projects` once with that
81
+ exact snapshot. After reconciliation, run `project list --json` once and
77
82
  verify every intended canonical path and its routing metadata before reporting
78
83
  the index as current.
79
84
 
@@ -135,3 +140,15 @@ TaskChef accepts configuration schema version 2 only. Its optional exact
135
140
  `false` opts out of MCP-lifecycle dashboard startup without disabling manual
136
141
  `$taskchef-dashboard` recovery. `githubRepos` is always an array; unsupported
137
142
  configuration is rejected without being rewritten.
143
+
144
+ Schema 2 also accepts an optional strict `projectIndex` object holding local
145
+ native identity bindings, explicit exclusions, and bounded routing hints.
146
+ Absence means empty state. Removing a project records an exclusion so later
147
+ reconciliation cannot silently re-add it; an explicit `include_project` clears
148
+ that exclusion. Aliases require explicit user selection. Repository facts
149
+ require an inspected exact origin, including a contained Git root when a
150
+ workspace owns child repositories. Report-derived responsibilities retain the
151
+ accepted task, thread, and turn as compact provenance. Forgetting retains a
152
+ bounded suppression entry so an old report retry cannot recreate the fact.
153
+ Older TaskChef releases reject configurations containing `projectIndex`;
154
+ downgrade by restoring a compatible backup rather than editing live state.
@@ -24,9 +24,10 @@ delegated tasks. Execute a valid one in the current task. Do not re-dispatch it
24
24
  merely because it concerns TaskChef or a configured project. Explicit requests
25
25
  to delegate separate work remain valid.
26
26
 
27
- Use the bundled `prepare_dispatch`, `record_task`, and `report_state` MCP tools
28
- directly. Never fall back to shell writes. If a required tool is unavailable,
29
- stop and report that the TaskChef plugin must be reloaded or installed.
27
+ Use the bundled `reconcile_projects`, `prepare_dispatch`, `record_task`, and
28
+ `report_state` MCP tools directly. Never fall back to shell writes. If a
29
+ required tool is unavailable, stop and report that the TaskChef plugin must be
30
+ reloaded or installed.
30
31
 
31
32
  ## Boundaries
32
33
 
@@ -45,12 +46,18 @@ stop and report that the TaskChef plugin must be reloaded or installed.
45
46
 
46
47
  1. Split the request into the smallest independently useful outcomes. Include
47
48
  constraints, expected testing, and reporting in every instruction.
48
- 2. In parallel, list native Codex projects once and call `prepare_dispatch`
49
- exactly once per outcome. Never reuse a task ID or marker. Do not take a
50
- pre-creation thread snapshot.
51
- 3. Route against configured project `name`, `description`, and canonical
52
- `githubRepos`; use `path` only as checkout identity. Require exactly one
53
- match and an exact native-project path. Ask instead of guessing.
49
+ 2. List native Codex projects once. Pass that exact schema-2 snapshot to
50
+ `reconcile_projects` once for the complete batch, then call
51
+ `prepare_dispatch` exactly once per outcome. Never reuse a task ID or marker.
52
+ Do not take a pre-creation thread snapshot.
53
+ 3. Route against configured project `name`, `description`, canonical
54
+ `githubRepos`, and the preparation's bounded aliases, repository ownership,
55
+ and responsibilities. Use `path` only as checkout identity. Before
56
+ `record_task` or native creation, require exactly one entry in the
57
+ reconciliation's `available` array whose `hostId`, `projectId`, and canonical
58
+ `path` exactly match the selected native project. A matching snapshot path or
59
+ configured preparation alone does not establish eligibility. Treat a missing
60
+ entry or duplicate learned matches as ambiguous and ask instead of guessing.
54
61
  Select the `orchestrator` preference from preparation for every visible
55
62
  parent. Resolve explicit choices and follow
56
63
  [model roles](references/model-roles.md). Missing configuration means omit
@@ -84,3 +91,7 @@ stop and report that the TaskChef plugin must be reloaded or installed.
84
91
  `report_state` with it as `turnRef`, `failed`, null thread and Codex turn IDs,
85
92
  and a bounded summary before returning the failure. Retain that UUID for an
86
93
  exact retry.
94
+
95
+ When the user explicitly selects or corrects a project name or alias, call
96
+ `update_project_hint` with explicit-user evidence after routing. A guessed
97
+ route, generic keywords, or ordinary task wording is never learning evidence.
@@ -124,6 +124,16 @@ and unnecessary personal data. Identical lifecycle retries are safe; never
124
124
  replace a same-`turnRef` report with different content or let an older turn
125
125
  overwrite newer state.
126
126
 
127
+ After an accepted terminal report, `update_project_hint` may optionally retain
128
+ one concise responsibility when that report coherently establishes it. Supply
129
+ the same task ID, self-linked thread ID, and current turn ref as provenance.
130
+ Repository ownership may be retained only after inspecting the exact selected
131
+ repository or a contained Git root and verifying that exact canonical origin;
132
+ include that repository path with the same accepted task/turn provenance.
133
+ Never learn aliases, scan the transcript, or derive generic keywords here. A
134
+ learning failure is nonfatal to the accepted task result: report it separately
135
+ and do not retry with weaker evidence.
136
+
127
137
  ## Preserve delivery context
128
138
 
129
139
  Summaries are the durable TaskChef timeline; the dashboard does not scan the
@@ -40,6 +40,12 @@ export function projectDiff(beforeProjects, afterProjects) {
40
40
 
41
41
  export function mutationPreview(workspace, operation, beforeConfig, afterConfig) {
42
42
  const diff = projectDiff(beforeConfig.projects, afterConfig.projects);
43
+ const emptyIndex = { bindings: [], exclusions: [], routingHints: [] };
44
+ const beforeProjectIndex = beforeConfig.projectIndex ?? emptyIndex;
45
+ const afterProjectIndex = afterConfig.projectIndex ?? emptyIndex;
46
+ const projectIndexDiff = JSON.stringify(beforeProjectIndex) === JSON.stringify(afterProjectIndex)
47
+ ? null
48
+ : { before: beforeProjectIndex, after: afterProjectIndex };
43
49
  const preview = {
44
50
  schemaVersion: 1,
45
51
  operation,
@@ -50,6 +56,7 @@ export function mutationPreview(workspace, operation, beforeConfig, afterConfig)
50
56
  beforeCount: beforeConfig.projects.length,
51
57
  afterCount: afterConfig.projects.length,
52
58
  diff,
59
+ projectIndexDiff,
53
60
  projects: afterConfig.projects,
54
61
  };
55
62
  return {
@@ -61,6 +68,7 @@ export function mutationPreview(workspace, operation, beforeConfig, afterConfig)
61
68
  beforeConfigHash: preview.beforeConfigHash,
62
69
  afterConfigHash: preview.afterConfigHash,
63
70
  diff,
71
+ projectIndexDiff,
64
72
  }, "taskchef-mutation-plan-v1"),
65
73
  };
66
74
  }