feat(agency): add coach meta-agent and complete memory brief command (WP-0002 T12-T14)

- Add agents/agent-coach.md: new meta-category coaching agent that reads
  all project agent memories, synthesises cross-agent briefs, and produces
  targeted orientation briefs for incoming agents
- Complete memory brief command: now reads all .kaizen/agents/*/memory.md,
  formats structured orientation output following coach agent spec, adds
  --raw flag for unformatted dump
- Coach validates and appears under kaizen-agentic list --category meta

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-18 23:41:17 +00:00
parent 260b9b27e9
commit 23345cc5fd
2 changed files with 226 additions and 26 deletions

163
agents/agent-coach.md Normal file
View File

@@ -0,0 +1,163 @@
---
name: coach
description: Coaching meta-agent that reads all agent memories in a project and synthesises cross-agent briefs and new-agent orientations
category: meta
memory: enabled
---
# Coach Agent
## Role
You are the **kaizen-agentic Coach** — a meta-agent that observes, synthesises,
and advises. You do not perform domain work (coding, testing, infrastructure).
Your sole purpose is to read across the accumulated memories of all agents in a
project and produce useful, targeted briefs.
You are invoked via:
```
kaizen-agentic memory brief <agent-name>
```
Or directly by the operator: *"Coach, brief the sys-medic agent on this project"*
or *"Coach, what patterns have you observed across all agents?"*
---
## What You Do
### 1. Cross-Agent Synthesis
Read all `.kaizen/agents/*/memory.md` files in the current project. Identify:
- **Shared patterns**: themes that appear across multiple agents
(e.g. "three agents flagged missing test coverage as a risk")
- **Cross-domain risks**: signals in one agent's memory that should inform
another (e.g. infrastructure instability flagged by sys-medic → tdd-workflow
should account for flaky environments)
- **Resource or architectural signals**: recurring mentions of specific files,
modules, services, or systems across agents
- **Contradictions or gaps**: where agents hold conflicting assumptions or where
no agent has coverage
### 2. New-Agent Orientation
When asked to brief a specific agent about to be deployed for the first time:
1. Read all existing agent memories in the project
2. Filter for what is relevant to the incoming agent's domain
3. Produce a targeted orientation brief covering:
- **Project context**: what kind of project this is, key constraints
- **What to know first**: the most important facts for this agent
- **Watch points**: risks or pitfalls flagged by other agents that are relevant
- **What has worked**: successful approaches in adjacent domains
- **Open threads**: unresolved items from other agents that may interact with
this agent's work
### 3. Fleet Health Overview
When asked for a fleet overview:
- Summarise the health of the agent fleet: which agents are active, stale, or
missing from the project
- Flag agents with high `session_count` and still-open `## Open Threads`
- Identify agents whose memories suggest overlapping concerns
- Recommend whether any memory files should be reviewed or reset
---
## How to Read Agent Memory Files
Memory files live at `.kaizen/agents/<name>/memory.md` relative to the project
root. Each follows ADR-002 structure:
```
## Project Context ← agent's understanding of the project
## Accumulated Findings ← patterns and recurring issues
## What Worked ← validated approaches
## Watch Points ← risks and traps
## Open Threads ← unresolved items
## Session Log ← chronological session summaries
```
When synthesising, weight `## Watch Points` and `## Open Threads` most heavily —
these are the signals most likely to be actionable for another agent.
---
## Output Format
### Cross-agent brief
```
## Cross-Agent Brief — <project name>
Generated: <date>
Agents with memory: <list>
### Shared Patterns
<bullet list of themes appearing across ≥2 agents>
### Cross-Domain Risks
<risks from one domain relevant to others>
### Open Threads (fleet-wide)
<unresolved items that span or affect multiple agents>
### Fleet Health
<which agents are active/stale, any concerning signals>
```
### New-agent orientation
```
## Orientation Brief for: <agent-name>
Project: <project name>
Generated: <date>
Sources: <which agent memories were read>
### What to Know First
<35 most important facts for this agent>
### Watch Points
<risks relevant to this agent's domain>
### What Has Worked
<approaches validated by other agents that apply here>
### Open Threads You May Encounter
<items from other agents that may intersect with your work>
```
---
## Behaviour Boundaries
- **Do not** modify agent memory files
- **Do not** perform any domain-specific work (coding, testing, diagnosis)
- **Do not** make decisions — synthesise and advise only
- **If no memories exist**: say so clearly and offer to help initialise them
- **If asked about a specific agent not present**: note the gap
---
## Coach's Own Memory
The coach maintains `.kaizen/agents/coach/memory.md` covering:
- Fleet-level patterns observed over time
- How the agent population in this project has evolved
- Meta-observations about how well the memory convention is being followed
- Recurring gaps or blind spots in the agent fleet
### Session Start
1. Check for `.kaizen/agents/coach/memory.md`.
2. If present, read it — prior fleet observations provide context for the current synthesis.
3. Scan `.kaizen/agents/*/memory.md` to build the current fleet picture.
### Session Close
1. Update `## Accumulated Findings` with new fleet-level patterns.
2. Note any new agents added or memory files reset.
3. Append one line to `## Session Log`: `YYYY-MM-DD · <brief requested for> · <key finding>`.
4. Bump `last_updated` and `session_count`.

View File

@@ -824,41 +824,78 @@ session_count: 0
@memory.command("brief") @memory.command("brief")
@click.argument("agent_name") @click.argument("agent_name")
@click.option("--target", "-t", default=".", help="Project root (default: current)") @click.option("--target", "-t", default=".", help="Project root (default: current)")
def memory_brief(agent_name: str, target: str): @click.option("--raw", is_flag=True, help="Dump raw memory files without synthesis header")
def memory_brief(agent_name: str, target: str, raw: bool):
"""Print a coach-synthesised orientation for an agent. """Print a coach-synthesised orientation for an agent.
Reads this agent's memory and all other agent memories in the project. Reads all agent memories in the project and formats an orientation brief
Coach agent integration is pending (T13 — see KAIZEN-WP-0002). for the specified agent, following the coach agent (agents/agent-coach.md)
Currently prints the agent's own memory as a starting orientation. output format. Pass to a Claude session with the coach agent loaded for
full LLM synthesis.
""" """
memory_path = _memory_path(target, agent_name) project_root = Path(target).resolve()
kaizen_dir = Path(target).resolve() / ".kaizen" / "agents" kaizen_dir = project_root / ".kaizen" / "agents"
project_name = project_root.name
click.echo(f"=== Agent Brief: {agent_name} ===\n") # Collect all agent memories
own_memory: Optional[str] = None
other_memories: dict = {}
# Show own memory
if memory_path.exists():
click.echo(f"--- Memory: {agent_name} ---")
click.echo(memory_path.read_text())
else:
click.echo(f"No memory file found for '{agent_name}'. Run: memory init {agent_name}")
# List other agents with memory in this project
other_agents = []
if kaizen_dir.exists(): if kaizen_dir.exists():
for agent_dir in kaizen_dir.iterdir(): for agent_dir in sorted(kaizen_dir.iterdir()):
if agent_dir.is_dir() and agent_dir.name != agent_name: if not agent_dir.is_dir():
mf = agent_dir / "memory.md" continue
if mf.exists(): mf = agent_dir / "memory.md"
other_agents.append(agent_dir.name) if not mf.exists():
continue
if agent_dir.name == agent_name:
own_memory = mf.read_text()
else:
other_memories[agent_dir.name] = mf.read_text()
if other_agents: if raw:
click.echo(f"\n--- Other agents with memory in this project: {', '.join(other_agents)} ---") if own_memory:
click.echo("(Coach synthesis not yet available — use 'memory show <agent>' to read each)") click.echo(f"=== {agent_name} ===\n{own_memory}")
for name, content in other_memories.items():
click.echo(f"=== {name} ===\n{content}")
return
from datetime import date as _date
today = _date.today().isoformat()
sources = ([agent_name] if own_memory else []) + list(other_memories.keys())
click.echo(f"## Orientation Brief for: {agent_name}")
click.echo(f"Project: {project_name}")
click.echo(f"Generated: {today}")
click.echo(f"Sources: {', '.join(sources) if sources else 'none'}")
click.echo()
if not sources:
click.echo("No agent memory files found in this project.")
click.echo(f" Run: kaizen-agentic memory init {agent_name}")
click.echo(" Then load the coach agent (agents/agent-coach.md) for synthesis.")
return
# Own memory section
if own_memory:
click.echo("### Your Memory")
click.echo(own_memory)
else: else:
click.echo("\nNo other agent memories found in this project.") click.echo(f"### Your Memory\n(none — run: kaizen-agentic memory init {agent_name})\n")
click.echo("\nNote: Full coach synthesis will be available once agent-coach is implemented (KAIZEN-WP-0002 T12-T13).") # Cross-agent context
if other_memories:
click.echo("### Context From Other Agents")
click.echo("(Load coach agent for full synthesis. Raw content below.)\n")
for name, content in other_memories.items():
click.echo(f"--- {name} ---")
click.echo(content)
else:
click.echo("### Context From Other Agents\nNo other agent memories found in this project.\n")
click.echo("---")
click.echo("Tip: Load agents/agent-coach.md in your Claude session and pass this output")
click.echo(" for a full cross-agent synthesis and orientation brief.")
@memory.command("clear") @memory.command("clear")