Skip to content

[Claude sub-agents] Add frontmatter capability hardening for high-use agents #378

Description

@azalio

Source

Source: https://code.claude.com/docs/en/sub-agents, read on 2026-07-21.

Relevant source takeaways:

  • Claude Code subagents are configured by Markdown frontmatter. Only name and description are required, so omitted capability fields inherit broad defaults.
  • The docs list tools, disallowedTools, permissionMode, maxTurns, skills, memory, background, effort, isolation, and hooks as supported fields.
  • If tools is omitted, a custom subagent inherits available tools. disallowedTools can remove capabilities from the inherited set.
  • Nested subagent spawning can be prevented by omitting Agent from the allowed tools or adding it to disallowedTools.
  • Claude docs recommend limiting tool access and using focused subagents.

Repo evidence

Inspected source-of-truth templates, not generated files:

  • src/mapify_cli/templates_src/agents/monitor.md.jinja: Monitor prompt says read-only and says workflow-gate blocks edits, but frontmatter has no tools or disallowedTools; only prompt-level restrictions and external hook enforcement carry the boundary.
  • src/mapify_cli/templates_src/agents/research-agent.md.jinja: Research agent prompt says read-only, no raw contents, no edits, but frontmatter has no tools or disallowedTools.
  • src/mapify_cli/templates_src/agents/predictor.md.jinja: Predictor is analysis-only but frontmatter has no capability allowlist/denylist.
  • src/mapify_cli/templates_src/agents/evaluator.md.jinja: Evaluator is scoring-only but frontmatter has no capability allowlist/denylist.
  • src/mapify_cli/templates_src/agents/task-decomposer.md.jinja: already has permissionMode: plan, so this is the positive existing pattern.
  • src/mapify_cli/templates_src/agents/final-verifier.md.jinja: verifier writes .map/<branch>/final_verification.json and progress markdown by design, so it should not be blindly made read-only.
  • src/mapify_cli/templates_src/agents/actor.md.jinja: Actor intentionally writes implementation and should not get read-only restrictions.
  • rg -n "^(tools|disallowedTools|permissionMode|memory|maxTurns|background|isolation|hooks|skills):" src/mapify_cli/templates_src/agents ... found only permissionMode: plan on task-decomposer among Claude agent templates.

Existing issue search

Commands/queries checked:

  • gh issue list --repo azalio/map-framework --state all --limit 120 --search "subagent OR sub-agent OR agent frontmatter OR persistent memory OR memory field OR tools allowlist OR disallowedTools OR permissionMode OR maxTurns OR isolation worktree OR background agents"
  • gh issue list --repo azalio/map-framework --state all --limit 80

Related issues inspected:

Why this is not already covered

MAP has prompt-level read-only instructions and workflow-gate enforcement, but Claude docs now expose first-class frontmatter capability controls. For high-use agents, prompt-only restrictions are weaker than an explicit provider-level capability manifest. The existing task-decomposer already proves MAP accepts frontmatter provider controls via permissionMode: plan; the same audit has not been applied to monitor/research/predictor/evaluator.

Problem

High-use non-writer agents can inherit more tools than their role needs. If Claude Code behavior, project settings, or plugin tools change, the effective capability set can drift while the prompt still says read-only. That creates avoidable risk and makes agent behavior harder to audit.

Proposed slice

Add an explicit capability-hardening pass for Claude agent templates:

  1. Introduce a small role capability table for shipped Claude agents.
  2. Add tools and/or disallowedTools frontmatter to non-writer high-use agents where the Claude Code docs support it.
  3. Keep Actor and final-verifier exceptions explicit because they legitimately write source or .map/ artifacts.
  4. Add tests that parse rendered .claude/agents/*.md and assert expected capability metadata for high-use agents.
  5. Update docs/architecture or usage notes only if user-visible behavior changes.

Initial target classification:

  • research-agent: read/search only; no Edit/Write; no Agent unless nested research is explicitly desired and tested.
  • predictor: read/search/shell grep style only; no Edit/Write; no Agent.
  • evaluator: read/search only unless review pipeline needs shell checks; no Edit/Write; no Agent.
  • monitor: allow read/search and build/test Bash, but deny Edit/Write and nested Agent.
  • task-decomposer: keep permissionMode: plan; consider explicit tool set only after checking plan-mode behavior.
  • actor and final-verifier: out of scope except documenting why they are exceptions.

Acceptance criteria

  • Generated Claude agent templates include explicit capability metadata for monitor, research-agent, predictor, evaluator, or a documented reason per agent for omission.
  • Actor and final-verifier remain able to perform their required writes.
  • Tests fail if a high-use non-writer agent drops its explicit capability metadata.
  • make render-templates and make check-render pass.
  • pytest tests/test_skills.py tests/test_template_render.py -v passes.
  • A dry-run uv run mapify init <tmp> --no-git --mcp none shows rendered .claude/agents/*.md with the expected frontmatter.

Guardrails

  • Do not blanket-deny Bash for Monitor unless build/test validation still works.
  • Do not add memory in this issue; persistent memory changes have separate trust and write-scope semantics.
  • Do not rely on prompt text alone as the acceptance proof.
  • Do not edit generated trees directly; change src/mapify_cli/templates_src/**/*.jinja and rerender.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions