Skip to content

Model tiering foundation: config/models.conf + doctor checks (#109) - #113

Merged
yihanzhu merged 1 commit into
mainfrom
coder/109-models-conf
Jul 11, 2026
Merged

Model tiering foundation: config/models.conf + doctor checks (#109)#113
yihanzhu merged 1 commit into
mainfrom
coder/109-models-conf

Conversation

@yihanzhu

Copy link
Copy Markdown
Owner

What

Adds the shell-sourceable config/models.conf shipped model-tiering defaults, a
per-target override convention, and static doctor validation. No behavior change —
nothing reads this config yet.

  • config/models.conf (POSIX-sh, comments explaining each key):
    • FABRICA_CODER_MODEL=sonnet — floating Claude alias; a full model ID may be
      used instead to pin an exact snapshot. Fixed ceiling by design, never
      escalated at runtime.
    • FABRICA_HANDS_MODEL=haiku
    • FABRICA_CODEX_MODEL= (empty = inherit the operator/CLI's own default
      frontier codex)
    • FABRICA_REVIEW_EFFORT=high, FABRICA_DEBATE_EFFORT=high — gates always max,
      no class-based routing.
  • Per-target override: same-format/same-keys file, sourced after the
    defaults, as a static per-repo commitment (never a per-task rescue). Template at
    templates/.fabrica/models.conf.
  • scripts/doctor.sh new checks:
    • (k) config/models.conf present + sourceable (sourced in a subshell so a
      syntax error can't abort doctor under set -e), and — once sourced —
      FABRICA_CODER_MODEL / FABRICA_HANDS_MODEL are non-empty.
    • (l) WARN if CLAUDE_CODE_SUBAGENT_MODEL is set in the environment (it
      would silently override a per-spawn model argument once wiring lands).
    • Both are static-only: no live model/API calls.
  • ci/required-files.txt: added config/models.conf (per spec) and
    templates/.fabrica/models.conf (the new shipped template — added for
    full-backup consistency with the existing templates/.fabrica/north-star.md
    entry, per CLAUDE.md's "add new restore-critical files to the manifest" rule).
  • README.md: new "Model policy" section — the spend-by-leverage-not-by-volume
    principle (gates decide → always max; producers type → fixed ceilings; frontier
    thinks, never types), the config table, and the per-target override convention.
    Also a short addition to templates/repo-setup.md (step 7, optional) so the
    target-repo setup checklist mentions the override alongside the north star.

Closes #109

Why (discovery decisions)

  1. Doctor integration point: extended the existing lettered-check
    scripts/doctor.sh (checks a–j, added by Per-target north star (98a): atomic gate+doctor+persona flip, reading committed target state #101/Greenfield tie-in + MapleFolio history (98b): bootstrap creates committed target north star #104) rather than inventing a
    parallel validator — added checks (k) and (l), following the same
    report/report_warn pattern and the same "static/diagnostic only, no
    mutation" discipline the rest of the script follows.
  2. Per-target override path: mirrored the north-star work's (Per-target north star (98a): atomic gate+doctor+persona flip, reading committed target state #101/Greenfield tie-in + MapleFolio history (98b): bootstrap creates committed target north star #104)
    per-target committed-state convention — a target repo's own state lives under
    its .fabrica/ directory (.fabrica/north-star.md today). The model override
    follows the same pattern at .fabrica/models.conf, sourced after the
    control-plane's shipped config/models.conf defaults, documented in
    README.md's new "Model policy" section and templates/repo-setup.md step 7.

No behavior change

Nothing reads config/models.conf or a target's .fabrica/models.conf yet beyond
doctor.sh's own static validation. Wiring the coder spawn, the hands policy, and
the gates to this config is follow-up work (issues #110#112).

Test plan

  • shellcheck -x -S style (pinned 0.9.0 binary, matching CI) over every
    *.sh in the repo — clean.
  • scripts/test/north-star-resolver.test.sh — 64 passed, 0 failed
    (no regression).
  • scripts/test/north-star-gate.test.sh — 190 passed, 0 failed
    (no regression).
  • CI's structure check (manifest presence + executable bits) run locally —
    passes.
  • Manual doctor.sh smoke test of checks (k)/(l): happy path (both pass),
    missing config (fail), empty required value (fail), shell syntax error (fail,
    doctor still completes and prints the summary), CLAUDE_CODE_SUBAGENT_MODEL
    set (warn).

🤖 Generated with Claude Code

Add the shell-sourceable config/models.conf shipped defaults (fixed
coder/hands ceilings, always-max gate model/effort), a per-target
override convention at .fabrica/models.conf (mirrors where the
north-star work put per-target committed state), and doctor checks
(k)/(l) that statically validate the config is present/sourceable
with non-empty coder/hands values and warn on a stray
CLAUDE_CODE_SUBAGENT_MODEL env override.

Closes #109

No behavior change: nothing reads config/models.conf or a target's
.fabrica/models.conf yet beyond doctor's own static validation —
wiring the coder spawn, hands policy, and gates to this config is
follow-up work (#110-#112).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@cloudflare-workers-and-pages

Copy link
Copy Markdown

Deploying fabrica with  Cloudflare Pages  Cloudflare Pages

Latest commit: 18892b0
Status: ✅  Deploy successful!
Preview URL: https://35e17028.fabrica-6yx.pages.dev
Branch Preview URL: https://coder-109-models-conf.fabrica-6yx.pages.dev

View logs

@yihanzhu

Copy link
Copy Markdown
Owner Author

Codex reviewer (cross-vendor, read-only)

Reviewed-head: 18892b0
Reviewed-base: 5151b46

Posted verbatim by codex-review.sh (codex exec review --base refs/codex-review/113-85298/base in an isolated temp worktree, sandbox forced read-only). Comments only — Codex never pushes, approves, or merges.

No actionable findings were identified in the available review context.

@yihanzhu
yihanzhu merged commit 1425781 into main Jul 11, 2026
2 checks passed
@yihanzhu
yihanzhu deleted the coder/109-models-conf branch July 11, 2026 16:16
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.

Model tiering foundation: config/models.conf + doctor checks

1 participant