generated from coulomb/repo-seed
feat(CUST-WP-0016): kaizen-agentic integration — MCP tools, templates, direct install
- Fix /domains/{slug}/ 500: EP/TD queries now use domain_id FK (not string column)
- Remove dead cascade-slug code in rename_domain (FK handles it)
- MCP: list_kaizen_agents(category?) + get_kaizen_agent(name) via resolve_repo_path()
- TOOLS.md: Kaizen Agents section with discovery/load pattern
- agents.template: new project rule for consumer repos
- claude-md.template + register_project.sh: include agents.md in new-project scaffolding
- agents/: direct install of 6 curated agents for hub sessions
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -73,16 +73,16 @@ async def get_domain(
|
||||
)
|
||||
ws_count = ws_count_row.scalar_one()
|
||||
|
||||
# Count EPs and TDs (domain is a string column there)
|
||||
# Count EPs and TDs
|
||||
ep_count_row = await session.execute(
|
||||
select(func.count()).select_from(ExtensionPoint)
|
||||
.where(ExtensionPoint.domain == slug)
|
||||
.where(ExtensionPoint.domain_id == domain.id)
|
||||
)
|
||||
ep_count = ep_count_row.scalar_one()
|
||||
|
||||
td_count_row = await session.execute(
|
||||
select(func.count()).select_from(TechnicalDebt)
|
||||
.where(TechnicalDebt.domain == slug)
|
||||
.where(TechnicalDebt.domain_id == domain.id)
|
||||
)
|
||||
td_count = td_count_row.scalar_one()
|
||||
|
||||
@@ -127,19 +127,6 @@ async def rename_domain(
|
||||
domain.slug = body.new_slug
|
||||
domain.name = body.new_name
|
||||
|
||||
# Cascade slug rename to EP/TD string columns
|
||||
if old_slug != body.new_slug:
|
||||
await session.execute(
|
||||
ExtensionPoint.__table__.update()
|
||||
.where(ExtensionPoint.domain == old_slug)
|
||||
.values(domain=body.new_slug)
|
||||
)
|
||||
await session.execute(
|
||||
TechnicalDebt.__table__.update()
|
||||
.where(TechnicalDebt.domain == old_slug)
|
||||
.values(domain=body.new_slug)
|
||||
)
|
||||
|
||||
await session.commit()
|
||||
await session.refresh(domain)
|
||||
return domain
|
||||
|
||||
@@ -127,6 +127,30 @@ Dashboard: `http://localhost:3000/inbox`
|
||||
|
||||
---
|
||||
|
||||
## Kaizen Agents
|
||||
|
||||
Specialized agent personas from `kaizen-agentic/agents/`. Each agent is a markdown
|
||||
instruction set — load it and follow the instructions it contains.
|
||||
|
||||
| Tool | Key Args | When to use |
|
||||
|------|----------|-------------|
|
||||
| `list_kaizen_agents(category?)` | `category`: optional filter (testing/quality/process/infrastructure) | Discover all 17 available agent personas with name, description, category. |
|
||||
| `get_kaizen_agent(name)` | `name`: e.g. `"tdd-workflow"`, `"code-refactoring"` | Load full agent instructions. Read and follow them. |
|
||||
|
||||
**Common agents:**
|
||||
|
||||
| Agent | Category | When to use |
|
||||
|-------|----------|-------------|
|
||||
| `tdd-workflow` | testing | Step-by-step TDD8 workflow for any feature |
|
||||
| `code-refactoring` | quality | Code quality analysis and safe refactoring |
|
||||
| `test-maintenance` | testing | Diagnose and fix failing tests |
|
||||
| `requirements-engineering` | process | Prevent interface/mock mismatches upfront |
|
||||
| `keepaTodofile` | process | Maintain TODO.md during work |
|
||||
| `project-management` | process | Track status, determine next steps |
|
||||
| `datamodel-optimization` | quality | Optimize dataclasses and data structures |
|
||||
|
||||
---
|
||||
|
||||
## Domain Slugs
|
||||
|
||||
Run `list_domains()` to get the live list. Default 6: `custodian` · `railiance` · `markitect` · `coulomb_social` · `personhood` · `foerster_capabilities`
|
||||
|
||||
@@ -992,6 +992,89 @@ def update_repo_path(repo_slug: str, path: str, host: str | None = None) -> str:
|
||||
return json.dumps(repo, indent=2)
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Kaizen Agents
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
def _kaizen_agents_dir() -> Path:
|
||||
"""Resolve the kaizen-agentic agents/ directory via host_paths → local_path fallback."""
|
||||
import socket as _socket
|
||||
repo = _get("/repos/kaizen-agentic")
|
||||
hostname = _socket.gethostname()
|
||||
host_paths = repo.get("host_paths") or {}
|
||||
base = host_paths.get(hostname) or repo.get("local_path") or ""
|
||||
if not base:
|
||||
raise FileNotFoundError("kaizen-agentic path not found for this host. Register it with update_repo_path().")
|
||||
agents_dir = Path(base) / "agents"
|
||||
if not agents_dir.is_dir():
|
||||
raise FileNotFoundError(f"agents/ directory not found at {agents_dir}")
|
||||
return agents_dir
|
||||
|
||||
|
||||
@mcp.tool()
|
||||
def list_kaizen_agents(category: str | None = None) -> str:
|
||||
"""List all available kaizen agent personas.
|
||||
|
||||
Reads agent metadata from kaizen-agentic/agents/agent-*.md frontmatter.
|
||||
Each agent is a specialized instruction set Claude can load and follow.
|
||||
|
||||
Args:
|
||||
category: Optional filter (e.g. 'testing', 'quality', 'process', 'infrastructure').
|
||||
Returns all agents when omitted.
|
||||
|
||||
Returns:
|
||||
JSON list of {name, description, category, file} objects.
|
||||
"""
|
||||
import re as _re
|
||||
agents_dir = _kaizen_agents_dir()
|
||||
result = []
|
||||
for f in sorted(agents_dir.glob("agent-*.md")):
|
||||
name = f.stem.removeprefix("agent-")
|
||||
text = f.read_text(encoding="utf-8")
|
||||
# Extract optional YAML frontmatter fields
|
||||
fm_match = _re.match(r"^---\n(.*?\n)---\n", text, _re.DOTALL)
|
||||
meta: dict = {}
|
||||
if fm_match:
|
||||
for line in fm_match.group(1).splitlines():
|
||||
if ":" in line:
|
||||
k, _, v = line.partition(":")
|
||||
meta[k.strip()] = v.strip()
|
||||
agent_category = meta.get("category", "")
|
||||
if category and agent_category.lower() != category.lower():
|
||||
continue
|
||||
# Fall back to first non-empty line after frontmatter as description
|
||||
desc = meta.get("description", "")
|
||||
if not desc:
|
||||
for line in text.split("\n"):
|
||||
line = line.strip()
|
||||
if line and not line.startswith("#") and not line.startswith("---"):
|
||||
desc = line[:120]
|
||||
break
|
||||
result.append({"name": name, "description": desc, "category": agent_category, "file": f.name})
|
||||
return json.dumps(result, indent=2)
|
||||
|
||||
|
||||
@mcp.tool()
|
||||
def get_kaizen_agent(name: str) -> str:
|
||||
"""Load the full instructions for a kaizen agent persona.
|
||||
|
||||
Read the returned markdown and follow the instructions it contains.
|
||||
Use list_kaizen_agents() to discover available agent names.
|
||||
|
||||
Args:
|
||||
name: Agent name without 'agent-' prefix (e.g. 'tdd-workflow', 'code-refactoring').
|
||||
|
||||
Returns:
|
||||
Full markdown content of the agent definition file.
|
||||
"""
|
||||
agents_dir = _kaizen_agents_dir()
|
||||
agent_file = agents_dir / f"agent-{name}.md"
|
||||
if not agent_file.exists():
|
||||
available = [f.stem.removeprefix("agent-") for f in sorted(agents_dir.glob("agent-*.md"))]
|
||||
return json.dumps({"error": f"Agent '{name}' not found.", "available": available})
|
||||
return agent_file.read_text(encoding="utf-8")
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# ADR-001 compliance validation
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
20
scripts/project_rules/agents.template
Normal file
20
scripts/project_rules/agents.template
Normal file
@@ -0,0 +1,20 @@
|
||||
## Kaizen Agents
|
||||
|
||||
Specialized agent personas available on demand via the state-hub MCP.
|
||||
|
||||
**Discover:** `list_kaizen_agents()` — returns all agents with name, description, category
|
||||
**Load:** `get_kaizen_agent("tdd-workflow")` — returns full instructions; read and follow them
|
||||
|
||||
Common agents:
|
||||
|
||||
| Agent | Category | When to use |
|
||||
|-------|----------|-------------|
|
||||
| `tdd-workflow` | testing | Step-by-step TDD8 workflow for any feature |
|
||||
| `code-refactoring` | quality | Code quality analysis and safe refactoring |
|
||||
| `test-maintenance` | testing | Diagnose and fix failing tests |
|
||||
| `requirements-engineering` | process | Prevent interface/mock mismatches upfront |
|
||||
| `keepaTodofile` | process | Maintain TODO.md during work |
|
||||
| `project-management` | process | Track status, determine next steps |
|
||||
| `datamodel-optimization` | quality | Optimize dataclasses and data structures |
|
||||
|
||||
All 17 agents: call `list_kaizen_agents()` for the full list.
|
||||
@@ -7,3 +7,4 @@
|
||||
@.claude/rules/stack-and-commands.md
|
||||
@.claude/rules/architecture.md
|
||||
@.claude/rules/repo-boundary.md
|
||||
@.claude/rules/agents.md
|
||||
|
||||
@@ -131,7 +131,7 @@ if [[ "$ADDITIONAL" != "--additional" ]]; then
|
||||
mkdir -p "$RULES_DIR"
|
||||
|
||||
for rule in repo-identity session-protocol first-session workplan-convention \
|
||||
stack-and-commands architecture repo-boundary; do
|
||||
stack-and-commands architecture repo-boundary agents; do
|
||||
tmpl="$RULES_TEMPLATES_DIR/${rule}.template"
|
||||
out="$RULES_DIR/${rule}.md"
|
||||
if [[ -f "$tmpl" ]]; then
|
||||
|
||||
Reference in New Issue
Block a user