Skip to content

feat(#347): promote utility agents to per-agent model: frontmatter (Wave 2 PR 4)#361

Merged
atlas-apex merged 2 commits into
devfrom
feature/GH-347-promote-utility-agents-model-frontmatter
May 21, 2026
Merged

feat(#347): promote utility agents to per-agent model: frontmatter (Wave 2 PR 4)#361
atlas-apex merged 2 commits into
devfrom
feature/GH-347-promote-utility-agents-model-frontmatter

Conversation

@atlas-apex

Copy link
Copy Markdown
Collaborator

Summary

  • 4 utility agents promoted off model: inherit to explicit AgDR-0050 § Axis 2 baselines: Rex (code-reviewer.md) inherit → opus per Axis 2 line 50 (PR diff review + handbook reasoning depth); Munir (dependency-auditor.md) inherit → sonnet per line 63 (pattern-matching across package files); Tariq (pr-manager.md) inherit → sonnet per line 64 (tool-call-heavy + PR body narrative quality); Idris (ticket-manager.md) inherit → sonnet per line 65 (schema-conforming output + interactive interview). Hakim was already promoted to opus in PR feat(#347)!: Hatim→Hakim consolidation + security + data sub-agents (Wave 2 PR 3) #360 as part of the Hatim→Hakim consolidation, completing the 5/5 utility-agent matrix.
  • Each frontmatter carries the # routing-config:override escape-hatch comment inside the YAML frontmatter so block-agent-routing-drift.sh accepts the intentional inherit→ framework-default change rather than blocking it as adopter-leak. The comment names the agent, the AgDR line number, and the rationale — visible + auditable per AgDR-0040's escape-hatch convention. Each commit landed cleanly through the drift guard on the first attempt (no PR-3-style "wrong comment style" retry).
  • test_agent_wrap_shape.sh extended with a UTILITY_AGENTS array and a new "Invariant 4b" block that asserts each utility agent has (a) explicit model: matching Axis 2, (b) correct persona_name, and (c) the escape-hatch comment in YAML frontmatter. Locks in the post-PR-4 baselines so a future revert-to-inherit trips the test instead of silently slipping. Bonus fix: the new awk uses POSIX [[:space:]] / [^[:space:]] instead of \S\S isn't portable across awk implementations (macOS BSD awk silently treated it as a literal, masking the regex bug). Other awk blocks in the test file already use POSIX classes, so this is a one-time gotcha that's now closed.
  • test_agent_routing_sync_and_drift.sh extended with a ticket-manager fixture in make_fork + new CASE 8 that exercises a utility-agent override (ticket-manager sonnet → opus). Proves the routing-sync mechanism doesn't distinguish utility from role-derived agents — same hook, same rewrite, same snapshot path. 8/8 cases PASS.

Testing

  • bash .claude/agents/tests/test_agent_wrap_shape.sh — PASS at 13 ROLE_AGENTS + 5 UTILITY_AGENTS + 19 ROLE_CLASSES.
  • bash .claude/hooks/tests/test_agent_routing_sync_and_drift.sh — PASS at 8/8 cases (case 8 new this PR).
  • Drift guard accepted both commits (0961572 model changes + 637f2d9 test extensions) without blocking — verifies the escape-hatch comment placement is correct on all 4 utility files.
  • Manual smoke (operator, post-merge): start a fresh session, observe Rex's review tone for any visible-model-bump effect on code-reviewer output quality. Not blocking this merge.
  • Manual smoke (operator, post-merge): apply an agent-routing.yaml override (e.g. ticket-manager: model: opus) and confirm SessionStart sync rewrites .claude/agents/ticket-manager.md's model: to opus; git checkout then restores sonnet. Not blocking.

Glossary

Term Definition
UTILITY_AGENTS array New companion to ROLE_AGENTS in test_agent_wrap_shape.sh. Format "<slug>:<expected_model>:<expected_persona_name>". Locks in AgDR-0050 § Axis 2 baselines for the 5 utility agents (Rex, Hakim, Munir, Tariq, Idris). Different from ROLE_AGENTS because utility agents don't have a canonical roles/<dept>/<slug>.md file — they're framework primitives, not role-derived personas.
# routing-config:override <reason> escape hatch YAML-frontmatter comment recognised by block-agent-routing-drift.sh (regex ^[[:space:]]*#[[:space:]]*routing-config:override[[:space:]]+\S). Used for intentional framework-default changes — e.g. this PR's 4 inherit→ bumps. The comment ships with the PR and makes the deliberate change visible. HTML <!-- --> form does NOT match — only the #-prefixed YAML comment form does (footgun from PR #360 is now documented in the test).
Axis 2 baseline vs adopter override AgDR-0050 § Axis 2 ships per-agent default models in the framework (this PR makes the utility-agent defaults explicit). Adopters override per-agent via agent-routing.yaml in their private portfolio repo (or gitignored single-fork). The SessionStart sync hook (apply-agent-routing.sh, from #357) rewrites the agent file's model: line at session start; the drift guard prevents that rewrite from leaking into a commit.
POSIX awk vs \S macOS BSD awk and other POSIX-strict implementations don't support \S (the Perl-style non-whitespace shorthand). They silently treat \S as a literal "S" character. The new test code uses [^[:space:]] instead — same semantics, portable across all awk implementations.

Refs #347 (4/5 PRs now landed; PR 5 — role-trigger integration — is the last)
Refs #348 (Idris is one of three candidates for the local-routing feasibility spike)

Note for the next reviewer

This PR keeps strictly to scope: 4 frontmatter promotions + 2 test extensions. No drive-by cleanups, no doc rewrites, no CLAUDE.md / site / AGENTS.md changes (agent count is unchanged — only model values change). Rex's 5 non-blocking suggestions on PR #360 (consolidation-exception test, stale Hatim in test file comment, AgDR-0018 lines 51+92 doc-debt, prose inaccuracy at security-reviewer.md:17, HTML-comment drift-guard footgun docs) are intentionally NOT included in this PR — they're tracked as follow-ups for a Wave-3 cleanup PR or discrete chore tickets.

me2resh and others added 2 commits May 21, 2026 02:38
…(Wave 2 PR 4)

Per AgDR-0050 § Axis 2, the framework's 5 utility sub-agents drop the
default model: inherit (which pays the parent thread's rate) for explicit
per-agent baselines optimised for the work each does. Hakim was promoted
in PR 3 (#360) as part of the Hatim→Hakim consolidation; this commit
finishes the remaining 4.

Frontmatter changes (each carries the # routing-config:override comment
inside the YAML frontmatter so block-agent-routing-drift.sh accepts the
intentional inherit→<model> framework-default change):

  Rex   (code-reviewer)      inherit → opus    AgDR-0050 § Axis 2 line 50
                                               (PR diff review + handbook
                                               reasoning depth)
  Munir (dependency-auditor) inherit → sonnet  AgDR-0050 § Axis 2 line 63
                                               (pattern-matching across
                                               package files)
  Tariq (pr-manager)         inherit → sonnet  AgDR-0050 § Axis 2 line 64
                                               (tool-call-heavy + PR
                                               body narrative quality)
  Idris (ticket-manager)     inherit → sonnet  AgDR-0050 § Axis 2 line 65
                                               (schema-conforming output
                                               + interactive interview)
                                               Local-routing candidate
                                               per #348 spike.

No body / role-file / count changes — the 23-agent count is unchanged,
just 4 model values + 4 YAML comments.

Refs #347

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…PR 4

Locks in the post-PR-4 utility-agent baselines so a future regression
(e.g. someone reverts a model: line to inherit, or strips the escape-hatch
comment) trips a test rather than silently slipping through.

test_agent_wrap_shape.sh:

- Added UTILITY_AGENTS array (mirror of ROLE_AGENTS, format
  "<slug>:<model>:<persona>"). Covers all 5 utility agents including
  Hakim (already promoted to opus in PR 3).
- New "Invariant 4b" block asserts each utility agent has (a) explicit
  model: matching AgDR-0050 § Axis 2, (b) correct persona_name, and
  (c) a # routing-config:override comment in YAML frontmatter (the
  drift-guard escape hatch required for any inherit → <model> change).
- Awk regex uses POSIX [[:space:]] / [^[:space:]] rather than \S — \S
  isn't portable across awk implementations (bug found while extending
  this test; macOS BSD awk silently treated \S as a literal).

test_agent_routing_sync_and_drift.sh:

- Added a ticket-manager fixture to make_fork (model: sonnet, escape-hatch
  comment, persona Idris). The fixture proves the routing-sync mechanism
  doesn't distinguish utility vs role-derived agents — same hook, same
  rewrite, same snapshot path.
- New CASE 8 exercises a utility-agent override (ticket-manager sonnet →
  opus). Asserts: agent frontmatter flips to opus, qa-engineer is
  untouched (single-override scope), the framework-defaults snapshot
  records the sonnet baseline (not the opus override).

Both tests PASS at the new HEAD.

Refs #347

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

@atlas-apex atlas-apex left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Code Review: PR #361

Commit: 637f2d9649434b8b99dd88cd1de99a088a41d8f3

Summary

Wave 2 PR 4 of #347. Promotes the remaining 4 utility sub-agents off model: inherit to explicit per-agent baselines per AgDR-0050 § Axis 2, completing the 5/5 utility-agent matrix (Hakim landed in PR #360). Two commits: the 4 frontmatter edits + 2 test extensions (UTILITY_AGENTS array with Invariant 4b block + CASE 8 in the routing smoke test). Strict scope: 6 files, +131 / −5.

Checklist Results

  • Architecture & Design: PASS
  • Code Quality: PASS
  • Testing: PASS — both extended test suites green at HEAD (18 wrap-shape PASS lines + 8/8 routing cases)
  • Security: N/A (no auth / secrets / crypto / user-data surface)
  • Performance: N/A
  • PR Description & Glossary: PASS — every bullet narrative; Glossary has 4 well-explained terms (UTILITY_AGENTS array, escape-hatch comment, Axis 2 baseline vs adopter override, POSIX awk vs \S)
  • Summary Bullet Narrative: PASS — each bullet answers what + why, ~3-5 sentences
  • Technical Decisions (AgDR): N/A — AgDR-0050 is cited 9 times in the PR body and governs this entire 5-PR series; the model assignments execute its § Axis 2 matrix rather than making new decisions
  • Adopter Handbooks: N/A — diff is .md frontmatter + .sh test scripts; no language handbooks fire, no findings against architecture/ or general/ always-load handbooks

Issues Found

None.

Verifications performed

  1. AgDR-0050 § Axis 2 line numbers — confirmed against docs/agdr/AgDR-0050-agent-runtime-overhaul.md lines 50, 63, 64, 65. Exact text from each line:

    • L50: | Code Reviewer (Rex) | opus | PR diff review + handbook reasoning (existing utility) | → Rex inherit → opus
    • L63: | Dependency Auditor (Munir, utility) | sonnet | Pattern-matching across package files | → Munir inherit → sonnet
    • L64: | PR Manager (Tariq, utility) | sonnet | Tool-call-heavy + narrative-quality PR bodies | → Tariq inherit → sonnet
    • L65: | Ticket Manager (Idris, utility) | sonnet | Schema-conforming output + interactive interview | → Idris inherit → sonnet
      All 4 frontmatter model values match the cited lines exactly.
  2. Escape-hatch comment shape — ran the live drift-guard regex (^[[:space:]]*#[[:space:]]*routing-config:override[[:space:]]+[^[:space:]]) against each of the 4 modified agent files inside its YAML frontmatter; all 4 match with non-empty reason text. The comment is on line 2 (inside ---/---) in each file — first thing the drift guard sees, no parser dependency on ordering. Each comment names the persona, AgDR line number, and rationale.

  3. UTILITY_AGENTS array completeness — array covers 5 entries (Rex, Hakim, Munir, Tariq, Idris) with model + persona triples matching AgDR-0050. Hakim's inclusion (already promoted in PR #360) is the right call — locking in the post-Wave-2 baseline so a future revert to inherit on any of the 5 trips this test, not just the 4 promoted today. Test ran at HEAD: 5/5 utility-agent PASS lines printed, plus 13 ROLE_AGENTS and 19 ROLE_CLASSES PASS.

  4. POSIX awk fix — confirmed on macOS BSD awk: echo "abc def" | awk '/\S/ { print "matched-S" } /[^[:space:]]/ { print "matched-POSIX" }' prints only matched-POSIX. The fix is correct. Scanned the broader hook/agent test suite for any other \S/\W/\D Perl-style classes in awk blocks — zero remaining. No follow-up needed; the gotcha is contained to this PR's new awk block.

  5. CASE 8 tightness — the case asserts FOUR independent properties:

    • after_tm = opus (override applied)
    • after_qa = haiku (single-override scope — unrelated agent untouched)
    • Banner reports applied 1 agent-routing override (exactly 1, not 0 / not 2+)
    • Framework-defaults snapshot records "ticket-manager":"sonnet" (pre-override baseline preserved, not the post-override opus)
      All four are load-bearing for the "utility override mechanism doesn't drift or lose baseline" invariant. The qa-engineer = haiku assertion is the load-bearing single-override-scope check — well-chosen, since it's the most-different model (haiku vs opus) and would catch any wholesale-rewrite bug.
  6. Scope disciplinegh pr diff --name-only returns exactly 6 files matching the PR description's claim. No drive-bys to CLAUDE.md / AGENTS.md / site / docs.

  7. AGENTS.md refresh — grepped: claims "23 sub-agents" (post-Hakim consolidation), no "inherit" references. Live count of model: lines: 6 opus + 15 sonnet + 2 haiku = 23. Matches. No refresh needed.

  8. Drift guard pre-commit cleanlinessgit log 0af3288..HEAD --format='%H %s' shows two clean commits with no revert-and-restage churn. Diff-stat per commit: 0961572 = 4 agent files only; 637f2d9 = 2 test files only. Both passed the drift guard on first try.

  9. CIgh pr checks 361: all checks pass (verify-ticket-id, lychee, markdownlint, shellcheck, site-counts-drift).

Suggestions

None blocking. Two non-blocking observations for context:

  • nit: the comment on test_agent_wrap_shape.sh line 253 still mentions \S to explain the gotcha. That's fine and informative — leaving it as-is preserves the institutional memory for whoever next reaches for \S in an awk block. No action.
  • nit: AgDR-0050 § Axis 2's matrix header says "24-entry default matrix" (line 112) but post-Hatim→Hakim consolidation the count is 23. This is pre-existing doc debt from PR #360, not introduced by this PR — flagged in the PR-360 follow-up list ("AgDR-0018 lines 51+92 doc-debt") and intentionally out-of-scope here. No action for this PR.

Verdict

APPROVED

The PR executes Wave 2 PR 4 of #347 to-spec: 4 frontmatter promotions matching the AgDR-0050 § Axis 2 baselines on the cited lines, drift-guard escape-hatch comments shaped correctly, two-test extension that mechanically locks in both the post-PR-4 invariants and the utility-vs-role-agent equivalence in the routing mechanism. POSIX awk fix is a clean side-fix contained to the new code (no other \S regex regressions in the suite). Scope discipline is exemplary — 6 files, both commits clean through the drift guard, no drive-bys.

The operator should write the approval marker on Rex's behalf per sandbox restriction:

echo 637f2d9649434b8b99dd88cd1de99a088a41d8f3 > .claude/session/reviews/361-rex.approved

Reviewed by Rex (Code Reviewer Agent)
Reviewed commit: 637f2d9649434b8b99dd88cd1de99a088a41d8f3

@atlas-apex atlas-apex merged commit af8d2c1 into dev May 21, 2026
5 checks passed
@atlas-apex atlas-apex deleted the feature/GH-347-promote-utility-agents-model-frontmatter branch May 21, 2026 01:54
me2resh added a commit that referenced this pull request Jun 5, 2026
…ave 2 PR 4) (#361)

* feat(#347): promote 4 utility agents to per-agent model: frontmatter (Wave 2 PR 4)

Per AgDR-0050 § Axis 2, the framework's 5 utility sub-agents drop the
default model: inherit (which pays the parent thread's rate) for explicit
per-agent baselines optimised for the work each does. Hakim was promoted
in PR 3 (#360) as part of the Hatim→Hakim consolidation; this commit
finishes the remaining 4.

Frontmatter changes (each carries the # routing-config:override comment
inside the YAML frontmatter so block-agent-routing-drift.sh accepts the
intentional inherit→<model> framework-default change):

  Rex   (code-reviewer)      inherit → opus    AgDR-0050 § Axis 2 line 50
                                               (PR diff review + handbook
                                               reasoning depth)
  Munir (dependency-auditor) inherit → sonnet  AgDR-0050 § Axis 2 line 63
                                               (pattern-matching across
                                               package files)
  Tariq (pr-manager)         inherit → sonnet  AgDR-0050 § Axis 2 line 64
                                               (tool-call-heavy + PR
                                               body narrative quality)
  Idris (ticket-manager)     inherit → sonnet  AgDR-0050 § Axis 2 line 65
                                               (schema-conforming output
                                               + interactive interview)
                                               Local-routing candidate
                                               per #348 spike.

No body / role-file / count changes — the 23-agent count is unchanged,
just 4 model values + 4 YAML comments.

Refs #347

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* test(#347): cover utility-agent invariants + routing case for Wave 2 PR 4

Locks in the post-PR-4 utility-agent baselines so a future regression
(e.g. someone reverts a model: line to inherit, or strips the escape-hatch
comment) trips a test rather than silently slipping through.

test_agent_wrap_shape.sh:

- Added UTILITY_AGENTS array (mirror of ROLE_AGENTS, format
  "<slug>:<model>:<persona>"). Covers all 5 utility agents including
  Hakim (already promoted to opus in PR 3).
- New "Invariant 4b" block asserts each utility agent has (a) explicit
  model: matching AgDR-0050 § Axis 2, (b) correct persona_name, and
  (c) a # routing-config:override comment in YAML frontmatter (the
  drift-guard escape hatch required for any inherit → <model> change).
- Awk regex uses POSIX [[:space:]] / [^[:space:]] rather than \S — \S
  isn't portable across awk implementations (bug found while extending
  this test; macOS BSD awk silently treated \S as a literal).

test_agent_routing_sync_and_drift.sh:

- Added a ticket-manager fixture to make_fork (model: sonnet, escape-hatch
  comment, persona Idris). The fixture proves the routing-sync mechanism
  doesn't distinguish utility vs role-derived agents — same hook, same
  rewrite, same snapshot path.
- New CASE 8 exercises a utility-agent override (ticket-manager sonnet →
  opus). Asserts: agent frontmatter flips to opus, qa-engineer is
  untouched (single-override scope), the framework-defaults snapshot
  records the sonnet baseline (not the opus override).

Both tests PASS at the new HEAD.

Refs #347

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: me2resh <ahmed.abdelaliem@gmail.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants