Skip to content

Commit b0c34fa

Browse files
LastStepclaude
andcommitted
feat: add workspace-guide skill and How to Work section in generated CLAUDE.md
Two-layer AI operational intelligence: compact decision heuristics injected into every agent's CLAUDE.md (layer 1) and a detailed workspace-guide skill loaded on-demand (layer 2). Supports per-agent-type conditional content. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 903b337 commit b0c34fa

5 files changed

Lines changed: 347 additions & 22 deletions

File tree

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
name: workspace-guide
2+
description: Bonsai workspace operational guide — how to use workflows, skills, routines, sensors, and the Playbook effectively
3+
agents: all
Lines changed: 174 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,174 @@
1+
---
2+
tags: [skill, workspace]
3+
description: How to operate effectively in a Bonsai workspace — decision patterns, system mechanics, workspace evolution.
4+
---
5+
6+
# Workspace Guide
7+
8+
> Operational reference for working in a Bonsai-managed workspace. Load this skill when you need deeper understanding of how the workspace systems work together.
9+
10+
---
11+
12+
## How This Workspace Is Organized
13+
14+
Your workspace follows a layered loading model:
15+
16+
1. **Core** (`agent/Core/`) — Identity, memory, self-awareness. Loaded every session, defines who you are.
17+
2. **Protocols** (`agent/Protocols/`) — Session-start procedures, scope boundaries, security rules, memory management. Loaded every session after Core.
18+
3. **Skills** (`agent/Skills/`) — Reference standards for specific domains (coding style, API design, test strategy). Loaded on-demand when relevant.
19+
4. **Workflows** (`agent/Workflows/`) — Multi-step procedures for activities (planning, reviewing, auditing, reporting). Loaded on-demand when starting an activity.
20+
5. **Sensors** (`agent/Sensors/`) — Event-driven hooks that run automatically. You never load these manually.
21+
6. **Routines** (`agent/Routines/`) — Periodic maintenance tasks. Checked at session start, executed when the user approves.
22+
23+
The **CLAUDE.md** at your workspace root is your navigation hub — it has tables listing every installed file with descriptions.
24+
25+
---
26+
27+
## When to Load What
28+
29+
**Load a Workflow when:**
30+
- You are starting a multi-step activity: planning a feature, reviewing code, auditing security, writing a session log.
31+
- Follow the workflow end-to-end — it defines the complete procedure.
32+
- Check the "Workflows" table in CLAUDE.md for the full list.
33+
34+
**Load a Skill when:**
35+
- You need reference standards for a specific domain: coding conventions, API design patterns, test strategy.
36+
- Load it, apply the standards, then move on. Skills are reference material, not procedures.
37+
- Check the "Skills" table in CLAUDE.md for the full list.
38+
39+
**Load both when:**
40+
- A workflow references a skill (e.g., code-review workflow references review-checklist skill).
41+
- The workflow tells you when to load supporting skills.
42+
43+
---
44+
45+
## Using the Playbook
46+
47+
The Playbook is your project management hub:
48+
49+
| File | Purpose | When to use |
50+
|------|---------|-------------|
51+
| `{{ .DocsPath }}Playbook/Status.md` | Task tracker | Check at session start for assigned work |
52+
| `{{ .DocsPath }}Playbook/Backlog.md` | Intake queue | Add out-of-scope findings here — never fix inline |
53+
| `{{ .DocsPath }}Playbook/Roadmap.md` | Long-term direction | Check before proposing new features |
54+
| `{{ .DocsPath }}Playbook/Plans/Active/` | Implementation plans | Read your assigned plan before starting work |
55+
| `{{ .DocsPath }}Logs/KeyDecisionLog.md` | Decision log | Log significant architectural decisions |
56+
| `{{ .DocsPath }}Playbook/Standards/SecurityStandards.md` | Security constraints | Hard security rules — always applies |
57+
58+
**Key rule:** When you discover bugs, improvements, or tech debt outside your current task, add them to `Backlog.md`. Don't fix them inline — stay focused on your assigned work.
59+
60+
---
61+
{{ if .Routines }}
62+
## How Routines Work
63+
64+
Routines are periodic self-maintenance tasks that keep the workspace healthy.
65+
66+
**Lifecycle:**
67+
1. **Session start:** The `routine-check` sensor parses `agent/Core/routines.md`, compares `last_ran` dates against frequencies, and flags overdue routines.
68+
2. **User decides:** You report which routines are overdue. The user decides whether to run them now or defer.
69+
3. **Execution:** Read the routine's procedure file in `agent/Routines/`, follow each step.
70+
4. **Logging:** Append results to `{{ .DocsPath }}Logs/RoutineLog.md` with date, routine name, outcome, and notes.
71+
5. **Dashboard update:** Set `last_ran` to today's date in `agent/Core/routines.md`.
72+
73+
**Rules:**
74+
- Every routine must be **idempotent** — safe to re-run if interrupted.
75+
- When validating facts, **mark stale entries as outdated** rather than deleting.
76+
- Never run a routine without user approval.
77+
78+
---
79+
{{ end }}
80+
## How Sensors Work
81+
82+
Sensors are event-driven hooks configured in `.claude/settings.json`. They fire automatically — you don't invoke them.
83+
84+
**Event types:**
85+
- `SessionStart` — fires once when the session begins (e.g., inject context, check routines)
86+
- `PreToolUse` — fires before a tool is used (e.g., block edits outside workspace)
87+
- `PostToolUse` — fires after a tool is used
88+
- `UserPromptSubmit` — fires before each user prompt is processed (e.g., inject behavioral constraints)
89+
- `Stop` — fires after each response (e.g., display status bar)
90+
91+
**Behavior types:**
92+
- **Blocking sensors** (scope guards) — prevent actions that violate rules. If a sensor blocks you, read the rule it's enforcing.
93+
- **Injecting sensors** (session-context) — add information to your context at specific events.
94+
- **Feedback sensors** (status-bar) — provide status information after responses.
95+
96+
**Key rule:** Don't fight sensors. If a sensor blocks an action, it's enforcing a workspace rule. Read the sensor's description in your CLAUDE.md to understand why.
97+
98+
---
99+
100+
## Working with Memory
101+
102+
`agent/Core/memory.md` is your persistent memory between sessions.
103+
104+
**Structure:**
105+
- **Flags** — Temporary signals for the current work cycle (clear when resolved)
106+
- **Work State** — Current task, branch, what you're doing
107+
- **Notes** — Stable facts about the project that future sessions need
108+
- **Feedback** — User corrections and preferences
109+
- **References** — External pointers (URLs, file paths, configs)
110+
111+
**When to write:**
112+
- You learn something future sessions need to know
113+
- The user corrects your behavior or provides preferences
114+
- You start or finish a task (update Work State)
115+
- You discover a project fact that isn't documented elsewhere
116+
117+
**When to read:**
118+
- Every session start — restore context from previous sessions
119+
- The session-start protocol handles this automatically
120+
121+
**Key rule:** Never use Claude Code's auto-memory system (`~/.claude/projects/*/memory/`). All persistent memory goes in `agent/Core/memory.md`.
122+
123+
---
124+
125+
## Evolving the Workspace
126+
127+
The workspace is managed by the `bonsai` CLI:
128+
129+
| Command | What it does |
130+
|---------|-------------|
131+
| `bonsai add` | Install new agents or add abilities (skills, workflows, protocols, sensors, routines) to existing agents |
132+
| `bonsai remove` | Remove agents or individual abilities |
133+
| `bonsai update` | Sync workspace after creating custom files with YAML frontmatter |
134+
| `bonsai guide` | View the custom files guide for creating your own abilities |
135+
| `bonsai list` | See what's installed in the current project |
136+
| `bonsai catalog` | Browse all available abilities |
137+
138+
**Custom files:** You can create custom skills, workflows, protocols, sensors, or routines by placing files with YAML frontmatter in the appropriate `agent/` subdirectory, then running `bonsai update` to register them.
139+
140+
---
141+
142+
## Agent-Specific Patterns
143+
{{ if eq .AgentName "tech-lead" }}
144+
### Tech Lead Operating Model
145+
146+
- **You plan and orchestrate** — never write application code directly. Your job is to break down features, create plans, dispatch to code agents, and review their output.
147+
- **Dispatch via worktrees** — each code agent works in an isolated worktree. Use the dispatch skill to send work.
148+
- **Check Backlog first** — before creating new work items, check `{{ .DocsPath }}Playbook/Backlog.md` for existing entries to avoid duplicates.
149+
- **Update Status after work** — when tasks complete, update `{{ .DocsPath }}Playbook/Status.md` and log results.
150+
- **Use issue-to-implementation** — for end-to-end feature delivery, follow the issue-to-implementation workflow from intake through close.
151+
- **Review all output** — before marking work done, review agent output against the plan for correctness, standards compliance, and security.
152+
{{ end }}{{ if or (eq .AgentName "backend") (eq .AgentName "frontend") (eq .AgentName "fullstack") }}
153+
### Code Agent Operating Model
154+
155+
- **Read your plan first** — check `{{ .DocsPath }}Playbook/Plans/Active/` for your assigned implementation plan before writing any code. Follow it exactly.
156+
- **Stop if ambiguous** — if the plan is unclear or you face a decision not covered by the plan, stop and report to the tech lead. Don't guess or make architectural decisions.
157+
- **Stay in scope** — only modify files within your workspace boundary. The scope-guard sensor enforces this.
158+
- **Report completion** — use the reporting workflow to communicate results back to the tech lead.
159+
- **Don't make architectural decisions** — that's the tech lead's job. Your job is to implement the plan precisely.
160+
{{ end }}{{ if eq .AgentName "devops" }}
161+
### DevOps Operating Model
162+
163+
- **Plan before apply** — never auto-approve destructive infrastructure operations. Always plan first, show the user what will change, and require explicit confirmation.
164+
- **Explicit confirmation for destructive ops** — any operation that deletes, replaces, or modifies live infrastructure requires the user to explicitly approve.
165+
- **Work with safety guards** — the iac-safety-guard sensor blocks dangerous commands. If it blocks you, the operation needs explicit approval.
166+
- **Stay in scope** — only modify infrastructure and deployment files within your workspace boundary.
167+
{{ end }}{{ if eq .AgentName "security" }}
168+
### Security Agent Operating Model
169+
170+
- **Audit and report** — you read the entire codebase but only modify security-owned files. Never implement application features.
171+
- **Evidence-based findings** — every finding must include: specific file path, line number, and standard reference (OWASP, CWE, CVE).
172+
- **Only modify security-owned files** — security policies, audit reports, security configurations. Never modify application code.
173+
- **Use security-audit workflow** — for structured audits, follow the security-audit workflow end-to-end.
174+
{{ end }}

internal/catalog/catalog.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -301,7 +301,7 @@ func loadItems(fsys fs.FS, category string) []CatalogItem {
301301
continue
302302
}
303303
for _, f := range dirEntries {
304-
if !f.IsDir() && strings.HasSuffix(f.Name(), ".md") {
304+
if !f.IsDir() && (strings.HasSuffix(f.Name(), ".md") || strings.HasSuffix(f.Name(), ".md.tmpl")) {
305305
item.ContentPath = itemDir + "/" + f.Name()
306306
break
307307
}

internal/generate/generate.go

Lines changed: 89 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -494,6 +494,62 @@ func SettingsJSON(projectRoot string, cfg *config.ProjectConfig, cat *catalog.Ca
494494
}
495495

496496

497+
// howToWorkLines generates the compact "How to Work" heuristics section for the workspace CLAUDE.md.
498+
func howToWorkLines(agentName string, docsPrefix string, hasRoutines bool, hasWorkspaceGuide bool) []string {
499+
var lines []string
500+
lines = append(lines,
501+
"### How to Work", "",
502+
"> Decision heuristics — how to use this workspace effectively.", "",
503+
)
504+
505+
// Shared heuristics (all agents)
506+
lines = append(lines,
507+
fmt.Sprintf("- **Before starting work:** Check `%sPlaybook/Status.md` for assigned tasks and `%sPlaybook/Plans/Active/` for your current plan.", docsPrefix, docsPrefix),
508+
"- **When to load a Workflow:** You are starting a multi-step activity (planning, reviewing, auditing). Load the matching workflow from the table above and follow it end-to-end.",
509+
"- **When to load a Skill:** You need reference standards for a specific domain (coding style, API design, test strategy). Load it, use it, move on.",
510+
fmt.Sprintf("- **Decision logging:** When you make or observe a significant architectural decision, append it to `%sLogs/KeyDecisionLog.md`.", docsPrefix),
511+
fmt.Sprintf("- **Out-of-scope findings:** Don't fix bugs, debt, or improvements outside your current task. Add them to `%sPlaybook/Backlog.md`.", docsPrefix),
512+
"- **Workspace evolution:** `bonsai add` (new abilities), `bonsai remove` (uninstall), `bonsai update` (sync custom files), `bonsai list` (see installed), `bonsai catalog` (browse available).",
513+
)
514+
515+
// Agent-type-specific heuristics
516+
switch agentName {
517+
case "tech-lead":
518+
lines = append(lines,
519+
"- **You orchestrate, not implement.** Plan features, dispatch to code agents via worktrees, review their output. Never write application code directly.",
520+
fmt.Sprintf("- **Check Backlog first:** Before creating new work items, check `%sPlaybook/Backlog.md` for existing entries.", docsPrefix),
521+
fmt.Sprintf("- **After completing work:** Update `%sPlaybook/Status.md` and log results.", docsPrefix),
522+
)
523+
case "backend", "frontend", "fullstack":
524+
lines = append(lines,
525+
fmt.Sprintf("- **Plan first:** Read your assigned plan in `%sPlaybook/Plans/Active/` before writing any code. Follow it exactly.", docsPrefix),
526+
"- **When stuck:** If the plan is ambiguous, stop and report — don't guess or make design decisions.",
527+
"- **Stay in scope:** Only modify files within your workspace boundary.",
528+
)
529+
case "devops":
530+
lines = append(lines,
531+
"- **Plan before apply:** Never auto-approve destructive infrastructure operations. Require explicit user confirmation.",
532+
"- **Stay in scope:** Only modify infrastructure and deployment files within your workspace boundary.",
533+
)
534+
case "security":
535+
lines = append(lines,
536+
"- **Audit and report.** You read the entire codebase but only modify security-owned files.",
537+
"- **Evidence-based findings:** Every finding must reference a specific file, line, and standard (OWASP, CWE, CVE).",
538+
)
539+
}
540+
541+
// Workspace guide pointer
542+
if hasWorkspaceGuide {
543+
lines = append(lines,
544+
"- **New to this workspace?** Load `agent/Skills/workspace-guide.md` for a full operational reference.",
545+
)
546+
}
547+
548+
lines = append(lines, "")
549+
550+
return lines
551+
}
552+
497553
const (
498554
bonsaiStartMarker = "<!-- BONSAI_START -->"
499555
bonsaiEndMarker = "<!-- BONSAI_END -->"
@@ -623,6 +679,17 @@ func WorkspaceClaudeMD(projectRoot string, workspaceRoot string, agentDef *catal
623679
"> Sensors run automatically — they are configured in `.claude/settings.json`.", "")
624680
}
625681

682+
// How to Work section
683+
hasWorkspaceGuide := false
684+
for _, s := range installed.Skills {
685+
if s == "workspace-guide" {
686+
hasWorkspaceGuide = true
687+
break
688+
}
689+
}
690+
htw := howToWorkLines(agentDef.Name, docsPrefix, len(installed.Routines) > 0, hasWorkspaceGuide)
691+
lines = append(lines, htw...)
692+
626693
lines = append(lines,
627694
"---", "",
628695
"## Memory", "",
@@ -962,18 +1029,34 @@ func AgentWorkspace(projectRoot string, agentDef *catalog.AgentDef, installed *c
9621029
result.Add(r)
9631030
}
9641031

965-
// 2. Skills
1032+
// Full template context — used by skills, sensors, and routines that have .tmpl files
1033+
fullCtx := &TemplateContext{
1034+
ProjectName: cfg.ProjectName,
1035+
ProjectDescription: cfg.Description,
1036+
AgentName: agentDef.Name,
1037+
AgentDisplayName: agentDef.DisplayName,
1038+
AgentDescription: agentDef.Description,
1039+
Workspace: installed.Workspace,
1040+
DocsPath: cfg.DocsPath,
1041+
Protocols: installed.Protocols,
1042+
Skills: installed.Skills,
1043+
Workflows: installed.Workflows,
1044+
Routines: installed.Routines,
1045+
OtherAgents: ctx.OtherAgents,
1046+
}
1047+
1048+
// 2. Skills (rendered through templates if .tmpl, otherwise copied as-is)
9661049
for _, skillName := range installed.Skills {
9671050
item := cat.GetSkill(skillName)
9681051
if item == nil {
9691052
continue
9701053
}
971-
data, err := fs.ReadFile(catFS, item.ContentPath)
1054+
content, err := renderContent(catFS, item.ContentPath, fullCtx)
9721055
if err != nil {
973-
return err
1056+
return fmt.Errorf("skill %s: %w", skillName, err)
9741057
}
9751058
relPath, _ := filepath.Rel(projectRoot, filepath.Join(agentDir, "Skills", skillName+".md"))
976-
r := writeFile(projectRoot, relPath, data, "catalog:skills/"+skillName, lock, force)
1059+
r := writeFile(projectRoot, relPath, content, "catalog:skills/"+skillName, lock, force)
9771060
result.Add(r)
9781061
}
9791062

@@ -1008,27 +1091,12 @@ func AgentWorkspace(projectRoot string, agentDef *catalog.AgentDef, installed *c
10081091
}
10091092

10101093
// 5. Sensors (rendered through templates)
1011-
sensorCtx := &TemplateContext{
1012-
ProjectName: cfg.ProjectName,
1013-
ProjectDescription: cfg.Description,
1014-
AgentName: agentDef.Name,
1015-
AgentDisplayName: agentDef.DisplayName,
1016-
AgentDescription: agentDef.Description,
1017-
Workspace: installed.Workspace,
1018-
DocsPath: cfg.DocsPath,
1019-
Protocols: installed.Protocols,
1020-
Skills: installed.Skills,
1021-
Workflows: installed.Workflows,
1022-
Routines: installed.Routines,
1023-
OtherAgents: ctx.OtherAgents,
1024-
}
1025-
10261094
for _, sensorName := range installed.Sensors {
10271095
sensor := cat.GetSensor(sensorName)
10281096
if sensor == nil {
10291097
continue
10301098
}
1031-
content, err := renderContent(catFS, sensor.ContentPath, sensorCtx)
1099+
content, err := renderContent(catFS, sensor.ContentPath, fullCtx)
10321100
if err != nil {
10331101
return fmt.Errorf("sensor %s: %w", sensorName, err)
10341102
}
@@ -1044,7 +1112,7 @@ func AgentWorkspace(projectRoot string, agentDef *catalog.AgentDef, installed *c
10441112
if routine == nil {
10451113
continue
10461114
}
1047-
content, err := renderContent(catFS, routine.ContentPath, sensorCtx)
1115+
content, err := renderContent(catFS, routine.ContentPath, fullCtx)
10481116
if err != nil {
10491117
return fmt.Errorf("routine %s: %w", routineName, err)
10501118
}

0 commit comments

Comments
 (0)