feat: support role-based agent prompts

This commit is contained in:
2026-06-02 17:56:38 +01:00
parent 3ccdea330a
commit 34f7364c86
4 changed files with 225 additions and 12 deletions
+16
View File
@@ -20,3 +20,19 @@
{"timestamp": "2026-06-02T16:13:04.692285+00:00", "event_type": "command", "target": "rdb status", "details": {}}
{"timestamp": "2026-06-02T16:13:54.568414+00:00", "event_type": "command", "target": "rdb status", "details": {}}
{"timestamp": "2026-06-02T16:15:17.596114+00:00", "event_type": "command", "target": "rdb status", "details": {}}
{"timestamp": "2026-06-02T16:19:12.880619+00:00", "event_type": "command", "target": "rdb status", "details": {}}
{"timestamp": "2026-06-02T16:19:17.322970+00:00", "event_type": "command", "target": "rdb next", "details": {}}
{"timestamp": "2026-06-02T16:25:21.115719+00:00", "event_type": "command", "target": "rdb status", "details": {}}
{"timestamp": "2026-06-02T16:25:26.933534+00:00", "event_type": "command", "target": "rdb next", "details": {}}
{"timestamp": "2026-06-02T16:25:36.969679+00:00", "event_type": "command", "target": "rdb next", "details": {}}
{"timestamp": "2026-06-02T16:25:40.245143+00:00", "event_type": "command", "target": "rdb status", "details": {}}
{"timestamp": "2026-06-02T16:25:42.679647+00:00", "event_type": "command", "target": "rdb next", "details": {}}
{"timestamp": "2026-06-02T16:25:52.729189+00:00", "event_type": "command", "target": "rdb prompt", "details": {}}
{"timestamp": "2026-06-02T16:27:38.835967+00:00", "event_type": "command", "target": "rdb status", "details": {}}
{"timestamp": "2026-06-02T16:27:46.509757+00:00", "event_type": "command", "target": "rdb next", "details": {}}
{"timestamp": "2026-06-02T16:28:22.926960+00:00", "event_type": "command", "target": "rdb status", "details": {}}
{"timestamp": "2026-06-02T16:28:27.925682+00:00", "event_type": "command", "target": "rdb next", "details": {}}
{"timestamp": "2026-06-02T16:29:40.982618+00:00", "event_type": "command", "target": "rdb status", "details": {}}
{"timestamp": "2026-06-02T16:29:43.405985+00:00", "event_type": "command", "target": "rdb next", "details": {}}
{"timestamp": "2026-06-02T16:29:59.879010+00:00", "event_type": "command", "target": "rdb prompt", "details": {}}
{"timestamp": "2026-06-02T16:47:40.958013+00:00", "event_type": "command", "target": "rdb status", "details": {}}
+124 -10
View File
@@ -282,34 +282,129 @@ Acceptance Criteria:
- Keep templates simple markdown
- Add/update tests
## TASK-017 — Generate context files from discovery answers
## TASK-017 — Support task roles in generated prompts
Status: Todo
Status: Done
Goal:
Use captured discovery answers to generate initial context files.
Allow tasks to define the agent role used by `rdb prompt`.
Implementation Gap:
Discovery questions can collect information, but the answers are not yet transformed into structured project context documents.
Tasks can now include a `Role:` field, but `rdb prompt` still always generates prompts beginning with `You are an implementation agent.`
Acceptance Criteria:
- Parse optional `Role:` field from task markdown
- If `Role:` exists, use it in the generated prompt opening
- If `Role:` is missing, default to `Implementation Agent`
- Add/update tests
- Do not change task execution behaviour
Definition of Done:
- `Role: Architecture Agent` generates `You are an architecture agent.`
- Tasks without a role still generate implementation prompts
- Tests pass
## TASK-018 — Role-based context selection
Status: Todo
Role: Implementation Agent
Goal:
Allow `rdb prompt` to select different context files based on task role.
Implementation Gap:
Tasks can now define a role, but every generated prompt still asks the agent to read the same set of files regardless of task type.
Acceptance Criteria:
- Architecture Agent receives architecture-focused context
- Implementation Agent receives implementation-focused context
- Documentation Agent receives documentation-focused context
- If no role exists, use current default file list
- Add/update tests
Definition of Done:
- Context files differ by role
- Existing prompts remain backward compatible
- Tests pass
## TASK-019 — Define discovery-to-context mappings
Status: Todo
Role: Architecture Agent
Goal:
Define how discovery answers should be transformed into project context files.
Implementation Gap:
Discovery answers are collected and stored, but there is no documented mapping between discovery questions and the context files they should populate.
Acceptance Criteria:
- Every discovery question maps to one or more context files
- Every discovery question maps to a specific section within those files
- Mapping is documented in markdown
- Mapping is understandable by future agents
- No context generation implementation yet
- Add/update tests if required
Definition of Done:
- Mapping document exists
- Mapping covers all discovery questions
- Future implementation work is clearly defined
## TASK-020 — Generate context files from discovery answers
Status: Todo
Role: Implementation Agent
Goal:
Generate initial context files using the approved discovery-to-context mapping.
Implementation Gap:
Discovery answers can be collected, but they are not yet transformed into structured project documentation.
Acceptance Criteria:
- Add command or function to generate context files from discovery data
- Use the approved mapping document
- Create missing context files safely
- Do not overwrite existing files without explicit behaviour
- Add/update tests
## TASK-018 — Add context completeness report
Definition of Done:
- Context files can be generated from discovery data
- Existing files are preserved
- Tests pass
## TASK-021 — Add context completeness report
Status: Todo
Role: Implementation Agent
Goal:
Report which expected context files exist and which sections still need information.
Implementation Gap:
There is no way to see whether a project has enough context for an AI agent to work effectively.
There is no way to determine whether a project has sufficient context for effective AI-assisted development.
Acceptance Criteria:
@@ -319,15 +414,34 @@ Acceptance Criteria:
- Report obvious placeholder sections still needing completion
- Add/update tests
## TASK-019 — Generate Claude Code permission profile
Definition of Done:
- Context report command exists
- Missing context is reported clearly
- Tests pass
## TASK-022 — Generate Claude Code permission profile
Status: Todo
Role: Documentation Agent
Goal:
Create a recommended Claude Code permissions configuration for RDB workflows.
Implementation Gap:
Claude Code permission settings are not currently documented, resulting in unnecessary approval prompts and inconsistent behaviour between projects.
Acceptance Criteria:
- Safe commands auto-approved
- Dangerous commands require approval
- Profile documented in CLAUDE.md
- Define recommended safe commands for auto-approval
- Define commands that should require approval
- Document the profile in CLAUDE.md
- Include rationale for each category
Definition of Done:
- Permission profile documented
- CLAUDE.md updated
+22 -2
View File
@@ -7,12 +7,21 @@ import re
TASK_HEADING_RE = re.compile(r"^##\s+(TASK-\d+)\s+[-–—]\s+(.+)$", re.MULTILINE)
STATUS_RE = re.compile(r"^Status:\s*(.+)$", re.MULTILINE)
GOAL_RE = re.compile(r"^Goal:\s*(.+)", re.MULTILINE)
AC_RE = re.compile(r"^- (.+)$", re.MULTILINE)
GAP_RE = re.compile(r"^Implementation Gap:\s*(.+)", re.MULTILINE)
def _indefinite_article(word: str) -> str:
"""Return 'a' or 'an' based on the first letter of word."""
if not word:
return "an"
first = word[0].lower()
if first in "aeiou":
return "an"
return "a"
@dataclass
class Task:
task_id: str
@@ -20,6 +29,15 @@ class Task:
status: str
body: str
def role(self, root: Path) -> tuple[str, str]:
if "Role:" not in self.body:
return ("Implementation Agent", _indefinite_article("Implementation Agent"))
parts = self.body.split("Role:", 1)
value = parts[1].splitlines()[0].strip()
if value:
return (value, _indefinite_article(value))
return ("Implementation Agent", _indefinite_article("Implementation Agent"))
def goal(self, root: Path) -> str:
match = GOAL_RE.search(self.body)
if match:
@@ -167,8 +185,10 @@ def generate_agent_prompt(root: Path) -> str:
if not task:
return "No Todo task found."
role_text, article = task.role(root)
sections = [
"You are an implementation agent.",
f"You are {article} {role_text.lower()}.",
"",
"---",
"",
+63
View File
@@ -259,3 +259,66 @@ def test_extract_test_commands_no_section(tmp_path: Path) -> None:
commands = _extract_test_commands_from_claude(tmp_path)
assert commands == []
def test_generate_agent_prompt_with_role(tmp_path: Path) -> None:
(tmp_path / "TASKS.md").write_text(
"# TASKS\n\n"
"## TASK-001 — First\nStatus: Done\n\n"
"Goal: x.\n\n"
"## TASK-002 — Second\nStatus: Todo\n\n"
"Role: Architecture Agent\n"
"Goal: y.\n",
encoding="utf-8",
)
prompt = generate_agent_prompt(tmp_path)
assert "You are an architecture agent." in prompt
def test_generate_agent_prompt_default_role_when_missing(tmp_path: Path) -> None:
(tmp_path / "TASKS.md").write_text(
"# TASKS\n\n"
"## TASK-001 — First\nStatus: Done\n\n"
"Goal: x.\n\n"
"## TASK-002 — Second\nStatus: Todo\n\n"
"Goal: y.\n",
encoding="utf-8",
)
prompt = generate_agent_prompt(tmp_path)
assert "You are an implementation agent." in prompt
def test_generate_agent_prompt_with_empty_role_defaults(tmp_path: Path) -> None:
(tmp_path / "TASKS.md").write_text(
"# TASKS\n\n"
"## TASK-001 — First\nStatus: Done\n\n"
"Goal: x.\n\n"
"## TASK-002 — Second\nStatus: Todo\n\n"
"Role:\n"
"Goal: y.\n",
encoding="utf-8",
)
prompt = generate_agent_prompt(tmp_path)
assert "You are an implementation agent." in prompt
def test_generate_agent_prompt_with_custom_role(tmp_path: Path) -> None:
(tmp_path / "TASKS.md").write_text(
"# TASKS\n\n"
"## TASK-001 — First\nStatus: Done\n\n"
"Goal: x.\n\n"
"## TASK-002 — Second\nStatus: Todo\n\n"
"Role: DevOps Engineer\n"
"Goal: y.\n",
encoding="utf-8",
)
prompt = generate_agent_prompt(tmp_path)
assert "You are a devops engineer." in prompt