Skip to content

fix(session-flow): make worker model tier an explicit spawn decision (0.9.1)#340

Merged
kyle-sexton merged 2 commits into
mainfrom
fix/orchestrate-worker-model-tiering
Jul 18, 2026
Merged

fix(session-flow): make worker model tier an explicit spawn decision (0.9.1)#340
kyle-sexton merged 2 commits into
mainfrom
fix/orchestrate-worker-model-tiering

Conversation

@kyle-sexton

@kyle-sexton kyle-sexton commented Jul 18, 2026

Copy link
Copy Markdown
Contributor

What

The /session-flow:orchestrate skill let an armed session fan out 100+ workers without a model stated on any spawn. Per the official subagents doc, an omitted model defaults to inherit (resolution order: CLAUDE_CODE_SUBAGENT_MODEL env var → per-invocation model param → agent frontmatter → main conversation's model), so every worker silently ran on the parent session's premium model. Observed: a 100–200-agent run entirely on Fable.

Changes

  • SPEC EVERY SPAWN (imperative 2): the per-worker spec now includes "a deliberately chosen model tier", with the silent-inheritance failure mode named.
  • CALIBRATE TO CONDITIONS (imperative 7): per-worker tiering added to sizing — high-volume mechanical work runs on a cheaper tier; the parent tier is reserved for judgment-heavy synthesis/verification/adjudication; the wider the fan-out, the cheaper the default per-worker tier; a wide premium-tier fan-out must be justified explicitly, never inherited.
  • context/sources.md: cites the subagents doc's verbatim cost-control guidance ("Control costs by routing tasks to faster, cheaper models like Haiku") and the model-resolution order.
  • session-flow 0.9.0 → 0.9.1 (rebased over the 0.9.0 reanchor-skill release), CHANGELOG entry.

Why guidance, not enforcement

The skill is instruction text — it cannot set a model itself. The blunt environment-level guard (CLAUDE_CODE_SUBAGENT_MODEL) remains available to consumers and is deliberately not prescribed: it flattens ALL subagents to one tier, including judgment-heavy verifiers.

Fresh-docs mandate

Fetched this session and cited: https://code.claude.com/docs/en/sub-agents (model resolution, omitted-defaults-to-inherit, cost-control quote).

Gates

  • markdownlint-cli2 (repo config) on the three changed markdown files: 0 errors
  • claude plugin validate ./plugins/session-flow: pass

🤖 Generated with Claude Code

https://claude.ai/code/session_01VLztic1sFn2CVFJsubr7pu

Related

No linked issue.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 1a7c5bfb05

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread plugins/autonomy/skills/setup/scripts/check-emission-conformance.mjs Outdated
@kyle-sexton
kyle-sexton force-pushed the fix/orchestrate-worker-model-tiering branch from 1a7c5bf to 622b5ef Compare July 18, 2026 18:46

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 622b5efc52

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread plugins/session-flow/skills/orchestrate/SKILL.md Outdated
@kyle-sexton
kyle-sexton force-pushed the fix/orchestrate-worker-model-tiering branch from 622b5ef to 8a4593c Compare July 18, 2026 20:49
@kyle-sexton kyle-sexton changed the title fix(session-flow): make worker model tier an explicit spawn decision (0.8.1) fix(session-flow): make worker model tier an explicit spawn decision (0.9.1) Jul 18, 2026
@claude

claude Bot commented Jul 18, 2026

Copy link
Copy Markdown

Claude finished @kyle-sexton's task in 1m 55s —— View job


PR Review: fix(session-flow): make worker model tier an explicit spawn decision

Tasks

  • Load tools
  • Read PR diff and changed files
  • Review for correctness, security, and CLAUDE.md alignment
  • Post findings

Summary

The changes are well-scoped and address a real silent-failure mode (premium-model fan-outs via inherit default). The instruction additions in SKILL.md and sources.md are clear, traceable to cited sources, and structurally consistent with the existing skill. Two issues worth calling out:


Findings

1. PR title version label is stale — cosmetic

The PR title says (0.8.1) but both plugin.json and CHANGELOG.md contain 0.9.1, and the commit message reads the same. The prior published version was 0.9.0 (reanchor skill), so 0.9.1 is correct. The title is just an artifact of the branch being authored before the 0.9.0 bump landed.

Not blocking, but it creates a confusing paper trail — the PR description also says "session-flow 0.8.0 → 0.8.1". Consider updating the PR title to (0.9.1) before merging.


2. Imperative 2 doesn't surface CLAUDE_CODE_SUBAGENT_MODEL precedence — minor gap

The Codex P2 review comment on SKILL.md:47 raises a legitimate concern.

Current text (imperative 2, line 45–47):

give each worker … and a deliberately chosen model tier. … an unspecified model silently inherits the parent session's — often its most expensive — model.

The gap: The resolution order documented in sources.md (correctly) is:
CLAUDE_CODE_SUBAGENT_MODEL → per-invocation model → frontmatter modelinherit

If a consumer has set CLAUDE_CODE_SUBAGENT_MODEL, the per-spawn tier stated by the orchestrator has no effect — it is silently overridden. A session armed by this skill could believe it is routing cheap work to Haiku while every worker actually runs on whatever the env var pins.

The PR body acknowledges this tradeoff deliberately ("it flattens ALL subagents to one tier, including judgment-heavy verifiers"), but the skill text doesn't, so the operational user gets half the picture.

Suggested minimal fix — add one parenthetical to the imperative 2 trailing clause:

…an unspecified model silently inherits the parent session's — often its most expensive — model
(unless the consumer has set CLAUDE_CODE_SUBAGENT_MODEL, which takes precedence over any
per-invocation tier choice and flattens all workers to one tier).

Fix this →


3. Codex P2 on check-emission-conformance.mjs — out of scope

The Codex review comment targeting plugins/autonomy/skills/setup/scripts/check-emission-conformance.mjs is valid as a standalone observation but is not related to any file changed in this PR. It's a pre-existing concern in the autonomy plugin. Nothing here introduced or touched that script.


4. Fresh-docs mandate — satisfied

sources.md correctly uses *(verbatim, verified)* markers for both the cost-control quote and the inherit default language, cites https://code.claude.com/docs/en/sub-agents as the source, and documents the full resolution order. The PR description confirms a same-session fetch. The mandate is met for the scope of this change.


5. CLAUDE.md design rules — all satisfied

Rule Status
Repo-agnostic (no hardcoded paths/names)
Configurable without editing the plugin
Plugin-form-safe (CLAUDE_PLUGIN_ROOT / CLAUDE_PLUGIN_DATA) ✅ (instruction-only skill, no file I/O)
No PII / secrets
Explicit semver version ✅ (0.9.1 in plugin.json)

Verdict

Approve with nits. Finding 2 is the only substantive gap — a single parenthetical in imperative 2 closes it. Finding 1 (PR title) is cosmetic. Finding 3 is pre-existing and out of scope.

…(0.9.1)

A session armed by /orchestrate could fan out 100+ workers with no model
stated on any spawn; an omitted model defaults to inherit per the
subagents doc, so every worker silently ran on the parent session's
premium model. SPEC EVERY SPAWN now includes a deliberately chosen model
tier, CALIBRATE TO CONDITIONS adds per-worker tiering (cheap tier for
high-volume mechanical work, parent tier reserved for judgment-heavy
synthesis/verify, wider fan-out defaults cheaper), and sources.md cites
the official model-resolution order and cost-control guidance.

Rebased over session-flow 0.9.0 (reanchor skill); version target moved
from 0.8.1 to 0.9.1.

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
@kyle-sexton
kyle-sexton force-pushed the fix/orchestrate-worker-model-tiering branch from 8a4593c to 7e79ac4 Compare July 18, 2026 21:05
@claude

claude Bot commented Jul 18, 2026

Copy link
Copy Markdown

Claude finished @kyle-sexton's task in 1m 38s —— View job


PR Review: fix(session-flow): make worker model tier an explicit spawn decision (0.9.1)

Tasks

  • Load tools
  • Read PR diff and changed files
  • Review for correctness, security, and CLAUDE.md alignment
  • Post findings

Summary

Rebase over 0.9.0 is clean. The four changed files are internally consistent and the changelog, version bump, SKILL.md additions, and sources citation all agree. One substantive gap carries over from the pre-rebase review and is still unaddressed.


Finding 1 — CLAUDE_CODE_SUBAGENT_MODEL precedence unmentioned in skill text (P2 / minor)

The new imperative 2 text at SKILL.md:44–47 closes the silent-inheritance failure mode but opens a related one: it tells practitioners to choose a tier per worker without noting that CLAUDE_CODE_SUBAGENT_MODEL, if set by the consumer, takes precedence over the per-invocation model parameter and will silently override any tier the orchestrator states. A session armed by this skill could believe it is routing high-volume work to Haiku while every worker actually runs on whatever the env var pins — the same kind of silent mismatch the PR is trying to prevent.

sources.md documents the full resolution order correctly at sources.md:115–122 — but the skill preamble explicitly says sources.md is "read only when judging a coverage question or extending the skill", so a practitioner armed by the skill will not see it during normal use.

The PR body correctly frames this as a tradeoff ("it flattens ALL subagents to one tier, including judgment-heavy verifiers") — the fix isn't to prescribe or prohibit the env var, just to keep the practitioner from being surprised.

Suggested minimal addition to the end of imperative 2's trailing clause:

…an unspecified model silently inherits the parent session's — often its most expensive — model
(if CLAUDE_CODE_SUBAGENT_MODEL is set in the consumer's environment, it takes precedence over
any per-invocation tier choice and pins all workers to one tier regardless).

Fix this →


Finding 2 — Imperative 7 compact export doesn't carry the new tiering signal (informational)

SKILL.md:110–111 notes that compact mode emits only the headline ("2. SPEC EVERY SPAWN", "7. CALIBRATE TO CONDITIONS"). The expanded sub-clauses — including the new model-tier guidance — are dropped. This is consistent with what compact has always done, so it's not a regression, and a worker receiving the full non-compact brief will see both tiering paragraphs. Just noting it so the tradeoff is visible: a worker armed with a compact brief gets no tier guidance at all.

Not blocking. The compact format's lossy-by-design behavior is documented.


Finding 3 — Pre-existing Codex P2 on check-emission-conformance.mjs — out of scope

The Codex review comment targeting plugins/autonomy/skills/setup/scripts/check-emission-conformance.mjs is not touched by this PR and is a pre-existing concern in the autonomy plugin. Nothing here introduced or changed that script.


Fresh-docs mandate — satisfied

sources.md uses *(verbatim, verified)* markers for both the cost-control quote and the inherit default text, cites https://code.claude.com/docs/en/sub-agents as the source, and documents the full resolution order. The PR body confirms a same-session fetch. The mandate is met for this change's scope.


CLAUDE.md design rules

Rule Status
Repo-agnostic (no hardcoded paths/names)
Configurable without editing the plugin
Plugin-form-safe (CLAUDE_PLUGIN_ROOT / CLAUDE_PLUGIN_DATA) ✅ (instruction-only skill, no file I/O)
No PII / secrets
Explicit semver version ✅ (0.9.1 in plugin.json)

Verdict

Approve with nit. The rebase is clean, the changelog and version bump are consistent, and the instruction additions are well-sourced. Finding 1 is the only substantive gap — a single parenthetical in imperative 2 closes the CLAUDE_CODE_SUBAGENT_MODEL blind spot. Finding 2 is informational. Finding 3 is pre-existing and out of scope.

… precedence

Review finding: CLAUDE_CODE_SUBAGENT_MODEL resolves before per-invocation
and frontmatter values, so an omitted model inherits the parent only when
no consumer-level override is set — as sources.md already documents.

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
@claude

claude Bot commented Jul 18, 2026

Copy link
Copy Markdown

Claude finished @kyle-sexton's task in 1m 48s —— View job


PR Review: fix(session-flow): make worker model tier an explicit spawn decision (0.9.1)

Tasks

  • Load tools
  • Read latest commit diff and changed files
  • Check if previous review findings were addressed
  • Review for correctness, security, and CLAUDE.md alignment
  • Post findings

Summary

The latest commit (690d42b) directly addresses the one substantive finding from both prior reviews: the silent CLAUDE_CODE_SUBAGENT_MODEL override was not surfaced in the skill text. The fix is clean and the four files remain internally consistent. This PR is ready to merge.


Previous finding — now resolved

Finding 1 (P2): CLAUDE_CODE_SUBAGENT_MODEL precedence unmentioned in skill text

Both prior reviews flagged that imperative 2 implied model inheritance always applies when a spawn omits model, without acknowledging the env-var override path. The fix at SKILL.md:46–47:

Before:

…an unspecified model silently inherits the parent session's — often its most expensive — model.

After:

absent a consumer-level subagent-model override, an unspecified model silently inherits the parent session's — often its most expensive — model.

The qualifier is accurate and keeps the imperative concise. The full resolution order and env-var name remain in sources.md:115–122 for practitioners who need the specifics — which is the right division of detail.

One very minor observation: "consumer-level subagent-model override" is technically correct but abstract for a practitioner who hasn't encountered it before. Adding "CLAUDE_CODE_SUBAGENT_MODEL" in parentheses would make it self-explanatory without the sources.md lookup. That said, the current wording is not wrong, and fixing it would be at-your-discretion cosmetic polish rather than a correction.


Remaining items from prior reviews

Finding Status
PR title stale at (0.8.1) ✅ Resolved — title now reads (0.9.1)
CLAUDE_CODE_SUBAGENT_MODEL precedence unmentioned ✅ Resolved by 690d42b
Compact mode drops tiering guidance (informational) No change needed — documented tradeoff
Codex P2 on check-emission-conformance.mjs Out of scope — pre-existing, not touched here

CLAUDE.md design rules

Rule Status
Repo-agnostic (no hardcoded paths/names)
Configurable without editing the plugin
Plugin-form-safe (CLAUDE_PLUGIN_ROOT / CLAUDE_PLUGIN_DATA) ✅ (instruction-only skill, no file I/O)
No PII / secrets
Explicit semver version (plugin.json = 0.9.1)

Fresh-docs mandate

sources.md retains *(verbatim, verified)* markers on both the cost-control quote and the inherit default text, cites https://code.claude.com/docs/en/sub-agents, and documents the full resolution order. Mandate satisfied.


Verdict

Approve. The one substantive gap has been closed. The four changed files (SKILL.md, sources.md, CHANGELOG.md, plugin.json) are internally consistent and the instruction additions are well-sourced. No blocking issues remain.

@kyle-sexton
kyle-sexton merged commit 6a9025e into main Jul 18, 2026
14 checks passed
@kyle-sexton
kyle-sexton deleted the fix/orchestrate-worker-model-tiering branch July 18, 2026 21:43
kyle-sexton added a commit that referenced this pull request Jul 21, 2026
)

## What

Sharpens the `orchestrate` skill's per-worker tiering (imperative 7)
into an explicit **volume-based default**, and broadens "tier" from
model-only to model **and** reasoning effort.

## Why

Carried from the re-anchor round-2 ledger (task #3), observed in
production: an `/orchestrate` run fanned out ~100–200 agents, all on the
top-tier model. PR #340 (0.9.1) fixed the root spawn-inherit bug — SPEC
EVERY SPAWN + CALIBRATE now carry a per-worker tier — but the residual
enhancement (making the tier *default* flip on volume) was never built.
The prior text stated the direction as a gradient ("the wider the
fan-out, the cheaper the default per-worker tier") without wiring the
verify/judge carve-out as the standing exception, and never named
reasoning effort as a tiering lever.

## Change

`plugins/session-flow/skills/orchestrate/SKILL.md` — imperative 7:

- Past a wide fan-out, the cheaper tier is now the **DEFAULT the whole
fleet inherits** (volume multiplies every notch of over-provisioning).
- The **standing exception** is an explicitly hard stage — verify,
judge/adjudicate, judgment-heavy synthesis — which keeps the parent
tier. A premium fan-out outside those stages is a per-stage decision to
justify, never a default to inherit.
- **Tier is model AND effort**: match reasoning depth (effort), not just
the model, to the subtask.

`context/sources.md` — three new verbatim citations grounding the change
in current official docs: the per-worker `effort` frontmatter lever, the
workflow fleet-model inherit mechanism, and the platform's own wide-run
threshold (its `Large workflow` warning + `/config` size guideline). Per
the skill's model-/tool-agnostic construction, these version-pinned
specifics stay in `sources.md`, never the imperatives or export brief.

## Grounding (fresh docs, this session)

- Subagent `model` precedence + `inherit` default, `effort` field,
cost-routing guidance — <https://code.claude.com/docs/en/sub-agents>
- Workflow fleet-model inheritance, per-stage routing, `Large workflow`
threshold + size guideline — <https://code.claude.com/docs/en/workflows>

## Gates

- `check-skill.sh orchestrate`: PASS (7/7 trigger phrases preserved,
125/500 lines, markdownlint clean)
- `check-changelog-parity.sh --check` and `--check-bump origin/main`:
PASS
- `validate-plugin-contracts.mjs`, `generate-catalog.mjs --check`,
`claude plugin validate .`: PASS
- Version bumped 0.12.2 → 0.12.3 with CHANGELOG entry in the same diff.

## Related

- PR #340 — the session-flow 0.9.1 spawn-inherit fix this builds on
(SPEC EVERY SPAWN + CALIBRATE carrying a per-worker tier); not closed by
this PR.
- The re-anchor round-2 ledger task #3 production observation that
motivated the residual enhancement.

Closes #863.

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant