create-byan-agent 2.21.0 → 2.22.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -9,6 +9,46 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
9
9
 
10
10
  ## [Unreleased]
11
11
 
12
+ ## [2.22.0] - 2026-06-09
13
+
14
+ ### Changed - byan_dispatch routes the model tier by task nature, not by size
15
+
16
+ `byan_dispatch` fused two unrelated decisions into one route string
17
+ (`mcp-worker-haiku`, `main-thread-opus`): a short sequential task was downgraded
18
+ to haiku purely on its length, and a long one was pinned up to opus. That is the
19
+ size-driven mis-tiering the native-workflow doctrine (`native-tiers.js`) was built
20
+ to forbid, so the two routers disagreed. This decouples the two axes and makes
21
+ `native-tiers.js` the single source of truth for the model tier across both worlds.
22
+
23
+ - **Two independent axes.** `dispatch.js` now returns
24
+ `{ score, strategy, nature, tier, model, parallelizable, reasoning }`. STRATEGY
25
+ (where the work runs: `main-thread` / `agent-subagent-worktree` / `mcp-worker`)
26
+ stays derived from the scalar score + `parallelizable`. TIER (which model) is
27
+ derived from the task NATURE, decoupled from size.
28
+ - **One source of truth.** `dispatch.js` imports `classifyLeaf` / `tierFor` /
29
+ `TIER_MODEL` directly from `native-tiers.js` — a one-way dependency toward the
30
+ tier authority rather than a duplicated rule. Only an `exploration` nature
31
+ downgrades to `haiku`; `implementation` / `verification` / `analysis` (and any
32
+ unmatched task) stay `deep` (inherit the session model). No pin-up to opus.
33
+ - **Conservative by default.** An optional `nature` arg sets the tier directly;
34
+ absent or invalid, the task text is classified, whose own default is
35
+ `implementation` (deep) — so a miss protects the work instead of downgrading it.
36
+ - **Consumers realigned.** The `byan_dispatch` tool schema gains an optional
37
+ `nature` enum; the three consuming skills (byan-byan Phase 4, byan-hermes-dispatch
38
+ step 3, byan-orchestrate) read `strategy` + `model` from the new shape. The
39
+ fused-route strings are dropped from the live routing path.
40
+ - 22 dispatch unit tests pin the contract (no downgrade for protected natures,
41
+ exploration to haiku, no pin-up, conservative fallback, strategy preserved across
42
+ the score bands) plus the hermes-e2e non-regression. Template re-synced.
43
+
44
+ ### Known debt
45
+
46
+ The legacy fused-route vocabulary (`mcp-worker-haiku` / `main-thread-opus`) still
47
+ appears in two doctrine docs (`_byan/worker/workers.md`,
48
+ `_byan/workflow/simple/byan/feature-workflow.md`) and a dead, unreferenced parallel
49
+ router (`src/core/dispatcher/execution-router.js` + its test). These have no live
50
+ consumer and are scoped to a follow-up cleanup.
51
+
12
52
  ## [2.21.0] - 2026-06-08
13
53
 
14
54
  ### Added - Template fidelity sync (the published package matches its CHANGELOG)
@@ -56,11 +56,16 @@ Never call `byan_update_apply` without explicit user consent. That tool returns
56
56
 
57
57
  ### Phase 4 — DISPATCH
58
58
  - **Who** : you + user. Route each feature to the right BYAN component.
59
- - **Decision table** per feature :
60
- - **Score < 15** inline main-thread, no subagent
61
- - **Score 15-39 parallelizable** → agent-subagent-worktree (use `byan_dispatch` MCP tool to verify)
62
- - **Score 15-39 sequential** → mcp-worker-haiku
63
- - **Score 40** → main-thread-opus or delegate to `byan-hermes-dispatch`
59
+ - **Decision table** per feature — TWO independent axes (`byan_dispatch` returns both) :
60
+ - **Strategy** (WHERE it runs), from the score :
61
+ - **Score < 15** → inline main-thread, no subagent
62
+ - **Score 15-39 parallelizable** → agent-subagent-worktree
63
+ - **Score 15-39 sequential** → mcp-worker
64
+ - **Score ≥ 40** → main-thread (heavy) or delegate to `byan-hermes-dispatch`
65
+ - **Model tier** (WHICH model), from the task NATURE — not its size (`byan_dispatch` returns it as `model`, via native-tiers, the single source of truth) :
66
+ - nature `exploration` (load/read/scan/list/parse/fetch...) → `haiku`
67
+ - nature `implementation` / `verification` / `analysis` / unknown → deep = **inherit the session model**
68
+ - Keep protected work (verify/analysis/implement) off haiku regardless of size ; no pin-up to opus. Pass an explicit `nature` to `byan_dispatch` when you know it.
64
69
  - **Output** : a table `{ feature → specialist → model → strategy → estimated_tokens }`.
65
70
  - **If no specialist matches** : halt. Ask user whether to run INT (agent recruitment) first. Do NOT fallback silently to general-purpose.
66
71
  - **Exit gate** : user validates the mapping.
@@ -50,18 +50,19 @@ Match keywords against the routing table below. Pick the single best match. If n
50
50
 
51
51
  ### 3. Pick the execution strategy (MCP call)
52
52
 
53
- Call the `byan_dispatch` MCP tool with `{ task: <goal>, parallelizable: <bool> }`. It returns `{ strategy, score, reasoning }` where strategy is one of :
53
+ Call the `byan_dispatch` MCP tool with `{ task: <goal>, parallelizable: <bool>, nature?: <leaf-type> }`. It returns `{ score, strategy, nature, tier, model, reasoning }` TWO independent axes :
54
54
 
55
- - `main-thread` do it inline, no delegation
56
- - `agent-subagent-worktree` — spawn Agent tool with isolation worktree
57
- - `mcp-worker-haiku` — spawn Agent tool with Haiku model, no worktree
58
- - `main-thread-opus` — keep in the current thread (don't delegate, Opus needed)
55
+ - **strategy** (WHERE it runs), from the score :
56
+ - `main-thread` — do it inline, no delegation
57
+ - `agent-subagent-worktree` — spawn Agent tool with isolation worktree
58
+ - `mcp-worker` — spawn Agent tool, no worktree
59
+ - **model** (WHICH model), from the task NATURE via native-tiers, not its size : `haiku` (exploration only) or `null` = deep (inherit the session model). Pass an explicit `nature` (`exploration`/`implementation`/`verification`/`analysis`) when you know it; protected natures stay off haiku.
59
60
 
60
61
  ### 4. Spawn the work
61
62
 
62
- Depending on strategy :
63
+ Depending on strategy (apply the returned `model` whenever you spawn) :
63
64
 
64
- **`main-thread` or `main-thread-opus`** : do not spawn. Execute inline yourself.
65
+ **`main-thread`** : do not spawn. Execute inline yourself — the work runs on the session model.
65
66
 
66
67
  **`agent-subagent-worktree`** : call the Agent tool with :
67
68
  ```
@@ -76,7 +77,9 @@ prompt: |
76
77
  When done, write a concise report (< 200 words).
77
78
  ```
78
79
 
79
- **`mcp-worker-haiku`** : same Agent tool call but without `isolation`, and add `model: "haiku"` in the prompt's instruction block if the receiving subagent honors it.
80
+ **`mcp-worker`** : same Agent tool call but without `isolation`. Set the Agent's `model` to the returned `model` — `haiku` for exploration nature, otherwise omit `model` to inherit the session model. The tier follows the task nature, not its size.
81
+
82
+ For any spawned strategy : pass `model` to the Agent tool when it is non-null; omit it when null so the subagent inherits the session model.
80
83
 
81
84
  ### 5. Specialist stub path lookup
82
85
 
@@ -9,7 +9,7 @@ You compose three existing building blocks into one multi-role flow :
9
9
 
10
10
  | Block | Role |
11
11
  |-------|------|
12
- | `byan_dispatch` MCP tool | Per-task execution strategy (main-thread / agent-subagent-worktree / mcp-worker-haiku / main-thread-opus) + complexity score |
12
+ | `byan_dispatch` MCP tool | Per-task strategy (main-thread / agent-subagent-worktree / mcp-worker) from the score + model tier by NATURE (haiku for exploration, else inherit the session model) + complexity score |
13
13
  | `byan-hermes-dispatch` skill | Specialist lookup (architect, dev, analyst, …) from a routing table |
14
14
  | `party-mode-native` workflow | Parallel spawn via Agent tool + worktree + coordination JSON |
15
15
 
@@ -42,7 +42,7 @@ Use this a priori mapping — override only if the task clearly needs more :
42
42
  | architect, quinn, tea, creative-problem-solver | opus | Deep reasoning, trade-offs |
43
43
  | carmack, rachid, marc, patnote | haiku | Narrow mechanical tasks |
44
44
 
45
- Then call `byan_dispatch` with each role's goal to get a complexity score. If the score demands a different tier (score >= 40bump to opus ; score < 15inline, no subagent), **override the default for that role**.
45
+ Then call `byan_dispatch` with each role's goal (and `nature` when known). Use its `score` for the STRATEGY only (score < 15inline, no subagent ; 15-39 subagent/worker ; ≥ 40 keep the heavy role in the main thread) and its nature-based `model` as the tier signal. The score sets WHERE the role runs, not WHICH model — keep protected roles (verify/analysis/implement) off haiku regardless of size, and avoid pinning a role up to opus on size alone. The per-role table above is the a-priori floor; `byan_dispatch`'s nature `model` refines it.
46
46
 
47
47
  ### 3. Compute the execution plan
48
48
 
@@ -69,7 +69,7 @@ Group roles by `parallelizable_with` graph. For each parallel cluster :
69
69
 
70
70
  - If cluster has N > 1 roles AND all use `agent-subagent-worktree` strategy → use the **party-mode-native** workflow : `coordination.initSession(roles, …)`, then dispatch all Agent tool calls in a single message.
71
71
  - If cluster has N = 1 OR strategy = `main-thread` → execute inline in the current turn.
72
- - If strategy = `mcp-worker-haiku` → spawn an Agent tool call WITHOUT worktree (faster boot, single-turn).
72
+ - If strategy = `mcp-worker` → spawn an Agent tool call WITHOUT worktree (faster boot, single-turn) ; set the Agent's model to the role's nature-based `model` (haiku for exploration, omit otherwise to inherit the session model).
73
73
 
74
74
  For each Agent tool call, the prompt must start with :
75
75
  ```
@@ -1,23 +1,75 @@
1
- export function dispatch({ task, complexity, parallelizable }) {
1
+ import { classifyLeaf, tierFor, TIER_MODEL, LEAF_TYPES } from './native-tiers.js';
2
+
3
+ // byan_dispatch routes a unit of work along TWO independent axes:
4
+ //
5
+ // STRATEGY — WHERE the work runs (inline / isolated subagent / mcp worker).
6
+ // Derived from the scalar score + parallelizable. This is
7
+ // dispatch's own concern: orchestration.
8
+ // TIER — WHICH model the work deserves. Delegated to native-tiers (the
9
+ // single source of truth), keyed on the task's NATURE, never on its
10
+ // size. Only exploration downgrades to a cheap tier; implementation,
11
+ // verification, analysis (and anything unmatched) stay deep =
12
+ // inherit the session model. We never PIN UP to opus.
13
+ //
14
+ // Before this split the two axes were fused into one route string
15
+ // ('mcp-worker-haiku', 'main-thread-opus'), so a short sequential task was
16
+ // silently downgraded to haiku purely on length, and a long one was pinned up to
17
+ // opus — exactly the size-driven mis-tiering native-tiers' anti-downgrade doctrine
18
+ // forbids. The score still picks the strategy; the model now comes from nature.
19
+ //
20
+ // The dependency on native-tiers is intentional and one-directional: dispatch
21
+ // CONSUMES the tier source of truth, it does not duplicate it. native-tiers is a
22
+ // pure, IO-free module, so the import is safe and keeps the tiering doctrine in a
23
+ // single place.
24
+
25
+ const VALID_NATURES = new Set(Object.values(LEAF_TYPES));
26
+
27
+ export function dispatch({ task, complexity, parallelizable, nature } = {}) {
2
28
  const score =
3
29
  typeof complexity === 'number'
4
30
  ? complexity
5
31
  : Math.min(100, Math.floor((task?.length || 0) / 10));
6
32
  const isPar = parallelizable === true;
7
33
 
8
- let route, reasoning;
34
+ // Axis 1 — strategy (where). Scalar, as before, minus the fused model suffix.
35
+ let strategy, strategyReason;
9
36
  if (score < 15) {
10
- route = 'main-thread';
11
- reasoning = `Score ${score} < 15. Inline in current context, no delegation overhead.`;
37
+ strategy = 'main-thread';
38
+ strategyReason = `score ${score} < 15: inline, no delegation overhead`;
12
39
  } else if (score < 40 && isPar) {
13
- route = 'agent-subagent-worktree';
14
- reasoning = `Score ${score} + parallelizable. Spawn Claude Code Agent tool with worktree isolation.`;
40
+ strategy = 'agent-subagent-worktree';
41
+ strategyReason = `score ${score} + parallelizable: isolated subagent (worktree)`;
15
42
  } else if (score < 40) {
16
- route = 'mcp-worker-haiku';
17
- reasoning = `Score ${score}, sequential. Delegate to lightweight Haiku worker via MCP.`;
43
+ strategy = 'mcp-worker';
44
+ strategyReason = `score ${score}, sequential: delegated MCP worker`;
18
45
  } else {
19
- route = 'main-thread-opus';
20
- reasoning = `Score ${score} >= 40. Complex task, keep in main thread with Opus reasoning.`;
46
+ strategy = 'main-thread';
47
+ strategyReason = `score ${score} >= 40: heavy, kept in the main thread`;
21
48
  }
22
- return { score, route, reasoning, parallelizable: isPar };
49
+
50
+ // Axis 2 — tier (which model). By nature, via native-tiers. An explicit, valid
51
+ // nature wins; otherwise classify the task text. An unknown nature falls back to
52
+ // classification rather than guessing, and classification's own default is
53
+ // IMPLEMENTATION (deep), so the conservative path is the worst case — protected
54
+ // work is never downgraded on a miss.
55
+ const leafType = VALID_NATURES.has(nature) ? nature : classifyLeaf({ label: task || '' });
56
+ const tier = tierFor(leafType);
57
+ const model = TIER_MODEL[tier]; // 'haiku' (exploration) or null (every other nature -> inherit session model). tierFor never auto-picks balanced/'sonnet'.
58
+
59
+ const tierReason =
60
+ model === null
61
+ ? `nature=${leafType} -> ${tier}: inherit the session model (protected, not downgraded)`
62
+ : `nature=${leafType} -> ${tier}: ${model}`;
63
+
64
+ // model applies to a DELEGATED strategy (subagent / mcp-worker leaf); for a
65
+ // main-thread strategy the work runs on the session model and model is advisory.
66
+ return {
67
+ score,
68
+ strategy,
69
+ nature: leafType,
70
+ tier,
71
+ model,
72
+ parallelizable: isPar,
73
+ reasoning: `${strategyReason}. ${tierReason}.`,
74
+ };
23
75
  }
@@ -292,7 +292,7 @@ const tools = [
292
292
  {
293
293
  name: 'byan_dispatch',
294
294
  description:
295
- 'BYAN Dispatcher: given a task description and complexity score (0-100), route it to the optimal execution target. Rule-based, no API call. Returns route and reasoning.',
295
+ 'BYAN Dispatcher: routes a unit of work along two independent axes. STRATEGY (where it runs: main-thread / agent-subagent-worktree / mcp-worker) from the scalar score + parallelizable. TIER (which model) from the task NATURE via native-tiers (the single source of truth): only exploration downgrades to haiku; implementation/verification/analysis stay deep (inherit the session model); never pins up to opus. Rule-based, no API call. Returns { score, strategy, nature, tier, model, reasoning }.',
296
296
  inputSchema: {
297
297
  type: 'object',
298
298
  properties: {
@@ -305,6 +305,11 @@ const tools = [
305
305
  type: 'boolean',
306
306
  description: 'Is the task parallelizable with other tasks?',
307
307
  },
308
+ nature: {
309
+ type: 'string',
310
+ enum: ['exploration', 'implementation', 'verification', 'analysis'],
311
+ description: 'Optional task nature. A valid value sets the model tier directly; otherwise the nature is classified from the task text. Only exploration is downgrade-safe.',
312
+ },
308
313
  },
309
314
  required: ['task'],
310
315
  additionalProperties: false,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-byan-agent",
3
- "version": "2.21.0",
3
+ "version": "2.22.0",
4
4
  "description": "BYAN v2.8 - Intelligent AI agent creator with ELO trust system + scientific fact-check + Hermes universal dispatcher + native Claude Code integration (hooks, skills, MCP server). Multi-platform (Copilot CLI, Claude Code, Codex). Merise Agile + TDD + 71 Mantras. ~54% LLM cost savings.",
5
5
  "main": "src/index.js",
6
6
  "bin": {