ennodia 0.1.1 → 0.2.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.
Files changed (46) hide show
  1. package/CONTRIBUTING.md +60 -36
  2. package/README.md +74 -58
  3. package/bench/README.md +7 -5
  4. package/bench/bug-recall/run.ts +12 -4
  5. package/bin/ennodia +23 -2
  6. package/docs/assets/agents/mcp.svg +1 -1
  7. package/docs/assets/orchestration-pipeline.svg +4 -3
  8. package/docs/comparisons/agent-frameworks.md +15 -10
  9. package/docs/comparisons/autogen.md +20 -15
  10. package/docs/comparisons/chathub.md +15 -14
  11. package/docs/comparisons/index.md +30 -22
  12. package/docs/comparisons/langgraph.md +19 -12
  13. package/docs/comparisons/mixture-of-agents.md +20 -17
  14. package/docs/comparisons/model-merging.md +7 -5
  15. package/docs/comparisons/openrouter.md +30 -22
  16. package/docs/concepts/compositional-audits.md +16 -13
  17. package/docs/concepts/data-governance.md +31 -15
  18. package/docs/concepts/how-ennodia-works.md +48 -22
  19. package/docs/concepts/interfaces-and-core.md +19 -6
  20. package/docs/concepts/second-opinions.md +20 -20
  21. package/docs/getting-started.md +55 -27
  22. package/docs/guides/agent-skills.md +16 -13
  23. package/docs/guides/budgets-and-limits.md +30 -20
  24. package/docs/guides/running-better-audits.md +50 -44
  25. package/docs/index.md +60 -37
  26. package/docs/install.md +41 -32
  27. package/docs/reference/benchmarks.md +6 -4
  28. package/docs/reference/controlled-english.md +130 -0
  29. package/docs/reference/ennodia-io.md +28 -22
  30. package/docs/reference/mcp-tools.md +244 -87
  31. package/docs/reference/supported-harnesses.md +9 -9
  32. package/package.json +7 -5
  33. package/src/advisor.ts +685 -0
  34. package/src/budget.ts +25 -6
  35. package/src/cli.ts +1 -1
  36. package/src/compare.ts +248 -52
  37. package/src/compositional.ts +18 -0
  38. package/src/core.ts +547 -16
  39. package/src/harnesses.ts +33 -2
  40. package/src/index.ts +38 -0
  41. package/src/plan-advice.ts +601 -0
  42. package/src/runs.ts +74 -9
  43. package/src/server.ts +312 -46
  44. package/src/skills.ts +131 -11
  45. package/src/tasks.ts +192 -22
  46. package/src/version.ts +1 -1
@@ -1,12 +1,12 @@
1
1
  ---
2
- title: MCP Tools
3
- description: The public MCP tool surface exposed by Ennodia.
2
+ title: Model Context Protocol (MCP) Tools
3
+ description: The public Model Context Protocol (MCP) tool surface exposed by Ennodia.
4
4
  ---
5
5
 
6
- This page describes the tools exposed by the Ennodia MCP server. The normal
7
- entrypoint is `ennodia_run`: it starts a visible orchestration and returns a run
8
- ID. Use `ennodia_get_run` to poll status, events, child task IDs, Compare state,
9
- and the final answer.
6
+ This page describes the tools exposed by the Ennodia Model Context Protocol
7
+ (MCP) server. The normal entrypoint is `ennodia_run`. It starts a visible
8
+ orchestration and returns a run ID. Use `ennodia_get_run` to poll status,
9
+ events, child task IDs, Judge + Result Advisor state, and the final answer.
10
10
 
11
11
  ## Common Workflows
12
12
 
@@ -15,10 +15,11 @@ and the final answer.
15
15
  | Check local setup | `ennodia_list_harnesses` |
16
16
  | Preview route and cost | `ennodia_estimate_budget` |
17
17
  | Preview compositional shard cost | `ennodia_estimate_compositional_budget` |
18
+ | Request a tailored team, inspect it, then launch it | `ennodia_start_plan_advice` -> `ennodia_get_plan_advice` -> `ennodia_start_advised_plan` |
18
19
  | Start a visible end-to-end run | `ennodia_run` -> `ennodia_get_run` |
19
20
  | Start focused review shards | `ennodia_start_compositional` -> `ennodia_get_compositional_status` |
20
21
  | Debug raw child tasks | `ennodia_start` -> `ennodia_get_task` |
21
- | Compare completed outputs | `ennodia_start_compare` -> `ennodia_get_compare` |
22
+ | Judge completed outputs and advise on the result | `ennodia_start_compare` -> `ennodia_get_compare` |
22
23
  | Install bundled skills | `ennodia_list_skills` -> `ennodia_install_skills` |
23
24
  | Inspect terminal receipts after restart | `ennodia_history` |
24
25
 
@@ -30,33 +31,35 @@ examples, see [Budgets and Limits](/docs/guides/budgets-and-limits/).
30
31
 
31
32
  `ennodia_plan`, `ennodia_estimate_budget`, `ennodia_start`, and `ennodia_run`
32
33
  use local harness discovery plus either a caller-provided `category` or a
33
- lightweight keyword fallback. Pass `category` when the agent caller already
34
- knows the task type, and pass `refresh: true` to re-scan installed commands
35
- before planning or starting work.
34
+ lightweight keyword fallback. Pass `category` when the agent caller knows
35
+ the task type. Pass `refresh: true` to re-scan installed commands before
36
+ planning or starting work.
36
37
 
37
38
  `ennodia_start` and `ennodia_run` also accept `skillIds`. Ennodia treats skills
38
- as native Agent Skills: folders containing `SKILL.md`, installed in the paths
39
- each harness already understands. It does not inline full skill content into the
39
+ as native Agent Skills: folders containing `SKILL.md`, installed in paths
40
+ supported by each harness. It does not inline full skill content into the
40
41
  delegated prompt. Task and run views include selected skill metadata in
41
42
  `appliedSkills`.
42
43
 
43
44
  `ennodia_estimate_budget`, `ennodia_estimate_compositional_budget`,
44
- `ennodia_start`, `ennodia_run`, and `ennodia_start_compare` support a `budget`
45
- object for local preflight enforcement. Budgeting is an input-token estimate plus
46
- child-task count guard. It does not claim to know provider billing, output
47
- tokens, cache behavior, harness-internal context, or private subscription
48
- quota.
45
+ `ennodia_start`, `ennodia_run`, `ennodia_start_compare`,
46
+ `ennodia_start_plan_advice`, and `ennodia_start_advised_plan` support a `budget`
47
+ object for local preflight enforcement. Budgeting is an input-token estimate
48
+ plus child-task count guard. It does not claim to know provider billing, output
49
+ tokens, cache behavior, harness-internal context, or private subscription quota.
49
50
 
50
51
  ### Routing hints
51
52
 
52
53
  Ennodia uses `category` before keyword classification. Valid categories are
53
54
  `code`, `research`, `browser`, `image`, and `general`. The fallback classifier
54
- uses strong browser, image, code, and research signals; bare words such as
55
- `review` or `page` are not enough on their own. Pass `harnessId` to skip
55
+ uses strong browser, image, code, and research signals. Bare words such as
56
+ `review` or `page` do not route on their own. Pass `harnessId` to skip
56
57
  adapter choice and target a specific adapter.
57
58
 
58
59
  `harnessId` forces a specific adapter. Current adapter IDs are:
59
60
 
61
+ Each adapter starts a supported command-line interface (CLI).
62
+
60
63
  | ID | Tool |
61
64
  | --- | --- |
62
65
  | `claude-code` | <span class="agent-logo agent-logo--claude-code" aria-hidden="true"></span>Claude Code |
@@ -76,8 +79,9 @@ and character counts.
76
79
 
77
80
  ### `ennodia_list_harnesses`
78
81
 
79
- Detects supported local AI tools and reports availability, runnable state,
80
- command path, version, capabilities, and adapter notes.
82
+ Detects supported local artificial intelligence (AI) tools and reports
83
+ availability, runnable state, command path, version, capabilities, and adapter
84
+ notes.
81
85
 
82
86
  | Input | Default | Meaning |
83
87
  | --- | --- | --- |
@@ -133,9 +137,112 @@ child process.
133
137
  | `includeMermaid` | `true` | Include a presentational Mermaid route diagram. Set `false` for compact machine reads. |
134
138
 
135
139
  Returns the category, routing reasons, ordered candidate harness IDs, selected
136
- harness, whether parallel execution is suggested, whether Compare is suggested,
137
- and, by default, a Mermaid route diagram. Run and polling views do not embed
138
- that diagram.
140
+ harness, parallel execution guidance, Judge + Result Advisor guidance, and, by
141
+ default, a Mermaid route diagram. Run and
142
+ polling views do not embed that diagram.
143
+
144
+ ## Plan Advisor
145
+
146
+ Plan Advisor turns a natural-language task into a suggested team without making
147
+ that suggestion executable by itself. Plan Advisor sees a frozen inventory of
148
+ allowed harnesses, caller-approved models, installed skills, and hard size
149
+ limits. It can propose only explicit worker slices containing a prompt, harness,
150
+ optional model, and skill IDs. It cannot choose `cwd`, environment variables,
151
+ arguments, permissions, isolation, timeouts, retries, or budgets.
152
+
153
+ The lifecycle is deliberately two-phase: request and inspect advice first, then
154
+ launch the exact validated plan in a separate call. Ennodia rejects invalid
155
+ Plan Advisor output as a whole and revalidates the plan digest and current inventory
156
+ before starting any worker.
157
+
158
+ ### `ennodia_start_plan_advice`
159
+
160
+ Starts one Plan Advisor task. It starts no proposed worker task and returns an
161
+ advice `id` for polling with `ennodia_get_plan_advice`.
162
+
163
+ | Input | Default | Meaning |
164
+ | --- | --- | --- |
165
+ | `prompt` | required | Work for which Plan Advisor proposes a team. |
166
+ | `cwd` | server process cwd | Target directory used only to inventory project skills. The Plan Advisor task runs in a separate empty temporary directory. |
167
+ | `refresh` | `false` | Re-scan harnesses before freezing the inventory snapshot. |
168
+ | `advisorHarnessId` | harness priority | Harness used for the single Plan Advisor task. |
169
+ | `advisorModel` | Plan Advisor harness default | Optional model override for the Plan Advisor task. |
170
+ | `allowedHarnessIds` | all runnable public adapters | Worker harness IDs the proposal may select. |
171
+ | `allowedModels` | `{}` | Exact caller-approved worker model IDs grouped by harness. An omitted worker model means the harness default. |
172
+ | `maxSlices` | `8` | Maximum explicit worker slices. Capped at 64 and by `budget.maxChildTasks` when supplied. |
173
+ | `maxSkillsPerSlice` | `8` | Maximum native skills on one slice. Capped at 64. |
174
+ | `maxTotalSkillAssignments` | `32` | Maximum skill assignments across the plan. Capped at 1024. |
175
+ | `timeoutMs` | `300000` | Timeout for the one Plan Advisor task, capped at 1 hour. |
176
+ | `budget.maxEstimatedInputTokens` | none | Fail before Plan Advisor starts, or reject its proposal, if the estimate exceeds this value. |
177
+ | `budget.maxChildTasks` | none | Bound both the Plan Advisor start and proposed worker count. |
178
+
179
+ The returned view begins in `advising`. Terminal states are `ready`, `consumed`,
180
+ `invalid`, `failed`, and `cancelled`. Only `ready` advice can be authorized.
181
+ Authorization changes the status to `consumed`. A consumed plan cannot run
182
+ again. A ready view has a validated `plan` and `planDigest`.
183
+
184
+ ### `ennodia_get_plan_advice`
185
+
186
+ Returns Plan Advisor status, validation issues, inventory snapshot ID, proposal,
187
+ validated inert plan, and plan digest. It also returns budget checks, events,
188
+ timing, and estimated time of arrival (ETA). A consumed view also returns
189
+ `consumedAt`.
190
+
191
+ | Input | Default | Meaning |
192
+ | --- | --- | --- |
193
+ | `adviceId` | required | ID returned by `ennodia_start_plan_advice`. |
194
+ | `includeProposal` | `true` | Include the untrusted model-authored proposal when available. |
195
+ | `includePlan` | `true` | Include the validated inert plan when ready. |
196
+ | `includeEvents` | `true` | Include bounded lifecycle events. |
197
+ | `maxEvents` | `100` | Maximum events to return. Capped at 300. Use 0 to omit them. |
198
+
199
+ ### `ennodia_start_advised_plan`
200
+
201
+ Explicitly launches the exact plan from a `ready` advice result. Before the first
202
+ worker starts, Ennodia checks the supplied digest and refreshes the inventory.
203
+ It validates every harness and skill again. It confirms that explicit models
204
+ remain in the unchanged caller allowlist and enforces the caller-owned runtime budget.
205
+
206
+ Provider model availability remains unverified until its harness runs. Digest
207
+ mismatch, inventory drift, or deterministic validation failure starts zero
208
+ workers. Successful authorization consumes the advice before task launch. The
209
+ same advice cannot authorize a second launch.
210
+
211
+ | Input | Default | Meaning |
212
+ | --- | --- | --- |
213
+ | `adviceId` | required | Ready advice ID returned by `ennodia_start_plan_advice`. |
214
+ | `expectedPlanDigest` | required | Exact `planDigest` returned by `ennodia_get_plan_advice`. |
215
+ | `cwd` | inventoried directory | Working directory for worker tasks. |
216
+ | `isolateCwd` | `false` | Run each worker against an ephemeral isolated copy of `cwd`. Isolation fails before task spawn if the copied tree contains a symbolic link. The reported task `cwd` is an execution trace. Ennodia deletes the temporary copy after the task becomes terminal. |
217
+ | `timeoutMs` | `300000` | Per-worker timeout, capped at 1 hour. |
218
+ | `budget.maxEstimatedInputTokens` | none | Fail before any worker starts if the exact plan estimate exceeds this value. |
219
+ | `budget.maxChildTasks` | none | Fail before any worker starts if the exact slice count exceeds this value. |
220
+
221
+ The response reports the frozen plan and digest, task IDs mapped to slice IDs,
222
+ execution controls, and the budget check. It also reports unrequested installed
223
+ skills observed on the selected harnesses. This operation does not automatically run the Judge
224
+ and Result Advisor comparison.
225
+
226
+ ### `ennodia_cancel_plan_advice`
227
+
228
+ Cancels an `advising` request and its single Plan Advisor task. Pass `adviceId` from
229
+ `ennodia_start_plan_advice`. Calling it for a terminal request returns
230
+ the existing terminal view.
231
+
232
+ | Input | Default | Meaning |
233
+ | --- | --- | --- |
234
+ | `adviceId` | required | ID returned by `ennodia_start_plan_advice`. |
235
+
236
+ ### `ennodia_list_plan_advice`
237
+
238
+ Lists recent Plan Advisor requests from the current MCP server process.
239
+
240
+ | Input | Default | Meaning |
241
+ | --- | --- | --- |
242
+ | `includeProposal` | `false` | Include model-authored proposals. |
243
+ | `includePlan` | `false` | Include validated inert plans. |
244
+ | `includeEvents` | `false` | Include bounded event history. |
245
+ | `maxEvents` | `25` | Maximum events per item when included. Capped at 300. |
139
246
 
140
247
  ### `ennodia_estimate_budget`
141
248
 
@@ -148,9 +255,9 @@ and checks optional limits.
148
255
  | `category` | fallback classifier | Optional caller-provided category. |
149
256
  | `harnessId` | planner choice | Force one adapter by ID. |
150
257
  | `mode` | `auto` | `auto`, `single`, or `parallel`. |
151
- | `compare` | `auto` | Include Compare in the estimate. |
258
+ | `compare` | `auto` | Include the Judge + Result Advisor pass in the estimate. |
152
259
  | `refresh` | `false` | Re-scan harness discovery before planning. |
153
- | `maxOutputChars` | effective 24000 | Characters per successful task assumed for Compare; values above the judge prompt cap are estimated at 24000. |
260
+ | `maxOutputChars` | effective 24000 | Characters assumed for each successful task in Compare. Ennodia estimates values above the Judge prompt cap at 24000. |
154
261
  | `budget.maxEstimatedInputTokens` | none | Mark the estimate exceeded above this input-token count. |
155
262
  | `budget.maxChildTasks` | none | Mark the estimate exceeded above this child-task count. |
156
263
 
@@ -164,18 +271,19 @@ input tokens and child task count without starting child processes.
164
271
 
165
272
  | Input | Default | Meaning |
166
273
  | --- | --- | --- |
167
- | `prompt` | required | Overall question or synthesis goal that every slice belongs to. |
274
+ | `prompt` | required | Overall task or question that every slice belongs to. |
168
275
  | `slices[].id` | generated | Optional stable slice ID. Supplied IDs must be unique. |
169
276
  | `slices[].title` | none | Optional short label for the slice. |
170
277
  | `slices[].prompt` | required | Focused task prompt for the slice. |
171
278
  | `slices[].category` | fallback classifier | Optional caller-provided route category for this slice. |
172
279
  | `slices[].harnessId` | slice planner choice | Optional adapter ID for this slice. |
173
280
  | `slices[].model` | adapter default | Optional model override retained in the resolved slice summary. |
281
+ | `slices[].skillIds` | inherited | Slice-specific native skill IDs. An explicit list, including `[]`, replaces batch `skillIds`. |
174
282
  | `cwd` | server process cwd | Optional working directory used to validate requested native skills. |
175
283
  | `refresh` | `false` | Re-scan harness discovery before resolving slice routes. |
176
- | `skillIds` | `[]` | Optional installed native skill IDs to validate against every selected slice harness. |
177
- | `includeCompareEstimate` | `true` | Include a later Compare pass in the returned budget estimate. |
178
- | `maxOutputChars` | effective 24000 | Characters per successful slice output assumed for Compare; values above the judge prompt cap are estimated at 24000. |
284
+ | `skillIds` | `[]` | Default installed native skill IDs for slices that omit `slices[].skillIds`. |
285
+ | `includeCompareEstimate` | `true` | Include a later Judge + Result Advisor pass in the returned budget estimate. |
286
+ | `maxOutputChars` | effective 24000 | Characters assumed for each successful slice in Compare. Ennodia estimates values above the Judge prompt cap at 24000. |
179
287
  | `budget.maxEstimatedInputTokens` | none | Mark the estimate exceeded above this input-token count. |
180
288
  | `budget.maxChildTasks` | none | Mark the estimate exceeded above this child-task count. |
181
289
 
@@ -186,11 +294,12 @@ assumptions, subscription-limit check status, and exceeded issues.
186
294
 
187
295
  ### `ennodia_run`
188
296
 
189
- Starts the full orchestration: plan, execute one or more child tasks, optionally
190
- Compare successful outputs, and expose the final answer through `ennodia_get_run`.
191
- Runs usually take minutes; callers should poll `ennodia_get_run` with sensible
192
- spacing and trust `remainingMs`/`etaConfidence` instead of giving up after a few
193
- seconds.
297
+ Starts the full orchestration. It plans and executes one or more child tasks.
298
+ It can run the Judge + Result Advisor over successful outputs. It exposes the
299
+ final answer through `ennodia_get_run`.
300
+
301
+ Runs usually take minutes. Poll `ennodia_get_run` at sensible intervals. Trust
302
+ `remainingMs` and `etaConfidence`. Do not give up after a few seconds.
194
303
 
195
304
  | Input | Default | Meaning |
196
305
  | --- | --- | --- |
@@ -199,22 +308,26 @@ seconds.
199
308
  | `harnessId` | planner choice | Force one adapter by ID. |
200
309
  | `mode` | `auto` | `auto`, `single`, or `parallel`. |
201
310
  | `cwd` | server process cwd | Working directory for child commands. |
311
+ | `isolateCwd` | `false` | Run each selected harness against an ephemeral isolated copy of `cwd`. Isolation fails before task spawn if the copied tree contains a symbolic link. The reported task `cwd` is an execution trace. Ennodia deletes the temporary copy after the task becomes terminal. |
202
312
  | `model` | adapter default | Optional model override passed to task harnesses. |
203
313
  | `timeoutMs` | `300000` | Timeout for each child task, capped at 1 hour. |
204
314
  | `compare` | `auto` | `auto`, `true`, or `false`. |
205
315
  | `refresh` | `false` | Re-scan harness discovery before planning. |
206
- | `judgeHarnessId` | Compare priority | Harness used for the judge pass. |
207
- | `judgeModel` | judge default | Optional judge model override. |
208
- | `synthesizerHarnessId` | judge harness | Harness used for final synthesis. |
209
- | `synthesizerModel` | judge model | Optional synthesizer model override. |
210
- | `maxOutputChars` | `80000` | Characters per successful task loaded for Compare before the 24000-character judge-prompt cap. |
211
- | `skillIds` | `[]` | Optional list of installed native skill IDs to ask selected harnesses to use. |
316
+ | `judgeHarnessId` | Compare priority | Harness used for the Judge pass. |
317
+ | `judgeModel` | Judge default | Optional Judge model override. |
318
+ | `advisorHarnessId` | Judge harness | Harness used for the Result Advisor pass. |
319
+ | `advisorModel` | Result Advisor harness default | Optional Result Advisor model override. |
320
+ | `synthesizerHarnessId` | deprecated | Compatibility alias for `advisorHarnessId`. Ennodia rejects conflicting values. |
321
+ | `synthesizerModel` | deprecated | Compatibility alias for `advisorModel`. Ennodia rejects conflicting values. |
322
+ | `maxOutputChars` | `80000` | Characters per successful task loaded for Compare before the 24000-character Judge prompt cap. |
323
+ | `skillIds` | `[]` | Optional installed native skill IDs for selected harnesses. |
212
324
  | `budget.maxEstimatedInputTokens` | none | Fail before starting if estimated input tokens exceed this value. |
213
325
  | `budget.maxChildTasks` | none | Fail before starting if selected child tasks exceed this value. |
214
326
 
215
- Returns a run view with `id`, status, selected harnesses, child task IDs, Compare
216
- ID when one exists, events, timing, ETA, budget estimate/check, and final answer
217
- when already available. The important value is `id`; poll it with
327
+ Returns a run view with `id`, status, selected harnesses, child task IDs,
328
+ comparison ID when one exists, events, timing, ETA, and budget estimate/check.
329
+ It also returns the final answer when available. The important value is `id`.
330
+ Poll it with
218
331
  `ennodia_get_run`.
219
332
 
220
333
  ### `ennodia_get_run`
@@ -228,19 +341,19 @@ Returns the current run state.
228
341
  | `maxEvents` | `100` | Maximum run events to return. Capped at 300. |
229
342
  | `maxAnswerChars` | `80000` | Maximum final-answer characters. Capped at 200000. |
230
343
 
231
- Terminal run states are `succeeded`, `failed`, and `cancelled`. A run should not
232
- be considered complete before it reaches one of those states.
344
+ Terminal run states are `succeeded`, `failed`, and `cancelled`. A run is not
345
+ complete before it reaches one of those states.
233
346
 
234
347
  ### `ennodia_cancel_run`
235
348
 
236
- Cancels a high-level run and any active child task or Compare.
349
+ Cancels a high-level run and any active child task, Judge, or Result Advisor.
237
350
 
238
351
  | Input | Default | Meaning |
239
352
  | --- | --- | --- |
240
353
  | `runId` | required | ID returned by `ennodia_run`. |
241
354
 
242
- Cancellation is explicit. A cancelled run should not be presented as a normal
243
- model failure.
355
+ Cancellation is explicit. Do not present a run with `cancelled` status as a
356
+ normal model failure.
244
357
 
245
358
  ### `ennodia_list_runs`
246
359
 
@@ -253,13 +366,13 @@ Lists runs started by the current MCP server process.
253
366
  | `maxAnswerChars` | `2000` | Maximum answer characters per run. Capped at 200000. |
254
367
 
255
368
  Live run history is bounded and in-memory. Restarting the MCP server clears
256
- in-progress state; terminal receipts can still be read through
369
+ in-progress state. Terminal receipts remain available through
257
370
  `ennodia_history` when history is enabled.
258
371
 
259
372
  ### `ennodia_history`
260
373
 
261
374
  Lists terminal run snapshots persisted under the local history directory. Use it
262
- after a restart to inspect previous final answers and Compare disagreement
375
+ after a restart to inspect previous final answers and Judge disagreement
263
376
  analysis.
264
377
 
265
378
  | Input | Default | Meaning |
@@ -274,8 +387,8 @@ runs. Set `ENNODIA_HISTORY=0` to opt out.
274
387
 
275
388
  ### `ennodia_start`
276
389
 
277
- Starts one or more raw child tasks without run-level Compare or final synthesis.
278
- Use it for debugging adapters or for manual Compare workflows.
390
+ Starts one or more raw child tasks without a run-level Judge + Result Advisor
391
+ pass. Use it for debugging adapters or manual comparison workflows.
279
392
 
280
393
  | Input | Default | Meaning |
281
394
  | --- | --- | --- |
@@ -284,10 +397,11 @@ Use it for debugging adapters or for manual Compare workflows.
284
397
  | `harnessId` | planner choice | Force one adapter by ID. |
285
398
  | `mode` | `single` | `single` or `parallel`. |
286
399
  | `cwd` | server process cwd | Working directory for child commands. |
400
+ | `isolateCwd` | `false` | Run each task against an ephemeral isolated copy of `cwd`. Isolation fails before task spawn if the copied tree contains a symbolic link. The reported task `cwd` is an execution trace. Ennodia deletes the temporary copy after the task becomes terminal. |
287
401
  | `model` | adapter default | Optional model override. |
288
402
  | `timeoutMs` | `300000` | Timeout for each child task, capped at 1 hour. |
289
403
  | `refresh` | `false` | Re-scan harness discovery before planning. |
290
- | `skillIds` | `[]` | Optional list of installed native skill IDs to ask selected harnesses to use. |
404
+ | `skillIds` | `[]` | Optional installed native skill IDs for selected harnesses. |
291
405
  | `budget.maxEstimatedInputTokens` | none | Fail before starting if estimated input tokens exceed this value. |
292
406
  | `budget.maxChildTasks` | none | Fail before starting if selected child tasks exceed this value. |
293
407
 
@@ -296,25 +410,27 @@ Returns started task IDs, the route plan, and the budget estimate/check.
296
410
  ### `ennodia_start_compositional`
297
411
 
298
412
  Starts one focused child task per slice. Use it for large reviews where each
299
- agent should inspect a smaller part of the problem. The tool returns task IDs;
413
+ agent can inspect a smaller part of the problem. The tool returns task IDs.
300
414
  poll them with `ennodia_get_task`, then pass the useful completed task IDs to
301
415
  `ennodia_start_compare`.
302
416
 
303
417
  | Input | Default | Meaning |
304
418
  | --- | --- | --- |
305
- | `prompt` | required | Overall question or synthesis goal that every slice belongs to. |
419
+ | `prompt` | required | Overall task or question that every slice belongs to. |
306
420
  | `slices[].id` | generated | Optional stable slice ID. Supplied IDs must be unique. |
307
421
  | `slices[].title` | none | Optional short label for the slice. |
308
422
  | `slices[].prompt` | required | Focused task prompt for the slice. |
309
423
  | `slices[].category` | fallback classifier | Optional caller-provided route category for this slice. |
310
424
  | `slices[].harnessId` | slice planner choice | Optional adapter ID for this slice. |
311
425
  | `slices[].model` | adapter default | Optional model override for this slice. |
426
+ | `slices[].skillIds` | inherited | Slice-specific native skill IDs. An explicit list, including `[]`, replaces batch `skillIds`. |
312
427
  | `cwd` | server process cwd | Working directory for child commands. |
428
+ | `isolateCwd` | `false` | Run each slice against an ephemeral isolated copy of `cwd`. Isolation fails before task spawn if the copied tree contains a symbolic link. The reported task `cwd` is an execution trace. Ennodia deletes the temporary copy after the task becomes terminal. |
313
429
  | `timeoutMs` | `300000` | Timeout for each slice task, capped at 1 hour. |
314
430
  | `refresh` | `false` | Re-scan harness discovery before resolving slice routes. |
315
- | `skillIds` | `[]` | Optional installed native skill IDs to ask every selected slice harness to use. |
316
- | `includeCompareEstimate` | `true` | Include a later Compare pass in the returned budget estimate. |
317
- | `maxOutputChars` | effective 24000 | Characters per successful slice output assumed for Compare; values above the judge prompt cap are estimated at 24000. |
431
+ | `skillIds` | `[]` | Default installed native skill IDs for slices that omit `slices[].skillIds`. |
432
+ | `includeCompareEstimate` | `true` | Include a later Judge + Result Advisor pass in the returned budget estimate. |
433
+ | `maxOutputChars` | effective 24000 | Characters assumed for each successful slice in Compare. Ennodia estimates values above the Judge prompt cap at 24000. |
318
434
  | `budget.maxEstimatedInputTokens` | none | Fail before starting if estimated input tokens exceed this value. |
319
435
  | `budget.maxChildTasks` | none | Fail before starting if slice child tasks exceed this value. |
320
436
 
@@ -323,21 +439,21 @@ ready-to-use `compareNext` object for the later `ennodia_start_compare` call.
323
439
 
324
440
  ### `ennodia_get_compositional_status`
325
441
 
326
- Inspects several shard task IDs at once, groups their states, and returns the
327
- successful non-empty task IDs that are ready for Compare.
442
+ Inspects multiple shard task IDs at once, groups their states, and returns the
443
+ successful non-empty task IDs ready for a Judge + Result Advisor comparison.
328
444
 
329
445
  | Input | Default | Meaning |
330
446
  | --- | --- | --- |
331
447
  | `taskIds` | required | Shard task IDs returned by `ennodia_start_compositional`. |
332
- | `prompt` | none | Optional synthesis prompt included in `compareNext` when enough outputs are ready. |
448
+ | `prompt` | none | Optional comparison prompt included in `compareNext` when the minimum outputs are ready. |
333
449
  | `minSuccessfulTasksForCompare` | `2` | Minimum successful non-empty outputs required for `compareReady`. |
334
450
  | `includeOutput` | `false` | Include bounded stdout and stderr previews for known tasks. |
335
451
  | `maxOutputChars` | `2000` | Maximum stdout and stderr characters per task when output is included. |
336
452
 
337
453
  The response includes `readyTaskIds`, `runningTaskIds`, `failedTaskIds`,
338
- `cancelledTaskIds`, `emptySucceededTaskIds`, `missingTaskIds`, grouped counts,
339
- compact task summaries, and `compareNext` when a synthesis prompt was supplied
340
- and enough task outputs are ready.
454
+ `cancelledTaskIds`, `emptySucceededTaskIds`, and `missingTaskIds`. It includes
455
+ grouped counts, compact task summaries, and `compareNext` when a comparison
456
+ prompt was supplied and the minimum task outputs are ready.
341
457
 
342
458
  ### `ennodia_get_task`
343
459
 
@@ -345,11 +461,11 @@ Returns task status, captured output, events, timing, and ETA.
345
461
 
346
462
  | Input | Default | Meaning |
347
463
  | --- | --- | --- |
348
- | `taskId` | required | ID returned by `ennodia_start`, `ennodia_run`, or Compare. |
464
+ | `taskId` | required | ID returned by a raw, compositional, advised-plan, run, Plan Advisor, or Compare start. |
349
465
  | `includeOutput` | `true` | Include bounded stdout and stderr. |
350
466
  | `includeEvents` | `true` | Include bounded task events. |
351
- | `maxOutputChars` | `200000` | Maximum stdout and stderr characters. Capped at 200000. |
352
- | `maxEvents` | `300` | Maximum task events. Capped at 300. |
467
+ | `maxOutputChars` | `20000` | Maximum stdout and stderr characters. Capped at 200000. |
468
+ | `maxEvents` | `100` | Maximum task events. Capped at 300. |
353
469
 
354
470
  A task is terminal only after the child process exits and stdout/stderr have
355
471
  drained or timed out visibly.
@@ -358,16 +474,32 @@ drained or timed out visibly.
358
474
 
359
475
  Cancels a running task by task ID.
360
476
 
477
+ | Input | Default | Meaning |
478
+ | --- | --- | --- |
479
+ | `taskId` | required | ID returned by a task start. |
480
+
361
481
  ### `ennodia_list_tasks`
362
482
 
363
483
  Lists recent tasks started by the current MCP server process. By default it
364
- returns a compact view; request output or events only when you need them.
484
+ returns a compact view. Request output or events only when you need them.
365
485
 
366
- ## Compare
486
+ | Input | Default | Meaning |
487
+ | --- | --- | --- |
488
+ | `includeOutput` | `false` | Include bounded stdout and stderr previews for each task. |
489
+ | `includeEvents` | `false` | Include bounded task events for each task. |
490
+ | `maxOutputChars` | `4000` | Maximum stdout and stderr characters per task. Capped at 200000. |
491
+ | `maxEvents` | `25` | Maximum events per task. Capped at 300. |
492
+
493
+ ## Judge + Result Advisor
494
+
495
+ The existing `ennodia_*_compare` tool names remain for compatibility. Their
496
+ public workflow is Judge + Result Advisor: the Judge analyzes the candidates,
497
+ then Result Advisor produces the final recommendation. Result Advisor can degrade
498
+ visibly to candidate-only advice when Judge analysis is unavailable.
367
499
 
368
500
  ### `ennodia_start_compare`
369
501
 
370
- Runs a judge pass and then a synthesizer pass over completed Ennodia tasks or
502
+ Runs a Judge pass and then a Result Advisor pass over completed Ennodia tasks or
371
503
  caller-supplied responses.
372
504
 
373
505
  | Input | Default | Meaning |
@@ -375,28 +507,53 @@ caller-supplied responses.
375
507
  | `prompt` | required | Original user task or question the candidates answer. |
376
508
  | `taskIds` | `[]` | Completed Ennodia task IDs to compare. |
377
509
  | `responses` | `[]` | Caller-supplied responses with IDs, labels, and text. |
378
- | `judgeHarnessId` | Compare priority | Harness used for the judge pass. |
379
- | `judgeModel` | judge default | Optional judge model override. |
380
- | `synthesizerHarnessId` | judge harness | Harness used for final synthesis. |
381
- | `synthesizerModel` | judge model | Optional synthesizer model override. |
382
- | `maxOutputChars` | `80000` | Characters per task candidate loaded for Compare before the 24000-character judge-prompt cap. |
383
- | `budget.maxEstimatedInputTokens` | none | Fail before starting if estimated judge/synthesizer input tokens exceed this value. |
384
- | `budget.maxChildTasks` | none | Fail before starting if the judge plus synthesizer task count exceeds this value. |
385
-
386
- Compare asks the judge for agreements, contradictions, unique insights, blind
387
- spots, and risks. The synthesizer uses that analysis plus the original
388
- candidates to produce one answer. This is model-led comparison, not formal
389
- voting.
510
+ | `judgeHarnessId` | Compare priority | Harness used for the Judge pass. |
511
+ | `judgeModel` | Judge default | Optional Judge model override. |
512
+ | `advisorHarnessId` | Judge harness | Harness used for the Result Advisor pass. |
513
+ | `advisorModel` | Result Advisor harness default | Optional Result Advisor model override. |
514
+ | `synthesizerHarnessId` | deprecated | Compatibility alias for `advisorHarnessId`. Ennodia rejects conflicting values. |
515
+ | `synthesizerModel` | deprecated | Compatibility alias for `advisorModel`. Ennodia rejects conflicting values. |
516
+ | `cwd` | server process cwd | Working directory for the Judge and Result Advisor tasks. |
517
+ | `timeoutMs` | `300000` | Timeout for each child task. Capped at 1 hour. |
518
+ | `maxOutputChars` | `80000` | Characters per task candidate loaded for Compare before the 24000-character Judge prompt cap. |
519
+ | `budget.maxEstimatedInputTokens` | none | Fail before starting if estimated Judge/Result Advisor input tokens exceed this value. |
520
+ | `budget.maxChildTasks` | none | Fail before starting if the Judge plus Result Advisor task count exceeds this value. |
521
+
522
+ Compare requests that the Judge map agreements, contradictions, unique insights,
523
+ blind spots, and risks. The Result Advisor uses that analysis plus the original
524
+ candidates to return a typed answer, basis, confidence, and open questions.
525
+ This is model-led comparison, not formal voting.
390
526
 
391
527
  ### `ennodia_get_compare`
392
528
 
393
- Returns Compare status, candidate inputs, judge analysis, synthesis, child task
394
- IDs, timing, and ETA.
529
+ Returns comparison status, candidate inputs, Judge analysis, and typed Result
530
+ Advisor output, child task IDs, degradation events, timing, and ETA. Deprecated
531
+ `synthesis` fields remain available for compatibility.
532
+
533
+ | Input | Default | Meaning |
534
+ | --- | --- | --- |
535
+ | `compareId` | required | ID returned by `ennodia_start_compare` or `ennodia_run`. |
536
+ | `includeCandidates` | `true` | Include bounded candidate response previews. |
537
+ | `includeEvents` | `true` | Include bounded Judge and Result Advisor events. |
538
+ | `maxCandidateChars` | `8000` | Maximum characters per candidate. Capped at 200000. |
539
+ | `maxEvents` | `100` | Maximum comparison events. Capped at 300. |
395
540
 
396
541
  ### `ennodia_cancel_compare`
397
542
 
398
- Cancels a running Compare and its active child task.
543
+ Cancels a running Judge + Result Advisor comparison and its active child task.
544
+
545
+ | Input | Default | Meaning |
546
+ | --- | --- | --- |
547
+ | `compareId` | required | ID returned by `ennodia_start_compare` or `ennodia_run`. |
399
548
 
400
549
  ### `ennodia_list_compares`
401
550
 
402
- Lists recent Compare runs started by the current MCP server process.
551
+ Lists recent Judge + Result Advisor comparisons started by the current MCP
552
+ server process.
553
+
554
+ | Input | Default | Meaning |
555
+ | --- | --- | --- |
556
+ | `includeCandidates` | `false` | Include bounded candidate response previews for each comparison. |
557
+ | `includeEvents` | `false` | Include bounded Judge and Result Advisor events. |
558
+ | `maxCandidateChars` | `2000` | Maximum characters per candidate. Capped at 200000. |
559
+ | `maxEvents` | `25` | Maximum events per comparison. Capped at 300. |
@@ -1,18 +1,18 @@
1
1
  ---
2
2
  title: Supported Harnesses
3
- description: Current Ennodia adapter IDs, local CLI surfaces, and setup notes for each supported harness.
3
+ description: Current Ennodia adapter IDs, local command-line interface (CLI) surfaces, and setup notes for each supported harness.
4
4
  ---
5
5
 
6
- Ennodia coordinates local agent CLIs through thin adapters. Use
7
- `ennodia_list_harnesses` to see what is installed and runnable on the current
8
- machine.
6
+ Ennodia coordinates local agents through thin adapters. Each harness uses a
7
+ local command-line interface (CLI). Use `ennodia_list_harnesses` to see what is
8
+ installed and runnable on the current machine.
9
9
 
10
10
  ## Adapter IDs
11
11
 
12
12
  | ID | Tool | Notes |
13
13
  | --- | --- | --- |
14
14
  | `claude-code` | <span class="agent-logo agent-logo--claude-code" aria-hidden="true"></span>Claude Code | Runs through `claude -p` without permission-bypass flags. |
15
- | `codex` | <span class="agent-logo agent-logo--codex" aria-hidden="true"></span>Codex CLI | Runs through `codex exec`; Ennodia-launched tasks default to read-only sandboxing. |
15
+ | `codex` | <span class="agent-logo agent-logo--codex" aria-hidden="true"></span>Codex CLI | Runs through `codex exec`. Ennodia tasks use read-only sandboxing by default. |
16
16
  | `opencode` | <span class="agent-logo agent-logo--opencode" aria-hidden="true"></span>OpenCode | Runs through `opencode run`. |
17
17
  | `kilo` | <span class="agent-logo agent-logo--kilo-code" aria-hidden="true"></span>Kilo Code | Uses the supported Kilo CLI surface when available. |
18
18
  | `kiro` | <span class="agent-logo agent-logo--kiro" aria-hidden="true"></span>Kiro CLI | Uses the supported Kiro CLI surface when available. |
@@ -37,7 +37,7 @@ capabilities, and adapter notes.
37
37
  ## Claude Code Models
38
38
 
39
39
  Claude Code model aliases can change. When exact model selection matters, pass
40
- the full model ID, such as `claude-sonnet-5` or `claude-fable-5`, instead of an
40
+ the full model ID, such as `claude-sonnet-5` or `claude-fable-5`, rather than an
41
41
  alias like `sonnet` or `fable`.
42
42
 
43
43
  Do not add permission-bypass flags by default.
@@ -57,7 +57,7 @@ such as `opencode-go/kimi-k2.7-code`.
57
57
 
58
58
  ## Antigravity
59
59
 
60
- Antigravity can fail setup when the `agy` CLI is not on `PATH`. Ask the user or
60
+ Antigravity can fail setup when the `agy` CLI is not on `PATH`. Tell the user or
61
61
  primary agent to verify:
62
62
 
63
63
  ```sh
@@ -67,5 +67,5 @@ agy models
67
67
  ```
68
68
 
69
69
  If the shell cannot find `agy` at all, open Antigravity and use its supported
70
- CLI install or shell-integration flow first. Then restart the MCP client and
71
- call `ennodia_list_harnesses` again.
70
+ CLI install or shell-integration flow first. Then restart the Model Context
71
+ Protocol (MCP) client and call `ennodia_list_harnesses` again.
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "ennodia",
3
- "version": "0.1.1",
3
+ "version": "0.2.0",
4
4
  "mcpName": "io.github.cherninlab/ennodia",
5
- "description": "MCP server for multi-agent review with Compare and traceable receipts",
5
+ "description": "Local MCP server for AI team advice, multi-agent review, Compare, and traceable receipts",
6
6
  "license": "MIT",
7
7
  "type": "module",
8
8
  "packageManager": "bun@1.3.14",
@@ -36,6 +36,7 @@
36
36
  "bench/fixtures/**/*",
37
37
  "bench/results/.gitkeep",
38
38
  "src/cli.ts",
39
+ "src/advisor.ts",
39
40
  "src/budget.ts",
40
41
  "src/compare.ts",
41
42
  "src/compositional.ts",
@@ -46,6 +47,7 @@
46
47
  "src/index.ts",
47
48
  "src/internal.ts",
48
49
  "src/planner.ts",
50
+ "src/plan-advice.ts",
49
51
  "src/priority.ts",
50
52
  "src/runs.ts",
51
53
  "src/server.ts",
@@ -63,8 +65,7 @@
63
65
  ".": "./src/index.ts"
64
66
  },
65
67
  "workspaces": [
66
- "website",
67
- "packages/ennodia-io"
68
+ "website"
68
69
  ],
69
70
  "bin": {
70
71
  "ennodia": "bin/ennodia"
@@ -80,6 +81,7 @@
80
81
  "smoke": "bun run src/dev/smoke.ts",
81
82
  "agent-font:build": "bun run src/dev/build-agent-font.ts",
82
83
  "mcp:smoke": "bun run src/dev/mcp-smoke.ts",
84
+ "controlled-english:check": "bun run src/dev/check-controlled-english.ts",
83
85
  "io:smoke": "bun run --cwd packages/ennodia-io smoke",
84
86
  "task:smoke": "bun run src/dev/task-smoke.ts",
85
87
  "bench:bug-recall": "bun run bench/bug-recall/run.ts",
@@ -93,7 +95,7 @@
93
95
  "website:dev": "bun run --cwd website dev",
94
96
  "website:build": "bun run --cwd website build",
95
97
  "website:deploy": "bun run --cwd website deploy",
96
- "verify": "bun run check && bun run lint && bun run test && bun run website:build && bun run task:smoke && bun run mcp:smoke && bun run io:smoke"
98
+ "verify": "bun run check && bun run lint && bun run test && bun run website:build && bun run controlled-english:check && bun run task:smoke && bun run mcp:smoke && bun run io:smoke"
97
99
  },
98
100
  "dependencies": {
99
101
  "@modelcontextprotocol/sdk": "^1.29.0",