orchestrator-workflow 0.21.0 → 0.23.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -5,6 +5,74 @@ All notable changes to `orchestrator-workflow` are documented here.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [0.23.0] - 2026-08-24
9
+
10
+ ### Changed
11
+
12
+ - **Tightened the `implementer-low` tier rule from discretion to a checkable
13
+ gate on the task contract.** `agents-md-section.md`'s Scaling delegation
14
+ bullet and `SKILL.md` step 6 ("Delegate implementation") no longer say
15
+ `-low` "fits mechanical, narrowly scoped tasks" for the implementer;
16
+ `implementer-low` is now spawned only when none of the following hold: an
17
+ acceptance criterion demands a test, typecheck, lint, or build run; the task
18
+ assignment names mutation probes to run; or the task slicer's
19
+ `suggested_tests` came back non-empty. A task with any of those, including a
20
+ bugfix that looks mechanical, runs on the unsuffixed implementer or higher.
21
+ When it is unclear whether a criterion demands a run, exclude
22
+ `implementer-low`. The explorer and the task-slicer keep the prior
23
+ discretionary `-low` guidance unchanged, since no equivalent measurement
24
+ exists for those roles. Operator decision 2026-08-24 after a Tier-A/B
25
+ measurement of implementer-low as installed (Haiku 4.5) against the default
26
+ implementer (Sonnet 5, effort medium) (agent-tasks task 7f38899d), blinded,
27
+ n=8, identical tasks in both tiers: implementer-low reached accept a median
28
+ 320 seconds slower (p=0.016), drew 9 high-plus-critical review findings
29
+ against 1, and needed 8 fix rounds against 1. The A/B's implementer-low ran
30
+ on Haiku 4.5, which does not support the `effort` parameter, so the harness
31
+ ignores the pinned `effort: low` on that model; the measurement compared
32
+ Haiku 4.5 without effort control against Sonnet 5 at `effort: medium`.
33
+
34
+ ## [0.22.0] - 2026-08-20
35
+
36
+ ### Changed
37
+
38
+ - **Default subagent spawns no longer inherit the orchestrator session's
39
+ effort.** Every unsuffixed default agent file (`explorer.md`,
40
+ `task-slicer.md`, `implementer.md`, `reviewer.md`, `advisor.md`) now
41
+ carries its own pinned default effort, unconditionally, regardless of
42
+ whether `--tiers` is on: `effort: medium` for explorer, task-slicer, and
43
+ implementer, `effort: high` for reviewer and advisor
44
+ (`TIER_DEFS[DEFAULT_TIER[role]].effort`, the same tier data `--tiers`
45
+ already used, applied by `composeClaudeAgent` for every install, tiers
46
+ flag or not). opencode gets the matching pinned line via
47
+ `opencodeEffortLine` (renamed from `opencodeVariantEffortLine`, now shared
48
+ by the default file and the tier variants): a resolved Claude-family model
49
+ gets `variant: high` for reviewer/advisor and no effort field at all for
50
+ the three medium-default roles (opencode's `variant:` option does not
51
+ distinguish an effort below `high`, the same collapse tier variants
52
+ already documented), a non-Claude-family provider-qualified model gets
53
+ `reasoningEffort: medium`/`reasoningEffort: high`, and Ollama, a
54
+ provider-less id, or an unresolved model gets no effort field either way.
55
+ Practically: on a high-effort orchestrator session, a default subagent
56
+ spawn used to silently run at that same high effort; it now runs at its
57
+ own role's pinned effort instead, which is weaker (and cheaper) for the
58
+ three medium-default roles. Escalate deliberately via the `-high`/`-xhigh`
59
+ tier variants (`--tiers`) when a task actually needs more.
60
+ **`CLAUDE_CODE_EFFORT_LEVEL` still beats this pin**: when the harness
61
+ environment sets that variable, it overrides every installed agent's
62
+ frontmatter `effort:`, default files and tier variants alike, the same
63
+ warning `--tiers` already carried. **opencode cannot express `medium` for
64
+ a Claude-family model at all**: the `variant:` field only distinguishes
65
+ `high`/`max`, so a Claude-family default file for explorer, task-slicer,
66
+ or implementer renders with no effort field, falling back to whatever the
67
+ resolved model's own default happens to be.
68
+ The default file's content stays byte-identical whether or not `--tiers`
69
+ is also on, since the pin does not read the `tiers` flag; this invariant
70
+ is now belt-and-suspenders tested directly (a two-target diff, not just
71
+ inferred from reading the source).
72
+ A `--tiers`-off install (the default) renders no variant files at all, so
73
+ it has no in-install escalation path off a default's pinned effort; pull
74
+ `init --tiers` afterward if a task needs one.
75
+
8
76
  ## [0.21.0] - 2026-08-20
9
77
 
10
78
  ### Added
package/INSTALL-AGENT.md CHANGED
@@ -146,10 +146,15 @@ steps in the repository you were asked to install into.
146
146
  for `full`; only `implementer` and `reviewer` for `minimal`),
147
147
  `.claude/agents/<role>.md` from
148
148
  `assets/agents/<role>.md` with `model: <operator's choice>` added as a
149
- new line directly after the `description:` line (that placement matches
150
- the installer's output byte for byte). For the explorer, reviewer, and
151
- advisor roles additionally, `disallowedTools: Edit, Write, NotebookEdit` goes on a new
152
- line directly after the `model:` line. Ensure `CLAUDE.md` exists and
149
+ new line directly after the `description:` line, then
150
+ `effort: <medium|high>` on the next line (`medium` for explorer,
151
+ task-slicer, and implementer; `high` for reviewer and advisor; this
152
+ pinned default effort is unconditional, not tied to whether the
153
+ operator asked for `--tiers`; see the package README's "Effort tiers"
154
+ section), that placement matching the installer's output byte for
155
+ byte. For the explorer, reviewer, and advisor roles additionally,
156
+ `disallowedTools: Edit, Write, NotebookEdit` goes on a new line
157
+ directly after the `effort:` line. Ensure `CLAUDE.md` exists and
153
158
  contains a line `@AGENTS.md`.
154
159
  - Codex: `.agents/skills/orchestrator-workflow/SKILL.md`, same skill file.
155
160
  - opencode: `.opencode/skills/orchestrator-workflow/SKILL.md` from
@@ -166,9 +171,21 @@ steps in the repository you were asked to install into.
166
171
  which is the safe portable fallback. The installed CLI resolves aliases
167
172
  to fully-qualified ids by running `opencode models` at install time; in a
168
173
  manual install you may not have a live catalog, so omitting `model:` is
169
- correct. For the explorer, reviewer, and advisor roles additionally, `permission:` goes on a new
170
- line directly after `mode: subagent` (or after `model:` when that line is
171
- present), followed by ` edit: deny` (two-space indent) on the next line.
174
+ correct. When you do have a fully-qualified `model:` value, add the same
175
+ pinned-default-effort line (see the package README's "Effort tiers"
176
+ section for the exact dispatch rule), keyed by
177
+ the role's own default tier instead of a suffix tier (`medium` for
178
+ explorer/task-slicer/implementer, `high` for reviewer/advisor): a
179
+ resolved Claude-family model gets `variant: high` for reviewer/advisor
180
+ and no effort line at all for the three medium-default roles, a
181
+ non-Claude-family provider-qualified model gets `reasoningEffort:
182
+ medium` or `reasoningEffort: high`, and Ollama or a provider-less id
183
+ gets no effort line either way; when `model:` is omitted (the common
184
+ manual-fallback case above), omit the effort line too, the same
185
+ no-live-catalog fallback. For the explorer, reviewer, and advisor roles
186
+ additionally, `permission:` goes on a new line directly after
187
+ `mode: subagent` (or after `model:`/the effort line when present),
188
+ followed by ` edit: deny` (two-space indent) on the next line.
172
189
  Example read-only role frontmatter (explorer, reviewer, or advisor) when
173
190
  no model is resolved:
174
191
  ```yaml
@@ -181,12 +198,13 @@ steps in the repository you were asked to install into.
181
198
  ```
182
199
  - `.ai/workflow/manifest.json`, exactly this shape (harnesses MUST be an
183
200
  array, `profile` is `"minimal"` or `"full"`, models keyed by role,
184
- version = the kit version you installed):
201
+ version = the kit version you installed, read from this kit's own
202
+ `packages/orchestrator-workflow/package.json` `version` field):
185
203
 
186
204
  ```json
187
205
  {
188
206
  "kit": "orchestrator-workflow",
189
- "version": "0.5.0",
207
+ "version": "<kit version you installed>",
190
208
  "harnesses": ["claude", "opencode"],
191
209
  "profile": "full",
192
210
  "tiers": false,
@@ -198,7 +216,7 @@ steps in the repository you were asked to install into.
198
216
  "advisor": "opus"
199
217
  },
200
218
  "files": {},
201
- "installedAt": "2026-06-12T00:00:00.000Z"
219
+ "installedAt": "<ISO 8601 timestamp of this install>"
202
220
  }
203
221
  ```
204
222
 
package/README.md CHANGED
@@ -215,8 +215,27 @@ non-default effort tier, alongside the one default (unsuffixed) agent file
215
215
  `--profile` already installs. Each tier variant is a standalone subagent
216
216
  definition, not a modification of the default file: the default file
217
217
  (`<role>.md`) stays byte-identical to what a tiers-off install already
218
- produces (still `manifest.models[role]`, no `effort:` key), and each variant
219
- lives next to it as `<role>-<tier>.md`.
218
+ produces, and each variant lives next to it as `<role>-<tier>.md`.
219
+
220
+ **Every default file carries its own pinned effort, independent of
221
+ `--tiers`.** Since 0.22.0, `composeClaudeAgent`/`composeOpencodeAgent` add
222
+ the role's own `TIER_DEFS[DEFAULT_TIER[role]].effort` to the default
223
+ (unsuffixed) file unconditionally: `effort: medium` for explorer,
224
+ task-slicer, and implementer; `effort: high` for reviewer and advisor
225
+ (opencode: a `variant: high` line when the resolved model is Claude-family,
226
+ following the same dispatch rule tier variants use, `reasoningEffort:
227
+ medium`/`reasoningEffort: high` for a non-Claude-family provider-qualified
228
+ model, nothing for Ollama, a provider-less id, or an unresolved model). This
229
+ pin does not depend on `tiers`, so a plain install (no `--tiers`) already
230
+ carries it; the flag only controls whether the additional `<role>-<tier>.md`
231
+ variant files are also rendered. The motivation: a default spawn used to
232
+ silently inherit the orchestrator session's own effort, so a `high`-effort
233
+ orchestrator session made every default subagent spawn at `high` too,
234
+ regardless of the role's own intended weight; the pin makes each role's
235
+ effort deterministic and independent of the caller's session. A `--tiers`-off
236
+ install (the default) has no variant files and therefore no in-install
237
+ escalation path off a default's pinned effort; run `init --tiers` afterward
238
+ if a task ever needs one.
220
239
 
221
240
  Default off, like every optional pack in this kit: a fresh install renders
222
241
  no variant files unless asked. `--tiers` turns the feature on for that run,
@@ -307,6 +326,14 @@ agent, tier variants and default files alike, not just the one this feature
307
326
  adds. Check for it before relying on a specific tier variant's requested
308
327
  effort actually taking effect.
309
328
 
329
+ The pin is also emitted unconditionally regardless of which model the role
330
+ resolves to via `--models`, including a model with no effort support at all
331
+ (e.g. `--models reviewer=haiku` still renders `model: haiku` followed by
332
+ `effort: high`). A wire probe on 2026-08-19 (not re-measured for this doc)
333
+ showed the Claude Code CLI silently drops the `effort:` parameter for Haiku
334
+ 4.5 rather than rejecting it: the value is ignored, not an install-time or
335
+ run-time error.
336
+
310
337
  ## Ownership and re-runs
311
338
 
312
339
  `init` is idempotent: a second run changes nothing. The rules:
@@ -50,16 +50,41 @@ default, not a ritual.
50
50
  changes whose risk or size warrants an independent skeptical pass. Either
51
51
  way, review is never skipped.
52
52
  - When tier variants are installed (manifest `tiers: true`), the orchestrator
53
- picks the effort tier per task by complexity and risk, at its own
54
- judgment. The unsuffixed default subagent is the normal case; a `-low`
55
- variant fits mechanical, narrowly scoped tasks; `-high`/`-xhigh` fit
56
- high-risk changes, hard problems, or repeated failed attempts. Not every
57
- role gets every tier: `-xhigh` exists only for the implementer, the
58
- reviewer, and the advisor. The reviewer's downshift is `-medium` rather
59
- than `-low`, since its default already sits at high. The advisor has no
60
- downshift at all: its default `high` is already its only non-`-xhigh`
61
- tier. Spawn only variants that are actually installed. Tier choice is a
62
- conscious decision, not a ritual; when unsure, use the default.
53
+ picks the effort tier per task by complexity and risk, at its own judgment.
54
+ The unsuffixed default subagent is the normal case; `-high`/`-xhigh` fit
55
+ high-risk changes, hard problems, or repeated failed attempts. For the
56
+ implementer specifically, `-low` is spawned only when none of the following
57
+ hold: an acceptance criterion demands a test, typecheck, lint, or build run;
58
+ the task assignment names mutation probes to run; or the task slicer's
59
+ `suggested_tests` came back non-empty. This is checkable against the task
60
+ contract rather than a judgment about how hard the task looks: any one of
61
+ those three excludes `implementer-low`, and the task runs on the unsuffixed
62
+ implementer or higher, even when the change looks mechanical (a bugfix
63
+ included); when it is unclear whether a criterion demands a run, exclude
64
+ `implementer-low`. This rule is anchored by an A/B measurement of
65
+ implementer-low as installed (Haiku 4.5) against the default implementer
66
+ (Sonnet 5, effort medium) (2026-08-24, n=8, identical tasks in both tiers,
67
+ blinded reviews, agent-tasks task 7f38899d): implementer-low reached accept
68
+ a median 320 seconds slower (p=0.016), drew 9 high-plus-critical review
69
+ findings against 1, and needed 8 fix rounds against 1. The A/B's
70
+ implementer-low ran on Haiku 4.5, which does not support the `effort`
71
+ parameter (per Anthropic's model reference), so the harness ignores the
72
+ pinned `effort: low` on that model; the measurement compared Haiku 4.5
73
+ without effort control against Sonnet 5 at `effort: medium`. For the
74
+ explorer and the task-slicer, a `-low` variant still suits narrowly scoped,
75
+ mechanical work; no equivalent measurement exists for those two roles, so
76
+ their rule is unchanged. Not every role gets every tier: `-xhigh` exists
77
+ only for the implementer, the reviewer, and the advisor. The reviewer's
78
+ downshift is `-medium` rather than `-low`, since its default already sits at
79
+ high. The advisor has no downshift at all: its default `high` is already its
80
+ only non-`-xhigh` tier. Spawn only variants that are actually installed.
81
+ Tier choice is a conscious decision, not a ritual; when unsure, use the
82
+ default.
83
+ - Every unsuffixed default subagent carries its own pinned default effort
84
+ baked into its own file, not inherited from the orchestrator session:
85
+ medium for the explorer, the task-slicer, and the implementer; high for
86
+ the reviewer and the advisor. This holds whether or not tier variants are
87
+ installed; it is not gated on `--tiers`.
63
88
  - Under the `full` profile, an advisor subagent is available for escalation
64
89
  only: architectural uncertainty, requirements that contradict each other,
65
90
  multiple valid solution paths where committing to one is expensive to
@@ -134,11 +134,23 @@ directory and the subagents.
134
134
  enough, testable, ordered correctly, and aligned with the goal. Fix the
135
135
  slicing before any implementation starts.
136
136
  6. **Delegate implementation.** Send each implementer subagent one narrow task
137
- contract (format below). When tier variants are installed, pick the
138
- implementer tier (the installed `implementer-<tier>` subagents, if any) by
139
- the task's complexity and risk, at your own judgment, defaulting to the
140
- unsuffixed subagent when unsure; record a non-default tier choice with a
141
- one-line reason in `03-decisions.md` when the task is non-trivial. When a
137
+ contract (format below). The unsuffixed implementer carries a pinned
138
+ effort: `medium` in its own file, whether or not tier variants are
139
+ installed, so a default spawn no longer inherits the session's effort.
140
+ When tier variants are installed, pick the implementer tier (the
141
+ installed `implementer-<tier>` subagents, if any) by the task's
142
+ complexity and risk, at your own judgment, defaulting to the unsuffixed
143
+ subagent when unsure; record a non-default tier choice with a
144
+ one-line reason in `03-decisions.md` when the task is non-trivial.
145
+ `implementer-low` is spawned only when none of the following hold: an
146
+ acceptance criterion demands a test, typecheck, lint, or build run; the
147
+ task assignment names mutation probes to run; or the task slicer's
148
+ `suggested_tests` came back non-empty. Any one of those three excludes
149
+ `implementer-low`, even for a change that looks mechanical (a bugfix
150
+ included) (2026-08-24 A/B measurement, n=8: implementer-low reached accept
151
+ a median 320 seconds slower, p=0.016, with 9 high-plus-critical review
152
+ findings against 1 and 8 fix rounds against 1). When it is unclear
153
+ whether a criterion demands a run, exclude `implementer-low`. When a
142
154
  task's acceptance rests on a test that must fail without the change, name
143
155
  the mutation probes to run in the task assignment; the implementer reports
144
156
  each one in the output contract's `mutation_probes` field (apply the mutant
package/dist/init.js CHANGED
@@ -95,6 +95,22 @@ export function readInstalledManifest(targetDir) {
95
95
  function yamlQuote(value) {
96
96
  return `"${value.replace(/\\/g, "\\\\").replace(/"/g, '\\"')}"`;
97
97
  }
98
+ /**
99
+ * Composes the unsuffixed default agent file. It carries a pinned
100
+ * `effort: <TIER_DEFS[DEFAULT_TIER[role]].effort>` line unconditionally
101
+ * (medium for explorer/task-slicer/implementer, high for reviewer/advisor),
102
+ * regardless of whether `--tiers` is on: this is the deterministic tier
103
+ * ladder's floor, not a tier-variant feature, so a default spawn no longer
104
+ * silently inherits the orchestrator session's effort. Since the pin does
105
+ * not depend on the `tiers` flag, the default file's content still stays
106
+ * byte-identical whether or not tier variants are also rendered, the same
107
+ * invariant `composeClaudeAgentVariant`'s own doc comment below describes.
108
+ * Computed inline here rather than passed in like `composeOpencodeAgent`'s
109
+ * `effortLine`: `TIER_DEFS[DEFAULT_TIER[role]].effort` is a pure function of
110
+ * `role` alone, with no model-dependent dispatch on Claude Code the way
111
+ * opencode's family-based `opencodeEffortLine` has, so there is no second,
112
+ * potentially-diverging computation here to guard against.
113
+ */
98
114
  function composeClaudeAgent(role, model) {
99
115
  const asset = readAgentAsset(role);
100
116
  const frontmatter = [
@@ -102,6 +118,7 @@ function composeClaudeAgent(role, model) {
102
118
  `name: ${asset.name}`,
103
119
  `description: ${yamlQuote(asset.description)}`,
104
120
  `model: ${claudeModelValue(model)}`,
121
+ `effort: ${TIER_DEFS[DEFAULT_TIER[role]].effort}`,
105
122
  ];
106
123
  // Read-only roles keep every read/search tool but cannot mutate files.
107
124
  if (READ_ONLY_ROLES.has(role)) {
@@ -110,7 +127,15 @@ function composeClaudeAgent(role, model) {
110
127
  frontmatter.push("---");
111
128
  return [...frontmatter, "", asset.body.trimEnd(), ""].join("\n");
112
129
  }
113
- function composeOpencodeAgent(role, modelValue) {
130
+ /**
131
+ * Composes the unsuffixed default opencode agent file. `effortLine` is the
132
+ * same pinned-default-effort line a tier variant would carry, decided once
133
+ * by the caller via `opencodeEffortLine(DEFAULT_TIER[role], modelValue)`
134
+ * (single source of truth, the same pattern `composeOpencodeAgentVariant`
135
+ * already uses for its own effort line) and passed in rather than
136
+ * recomputed here.
137
+ */
138
+ function composeOpencodeAgent(role, modelValue, effortLine) {
114
139
  const asset = readAgentAsset(role);
115
140
  const frontmatter = [
116
141
  "---",
@@ -122,6 +147,9 @@ function composeOpencodeAgent(role, modelValue) {
122
147
  if (modelValue) {
123
148
  frontmatter.push(`model: ${modelValue}`);
124
149
  }
150
+ if (effortLine) {
151
+ frontmatter.push(effortLine);
152
+ }
125
153
  if (READ_ONLY_ROLES.has(role)) {
126
154
  frontmatter.push("permission:", " edit: deny");
127
155
  }
@@ -134,8 +162,8 @@ function tierDescriptionSuffix(asset, tier) {
134
162
  /**
135
163
  * Composes a tier-variant sibling of `composeClaudeAgent` (`<role>-<tier>.md`).
136
164
  * The default-tier file is never rendered here (callers skip it via
137
- * `DEFAULT_TIER`), so `composeClaudeAgent`'s own output stays byte-identical
138
- * whether or not tiers are on.
165
+ * `DEFAULT_TIER`), so `composeClaudeAgent`'s own output (pinned default
166
+ * effort included) stays byte-identical whether or not tiers are on.
139
167
  */
140
168
  function composeClaudeAgentVariant(role, tier) {
141
169
  const asset = readAgentAsset(role);
@@ -177,8 +205,12 @@ function isClaudeFamilyModel(modelValue) {
177
205
  * effort passthrough, and every other model accepts a plain
178
206
  * `reasoningEffort:` value. An unresolved (`undefined`) model gets no
179
207
  * effort field either, since there is then no model to key the decision on.
208
+ * Shared by both the default (unsuffixed) agent file, keyed by the role's
209
+ * own `DEFAULT_TIER`, and the tier-variant files, keyed by the variant's own
210
+ * suffix tier: the dispatch rule is identical either way, only which tier
211
+ * gets passed in differs.
180
212
  */
181
- function opencodeVariantEffortLine(tier, modelValue) {
213
+ function opencodeEffortLine(tier, modelValue) {
182
214
  if (!modelValue)
183
215
  return undefined;
184
216
  if (isClaudeFamilyModel(modelValue)) {
@@ -197,7 +229,7 @@ function opencodeVariantEffortLine(tier, modelValue) {
197
229
  /**
198
230
  * Composes a tier-variant sibling of `composeOpencodeAgent`. `effortLine` is
199
231
  * decided once, at the single call site in the opencode tier loop of
200
- * `runInit` (via `opencodeVariantEffortLine`), and passed in rather than
232
+ * `runInit` (via `opencodeEffortLine`), and passed in rather than
201
233
  * recomputed here, so there is exactly one place that decides it instead
202
234
  * of a second, independent source of truth for the same value.
203
235
  */
@@ -356,7 +388,8 @@ export function runInit(options) {
356
388
  const modelValue = options.opencodeModels !== undefined
357
389
  ? options.opencodeModels[role]
358
390
  : opencodeModelValue(options.models[role]);
359
- installKitFile(join(".opencode", "agents", `${role}.md`), composeOpencodeAgent(role, modelValue));
391
+ const defaultEffortLine = opencodeEffortLine(DEFAULT_TIER[role], modelValue);
392
+ installKitFile(join(".opencode", "agents", `${role}.md`), composeOpencodeAgent(role, modelValue, defaultEffortLine));
360
393
  if (tiers) {
361
394
  for (const tier of ROLE_TIERS[role]) {
362
395
  if (tier === DEFAULT_TIER[role])
@@ -364,8 +397,8 @@ export function runInit(options) {
364
397
  const modelClass = TIER_DEFS[tier].modelClass;
365
398
  const variantModelValue = options.opencodeClassModels?.[modelClass];
366
399
  if (variantModelValue === undefined) {
367
- // No model resolved for this class: opencodeVariantEffortLine
368
- // always returns undefined too when its modelValue argument is
400
+ // No model resolved for this class: opencodeEffortLine always
401
+ // returns undefined too when its modelValue argument is
369
402
  // undefined (it short-circuits on that first), so this variant
370
403
  // would carry neither a model: nor an effort line, a silent
371
404
  // no-op duplicate of the base file's own (possibly also
@@ -375,10 +408,10 @@ export function runInit(options) {
375
408
  // (e.g. a low/medium tier on a Claude-family model, or any
376
409
  // Ollama model) is NOT skipped by this check: it still renders
377
410
  // with just its model: line, see the effort-field dispatch
378
- // rules in opencodeVariantEffortLine above.
411
+ // rules in opencodeEffortLine above.
379
412
  continue;
380
413
  }
381
- const effortLine = opencodeVariantEffortLine(tier, variantModelValue);
414
+ const effortLine = opencodeEffortLine(tier, variantModelValue);
382
415
  installKitFile(join(".opencode", "agents", `${role}-${tier}.md`), composeOpencodeAgentVariant(role, tier, variantModelValue, effortLine));
383
416
  }
384
417
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "orchestrator-workflow",
3
- "version": "0.21.0",
3
+ "version": "0.23.0",
4
4
  "description": "Installer for an orchestrator-led agent workflow: .ai/ run state, an AGENTS.md policy section, and per-harness subagent definitions for Claude Code, OpenAI Codex, and opencode",
5
5
  "main": "dist/index.js",
6
6
  "type": "module",