guild-agents 1.1.0 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -62,7 +62,7 @@ Six phases: **evaluate**, **specify**, **plan**, **implement**, **review**, **va
62
62
 
63
63
  ## Skills Reference
64
64
 
65
- All 11 skills, grouped by function:
65
+ All 15 skills, grouped by function:
66
66
 
67
67
  | Skill | Group | Description |
68
68
  | --- | --- | --- |
@@ -72,7 +72,11 @@ All 11 skills, grouped by function:
72
72
  | `/council` | Decision | Multi-perspective deliberation on a decision or feature |
73
73
  | `/review` | Quality | Code review on the current diff |
74
74
  | `/qa-cycle` | Quality | QA and bugfix loop until clean |
75
+ | `/tdd` | Discipline | TDD red-green-refactor cycle |
76
+ | `/debug` | Discipline | Systematic 4-phase debugging |
77
+ | `/verify` | Discipline | Evidence-before-claims verification |
75
78
  | `/guild-specialize` | Context | Explore codebase, enrich CLAUDE.md with real conventions |
79
+ | `/re-specialize` | Context | Incremental update of auto-generated CLAUDE.md zones |
76
80
  | `/session-start` | Context | Load context and resume work |
77
81
  | `/session-end` | Context | Save state to SESSION.md |
78
82
  | `/status` | Context | Project and session state overview |
@@ -89,6 +93,9 @@ guild list # List agents and skills
89
93
  guild run <skill> # Preview a skill's execution plan (dry-run)
90
94
  guild logs # View execution traces
91
95
  guild logs clean # Remove old traces (--days N, --all)
96
+ guild workspace init <name> <members...> # Create a workspace
97
+ guild workspace add <path> # Add a member repo
98
+ guild workspace status # Show workspace state
92
99
  ```
93
100
 
94
101
  ## Under the Hood
package/bin/guild.js CHANGED
@@ -168,4 +168,88 @@ logsCmd
168
168
  }
169
169
  });
170
170
 
171
+ // guild workspace
172
+ const workspaceCmd = program
173
+ .command('workspace')
174
+ .description('Manage multi-repo workspaces');
175
+
176
+ // guild workspace init
177
+ workspaceCmd
178
+ .command('init')
179
+ .description('Initialize a workspace in the current directory')
180
+ .argument('<name>', 'Workspace name')
181
+ .argument('<members...>', 'Paths to member repos (e.g., ./backend ./frontend)')
182
+ .action(async (name, members) => {
183
+ try {
184
+ const { createWorkspaceFile } = await import('../src/commands/workspace.js');
185
+ await createWorkspaceFile(name, members);
186
+ console.log(`Workspace "${name}" created with ${members.length} member(s).`);
187
+ } catch (err) {
188
+ console.error(err.message);
189
+ process.exit(1);
190
+ }
191
+ });
192
+
193
+ // guild workspace add
194
+ workspaceCmd
195
+ .command('add')
196
+ .description('Add a member repo to the workspace')
197
+ .argument('<path>', 'Path to the member repo')
198
+ .action(async (memberPath) => {
199
+ try {
200
+ const { addWorkspaceMember } = await import('../src/commands/workspace.js');
201
+ await addWorkspaceMember(memberPath);
202
+ console.log(`Added "${memberPath}" to workspace.`);
203
+ } catch (err) {
204
+ console.error(err.message);
205
+ process.exit(1);
206
+ }
207
+ });
208
+
209
+ // guild workspace status
210
+ workspaceCmd
211
+ .command('status')
212
+ .description('Show workspace members and their state')
213
+ .action(async () => {
214
+ try {
215
+ const { getWorkspaceStatus } = await import('../src/commands/workspace.js');
216
+ const status = await getWorkspaceStatus();
217
+ console.log(`Workspace: ${status.name}`);
218
+ for (const m of status.members) {
219
+ const state = m.initialized ? 'initialized' : 'not initialized';
220
+ console.log(` ${m.name} (${m.path}) — ${state}`);
221
+ }
222
+ } catch (err) {
223
+ console.error(err.message);
224
+ process.exit(1);
225
+ }
226
+ });
227
+
228
+ // guild workspace run
229
+ workspaceCmd
230
+ .command('run')
231
+ .description('Run a command in a workspace member repo')
232
+ .argument('[member]', 'Member name (or omit with --all)')
233
+ .argument('[preset]', 'Preset command: test, lint, build')
234
+ .option('--cmd <command>', 'Custom command to run')
235
+ .option('--all', 'Run in all workspace members')
236
+ .action(async (member, preset, options) => {
237
+ try {
238
+ const { runWorkspaceCommand } = await import('../src/commands/workspace.js');
239
+ const results = runWorkspaceCommand(member, preset, options);
240
+ for (const r of results) {
241
+ const icon = r.status === 'passed' ? '\u2705' : '\u274C';
242
+ console.log(`${icon} ${r.member}: ${r.status} (${r.duration}ms)`);
243
+ if (r.status === 'failed' && r.output) {
244
+ console.log(r.output);
245
+ }
246
+ }
247
+ const failed = results.filter(r => r.status === 'failed');
248
+ if (failed.length > 0) process.exit(1);
249
+ } catch (err) {
250
+ console.error(err.message);
251
+ process.exit(1);
252
+ }
253
+ });
254
+
171
255
  program.parse();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "guild-agents",
3
- "version": "1.1.0",
3
+ "version": "1.3.0",
4
4
  "description": "Specification-driven development CLI for Claude Code — think before you build",
5
5
  "type": "module",
6
6
  "files": [
@@ -28,7 +28,10 @@
28
28
  "publish:snapshot": "npm run version:snapshot && npm publish --tag snapshot",
29
29
  "publish:beta": "npm run version:beta && npm publish --tag beta",
30
30
  "publish:stable": "npm run version:stable && npm publish --tag latest",
31
- "publish:promote-beta": "npm dist-tag add guild-agents@$(node --input-type=commonjs -p \"require('./package.json').version\") beta"
31
+ "publish:promote-beta": "npm dist-tag add guild-agents@$(node --input-type=commonjs -p \"require('./package.json').version\") beta",
32
+ "eval": "node scripts/run-evals.js",
33
+ "eval:build-feature": "node scripts/run-evals.js build-feature",
34
+ "eval:council": "node scripts/run-evals.js council"
32
35
  },
33
36
  "keywords": [
34
37
  "claude",
@@ -14,11 +14,18 @@ import chalk from 'chalk';
14
14
  import { existsSync } from 'fs';
15
15
  import { generateProjectMd, generateSessionMd, generateClaudeMd } from '../utils/generators.js';
16
16
  import { copyTemplates, getAgentNames, getSkillNames } from '../utils/files.js';
17
+ import { loadWorkspace } from '../utils/workspace.js';
17
18
 
18
19
  export async function runInit() {
19
20
  console.log('');
20
21
  p.intro(chalk.bold.cyan('Guild v1 — New project'));
21
22
 
23
+ // Detect workspace membership
24
+ const workspace = loadWorkspace();
25
+ if (workspace) {
26
+ p.log.info(chalk.gray(`Workspace detected: ${workspace.name} (${workspace.root})`));
27
+ }
28
+
22
29
  // Check for existing installation
23
30
  if (existsSync('.claude/agents')) {
24
31
  const overwrite = await p.confirm({
@@ -107,7 +114,7 @@ export async function runInit() {
107
114
  try {
108
115
  await copyTemplates();
109
116
  spinner.message('Generating CLAUDE.md...');
110
- await generateClaudeMd(projectData);
117
+ await generateClaudeMd(projectData, workspace, name);
111
118
 
112
119
  spinner.message('Generating PROJECT.md...');
113
120
  await generateProjectMd(projectData);
@@ -0,0 +1,92 @@
1
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'fs';
2
+ import { basename, join } from 'path';
3
+ import { findWorkspaceRoot, loadWorkspace, runInMember, PRESET_COMMANDS, WORKSPACE_FILE } from '../utils/workspace.js';
4
+
5
+ export async function createWorkspaceFile(name, memberPaths) {
6
+ const members = memberPaths.map(p => ({
7
+ name: basename(p),
8
+ path: p,
9
+ }));
10
+
11
+ const config = {
12
+ name,
13
+ members,
14
+ shared: {
15
+ agents: '.guild/agents',
16
+ skills: '.guild/skills',
17
+ },
18
+ };
19
+
20
+ writeFileSync(WORKSPACE_FILE, JSON.stringify(config, null, 2) + '\n', 'utf8');
21
+ mkdirSync(join('.guild', 'agents'), { recursive: true });
22
+ mkdirSync(join('.guild', 'skills'), { recursive: true });
23
+ }
24
+
25
+ export async function addWorkspaceMember(memberPath) {
26
+ const root = findWorkspaceRoot();
27
+ if (!root) throw new Error('No workspace found. Run `guild workspace init` first.');
28
+
29
+ const filePath = join(root, WORKSPACE_FILE);
30
+ const config = JSON.parse(readFileSync(filePath, 'utf8'));
31
+ const name = basename(memberPath);
32
+
33
+ if (config.members.some(m => m.path === memberPath || m.name === name)) {
34
+ throw new Error(`"${name}" is already a member of this workspace.`);
35
+ }
36
+
37
+ config.members.push({ name, path: memberPath });
38
+ writeFileSync(filePath, JSON.stringify(config, null, 2) + '\n', 'utf8');
39
+ }
40
+
41
+ export function runWorkspaceCommand(memberName, preset, options) {
42
+ const workspace = loadWorkspace();
43
+ if (!workspace) throw new Error('No workspace found. Run `guild workspace init` first.');
44
+
45
+ // Resolve command
46
+ let cmd, args;
47
+ if (options.cmd) {
48
+ const parts = options.cmd.split(/\s+/);
49
+ cmd = parts[0];
50
+ args = parts.slice(1);
51
+ } else if (preset && PRESET_COMMANDS[preset]) {
52
+ ({ cmd, args } = PRESET_COMMANDS[preset]);
53
+ } else {
54
+ throw new Error(`Unknown command: "${preset}". Use test, lint, build, or --cmd "...".`);
55
+ }
56
+
57
+ // Resolve members
58
+ let targets;
59
+ if (options.all) {
60
+ targets = workspace.members;
61
+ } else {
62
+ const member = workspace.members.find(m => m.name === memberName);
63
+ if (!member) {
64
+ const available = workspace.members.map(m => m.name).join(', ');
65
+ throw new Error(`Member "${memberName}" not found. Available: ${available}`);
66
+ }
67
+ targets = [member];
68
+ }
69
+
70
+ // Execute sequentially, collect all
71
+ const results = [];
72
+ for (const target of targets) {
73
+ results.push(runInMember(target, cmd, args));
74
+ }
75
+ return results;
76
+ }
77
+
78
+ export async function getWorkspaceStatus() {
79
+ const root = findWorkspaceRoot();
80
+ if (!root) throw new Error('No workspace found. Run `guild workspace init` first.');
81
+
82
+ const filePath = join(root, WORKSPACE_FILE);
83
+ const config = JSON.parse(readFileSync(filePath, 'utf8'));
84
+
85
+ const members = config.members.map(m => {
86
+ const absPath = join(root, m.path);
87
+ const initialized = existsSync(join(absPath, '.claude'));
88
+ return { ...m, absolutePath: absPath, initialized };
89
+ });
90
+
91
+ return { name: config.name, root, members };
92
+ }
@@ -0,0 +1,53 @@
1
+ {
2
+ "skill": "build-feature",
3
+ "evals": [
4
+ {
5
+ "id": "bf-has-core-phases",
6
+ "description": "Plan contains evaluate, specify, design, implement phases",
7
+ "expectations": [
8
+ { "text": "Has evaluate step", "assertion": "step-exists:evaluate" },
9
+ { "text": "Has specify step", "assertion": "step-exists:specify" },
10
+ { "text": "Has design step", "assertion": "step-exists:design" },
11
+ { "text": "Has implement step", "assertion": "step-exists:implement" }
12
+ ]
13
+ },
14
+ {
15
+ "id": "bf-has-quality-phases",
16
+ "description": "Plan contains review, QA, and completion phases",
17
+ "expectations": [
18
+ { "text": "Has review step", "assertion": "step-exists:review" },
19
+ { "text": "Has QA phase", "assertion": "step-exists:qa-phase" },
20
+ { "text": "Has completion step", "assertion": "step-exists:completion" }
21
+ ]
22
+ },
23
+ {
24
+ "id": "bf-advisor-uses-reasoning",
25
+ "description": "Advisor (evaluate) uses reasoning tier",
26
+ "expectations": [
27
+ { "text": "Evaluate uses reasoning tier", "assertion": "step-model-tier:evaluate:reasoning" }
28
+ ]
29
+ },
30
+ {
31
+ "id": "bf-developer-uses-execution",
32
+ "description": "Developer (implement) uses execution tier",
33
+ "expectations": [
34
+ { "text": "Implement uses execution tier", "assertion": "step-model-tier:implement:execution" }
35
+ ]
36
+ },
37
+ {
38
+ "id": "bf-gates-exist",
39
+ "description": "Quality gates exist at pre-review and final",
40
+ "expectations": [
41
+ { "text": "Pre-review gate exists", "assertion": "gate-exists:gate-pre-review" },
42
+ { "text": "Final gate exists", "assertion": "gate-exists:gate-final" }
43
+ ]
44
+ },
45
+ {
46
+ "id": "bf-minimum-steps",
47
+ "description": "Plan has at least 10 steps",
48
+ "expectations": [
49
+ { "text": "At least 10 steps", "assertion": "step-count:10" }
50
+ ]
51
+ }
52
+ ]
53
+ }
@@ -11,24 +11,30 @@ workflow:
11
11
  requires: [user-question]
12
12
  produces: [council-type, participant-roles]
13
13
  gate: true
14
+ - id: workspace-context
15
+ role: system
16
+ intent: "Detect workspace membership. If in a workspace, collect context from sibling repos (CLAUDE.md, PROJECT.md, SESSION.md) and build workspace context block."
17
+ requires: [council-type]
18
+ produces: [workspace-context]
19
+ condition: in-workspace
14
20
  - id: agent-1
15
21
  role: dynamic
16
22
  intent: "Analyze the question from specialized perspective. State position with concrete arguments."
17
- requires: [user-question, council-type]
23
+ requires: [user-question, council-type, workspace-context]
18
24
  produces: [perspective-1]
19
25
  model-tier: reasoning
20
26
  parallel: [agent-2, agent-3]
21
27
  - id: agent-2
22
28
  role: dynamic
23
29
  intent: "Analyze the question from specialized perspective. State position with concrete arguments."
24
- requires: [user-question, council-type]
30
+ requires: [user-question, council-type, workspace-context]
25
31
  produces: [perspective-2]
26
32
  model-tier: reasoning
27
33
  parallel: [agent-1, agent-3]
28
34
  - id: agent-3
29
35
  role: dynamic
30
36
  intent: "Analyze the question from specialized perspective. State position with concrete arguments."
31
- requires: [user-question, council-type]
37
+ requires: [user-question, council-type, workspace-context]
32
38
  produces: [perspective-3]
33
39
  model-tier: reasoning
34
40
  parallel: [agent-1, agent-2]
@@ -114,12 +120,23 @@ Analyze the user's question and determine which council type applies:
114
120
 
115
121
  ### Step 2 — Convene agents
116
122
 
123
+ **Workspace detection:** Before invoking agents, check if the project is inside a workspace:
124
+
125
+ 1. Look for a `guild-workspace.json` file by searching upward from the project root
126
+ 2. If found, load the workspace config and identify which member this project is
127
+ 3. Read CLAUDE.md, PROJECT.md, and SESSION.md from each sibling member repo
128
+ 4. Build a workspace context block with:
129
+ - Workspace name
130
+ - Each sibling's stack, structure summary, and current task
131
+ - Absolute paths so the agent can read any sibling file for deeper analysis
132
+
117
133
  Invoke the 3 corresponding agents IN PARALLEL using Task tool with `model: "opus"` (all council agents use reasoning tier). Each agent:
118
134
 
119
135
  1. Reads their `.claude/agents/[name].md` file to assume their role
120
136
  2. Reads `CLAUDE.md` and `SESSION.md` for project context
121
- 3. Analyzes the question from their specialized perspective
122
- 4. States their position with concrete arguments
137
+ 3. **If in a workspace:** receives the workspace context block and considers cross-repo impact as part of their analysis. They may read files from sibling repos using the provided paths.
138
+ 4. Analyzes the question from their specialized perspective
139
+ 5. States their position with concrete arguments
123
140
 
124
141
  ### Step 3 — Present debate
125
142
 
@@ -191,7 +208,11 @@ Example:
191
208
  Task tool with:
192
209
  subagent_type: "general-purpose"
193
210
  model: "opus"
194
- prompt: "Read .claude/agents/tech-lead.md and assume that role. Then: [debate question]"
211
+ prompt: "Read .claude/agents/tech-lead.md and assume that role. Then: [debate question]
212
+
213
+ [If in workspace, append:]
214
+ ## Workspace context
215
+ [workspace context block from Step 2]"
195
216
  ```
196
217
 
197
218
  The `model` parameter is resolved from the step's `model-tier`: all council agents use reasoning→`"opus"`.
@@ -0,0 +1,41 @@
1
+ {
2
+ "skill": "council",
3
+ "evals": [
4
+ {
5
+ "id": "council-three-parallel-agents",
6
+ "description": "Council has 3 agent steps in parallel",
7
+ "expectations": [
8
+ { "text": "Agent-1 exists", "assertion": "step-exists:agent-1" },
9
+ { "text": "Agent-2 exists", "assertion": "step-exists:agent-2" },
10
+ { "text": "Agent-3 exists", "assertion": "step-exists:agent-3" },
11
+ { "text": "Agent-1 is parallel", "assertion": "step-parallel:agent-1" },
12
+ { "text": "Agent-2 is parallel", "assertion": "step-parallel:agent-2" },
13
+ { "text": "Agent-3 is parallel", "assertion": "step-parallel:agent-3" }
14
+ ]
15
+ },
16
+ {
17
+ "id": "council-agents-use-reasoning",
18
+ "description": "All council agents use reasoning tier",
19
+ "expectations": [
20
+ { "text": "Agent-1 uses reasoning", "assertion": "step-model-tier:agent-1:reasoning" },
21
+ { "text": "Agent-2 uses reasoning", "assertion": "step-model-tier:agent-2:reasoning" },
22
+ { "text": "Agent-3 uses reasoning", "assertion": "step-model-tier:agent-3:reasoning" }
23
+ ]
24
+ },
25
+ {
26
+ "id": "council-synthesize-gate",
27
+ "description": "Synthesize step exists with gate",
28
+ "expectations": [
29
+ { "text": "Synthesize step exists", "assertion": "step-exists:synthesize" },
30
+ { "text": "Synthesize has gate", "assertion": "gate-exists:synthesize" }
31
+ ]
32
+ },
33
+ {
34
+ "id": "council-workspace-context",
35
+ "description": "Workspace context step exists with condition",
36
+ "expectations": [
37
+ { "text": "Workspace-context step exists", "assertion": "step-exists:workspace-context" }
38
+ ]
39
+ }
40
+ ]
41
+ }
@@ -0,0 +1,145 @@
1
+ ---
2
+ name: debug
3
+ description: "Discipline skill — systematic debugging process. Use when encountering any bug, test failure, or unexpected behavior, before proposing fixes."
4
+ user-invocable: true
5
+ ---
6
+
7
+ # Systematic Debugging
8
+
9
+ Random fixes waste time and create new bugs. Quick patches mask underlying issues.
10
+
11
+ **Core principle:** ALWAYS find root cause before attempting fixes.
12
+
13
+ ## Usage
14
+
15
+ `/debug`
16
+
17
+ Invoke this skill when encountering any bug, test failure, or unexpected behavior. Follow the four phases in order.
18
+
19
+ ## When to use
20
+
21
+ - Test failures
22
+ - Bugs in production
23
+ - Unexpected behavior
24
+ - Performance problems
25
+ - Build failures
26
+ - Integration issues
27
+
28
+ **Use this ESPECIALLY when:**
29
+
30
+ - Under time pressure (emergencies make guessing tempting)
31
+ - "Just one quick fix" seems obvious
32
+ - You've already tried multiple fixes
33
+ - Previous fix didn't work
34
+
35
+ ## The Iron Law
36
+
37
+ ```text
38
+ NO FIXES WITHOUT ROOT CAUSE INVESTIGATION FIRST
39
+ ```
40
+
41
+ If you haven't completed Phase 1, you cannot propose fixes.
42
+
43
+ ## The Four Phases
44
+
45
+ Complete each phase before proceeding to the next.
46
+
47
+ ### Phase 1: Root Cause Investigation
48
+
49
+ **BEFORE attempting ANY fix:**
50
+
51
+ 1. **Read Error Messages Carefully**
52
+ - Don't skip past errors or warnings
53
+ - Read stack traces completely
54
+ - Note line numbers, file paths, error codes
55
+
56
+ 2. **Reproduce Consistently**
57
+ - Can you trigger it reliably?
58
+ - What are the exact steps?
59
+ - If not reproducible, gather more data — don't guess
60
+
61
+ 3. **Check Recent Changes**
62
+ - What changed that could cause this?
63
+ - Git diff, recent commits
64
+ - New dependencies, config changes
65
+
66
+ 4. **Gather Evidence in Multi-Component Systems**
67
+ - Log what data enters each component boundary
68
+ - Log what data exits each component boundary
69
+ - Verify environment/config propagation
70
+ - Run once to gather evidence showing WHERE it breaks
71
+ - THEN investigate that specific component
72
+
73
+ 5. **Trace Data Flow**
74
+ - Where does the bad value originate?
75
+ - What called this with the bad value?
76
+ - Keep tracing up until you find the source
77
+ - Fix at source, not at symptom
78
+
79
+ ### Phase 2: Pattern Analysis
80
+
81
+ 1. **Find Working Examples** — locate similar working code in the same codebase
82
+ 2. **Compare Against References** — read reference implementations COMPLETELY, don't skim
83
+ 3. **Identify Differences** — list every difference between working and broken, however small
84
+ 4. **Understand Dependencies** — what components, settings, environment does it need?
85
+
86
+ ### Phase 3: Hypothesis and Testing
87
+
88
+ 1. **Form Single Hypothesis** — "I think X is the root cause because Y"
89
+ 2. **Test Minimally** — smallest possible change, one variable at a time
90
+ 3. **Verify** — did it work? Yes = Phase 4. No = new hypothesis. DON'T stack fixes.
91
+
92
+ ### Phase 4: Implementation
93
+
94
+ 1. **Create Failing Test Case** — simplest possible reproduction, automated if possible. Use `/tdd` for proper failing tests.
95
+ 2. **Implement Single Fix** — address the root cause, ONE change at a time, no "while I'm here" improvements.
96
+ 3. **Verify Fix** — test passes? No other tests broken? Issue actually resolved? Use `/verify` before claiming done.
97
+
98
+ **If fix doesn't work:**
99
+
100
+ - If < 3 attempts: return to Phase 1, re-analyze with new information
101
+ - **If >= 3 attempts: STOP and question the architecture**
102
+
103
+ **3+ failed fixes indicate an architectural problem:**
104
+
105
+ - Each fix reveals new coupling in different places
106
+ - Fixes require massive refactoring
107
+ - Each fix creates new symptoms elsewhere
108
+ - Discuss with the user before attempting more fixes
109
+
110
+ ## Red Flags - STOP and Follow Process
111
+
112
+ - "Quick fix for now, investigate later"
113
+ - "Just try changing X and see if it works"
114
+ - "Add multiple changes, run tests"
115
+ - "It's probably X, let me fix that"
116
+ - "I don't fully understand but this might work"
117
+ - Proposing solutions before tracing data flow
118
+ - "One more fix attempt" (when already tried 2+)
119
+
120
+ **ALL of these mean: STOP. Return to Phase 1.**
121
+
122
+ ## Common Rationalizations
123
+
124
+ | Excuse | Reality |
125
+ | ----------------------------------------- | ------------------------------------------------------------------------ |
126
+ | "Issue is simple, don't need process" | Simple issues have root causes too. Process is fast for simple bugs. |
127
+ | "Emergency, no time for process" | Systematic debugging is FASTER than guess-and-check thrashing. |
128
+ | "Just try this first, then investigate" | First fix sets the pattern. Do it right from the start. |
129
+ | "I'll write test after confirming fix" | Untested fixes don't stick. Test first proves it. |
130
+ | "Multiple fixes at once saves time" | Can't isolate what worked. Causes new bugs. |
131
+ | "I see the problem, let me fix it" | Seeing symptoms is not understanding root cause. |
132
+
133
+ ## Quick Reference
134
+
135
+ | Phase | Key Activities | Success Criteria |
136
+ | ---------------------- | ------------------------------------------------------ | --------------------------- |
137
+ | **1. Root Cause** | Read errors, reproduce, check changes, gather evidence | Understand WHAT and WHY |
138
+ | **2. Pattern** | Find working examples, compare | Identify differences |
139
+ | **3. Hypothesis** | Form theory, test minimally | Confirmed or new hypothesis |
140
+ | **4. Implementation** | Create test, fix, verify | Bug resolved, tests pass |
141
+
142
+ ## Related Skills
143
+
144
+ - `/tdd` — TDD cycle for creating failing test cases in Phase 4
145
+ - `/verify` — verification before claiming the fix is complete
@@ -113,6 +113,13 @@ Invoke the Tech Lead agent using Task tool with `model: "opus"` (reasoning tier)
113
113
  - **Visible limitations and technical debt**: outdated dependencies, TODOs found
114
114
  - **Useful project commands**: detected npm/make/cargo scripts
115
115
 
116
+ CLAUDE.md now uses zone markers (`<!-- guild:auto-start:ID -->` / `<!-- guild:auto-end:ID -->`) to delimit auto-generated sections. When enriching:
117
+
118
+ - Replace content BETWEEN the markers, preserving the markers themselves
119
+ - The following zones exist: `structure`, `architecture`, `conventions`, `env-vars`
120
+ - Do NOT modify content outside of zone markers (user-owned sections)
121
+ - If markers are missing (legacy project), replace `[PENDING: guild-specialize]` placeholders directly
122
+
116
123
  ### Step 4 — Specialize agents
117
124
 
118
125
  Invoke the Tech Lead agent using Task tool with `model: "sonnet"` (execution tier) to add project-specific context for each agent in `.claude/agents/*.md`:
@@ -127,6 +134,19 @@ Invoke the Tech Lead agent using Task tool with `model: "sonnet"` (execution tie
127
134
  - **db-migration.md**: ORM, migration tool, current schema (if applicable)
128
135
  - **platform-expert.md**: Claude Code version, known permission bugs, hook configuration
129
136
 
137
+ When specializing agents, append a zone at the bottom of each agent file:
138
+
139
+ ```markdown
140
+ <!-- guild:auto-start:agent-context -->
141
+ ## Project-Specific Context
142
+ - Stack: [detected stack]
143
+ - Architecture: [detected patterns]
144
+ - Conventions: [detected conventions]
145
+ <!-- guild:auto-end:agent-context -->
146
+ ```
147
+
148
+ This zone allows `guild-re-specialize` to update agent context later without touching the agent's core role definition.
149
+
130
150
  Use the `Task` tool with `model: "sonnet"` to invoke each agent by reading their `.claude/agents/[name].md` if you need a specialized perspective to enrich their configuration.
131
151
 
132
152
  The `model` parameter is resolved from the step's `model-tier`: reasoning→`"opus"`, execution→`"sonnet"`. System/gate steps run inline (no Task tool).