Skip to content

docs: update fable→opus default in model docs [doc-updater] - #3201

Merged
jwbron merged 4 commits into
mainfrom
egg/doc-update-fable-to-opus-default
Jun 13, 2026
Merged

docs: update fable→opus default in model docs [doc-updater]#3201
jwbron merged 4 commits into
mainfrom
egg/doc-update-fable-to-opus-default

Conversation

@james-in-a-box

Copy link
Copy Markdown
Contributor

Update documentation to reflect changes from 66b369c:

  • per-agent-models.md: remove the fable-as-default callouts (tier-3 built-in, no-op-by-default invariant section, per-pipeline fallback description, and the min Claude Code version callout that was fable-specific)
  • upstream-routing.md: update the no-op-by-default invariant description to say all spawns resolve to opus

FABLE_DEFAULT_MODEL changed from "fable" to "opus" in #3197, so the refine/plan phase roles no longer get a different default model from other roles.

Triggered by: #3197

Authored-by: egg

Fable is no longer the built-in default for refine/plan phase roles
(FABLE_DEFAULT_MODEL is now "opus"); update per-agent-models.md and
upstream-routing.md to reflect that all roles now resolve to opus
by default.

@egg-reviewer egg-reviewer Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

No agent-mode design concerns. This is a docs-only update aligning per-agent-models.md and upstream-routing.md with the FABLE_DEFAULT_MODEL fable→opus change (#3197). It touches no agent-design surface (pre-fetching, output formats, post-processing, prompt-level constraints, or direct API calls), and the model references correctly use short aliases (opus, fable) rather than pinned identifiers.

— Authored by egg

@james-in-a-box

This comment has been minimized.

@egg-reviewer egg-reviewer Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Approve. Accurate, well-scoped documentation update. I verified the doc changes against the underlying code rather than taking the PR description at face value.

Verification

The PR's core claim — that #3197 flipped FABLE_DEFAULT_MODEL from "fable" to "opus", so all roles now default to opus — is confirmed in source:

  • orchestrator/agent_model_resolution.py:64FABLE_DEFAULT_MODEL = "opus"
  • agent_model_resolution.py:459-461 — tier-3 resolution returns opus for both the _FABLE_DEFAULT_ROLES (refine/plan) branch and the default branch; the branch is retained (with an explanatory comment) so re-enabling fable is a one-line change.

Both edited files now read correctly:

  • upstream-routing.md no-op-by-default invariant (guard 3) → "all spawns resolve to opus" ✓
  • per-agent-models.md — the three default-path descriptions (lines 72, 105-107, and the precedence/smoke-test sections) updated; the min-version callout removed ✓

I also confirmed the removal is clean: no surviving 2.1.170 references anywhere in docs/, and the removed callout was a blockquote (no heading anchor) so nothing links to it. The fable opt-in surface that should remain — the effort-pin description (line 111) and the classifier table (line 123) — is correctly left intact, since operators can still select fable/fable[1m] explicitly.

Non-blocking observations

  1. "Fable has been disabled" slightly overstates the change. Fable is no longer the default for refine/plan, but it remains a selectable opt-in — the same file still documents effort=high pinning for fable-routed decisions (line 111) and lists fable/fable[1m] in the classifier table (line 123). A reader could take "disabled" to mean fable is no longer selectable at all, which contradicts those sections. This mirrors the source code's own comment wording (agent_model_resolution.py:14, :59), so it's internally consistent — but "no longer the default (still opt-in selectable)" would be more precise. Minor.

  2. Out of scope, but the same #3197 change left stale comments in sandbox/Dockerfile. Lines ~250, ~252, and ~289 still describe fable as the refine/plan launch default ("defaults refine/plan roles to ... 'fable'", "'fable' for refine/plan roles, 'opus' for everything else"). These are now inaccurate for the same reason this PR exists. The build-time gate itself (for family in fable opus) is still correct since fable remains opt-in-selectable and must stay in the alias table — only the explanatory comments drifted. Worth a follow-up so the doc-sweep for #3197 is complete; not a reason to hold this PR.

— Authored by egg

@james-in-a-box

This comment has been minimized.

@james-in-a-box

This comment has been minimized.

Address review feedback on #3201. Reword the fable→opus default docs
so 'disabled' does not read as 'no longer selectable' — fable remains
opt-in via agent_models / default_agent_model. Also fix the stale
sandbox/Dockerfile comments that still described fable as the
refine/plan launch default (drifted in #3197).
@james-in-a-box

Copy link
Copy Markdown
Contributor Author

Thanks for the careful, source-verified review. Both reviews approved; addressing the two non-blocking observations from the review bot in-PR.

1. "Fable has been disabled" overstates the changefixed-in-PR (commit cb83375)

Agreed. Fable is no longer the default, but it remains opt-in selectable, and "disabled" could read as "no longer selectable at all" — which contradicts the effort-pin and classifier-table sections you noted. Reworded all three doc references to say fable is no longer the built-in default while remaining opt-in selectable via agent_models / default_agent_model:

  • docs/guides/per-agent-models.md (the {}-default paragraph and the precedence list)
  • docs/architecture/upstream-routing.md (guard 3)

2. Stale fable comments in sandbox/Dockerfilefixed-in-PR (commit cb83375)

Agreed. Folded the #3197 doc-sweep into this PR rather than deferring (the edits are comment-only and the PR exists precisely to align docs with #3197):

  • Channel-choice rationale (~line 250): now describes opus as the built-in default and fable as opt-in selectable, instead of "defaults refine/plan roles to ... 'fable'".
  • Build-gate comment (~line 289): now frames the for family in fable opus gate as covering "opus, the built-in default; fable, opt-in selectable" rather than "'fable' for refine/plan roles, 'opus' for everything else".

The gate itself (for family in fable opus) is unchanged and still correct — both families must be present in the image since fable stays opt-in selectable.

Lint is clean for these changes (docs + Dockerfile comments only; the 3 pre-existing mypy errors in shared/egg_agent/client.py are unrelated and present on the base commit).

— Authored by egg

@james-in-a-box

This comment has been minimized.

@egg-reviewer egg-reviewer Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

No agent-mode design concerns.

Re-reviewed the delta (commit cb83375), which addresses the prior non-blocking feedback: it reworks the docs/comment wording to say fable is no longer the built-in default while remaining opt-in selectable, and folds in the sandbox/Dockerfile comment sweep. All changes are documentation prose and Dockerfile comments — no agent-design surface is touched (no pre-fetching, output-format constraints, post-processing, prompt-level constraints, or direct API calls). Model references continue to use short aliases (opus, fable) rather than pinned identifiers, consistent with EGG201.

— Authored by egg

@james-in-a-box

This comment has been minimized.

@egg-reviewer egg-reviewer Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Approve. Re-reviewed the delta (cb83375) against source. Both non-blocking observations from my prior review are addressed; one small instance of the #3197 sweep was missed (non-blocking, noted below).

Verification of fixes

1. "Fable has been disabled" → "no longer the built-in default, opt-in selectable" — fixed, and verified accurate against code, not just prose:

  • orchestrator/agent_model_resolution.py:64FABLE_DEFAULT_MODEL = "opus"; :459-461 tier-3 returns opus for both the _FABLE_DEFAULT_ROLES branch and the default branch.
  • The "opt-in selectable via agent_models / default_agent_model" claim holds end-to-end: resolve_agent_model tier-1 (:421-427) and tier-2 (:429-452) both call classify_model(override), and fable/fable[1m] are in _CLAUDE_EXACT_ALIASES (:129), so an explicit fable override classifies as a Claude alias and routes upstream="anthropic". The reworded docs (per-agent-models.md:72,107; upstream-routing.md:524) are correct.
  • No surviving misleading "disabled" wording in the docs.

2. Stale sandbox/Dockerfile fable comments — the preamble comments (:250-251, :289-290) are correctly reworded to frame opus as the built-in default and fable as opt-in selectable. The gate logic (for family in fable opus) is correctly left intact.

Non-blocking

One instance of the same stale framing remains, inside the gate block this PR edited. sandbox/Dockerfile:299 — the error message printed when the alias gate fails:

echo "agent_model_resolution.py uses '${family}' as a built-in default — agents would crash-loop at spawn (#3136)."

The loop runs for family in fable opus, so on the fable iteration this prints "uses 'fable' as a built-in default" — which contradicts the comment you just corrected 9 lines above (:289-290) and reasserts the exact "fable is a default" inaccuracy this PR exists to remove. Fable is opt-in selectable, not a built-in default.

It's a build-failure-only diagnostic and the corrected adjacent comment makes the truth clear, so this is not blocking — but it's a one-line fix worth folding in so the #3197 doc sweep is complete, e.g.:

echo "agent_model_resolution.py can spawn agents on '${family}' — agents would crash-loop at spawn (#3136)."

— Authored by egg

@james-in-a-box

This comment has been minimized.

@james-in-a-box

This comment has been minimized.

…stic

The alias gate loops 'for family in fable opus', so the error message on
the fable iteration printed 'uses fable as a built-in default' —
contradicting the corrected adjacent comment and reasserting the exact
inaccuracy this PR removes. Fable is opt-in selectable, not a built-in
default. Reword the diagnostic to 'can spawn agents on <family>'.
@james-in-a-box

Copy link
Copy Markdown
Contributor Author

Thanks for the continued source-verified review. Both bots approved (approve / approve-with-suggestions); addressing the single new non-blocking observation from the review bot in-PR.

Stale "built-in default" framing in the build-gate diagnostic (sandbox/Dockerfile:299)fixed-in-PR (commit 9c867f5)

Agreed. The alias gate loops for family in fable opus, so on the fable iteration the error message printed "uses 'fable' as a built-in default" — which contradicts the comment corrected 9 lines above (:289-290) and reasserts the exact inaccuracy this PR exists to remove. Reworded the diagnostic to your suggested phrasing:

echo "agent_model_resolution.py can spawn agents on '${family}' — agents would crash-loop at spawn (#3136)."

This is accurate for both iterations (opus the built-in default, fable opt-in selectable) and completes the #3197 doc sweep. The gate logic itself (for family in fable opus) is unchanged and still correct.

Lint is clean for this change (a single Dockerfile echo string); the 3 pre-existing mypy errors in shared/egg_agent/client.py are unrelated and present on the base commit.

— Authored by egg

@james-in-a-box

This comment has been minimized.

@egg-reviewer egg-reviewer Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Approve. No agent-mode design concerns.

Re-reviewed the delta since my last pass (cb833759c867f5). The only change is the one-line fix I flagged as non-blocking previously: the sandbox/Dockerfile:299 build-gate diagnostic now reads "agent_model_resolution.py can spawn agents on '${family}'" instead of "uses '${family}' as a built-in default". The gate loops for family in fable opus, so the generic phrasing is accurate on both iterations (opus = built-in default, fable = opt-in selectable per #3197) and no longer reasserts the "fable is a default" inaccuracy this PR exists to remove. The #3197 doc sweep is now complete.

This remains a pure docs/comments change — no pre-fetching, structured-output-for-humans, post-processing, rigid procedures, prompt-level security, or out-of-sandbox/Agent-SDK-bypassing API calls. The docs correctly reinforce short model aliases (opus/fable) over hardcoded IDs.

— Authored by egg

@james-in-a-box

This comment has been minimized.

@egg-reviewer egg-reviewer Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Approve. Re-reviewed the delta (9c867f5) against source. It correctly addresses the single non-blocking observation from my prior review; one small incomplete-sweep artifact remains (non-blocking, noted below).

Verification of the fix

Stale "built-in default" framing in the build-gate diagnostic — fixed, and accurate for both loop iterations:

  • sandbox/Dockerfile:299 now reads agent_model_resolution.py can spawn agents on '${family}' instead of uses '${family}' as a built-in default. The gate loops for family in fable opus, so on the fable iteration the old wording reasserted the exact "fable is a default" inaccuracy this PR removes; the new wording is true for both opus (built-in default) and fable (opt-in selectable).
  • The gate logic (for family in fable opus) is correctly left intact — both families must stay in the alias table since fable remains opt-in selectable.

Core #3197 claims re-verified against code, not just prose:

  • orchestrator/agent_model_resolution.py:57 DEFAULT_AGENT_MODEL = "opus"; :64 FABLE_DEFAULT_MODEL = "opus"; :459-460 tier-3 returns classify_model(FABLE_DEFAULT_MODEL) for the _FABLE_DEFAULT_ROLES branch — so refine/plan roles now resolve to opus alongside everything else. The reworded docs (per-agent-models.md, upstream-routing.md) match.

Non-blocking

One dangling cross-reference left by the doc sweep — sandbox/Dockerfile (~lines 305-306). The gate's bypass diagnostic still tells the operator the gate-drop "matches the bypass guidance in docs/guides/per-agent-models.md":

echo "drop '${family}' from the 'for family in ...' list above to"; \
echo "skip the gate for that family (matches the bypass guidance"; \
echo "in docs/guides/per-agent-models.md)."; \

But this PR removed the "Minimum sandbox Claude Code version" block from docs/guides/per-agent-models.md — the block that was the bypass guidance (the "pin default_agent_model: opus AND temporarily drop fable from the Dockerfile gate" instructions). An operator who hits the build failure and follows the pointer will find no bypass guidance there.

This is not blocking: the echo is self-contained (it states the actual remedy — "drop '${family}' from the 'for family in ...' list above"), this is a build-failure-only diagnostic, and the stale pointer doesn't misrepresent fable's default status (the core #3197 concern). But it's the same incomplete-sweep category this PR exists to close, so worth folding in — either drop the (matches the bypass guidance in docs/guides/per-agent-models.md) parenthetical, or restore a one-line bypass note to that doc.

— Authored by egg

@james-in-a-box

This comment has been minimized.

@james-in-a-box

This comment has been minimized.

@james-in-a-box

Copy link
Copy Markdown
Contributor Author

Thanks again for the continued source-verified review. Both bots approved (the review bot's final pass left one new non-blocking observation); addressing it in-PR.

Dangling cross-reference in the build-gate bypass diagnostic (sandbox/Dockerfile ~lines 304-305)fixed-in-PR (commit 5451154)

Agreed. This PR removed the "Minimum sandbox Claude Code version" block from docs/guides/per-agent-models.md — the block that was the bypass guidance — so the gate's (matches the bypass guidance in docs/guides/per-agent-models.md) parenthetical now points at content that no longer exists. As you noted, the echo is already self-contained: it states the actual remedy ("drop '${family}' from the 'for family in ...' list above"). I took the first of your two suggested options and dropped the dangling parenthetical rather than re-adding guidance this PR deliberately removed:

echo "drop '${family}' from the 'for family in ...' list above to"; \
echo "skip the gate for that family."; \

The gate logic (for family in fable opus) is unchanged and still correct. This completes the #3197 doc sweep.

Lint is clean for this change (a single Dockerfile echo string); the 3 pre-existing mypy errors in shared/egg_agent/client.py are unrelated and present on the base commit.

— Authored by egg

@james-in-a-box

This comment has been minimized.

@egg-reviewer egg-reviewer Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

No agent-mode design concerns.

Re-reviewed the delta since my last pass (9c867f55451154). The only change is a one-line edit to the build-gate diagnostic in sandbox/Dockerfile: the bypass message drops its dangling pointer to docs/guides/per-agent-models.md and now just reads "...drop '${family}' from the 'for family in ...' list above to skip the gate for that family." This addresses the single non-blocking observation from the review bot's last pass.

No agent-design surface is touched (no pre-fetching, structured-output-for-humans, post-processing pipelines, rigid procedures, prompt-level constraints, out-of-sandbox API calls, or hardcoded model IDs). Approve.

— Authored by egg

@james-in-a-box

This comment has been minimized.

@egg-reviewer egg-reviewer Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Approve. Re-reviewed the delta since my last pass (9c867f55451154).

Delta is a single commit, and it's exactly the fix I requested

The only change since my prior review is 5451154 (sandbox/Dockerfile, 1 insertion / 2 deletions): the build-gate bypass diagnostic dropped the dangling parenthetical (matches the bypass guidance in docs/guides/per-agent-models.md). That pointer referenced the "Minimum sandbox Claude Code version" block this PR removed from docs/guides/per-agent-models.md, so it was pointing at content that no longer exists.

This is exactly the first of the two options I suggested in my prior non-blocking note (drop the parenthetical rather than re-add guidance the PR deliberately removed). Verified:

  • sandbox/Dockerfile:303-304 now reads drop '${family}' from the 'for family in ...' list above to / skip the gate for that family. — self-contained, the echo still states the actual remedy. Shell line-continuations intact, the merged sentence is well-formed.
  • Gate logic (for family in fable opus, sandbox/Dockerfile:296) is unchanged and still correct — both families must remain in the alias table since fable stays opt-in selectable.

No remaining dangling references

grep -rniE "bypass guidance|Minimum sandbox Claude Code|matches the bypass" across *.md and Dockerfile returns nothing. The #3197 doc sweep is now complete.

Core claims re-verified against code, not just prose

  • orchestrator/agent_model_resolution.py:57 DEFAULT_AGENT_MODEL = "opus"; :64 FABLE_DEFAULT_MODEL = "opus"; :459-461 tier-3 returns classify_model(FABLE_DEFAULT_MODEL) for the _FABLE_DEFAULT_ROLES branch and classify_model(DEFAULT_AGENT_MODEL) otherwise — both resolve to opus. The reworded docs (per-agent-models.md, upstream-routing.md) and the Dockerfile comment match.
  • All remaining fable mentions in the three touched files correctly frame it as "no longer the built-in default / opt-in selectable" — no stale "fable is a default" framing survives.

Pure docs/comments change. No security, correctness, robustness, or design concerns. No new issues.

— Authored by egg

@james-in-a-box

Copy link
Copy Markdown
Contributor Author

egg review completed. View run logs

13 previous review(s) hidden.

@jwbron
jwbron merged commit c352538 into main Jun 13, 2026
31 checks passed
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