Skip to content

feat: strengthen agent action definitions using Claude Code subagent frontmatter conventions #80

Description

@monkut

Problem Statement

askcc action prompts in askcc/definitions.py (and their user-overridable templates under ~/.askcc/templates/) are plain prompt strings. They lack the structural controls that Claude Code's native subagent format provides — no per-action tool allowlist, no model selection, no effort/thinking overrides, no permission mode, no maxTurns.

This means every action runs with the same tool surface, same model, and same effort level regardless of what it actually needs. That is suboptimal on three axes:

  1. Security / blast radiusissue-review, validate, explore, and diagnose are analysis-only, yet they currently inherit full Edit/Write/Bash(*) capability from the invoking claude subprocess. A misbehaving run could mutate the tree.
  2. Cost — read-only analysis actions (issue-review, explore, diagnose) do not need Opus-tier reasoning; develop and plan do. Today there is no way to declare this per-action.
  3. Focus / prompt quality — Claude Code's official subagent best-practice is a tight frontmatter contract (narrow description, explicit tools, explicit model). askcc's prompts declare none of this at the definition layer.

Reference: https://code.claude.com/docs/en/subagents.md

Current State

  • askcc/definitions.pyAgentConfig captures action_name, description, system_prompt, user_prompt_template, template filenames, and required_variables. No tool/model/effort/permission fields.
  • ~/.askcc/templates/*_SYSTEM_PROMPT.md — plain markdown, no frontmatter parsed.
  • askcc/cli.py--effort, --max-thinking-tokens, --disable-thinking are global CLI flags applied uniformly to every action (cli.py:108-136).
  • askcc/runners/ — runners receive effort/thinking as a single value, no per-action override path.

Proposal

Adopt a Claude Code subagent-style frontmatter on each *_SYSTEM_PROMPT.md template file. load_agent_config parses it; the runner translates declared fields into claude CLI flags when spawning the subprocess.

Frontmatter schema (per-action, all optional except description)

---
name: develop
description: Implements a planned GitHub issue end-to-end; opens a PR linked to the issue.
tools: Read, Write, Edit, Bash, Grep, Glob, WebFetch
model: opus          # or sonnet | haiku | inherit
effort: max          # low | medium | high | xhigh | max
max_thinking_tokens: 32000
permission_mode: acceptEdits   # default | acceptEdits | plan | bypassPermissions
max_turns: 200
---

You are an expert software developer operating inside Claude Code...

Proposed per-action defaults

Action tools (allowlist) model effort permission_mode Rationale
prepare Read, Grep, Glob, Bash(gh:*) sonnet medium default Analysis + gh comment/edit; no file mutation
plan Read, Grep, Glob, Bash(gh:*) opus high default Heavy reasoning, no file mutation
develop Read, Write, Edit, Bash, Grep, Glob opus max acceptEdits Full implementation authority
issue-review Read, Grep, Glob, Bash(gh:*) sonnet medium default Read-only + gh comment
pr-review Read, Grep, Glob, Bash(gh:,git:) opus high default Reads branch, posts review — no repo mutation
explore Read, Grep, Glob, Bash(gh:*) sonnet high default Investigation only
diagnose Read, Grep, Glob, Bash(gh:,git:) sonnet high default Root-cause analysis, no fixes
fix-ci Read, Write, Edit, Bash, Grep, Glob sonnet high acceptEdits Narrow-scope code changes

Values are defaults — existing global CLI flags (--effort, --max-thinking-tokens, etc.) and env vars continue to work and take precedence when explicitly set, preserving backwards compatibility.

Benefits

  1. Least-privilege tool surface per actionissue-review cannot accidentally Edit files; validate/diagnose stay read-only.
  2. Cost-appropriate model per action — heavy reasoning actions (plan, develop, pr-review) on Opus; analysis actions on Sonnet.
  3. Alignment with Claude Code conventions — users who read https://code.claude.com/docs/en/subagents.md will recognize the format. Templates become portable — a user can drop an askcc template into .claude/agents/ with minimal changes.
  4. Structural validation at load time — a typo in model: opuz fails fast at load_agent_config, not mid-run.
  5. Discoverabilityaskcc --help and README can surface per-action defaults; users know what each action will and won't do.

Acceptance Criteria

  • AgentConfig gains optional fields: tools, disallowed_tools, model, effort, max_thinking_tokens, permission_mode, max_turns
  • load_agent_config parses YAML frontmatter from *_SYSTEM_PROMPT.md template files when present; falls back to the existing plain-prompt behaviour when no frontmatter is found (backwards compatible)
  • Built-in *_AGENT_PROMPT constants in askcc/definitions.py are updated to emit frontmatter-bearing defaults matching the table above
  • Runner(s) translate declared frontmatter fields into claude CLI flags (--model, --allowedTools, --disallowedTools, --permission-mode, --max-turns, effort/thinking)
  • CLI flags and env vars (--effort, --model, ASKCC_CLAUDE_EFFORT_LEVEL, etc.) continue to override per-action frontmatter when explicitly set
  • Invalid frontmatter values raise a clear error at load time with the field name and allowed values
  • Existing user templates without frontmatter continue to work unchanged (back-compat)
  • bootstrap_templates writes new defaults with frontmatter on first run; existing ~/.askcc/templates/ files are not overwritten
  • README documents the frontmatter schema, per-action defaults table, and override precedence
  • Tests cover: frontmatter parsing, missing-frontmatter back-compat, CLI/env override precedence, invalid-value rejection

Dependencies

Non-Goals

Notes / Open Questions

  • Tool syntax: Claude Code allows Bash(gh:*) style scoping. Decide whether askcc's defaults use coarse Bash or scoped forms — the table above proposes scoped where practical.
  • Frontmatter parser: prefer a stdlib-only approach (yaml is not stdlib). Options: tomllib + TOML frontmatter, or add pyyaml as a dep. Recommend pyyaml to match the Claude Code ecosystem convention.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions