Skip to content

feat(#347): promote engineering-dept roles to sub-agents + Activation mode (Wave 1 PR 1)#355

Merged
atlas-apex merged 4 commits into
devfrom
feature/GH-347-promote-engineering-roles-to-agents
May 20, 2026
Merged

feat(#347): promote engineering-dept roles to sub-agents + Activation mode (Wave 1 PR 1)#355
atlas-apex merged 4 commits into
devfrom
feature/GH-347-promote-engineering-roles-to-agents

Conversation

@atlas-apex

Copy link
Copy Markdown
Collaborator

Summary

  • 7 engineering-dept sub-agent wrappers shipped at .claude/agents/ (head-of-engineering, tech-lead, backend-engineer, frontend-engineer, qa-engineer, platform-engineer, sre) — promotes the engineering personas from passive markdown role docs to first-class Claude Code sub-agents with explicit model assignment and tool restriction. Wave 1 PR 1 of the agent-runtime-overhaul shipped against AgDR-0050.
  • Agent files are THIN WRAPPERS per AgDR-0050 § Axis 1 — each file owns only name / description / model / allowed-tools / persona_name frontmatter + a body that references @roles/engineering/<role>.md. The persona definition stays in roles/; agent files are the runtime overlay. Zero content duplication, so a persona edit lands in one place and the wrapper stays inert.
  • Default model matrix per AgDR-0050 § Axis 2opus for depth (Khalid, Hisham, Saif), sonnet for implementation default (Karim, Yasmin, Adel), haiku for repeatable checklist work (Salim, QA Engineer). QA also ships without Edit/Write per its read-only contract: QA verifies, doesn't ship; the fix flows back to an engineer through a fresh ticket. Adopters override per-agent via the routing config landing in [Feature] Centralised agent-routing config — agent-routing.yaml in private repo, propagates to .claude/agents/*.md at SessionStart #351 (Wave 1 PR 1 of that ticket runs in parallel).
  • ## Activation mode section added to all 19 role files per AgDR-0050 § Axis 6 — every persona definition now declares its activation class explicitly (isolated-work-class for 12 roles like QA / Pen Tester / Data Analyst / all 5 Heads of / Security Auditor / Tech Lead; in-flow-class for 7 roles like Backend / Frontend Engineer / Platform Engineer / PM / Designers / Data Engineer). Closes the gap where the hybrid sub-agent vs in-thread choice lived only in the AgDR body — operators can now see at a glance whether activating a role spawns an isolated sub-agent or adopts the persona in-thread.
  • Smoke test at .claude/agents/tests/test_engineering_agents_wrap_shape.sh pins 26 invariants (agent files exist, frontmatter complete, model values in the matrix, role-file references present, all 19 role files declare a ## Activation mode Class matching the AgDR table). First test under .claude/agents/tests/; style matches .claude/hooks/tests/ (set -u, ROOT from dirname, red/green helpers, FAIL counter, exit 0/1). All PASS at this commit.
  • CLAUDE.md "Agents" row refreshed from "5 sub-agents" to "12 sub-agents (5 utility + 7 engineering). Growing to 24 per AgDR-0050." Stays within the Wave 1 ≤ 25-word budget on table rows per AgDR-0044; test_token_efficiency_wave1.sh continues to pass (all four invariants OK).

This is Wave 1 PR 1 of 4 for #347. Per the AgDR-0050 PR plan: PR 1 (this) + #351 PR 1 are parallelisable. PR 2 ships the product + design agents (6); PR 3 ships security + data (6) + Hatim/Hakim consolidation decision; PR 4 adds model: frontmatter to the 5 utility agents (Rex, Hatim, Munir, Tariq, Idris); PR 5 wires detect-role-trigger.sh to spawn sub-agents for isolated-work-class roles. The role-trigger integration is deliberately deferred to PR 5 — until then, the ## Activation mode sections document the intended state, and in-thread role-adoption remains the active mechanism for un-shipped roles.

Per AgDR-0050-agent-runtime-overhaul.

Testing

  • bash .claude/agents/tests/test_engineering_agents_wrap_shape.sh — all 26 invariants PASS (7 engineering agents pass file-exists + frontmatter shape + model-matrix + role-reference; all 19 role files pass ## Activation mode Class match)
  • bash .claude/hooks/tests/test_token_efficiency_wave1.sh — all four Wave 1 invariants PASS (CLAUDE.md skill-table row word-count, SKILL.md description char budget, skill catalogue completeness, SessionStart banner char budget)
  • Manual: head -8 .claude/agents/qa-engineer.md shows model: haiku + allowed-tools: Bash, Read, Grep, Glob (NO Edit/Write — read-only by mechanical contract per roles/engineering/qa-engineer.md)
  • Manual: head -8 .claude/agents/tech-lead.md shows model: opus, persona_name: Hisham
  • Manual: grep -c "## Activation mode" roles/*/*.md | wc -l returns 19 (every role file gained the section)

Refs #347

Glossary

Term Definition
WRAP (AgDR-0050 § Axis 1) The file-shape decision for promoting roles to sub-agents: persona definition stays in roles/<dept>/<role>.md; the runtime wrapper at .claude/agents/<slug>.md owns only frontmatter (model, allowed-tools, persona_name) plus a body that references the role file. Zero content duplication.
isolated-work-class Per AgDR-0050 § Axis 6, the activation class for roles whose work benefits from a separate sub-agent context — QA verification, pen testing, data analysis, Heads-of strategy calls, Security Auditor reviews, Tech Lead architectural design. Activation spawns the sub-agent; the main thread folds in the verdict.
in-flow-class Per AgDR-0050 § Axis 6, the activation class for roles whose work is conversational + iterative + lives in the main-thread context — Backend / Frontend / Platform / Data Engineers, Product Manager, UI / UX Designers. Activation adopts the persona in-thread; sub-agent CAN still be invoked manually via the Agent tool for parallel work.
persona_name frontmatter field YAML frontmatter key in agent files (introduced in #204 / AgDR-0018) that carries the short Arabic persona identifier (Khalid / Hisham / Karim / Yasmin / Salim / Adel / Saif for engineering). Surfaces in the ▸ Activating <name> (<role>) for #<ticket> activation-marker line.
Framework default model matrix (AgDR-0050 § Axis 2) The 24-entry table assigning each role a default model (opus / sonnet / haiku). Opus for depth + reasoning; Sonnet for implementation + tool-use-heavy work; Haiku for repeatable checklist-shaped work. Adopters override per-agent via the routing config landing in #351.
Wave 1 invariants (AgDR-0044) Token-efficiency invariants pinned by .claude/hooks/tests/test_token_efficiency_wave1.sh — CLAUDE.md skill-table row ≤ 25 words, SKILL.md description: ≤ 200 chars hard / ≤ 120 soft, every skill catalogued in CLAUDE.md, SessionStart banner ≤ 600 chars. This PR adjusts the Agents row to a 23-word description so it stays under the row-length cap.

me2resh added 4 commits May 20, 2026 20:14
…/*) per AgDR-0050 Axis 1 + 2

Promotes the 7 engineering-department personas to first-class Claude
Code sub-agents — Wave 1 PR 1 of the agent-runtime-overhaul shipped
against AgDR-0050.

Agent files are THIN WRAPPERS per AgDR-0050 Axis 1 (WRAP):
- roles/engineering/<role>.md stays the canonical persona definition
- .claude/agents/<slug>.md owns only name/description/model/
  allowed-tools/persona_name frontmatter + a body that references
  @roles/engineering/<slug>.md
- No content duplication; the persona is read at activation time

Default model matrix per AgDR-0050 Axis 2:
- opus: head-of-engineering (Khalid), tech-lead (Hisham), sre (Saif)
- sonnet: backend-engineer (Karim), frontend-engineer (Yasmin),
  platform-engineer (Adel)
- haiku: qa-engineer (Salim) — read-only by design (no Edit/Write),
  AC verification + checklist work is repeatable + cheap

Adopters will override per-agent via the routing config landing in
#351 (Wave 1 PR 1 of that ticket runs in parallel with this).

Refs #347
…gDR-0050 Axis 6

Every persona definition in roles/{department}/<role>.md now declares
its activation class explicitly. This closes the gap where the
hybrid sub-agent vs in-thread choice from AgDR-0050 § Axis 6 lived
only in the AgDR body — operators couldn't see at a glance whether
activating a role spawns an isolated sub-agent or adopts the persona
in-thread.

Section format per role:
- **Class**: isolated-work-class | in-flow-class
- **Sub-agent file**: .claude/agents/<slug>.md + which PR ships it
- **On trigger**: what detect-role-trigger.sh does once the sub-agent
  is wired in (PR 5)
- **Rationale**: one sentence tying the class choice to the AgDR

Classification follows AgDR-0050 § Axis 6 table exactly:
- isolated-work-class (12): all 5 Heads of, Tech Lead, QA Engineer,
  SRE, Security Auditor, Pen Tester, Product Analyst, Data Analyst
- in-flow-class (7): Backend / Frontend Engineer, Platform Engineer,
  Data Engineer, Product Manager, UI Designer, UX Designer

The 7 engineering-dept sub-agent files exist as of the prior commit
(this PR); the other 12 ship in #347 PR 2 (product + design) and
PR 3 (security + data). Until those land, the in-thread role-
adoption mechanism continues to apply for un-shipped roles — the
section documents the intended state, not a runtime guarantee.

Refs #347
…ivation mode coverage

Pins the AgDR-0050 invariants this PR establishes so future Wave 1-4
work (and any drift from the agent-routing config sync hook landing
in #351) can verify it isn't regressing them:

1. All 7 engineering agent files exist at .claude/agents/<slug>.md
2. Each has the required frontmatter (name, description, model,
   allowed-tools, persona_name)
3. Each model value is one of opus | sonnet | haiku AND matches the
   AgDR-0050 § Axis 2 default matrix entry for that role
4. Each agent body references @roles/engineering/<slug>.md (the
   WRAP contract — agents delegate identity to roles/, no
   duplication)
5. All 19 role files have a ## Activation mode section
6. Each role's Class value matches the AgDR-0050 § Axis 6 hybrid
   table exactly

Style follows the existing framework convention (set -u, ROOT from
dirname, red/green helpers, FAIL counter, exit 0/1). No external
test framework. Tests live under .claude/agents/tests/ — first
file in that new tree; sibling to .claude/hooks/tests/ and
.claude/skills/<name>/tests/.

26 invariants verified, all PASS at this commit.

Refs #347
… 7 engineering)

The framework-integration table's Agents row previously named the 5
utility agents (Rex, Hatim, Munir, Tariq, Idris). After this PR, 7
engineering-role-derived agents land in .claude/agents/ alongside
the utility agents, so the row needs to name the new shape.

New row text (23 words, under the ≤ 25-word Wave 1 invariant on
table rows per AgDR-0044):

  12 sub-agents (5 utility: Rex, Hatim, Munir, Tariq, Idris;
  7 engineering: Khalid, Hisham, Karim, Yasmin, Salim, Adel,
  Saif). Growing to 24 per AgDR-0050.

The growth footer ("Growing to 24 per AgDR-0050") signals the
direction without spelling out the per-wave breakdown — that lives
in AgDR-0050's PR plan section + each PR's body.

test_token_efficiency_wave1.sh continues to pass (all four
invariants OK) — the row stays terse and discoverable.

Refs #347

@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 #355

Commit: b68bb5c9e507e02f2e62af5d45574b196ea1f6ee

Summary

Wave 1 PR 1 of #347 (AgDR-0050 agent-runtime-overhaul). Ships the 7 engineering-department sub-agent wrappers per Axis 1 (thin WRAP shape — frontmatter + body referencing @roles/engineering/<slug>.md), assigns the framework default model matrix per Axis 2, restricts the QA Engineer to read-only tools by design, and adds a ## Activation mode section to all 19 role files per Axis 6. CLAUDE.md's Agents row updates from "5 sub-agents" to "12 sub-agents (5 utility + 7 engineering). Growing to 24 per AgDR-0050." — 23 words, under the 25-word Wave 1 budget.

Checklist Results

  • Architecture & Design: Pass — clean WRAP separation, agent files own runtime overlay only, role files remain canonical persona definitions, zero content duplication
  • Code Quality: Pass — 26-invariant smoke test follows the framework .claude/hooks/tests/ convention (set -u, ROOT-from-dirname, red/green helpers, FAIL counter, exit 0/1)
  • Testing: Pass — the test asserts file existence, all 5 required frontmatter keys, model values strictly in the matrix, persona-name match, role-file reference in each body, every role-file ## Activation mode heading + **Class**: value matching the AgDR-0050 § Axis 6 table
  • Security: Pass — no secrets, no auth surface touched; QA Engineer's read-only contract is now mechanical (allowed-tools: Bash, Read, Grep, Glob)
  • Performance: Pass — model matrix routes haiku for repeatable QA, sonnet for implementation, opus for depth; matches the cost/latency design in AgDR-0050
  • PR Description & Glossary: Pass — 6 narrative bullets, each answers what + why; Glossary covers WRAP, isolated-work-class, in-flow-class, persona_name, model matrix, Wave 1 invariants
  • Technical Decisions (AgDR):Pass (N/A new) — implements AgDR-0050 (already merged on dev); no new decisions introduced, no scope-creep needing a fresh AgDR
  • Adopter Handbooks: N/A — diff is markdown + bash only; no language handbooks apply, no public handbooks/architecture or handbooks/general rule trips

Issues Found

None blocking. Verified against the requested 11 invariants:

  1. WRAP shape uniform across 7 agents — every file has the 5 frontmatter keys, body references @roles/engineering/<slug>.md, no duplicated persona content. QA wrapper carries one extra paragraph explaining the read-only ticket-bounce-back contract — appropriate, the tool restriction is load-bearing.
  2. Model matrix matches AgDR-0050 § Axis 2 EXACTLY — opus (head-of-engineering, tech-lead, sre), sonnet (backend, frontend, platform), haiku (qa-engineer). No drift.
  3. QA Engineer tool restriction correctallowed-tools: Bash, Read, Grep, Glob (no Edit, no Write); the other 6 carry the full set.
  4. All 19 role files have ## Activation mode with correct class — 12 isolated-work-class + 7 in-flow-class match the AgDR table exactly.
  5. Smoke test would FAIL on any drift — per-agent loop checks 4 invariants per agent, per-role loop checks 2 per role; both encode the matrix as data so a future regression is mechanically caught.
  6. CLAUDE.md Agents row 23 wordswc -w confirms; under 25-word budget; "Growing to 24" matches the wave plan (5 + 7 + 6 + 6 = 24).
  7. No model: frontmatter on utility agentscode-reviewer.md / security-reviewer.md / dependency-auditor.md / pr-manager.md / ticket-manager.md are NOT in the diff. PR 4 territory preserved.
  8. No routing config / sync hook / drift guards — diff stays within .claude/agents/{7 wrappers + 1 test} + 19 role files + CLAUDE.md. No .claude/hooks/, no project-config.defaults.json. #351 territory preserved.
  9. No role-trigger integrationdetect-role-trigger.sh unchanged; ## Activation mode sections document the future state with "once PR 5 lands…" prose. PR 5 territory preserved.
  10. PR body — narrative bullets, Glossary, Refs #347 (not Closes), Per AgDR-0050-agent-runtime-overhaul. reference, wave plan documented in body.
  11. Wave 1 invariants PASS — Agents row at 23 words confirms the row-length invariant directly; agent's reported 4/4 PASS on test_token_efficiency_wave1.sh is consistent with the diff (no SKILL.md changes, no banner changes).

Handbook Findings

No handbook findings. Diff is markdown + bash. No architecture/ or general/ always-load handbooks trip on this content; no language/typescript|python|go|rust/ handbooks apply.

Suggestions

nit: (non-blocking)

  • N1 — The smoke test's invariant list (header comment, lines 162-173 of the test) doesn't explicitly note that the QA wrapper is allowed to carry one extra paragraph by design. A future contributor adding similar prose to another wrapper might cite QA as precedent. Consider a one-line note in the header: "Wrappers are thin by convention; the QA wrapper carries one additional read-only-contract paragraph by design (AgDR-0050 § Axis 2)."
  • N2## Activation context (in agent bodies) vs ## Activation mode (in role files) are visually close. Both reference AgDR-0050 § Axis 6, so the rendered hierarchy is coherent, but a future reader could conflate them. The smoke test pins the role-file heading exactly, so accidental drift would surface — leave as is or rename one in a follow-up if it bites.
  • N3roles/data/head-of-data.md and roles/security/head-of-security.md Rationale lines are terser ("strategy; sparse.") than the engineering-side Heads. Consistency would be nicer, but the role files belong to PR 2/3's stewardship and the activation-class is what's load-bearing.

Verdict

APPROVED

The PR ships exactly what AgDR-0050 Wave 1 PR 1 specifies, with mechanical drift-protection via the smoke test, and zero scope-creep into PR 2-5 or #351. CI 4/4 green. The model matrix, tool-restriction, and activation-class assignments all match the AgDR. Wave 1 token-budget invariants pass.

Sandbox blocked the approval-marker write — operator should write the marker on Rex's behalf:

printf '%s\n' "b68bb5c9e507e02f2e62af5d45574b196ea1f6ee" > /Users/ahmed/Projects/apexstack/.claude/session/reviews/355-rex.approved

(Per the operator's MEMORY note feedback_rex_marker_sandbox_workaround.md.)


🤖 Reviewed by Rex (Code Reviewer Agent)
📌 Reviewed commit: b68bb5c9e507e02f2e62af5d45574b196ea1f6ee

@atlas-apex atlas-apex merged commit 0356f0f into dev May 20, 2026
4 checks passed
@atlas-apex atlas-apex deleted the feature/GH-347-promote-engineering-roles-to-agents branch May 20, 2026 19:22
me2resh added a commit that referenced this pull request Jun 5, 2026
… mode (Wave 1 PR 1) (#355)

* feat(#347): add 7 engineering-dept sub-agent wrappers (.claude/agents/*) per AgDR-0050 Axis 1 + 2

Promotes the 7 engineering-department personas to first-class Claude
Code sub-agents — Wave 1 PR 1 of the agent-runtime-overhaul shipped
against AgDR-0050.

Agent files are THIN WRAPPERS per AgDR-0050 Axis 1 (WRAP):
- roles/engineering/<role>.md stays the canonical persona definition
- .claude/agents/<slug>.md owns only name/description/model/
  allowed-tools/persona_name frontmatter + a body that references
  @roles/engineering/<slug>.md
- No content duplication; the persona is read at activation time

Default model matrix per AgDR-0050 Axis 2:
- opus: head-of-engineering (Khalid), tech-lead (Hisham), sre (Saif)
- sonnet: backend-engineer (Karim), frontend-engineer (Yasmin),
  platform-engineer (Adel)
- haiku: qa-engineer (Salim) — read-only by design (no Edit/Write),
  AC verification + checklist work is repeatable + cheap

Adopters will override per-agent via the routing config landing in
#351 (Wave 1 PR 1 of that ticket runs in parallel with this).

Refs #347

* feat(#347): add ## Activation mode section to all 19 role files per AgDR-0050 Axis 6

Every persona definition in roles/{department}/<role>.md now declares
its activation class explicitly. This closes the gap where the
hybrid sub-agent vs in-thread choice from AgDR-0050 § Axis 6 lived
only in the AgDR body — operators couldn't see at a glance whether
activating a role spawns an isolated sub-agent or adopts the persona
in-thread.

Section format per role:
- **Class**: isolated-work-class | in-flow-class
- **Sub-agent file**: .claude/agents/<slug>.md + which PR ships it
- **On trigger**: what detect-role-trigger.sh does once the sub-agent
  is wired in (PR 5)
- **Rationale**: one sentence tying the class choice to the AgDR

Classification follows AgDR-0050 § Axis 6 table exactly:
- isolated-work-class (12): all 5 Heads of, Tech Lead, QA Engineer,
  SRE, Security Auditor, Pen Tester, Product Analyst, Data Analyst
- in-flow-class (7): Backend / Frontend Engineer, Platform Engineer,
  Data Engineer, Product Manager, UI Designer, UX Designer

The 7 engineering-dept sub-agent files exist as of the prior commit
(this PR); the other 12 ship in #347 PR 2 (product + design) and
PR 3 (security + data). Until those land, the in-thread role-
adoption mechanism continues to apply for un-shipped roles — the
section documents the intended state, not a runtime guarantee.

Refs #347

* test(#347): smoke test for engineering agent wrap-shape + 19-role Activation mode coverage

Pins the AgDR-0050 invariants this PR establishes so future Wave 1-4
work (and any drift from the agent-routing config sync hook landing
in #351) can verify it isn't regressing them:

1. All 7 engineering agent files exist at .claude/agents/<slug>.md
2. Each has the required frontmatter (name, description, model,
   allowed-tools, persona_name)
3. Each model value is one of opus | sonnet | haiku AND matches the
   AgDR-0050 § Axis 2 default matrix entry for that role
4. Each agent body references @roles/engineering/<slug>.md (the
   WRAP contract — agents delegate identity to roles/, no
   duplication)
5. All 19 role files have a ## Activation mode section
6. Each role's Class value matches the AgDR-0050 § Axis 6 hybrid
   table exactly

Style follows the existing framework convention (set -u, ROOT from
dirname, red/green helpers, FAIL counter, exit 0/1). No external
test framework. Tests live under .claude/agents/tests/ — first
file in that new tree; sibling to .claude/hooks/tests/ and
.claude/skills/<name>/tests/.

26 invariants verified, all PASS at this commit.

Refs #347

* docs(#347): CLAUDE.md agent-count row reflects 12 agents (5 utility + 7 engineering)

The framework-integration table's Agents row previously named the 5
utility agents (Rex, Hatim, Munir, Tariq, Idris). After this PR, 7
engineering-role-derived agents land in .claude/agents/ alongside
the utility agents, so the row needs to name the new shape.

New row text (23 words, under the ≤ 25-word Wave 1 invariant on
table rows per AgDR-0044):

  12 sub-agents (5 utility: Rex, Hatim, Munir, Tariq, Idris;
  7 engineering: Khalid, Hisham, Karim, Yasmin, Salim, Adel,
  Saif). Growing to 24 per AgDR-0050.

The growth footer ("Growing to 24 per AgDR-0050") signals the
direction without spelling out the per-wave breakdown — that lives
in AgDR-0050's PR plan section + each PR's body.

test_token_efficiency_wave1.sh continues to pass (all four
invariants OK) — the row stays terse and discoverable.

Refs #347

---------

Co-authored-by: me2resh <ahmed.abdelaliem@gmail.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