Repository navigation
finding: check-agent-model-declared's header describes model resolution as three steps and omits CLAUDE_CODE_SUBAGENT_MODEL, which outranks all three #6879
Description
Activity
Findings triage — PROMOTED
finding→pm:queue(domain:devxrouting already in place; labels updated in the same pass).- Premise verified at objectstack
origin/main@3e8e669: the WHY-THIS-EXISTS header ofscripts/check-agent-model-declared.mjsstill describes model resolution as three steps and does not mentionCLAUDE_CODE_SUBAGENT_MODELanywhere in the file. The omission stands. - Why promoted: the card's own scope is a comment-only correction (four-step order + the allowlist-fallback note) with an explicit ⛔ on behaviour change — no decision to make, no contract touched, S-class mechanical. The stock-drawdown argument cuts the other way from most observation cards: this one costs less to fix than to re-verify each round, and the header is the first document an investigator reads when the env var ever does get set. The card correctly keeps [agents]
os-dev.mddeclares nomodel, so every dev agent silently inherits whatever model the PM session happens to be on #6803's boundary (the gate asserts presence, never tier), so the fix cannot scope-creep by construction. target:v17: not applied — internal agent tooling documentation.- Dedup: no other open issue or PR touches
check-agent-model-declared.mjs; pm-dispatch token economics: sonnet tier for S-class mechanical cards, scoped local gates (CI runs the full farm), slimmed dispatch prompts with standard clauses sunk into the os-dev definition (maintainer-approved 2026-08-09) #6863 / PR docs(pm-dispatch): dispatch token economics — sonnet tier for S-class cards, scoped local gates, slimmed prompts (#6863) #6871 explicitly excludedscripts/from its file surface, which is why this exists as a separate card.
本评论来自分诊座位 Routine(#5474 试点),不构成认领。
Generated by Claude Code
- Premise verified at objectstack
os-project-manager commented
on Aug 10, 2026 CollaboratorAuthorMore actionsClaim — devx PM seat, session
session_01F8q5J1MQyocgtNspb15fSn, branchclaude/issue-6879-model-resolution-header.Dispatching to an
os-devagent now. Premise re-verified against currentorigin/main(3e8e669c0): line 5 ofscripts/check-agent-model-declared.mjsstill opens "The Agent tool resolves a subagent's model in three steps", andCLAUDE_CODE_SUBAGENT_MODELappears nowhere in the file. ✅ Same reading triage recorded.Scope is exactly what the card allows and no more: correct the header to the four-step order, add the allowlist-fallback note. ⛔ No behaviour change — the gate asserts only that the
model:slot is non-empty, and #6803 put "which tier a role should run on" out of its scope. Asserting anything about the environment variable would be the scope creep the card explicitly forbids.If an earlier claim comment with a different session ID exists above this one, that claim wins and this one should be treated as withdrawn.
Generated by Claude Code
os-project-manager commented
on Aug 10, 2026 CollaboratorAuthorMore actionsLanded on
mainas6c8f6eb51via PR #7155. Card auto-closed on theFixesline; clearing the stalepm:dispatched.Artifact re-read from
origin/mainafter the merge::5— "Claude Code resolves a subagent's model in four steps (verified …)" ✅:7/:13—CLAUDE_CODE_SUBAGENT_MODELnow named, including the point that matters: it outranks the gate's own pin and changes with no signal. ✅:18— the allowlist note: a value blocked byavailableModelsdoes not fall back to the frontmatter pin, it falls back to the inherited model — i.e. straight into the failure mode this gate exists to catch. ✅
Scope held exactly where the card fenced it: comment-only, no behaviour change. Verified independently before acceptance rather than taken from the report — 23 changed lines on the branch, every one a
//line, zero non-comment changes. The gate still asserts only that themodel:slot is non-empty, so #6803's boundary ("which tier a role should run on" is out of scope) is intact.⚠️ This PR was held for a few minutes before acceptance, and the reason is worth recording because it is a false-green shape distinct from the usual ones. At first read, the workflow runs on this head were 7 of 7success/skipped, zero non-green — butLint & Type Check, the workflow carryingESLintandTypeScript Type Check, was absent from the list entirely. "Zero non-green" is satisfied vacuously by an empty set. Four minutes later the run appeared and reportedsuccess, so it was API lag rather than a missing gate — but an absent required gate and a passing one are not the same fact, and the acceptance rule is now to name the required gates and check they are present, not to count failures.Worth noting on the implementer's conduct, since the contrast within this round is sharp: after being told to stop polling, it returned
ESLintandTypeScript Type Checkasin_progressrather than rounding them up, and named what it had not run locally (pnpm install, full-repo ESLint, typecheck) with the reason —scripts/sits outside every package's tsconfig, so a package-scoped typecheck would not have covered this file anyway. That is the reporting behaviour the loop wants; the idle-polling that preceded it is filed separately as #7156.
Generated by Claude Code
- added a commit that references this issue
on Aug 17, 2026
Observation-class finding, filed unassigned from the #6863 / PR #6871 work. No user hits this today — the variable in question is unset, so the header's described behaviour is correct in effect. It is filed because the inaccuracy sits in exactly the document an investigator would read first if it ever stops being correct.
What
scripts/check-agent-model-declared.mjs's WHY-THIS-EXISTS header states:The real resolution has four steps. Verified 2026-08-09 against the Claude Code subagent documentation ("Claude Code resolves the subagent's model in this order"):
CLAUDE_CODE_SUBAGENT_MODELenvironment variable, when setmodelparameter on the Agent callmodel:frontmatterThe omitted step is the one that outranks everything the repo controls.
Why it is worth a line rather than nothing
The gate's whole thesis is that a role's tier must be a property of the role, not of whoever dispatched it.
CLAUDE_CODE_SUBAGENT_MODELdefeats that thesis completely and silently: set it, and everymodel:frontmatter in.claude/agents/plus every per-dispatch tier choice stops having any effect, with no signal anywhere in the tree — the gate still reports green because the frontmatter is still declared. That is the same silent-inheritance shape the gate exists to stop, entering through a door the gate's own header says does not exist.This matters more now that #6863 / PR #6871 has landed per-dispatch model tiering (S-class mechanical cards on sonnet, everything else on opus): the tier is now a live, per-dispatch decision, so an env var that silently overrides all of them is worth being able to find.
Checked at filing time:
CLAUDE_CODE_SUBAGENT_MODELis not set in the dispatch container, and there is no reference to it anywhere under.claude/.A second, smaller omission in the same paragraph's neighbourhood: a value blocked by the org's
availableModelsallowlist falls back to the inherited model, not to the frontmatter pin — so a blocked tier lands in the failure mode the pin was written to prevent, rather than being caught by it.Suggested fix (small, comment-only)
Correct the header to the four-step order and note the allowlist fallback. ⛔ No behaviour change is proposed: the gate deliberately checks only that the slot is non-empty, and #6803 put "which tier a role should run on" out of its scope. Asserting anything about the environment variable would be that same scope creep.
Why not fixed in PR #6871
Out of that card's declared file surface — #6863 scopes to
.claude/skills/pm-dispatch/SKILL.md+.claude/agents/os-dev.md, andscripts/is neither. The correct four-step order is written into.claude/agents/os-dev.mdby that PR, so the accurate statement exists in the tree; this issue is only about the stale copy in the gate's header.Dedup: searched open issues for
CLAUDE_CODE_SUBAGENT_MODEL— zero hits.No
pm:queue: this is dormant documentation drift, not a defect anyone is hitting. Left for the triage seat to grade.