@fredericboyer/dev-team 0.5.0 → 0.7.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.
Files changed (43) hide show
  1. package/README.md +12 -11
  2. package/dist/bin/dev-team.js +12 -12
  3. package/dist/bin/dev-team.js.map +1 -1
  4. package/dist/create-agent.js +6 -6
  5. package/dist/create-agent.js.map +1 -1
  6. package/dist/doctor.js +15 -16
  7. package/dist/doctor.js.map +1 -1
  8. package/dist/files.js +2 -0
  9. package/dist/files.js.map +1 -1
  10. package/dist/init.js +53 -40
  11. package/dist/init.js.map +1 -1
  12. package/dist/scan.js +9 -9
  13. package/dist/scan.js.map +1 -1
  14. package/dist/status.js +11 -11
  15. package/dist/status.js.map +1 -1
  16. package/dist/update.d.ts +1 -4
  17. package/dist/update.js +178 -59
  18. package/dist/update.js.map +1 -1
  19. package/package.json +2 -2
  20. package/templates/CLAUDE.md +14 -11
  21. package/templates/agent-memory/dev-team-hamilton/MEMORY.md +12 -0
  22. package/templates/agents/dev-team-beck.md +7 -0
  23. package/templates/agents/dev-team-borges.md +4 -4
  24. package/templates/agents/dev-team-brooks.md +42 -5
  25. package/templates/agents/dev-team-conway.md +7 -0
  26. package/templates/agents/dev-team-deming.md +16 -2
  27. package/templates/agents/dev-team-drucker.md +17 -5
  28. package/templates/agents/dev-team-hamilton.md +77 -0
  29. package/templates/agents/dev-team-mori.md +11 -2
  30. package/templates/agents/dev-team-tufte.md +24 -0
  31. package/templates/agents/dev-team-voss.md +12 -3
  32. package/templates/hooks/dev-team-post-change-review.js +69 -40
  33. package/templates/hooks/dev-team-pre-commit-gate.js +65 -52
  34. package/templates/hooks/dev-team-tdd-enforce.js +27 -6
  35. package/templates/hooks/dev-team-watch-list.js +3 -3
  36. package/templates/settings.json +6 -16
  37. package/templates/skills/dev-team-assess/SKILL.md +167 -0
  38. package/templates/skills/dev-team-audit/SKILL.md +8 -3
  39. package/templates/skills/dev-team-merge/SKILL.md +95 -0
  40. package/templates/skills/dev-team-review/SKILL.md +9 -4
  41. package/templates/skills/dev-team-security-status/SKILL.md +43 -0
  42. package/templates/skills/dev-team-task/SKILL.md +28 -41
  43. package/templates/hooks/dev-team-task-loop.js +0 -73
@@ -74,20 +74,14 @@ if (API_PATTERNS.some((p) => p.test(fullPath))) {
74
74
  flags.push("@dev-team-mori (API contract may affect UI)");
75
75
  }
76
76
 
77
- // Config/infra patterns → flag for Voss
78
- const INFRA_PATTERNS = [
79
- /docker/,
80
- /\.env/,
81
- /config/,
82
- /migration/,
83
- /database/,
84
- /\.sql$/,
85
- /infrastructure/,
86
- /deploy/,
87
- ];
77
+ // App config patterns → flag for Voss
78
+ // Voss owns: application config, migrations, database, .env (app-specific)
79
+ // Intentional overlap: Docker files trigger Hamilton below; .env files trigger
80
+ // Voss here for app-config review. Both perspectives are valuable.
81
+ const APP_CONFIG_PATTERNS = [/\.env/, /config/, /migration/, /database/, /\.sql$/];
88
82
 
89
- if (INFRA_PATTERNS.some((p) => p.test(fullPath))) {
90
- flags.push("@dev-team-voss (architectural/config change)");
83
+ if (APP_CONFIG_PATTERNS.some((p) => p.test(fullPath))) {
84
+ flags.push("@dev-team-voss (app config/data change)");
91
85
  }
92
86
 
93
87
  // Tooling patterns → flag for Deming
@@ -123,7 +117,29 @@ if (DOC_PATTERNS.some((p) => p.test(fullPath))) {
123
117
  flags.push("@dev-team-tufte (documentation changed)");
124
118
  }
125
119
 
126
- // Architecture patterns → flag for Architect
120
+ // Doc-drift patterns → flag Tufte for implementation changes that may need doc updates
121
+ const DOC_DRIFT_PATTERNS = [
122
+ /(?:^|\/)src\/.*\.(ts|js)$/, // New or changed source files
123
+ /(?:^|\/)templates\/agents\//, // New or changed agent definitions
124
+ /(?:^|\/)templates\/skills\//, // New or changed skill definitions
125
+ /(?:^|\/)templates\/hooks\//, // New or changed hook definitions
126
+ /(?:^|\/)src\/init\.(ts|js)$/, // Installer changes
127
+ /(?:^|\/)src\/cli\.(ts|js)$/, // CLI entry point changes
128
+ /(?:^|\/)bin\//, // CLI shim changes
129
+ /(?:^|\/)package\.json$/, // Dependency or script changes
130
+ ];
131
+
132
+ // Only flag for doc-drift if Tufte was not already flagged for a direct doc change
133
+ const alreadyFlaggedTufte = flags.some((f) => f.startsWith("@dev-team-tufte"));
134
+ if (!alreadyFlaggedTufte && DOC_DRIFT_PATTERNS.some((p) => p.test(fullPath))) {
135
+ flags.push("@dev-team-tufte (implementation changed — check for doc drift)");
136
+ }
137
+
138
+ // Architecture patterns → flag for Architect. For architectural boundary files,
139
+ // Brooks is flagged here with the "architectural boundary touched" reason. The
140
+ // dedupe check below skips the generic "quality attribute review" reason for
141
+ // these files — this is intentional because Brooks's expanded agent definition
142
+ // already includes quality attribute assessment in every review.
127
143
  const ARCH_PATTERNS = [
128
144
  /\/adr\//,
129
145
  /architecture/,
@@ -163,12 +179,49 @@ if (RELEASE_PATTERNS.some((p) => p.test(fullPath))) {
163
179
  flags.push("@dev-team-conway (version/release artifact changed)");
164
180
  }
165
181
 
166
- // Always flag Knuth for non-test implementation files
182
+ // Operations/infra patterns → flag for Hamilton
183
+ // NOTE: Docker and .env patterns intentionally overlap with INFRA_PATTERNS (Voss).
184
+ // Voss reviews Docker files for infrastructure correctness (base images, build stages, networking),
185
+ // while Hamilton reviews them for operational concerns (resource limits, health checks, image optimization).
186
+ // This dual-review is by design — both perspectives add value.
187
+ const OPS_PATTERNS = [
188
+ /dockerfile/,
189
+ /docker-compose/,
190
+ /\.dockerignore$/,
191
+ /\.github\/workflows\//,
192
+ /\.gitlab-ci/,
193
+ /jenkinsfile/i,
194
+ /terraform\//,
195
+ /pulumi\//,
196
+ /cloudformation\//,
197
+ /helm\//,
198
+ /k8s\//,
199
+ /\.tf$/,
200
+ /\.tfvars$/,
201
+ /health[-_]?check/,
202
+ /(?:^|\/)(?:monitoring|prometheus|grafana|datadog)\.(?:ya?ml|json|conf|config|toml)$/, // monitoring config files (not src/monitoring.ts)
203
+ /(?:^|\/)(?:logging|logs)\.(?:ya?ml|json|conf|config|toml)$/, // logging config files (not src/logging.ts)
204
+ /(?:^|\/)(?:alerting|alerts?)\.(?:ya?ml|json|conf|config|toml)$/, // alerting config files
205
+ /(?:^|\/)(?:observability|otel|opentelemetry)\.(?:ya?ml|json|conf|config|toml)$/, // observability config files
206
+ /(?<!\/src)\/(?:monitoring|logging|alerting|observability)\//, // ops directories (but not under src/)
207
+ /\.env\.example$/,
208
+ /\.env\.template$/,
209
+ /env\.template$/,
210
+ ];
211
+
212
+ if (OPS_PATTERNS.some((p) => p.test(fullPath) || p.test(basename))) {
213
+ flags.push("@dev-team-hamilton (infrastructure/operations change)");
214
+ }
215
+
216
+ // Always flag Knuth and Brooks for non-test implementation files
167
217
  const isTestFile = /\.(test|spec)\.|__tests__|\/tests?\//.test(fullPath);
168
218
  const isCodeFile = /\.(js|ts|jsx|tsx|py|rb|go|java|rs|c|cpp|cs)$/.test(fullPath);
169
219
 
170
220
  if (isCodeFile && !isTestFile) {
171
221
  flags.push("@dev-team-knuth (new or changed code path to audit)");
222
+ if (!flags.some((f) => f.startsWith("@dev-team-brooks"))) {
223
+ flags.push("@dev-team-brooks (quality attribute review)");
224
+ }
172
225
  }
173
226
 
174
227
  // Flag Beck for test file changes (test quality review)
@@ -180,37 +233,13 @@ if (flags.length === 0) {
180
233
  process.exit(0);
181
234
  }
182
235
 
183
- // Track which agents have been flagged this session (for pre-commit gate to verify)
184
- const fs = require("fs");
185
- const trackingPath = path.join(process.cwd(), ".claude", "dev-team-review-pending.json");
186
- let pending = [];
187
- try {
188
- pending = JSON.parse(fs.readFileSync(trackingPath, "utf-8"));
189
- } catch {
190
- // No tracking file yet
191
- }
192
-
193
- for (const flag of flags) {
194
- const agent = flag.split(" ")[0]; // e.g. "@dev-team-szabo"
195
- if (!pending.includes(agent)) {
196
- pending.push(agent);
197
- }
198
- }
199
-
200
- try {
201
- fs.mkdirSync(path.dirname(trackingPath), { recursive: true });
202
- fs.writeFileSync(trackingPath, JSON.stringify(pending, null, 2));
203
- } catch {
204
- // Best effort — don't fail the hook over tracking
205
- }
206
-
207
236
  // Output as a DIRECTIVE, not a suggestion. CLAUDE.md instructs the LLM to act on this.
208
237
  console.log(`[dev-team] ACTION REQUIRED — spawn these agents as background reviewers:`);
209
238
  for (const flag of flags) {
210
239
  console.log(` → ${flag}`);
211
240
  }
212
241
  console.log(
213
- `Use the Agent tool to spawn each as a general-purpose subagent with their agent definition from .claude/agents/.`,
242
+ `Use the Agent tool to spawn each as a general-purpose subagent with their agent definition from .dev-team/agents/.`,
214
243
  );
215
244
 
216
245
  process.exit(0);
@@ -2,14 +2,12 @@
2
2
 
3
3
  /**
4
4
  * dev-team-pre-commit-gate.js
5
- * TaskCompleted hook.
5
+ * Pre-commit hook — memory freshness gate.
6
6
  *
7
- * When a task completes, checks:
8
- * 1. Whether flagged review agents were actually spawned
9
- * 2. Whether memory files need updating
10
- *
11
- * BLOCKS (exit 2) if review agents were flagged but not consulted.
12
- * Advisory (exit 0) for memory reminders.
7
+ * Runs before each commit. Checks whether memory files need updating.
8
+ * Blocks (exit 1) when implementation files are staged without memory updates.
9
+ * Override: create an empty `.dev-team/.memory-reviewed` file to acknowledge
10
+ * that memory was reviewed and nothing needs updating.
13
11
  */
14
12
 
15
13
  "use strict";
@@ -29,19 +27,40 @@ function cachedGitDiff(args, timeoutMs) {
29
27
  const cwdHash = createHash("md5").update(process.cwd()).digest("hex").slice(0, 8);
30
28
  const argsKey = args.join("-").replace(/[^a-zA-Z0-9-]/g, "");
31
29
  const cacheFile = path.join(os.tmpdir(), `dev-team-git-cache-${cwdHash}-${argsKey}.txt`);
30
+ let skipWrite = false;
32
31
  try {
33
- const stat = fs.statSync(cacheFile);
34
- if (Date.now() - stat.mtimeMs < 5000) {
32
+ const stat = fs.lstatSync(cacheFile);
33
+ // Reject symlinks to prevent symlink attacks (attacker could point cache
34
+ // file at a sensitive path and have us overwrite it on the next write)
35
+ if (stat.isSymbolicLink()) {
36
+ try {
37
+ fs.unlinkSync(cacheFile);
38
+ } catch {
39
+ // If we can't remove the symlink, skip writing to avoid following it
40
+ skipWrite = true;
41
+ }
42
+ } else if (Date.now() - stat.mtimeMs < 5000) {
35
43
  return fs.readFileSync(cacheFile, "utf-8");
36
44
  }
37
45
  } catch {
38
46
  // No cache or stale — fall through to git call
39
47
  }
40
48
  const result = execFileSync("git", args, { encoding: "utf-8", timeout: timeoutMs });
41
- try {
42
- fs.writeFileSync(cacheFile, result);
43
- } catch {
44
- // Best effort — don't fail the hook over caching
49
+ if (!skipWrite) {
50
+ try {
51
+ // Atomic write: write to a temp file then rename to close the TOCTOU window
52
+ const tmpFile = `${cacheFile}.${process.pid}.tmp`;
53
+ fs.writeFileSync(tmpFile, result, { mode: 0o600 });
54
+ fs.renameSync(tmpFile, cacheFile);
55
+ // Best-effort permission tightening for cache files from older versions
56
+ try {
57
+ fs.chmodSync(cacheFile, 0o600);
58
+ } catch {
59
+ /* best effort */
60
+ }
61
+ } catch {
62
+ // Best effort — don't fail the hook over caching
63
+ }
45
64
  }
46
65
  return result;
47
66
  }
@@ -63,69 +82,63 @@ if (files.length === 0) {
63
82
  process.exit(0);
64
83
  }
65
84
 
66
- // Check for pending reviews that were never completed
67
- const trackingPath = path.join(process.cwd(), ".claude", "dev-team-review-pending.json");
68
- let pendingReviews = [];
69
- try {
70
- pendingReviews = JSON.parse(fs.readFileSync(trackingPath, "utf-8"));
71
- } catch {
72
- // No tracking file — no pending reviews
73
- }
74
-
75
- if (pendingReviews.length > 0) {
76
- console.error(
77
- `[dev-team pre-commit] BLOCKED — these agents were flagged for review but not yet spawned:`,
78
- );
79
- for (const agent of pendingReviews) {
80
- console.error(` → ${agent}`);
81
- }
82
- console.error("");
83
- console.error(
84
- "Spawn each agent as a background subagent using the Agent tool with their definition",
85
- );
86
- console.error("from .claude/agents/. After review completes, clear the tracking file:");
87
- console.error(" rm .claude/dev-team-review-pending.json");
88
- console.error("");
89
- console.error("To skip this check (e.g. for trivial changes), delete the tracking file first.");
90
- process.exit(2);
91
- }
92
-
93
- // Memory freshness check (advisory only)
94
- const reminders = [];
85
+ // Memory freshness check (blocking unless overridden)
95
86
 
96
87
  const hasImplFiles = files.some(
97
88
  (f) => /\.(js|ts|jsx|tsx|py|rb|go|java|rs)$/.test(f) && !/\.(test|spec)\./.test(f),
98
89
  );
99
90
 
100
91
  const hasMemoryUpdates = files.some(
101
- (f) => f.endsWith("dev-team-learnings.md") || /agent-memory\/.*MEMORY\.md$/.test(f),
92
+ (f) => f.endsWith("learnings.md") || /agent-memory\/.*MEMORY\.md$/.test(f),
102
93
  );
103
94
 
104
95
  if (hasImplFiles && !hasMemoryUpdates) {
96
+ // Check for .memory-reviewed override marker
97
+ const markerPath = path.join(process.cwd(), ".dev-team", ".memory-reviewed");
98
+ let hasOverride = false;
99
+ try {
100
+ const stat = fs.lstatSync(markerPath);
101
+ // Require regular file — reject symlinks, directories, FIFOs, etc.
102
+ hasOverride = stat.isFile() && !stat.isSymbolicLink();
103
+ } catch {
104
+ // No marker file
105
+ }
106
+
107
+ if (hasOverride) {
108
+ // Override acknowledged — clean up the marker file after this commit
109
+ try {
110
+ fs.unlinkSync(markerPath);
111
+ } catch {
112
+ // Best effort — don't fail the hook over cleanup
113
+ }
114
+ process.exit(0);
115
+ }
116
+
105
117
  let unstagedMemory = false;
106
118
  try {
107
119
  const unstaged = cachedGitDiff(["diff", "--name-only"], 2000);
108
120
  unstagedMemory = unstaged
109
121
  .split("\n")
110
122
  .map((f) => f.split("\\").join("/"))
111
- .some((f) => f.endsWith("dev-team-learnings.md") || /agent-memory\/.*MEMORY\.md$/.test(f));
123
+ .some((f) => f.endsWith("learnings.md") || /agent-memory\/.*MEMORY\.md$/.test(f));
112
124
  } catch {
113
125
  // Ignore — best effort
114
126
  }
115
127
 
116
128
  if (unstagedMemory) {
117
- reminders.push(
118
- "Memory files were updated but not staged — run `git add .claude/dev-team-learnings.md .claude/agent-memory/` if learnings should be included",
129
+ console.error(
130
+ "[dev-team pre-commit] BLOCKED: Memory files were updated but not staged. " +
131
+ "Run `git add .dev-team/learnings.md .dev-team/agent-memory/` to include learnings, " +
132
+ "or create an empty `.dev-team/.memory-reviewed` file to acknowledge that memory was reviewed.",
119
133
  );
120
134
  } else {
121
- reminders.push(
122
- "Update .claude/dev-team-learnings.md or agent memory with any patterns, conventions, or decisions from this work",
135
+ console.error(
136
+ "[dev-team pre-commit] BLOCKED: Implementation files staged without memory updates. " +
137
+ "Update .dev-team/learnings.md or agent memory with any patterns, conventions, or decisions from this work. " +
138
+ "If no learnings apply, create an empty `.dev-team/.memory-reviewed` file to acknowledge.",
123
139
  );
124
140
  }
125
- }
126
-
127
- if (reminders.length > 0) {
128
- console.log(`[dev-team pre-commit] Before committing, consider: ${reminders.join("; ")}`);
141
+ process.exit(1);
129
142
  }
130
143
 
131
144
  process.exit(0);
@@ -29,19 +29,40 @@ function cachedGitDiff(args, timeoutMs) {
29
29
  const cwdHash = createHash("md5").update(process.cwd()).digest("hex").slice(0, 8);
30
30
  const argsKey = args.join("-").replace(/[^a-zA-Z0-9-]/g, "");
31
31
  const cacheFile = path.join(os.tmpdir(), `dev-team-git-cache-${cwdHash}-${argsKey}.txt`);
32
+ let skipWrite = false;
32
33
  try {
33
- const stat = fs.statSync(cacheFile);
34
- if (Date.now() - stat.mtimeMs < 5000) {
34
+ const stat = fs.lstatSync(cacheFile);
35
+ // Reject symlinks to prevent symlink attacks (attacker could point cache
36
+ // file at a sensitive path and have us overwrite it on the next write)
37
+ if (stat.isSymbolicLink()) {
38
+ try {
39
+ fs.unlinkSync(cacheFile);
40
+ } catch {
41
+ // If we can't remove the symlink, skip writing to avoid following it
42
+ skipWrite = true;
43
+ }
44
+ } else if (Date.now() - stat.mtimeMs < 5000) {
35
45
  return fs.readFileSync(cacheFile, "utf-8");
36
46
  }
37
47
  } catch {
38
48
  // No cache or stale — fall through to git call
39
49
  }
40
50
  const result = execFileSync("git", args, { encoding: "utf-8", timeout: timeoutMs });
41
- try {
42
- fs.writeFileSync(cacheFile, result);
43
- } catch {
44
- // Best effort — don't fail the hook over caching
51
+ if (!skipWrite) {
52
+ try {
53
+ // Atomic write: write to a temp file then rename to close the TOCTOU window
54
+ const tmpFile = `${cacheFile}.${process.pid}.tmp`;
55
+ fs.writeFileSync(tmpFile, result, { mode: 0o600 });
56
+ fs.renameSync(tmpFile, cacheFile);
57
+ // Best-effort permission tightening for cache files from older versions
58
+ try {
59
+ fs.chmodSync(cacheFile, 0o600);
60
+ } catch {
61
+ /* best effort */
62
+ }
63
+ } catch {
64
+ // Best effort — don't fail the hook over caching
65
+ }
45
66
  }
46
67
  return result;
47
68
  }
@@ -4,11 +4,11 @@
4
4
  * dev-team-watch-list.js
5
5
  * PostToolUse hook on Edit/Write.
6
6
  *
7
- * Reads configurable file-pattern-to-agent mappings from .claude/dev-team.json
7
+ * Reads configurable file-pattern-to-agent mappings from .dev-team/config.json
8
8
  * and outputs structured spawn recommendations when patterns match.
9
9
  * Advisory only — always exits 0.
10
10
  *
11
- * Config format in dev-team.json:
11
+ * Config format in config.json:
12
12
  * {
13
13
  * "watchLists": [
14
14
  * { "pattern": "src/db/", "agents": ["dev-team-codd"], "reason": "database code changed" },
@@ -42,7 +42,7 @@ if (!filePath) {
42
42
  // Read watch list config
43
43
  let watchLists = [];
44
44
  try {
45
- const prefsPath = path.join(process.cwd(), ".claude", "dev-team.json");
45
+ const prefsPath = path.join(process.cwd(), ".dev-team", "config.json");
46
46
  const prefs = JSON.parse(fs.readFileSync(prefsPath, "utf-8"));
47
47
  watchLists = prefs.watchLists || [];
48
48
  } catch {
@@ -6,15 +6,15 @@
6
6
  "hooks": [
7
7
  {
8
8
  "type": "command",
9
- "command": "node .claude/hooks/dev-team-post-change-review.js"
9
+ "command": "node .dev-team/hooks/dev-team-post-change-review.js"
10
10
  },
11
11
  {
12
12
  "type": "command",
13
- "command": "node .claude/hooks/dev-team-tdd-enforce.js"
13
+ "command": "node .dev-team/hooks/dev-team-tdd-enforce.js"
14
14
  },
15
15
  {
16
16
  "type": "command",
17
- "command": "node .claude/hooks/dev-team-watch-list.js"
17
+ "command": "node .dev-team/hooks/dev-team-watch-list.js"
18
18
  }
19
19
  ]
20
20
  }
@@ -25,11 +25,11 @@
25
25
  "hooks": [
26
26
  {
27
27
  "type": "command",
28
- "command": "node .claude/hooks/dev-team-safety-guard.js"
28
+ "command": "node .dev-team/hooks/dev-team-safety-guard.js"
29
29
  },
30
30
  {
31
31
  "type": "command",
32
- "command": "node .claude/hooks/dev-team-pre-commit-lint.js"
32
+ "command": "node .dev-team/hooks/dev-team-pre-commit-lint.js"
33
33
  }
34
34
  ]
35
35
  }
@@ -39,17 +39,7 @@
39
39
  "hooks": [
40
40
  {
41
41
  "type": "command",
42
- "command": "node .claude/hooks/dev-team-pre-commit-gate.js"
43
- }
44
- ]
45
- }
46
- ],
47
- "Stop": [
48
- {
49
- "hooks": [
50
- {
51
- "type": "command",
52
- "command": "node .claude/hooks/dev-team-task-loop.js"
42
+ "command": "node .dev-team/hooks/dev-team-pre-commit-gate.js"
53
43
  }
54
44
  ]
55
45
  }
@@ -0,0 +1,167 @@
1
+ ---
2
+ name: dev-team:assess
3
+ description: Audit the health of your project's dev-team knowledge base — learnings, agent memory, and CLAUDE.md. Finds stale entries, contradictions, enforcement gaps, and promotion opportunities. Use periodically or after major changes.
4
+ ---
5
+
6
+ Assess the health of the dev-team knowledge base for: $ARGUMENTS
7
+
8
+ ## Scope
9
+
10
+ This skill audits **only update-safe files** — files that survive `dev-team update`:
11
+
12
+ - `.dev-team/learnings.md` — shared project learnings
13
+ - `.dev-team/agent-memory/*/MEMORY.md` — per-agent calibration memory
14
+ - Project `CLAUDE.md` — project instructions (content outside `<!-- dev-team:begin/end -->` markers)
15
+
16
+ **NEVER modify** agent definitions (`.dev-team/agents/`), hook scripts (`.dev-team/hooks/`), skill definitions (`.dev-team/skills/`), or settings (`.claude/settings.json`). These are managed by templates and get overwritten on `dev-team update`.
17
+
18
+ ## Setup
19
+
20
+ 1. Read the following files to build a complete picture:
21
+ - `.dev-team/learnings.md`
22
+ - All `.dev-team/agent-memory/*/MEMORY.md` files (use Glob to discover them)
23
+ - The project's `CLAUDE.md` (root of repo)
24
+ - `.dev-team/config.json` (to know which agents are installed)
25
+
26
+ 2. If `$ARGUMENTS` specifies a focus area (e.g., "learnings", "memory", "claude.md"), scope the audit to that area only. Otherwise, audit all three.
27
+
28
+ ## Phase 1: Learnings audit (`.dev-team/learnings.md`)
29
+
30
+ Check for:
31
+
32
+ ### Staleness
33
+ - Entries that reference removed files, deprecated patterns, or old tool versions
34
+ - Entries contradicted by current code (e.g., "We use Express" when the codebase uses Fastify)
35
+ - Date-stamped entries older than 6 months without recent revalidation
36
+
37
+ ### Contradictions
38
+ - Entries that contradict each other (e.g., one says "always use snake_case" and another says "we adopted camelCase")
39
+ - Entries that contradict the project's `CLAUDE.md` instructions
40
+ - Entries that contradict agent memory files
41
+
42
+ ### Enforcement gaps
43
+ - Learnings that state a rule but have no corresponding hook, linter rule, or agent check to enforce it
44
+ - Learnings about process that are not reflected in `CLAUDE.md`
45
+
46
+ ### Promotion opportunities
47
+ - Learnings that are mature enough to become formal project instructions in `CLAUDE.md`
48
+ - Learnings that should be elevated to an ADR in `docs/adr/`
49
+ - Learnings that are really agent-specific calibration and should move to the appropriate agent's `MEMORY.md`
50
+
51
+ ## Phase 2: Agent memory audit (`.dev-team/agent-memory/*/MEMORY.md`)
52
+
53
+ Check each agent's memory file for:
54
+
55
+ ### Empty or boilerplate files
56
+ - Memory files that are empty or contain only the initial template header
57
+ - Agents that have been active (based on learnings references or git history) but have no memory entries
58
+
59
+ ### Staleness
60
+ - Memory entries that reference files, patterns, or decisions that no longer exist
61
+ - Calibration notes about overruled findings when the underlying code has since changed
62
+ - Entries that duplicate what is already in `.dev-team/learnings.md` (should be deduplicated)
63
+
64
+ ### Inconsistencies
65
+ - Agent memory that contradicts `.dev-team/learnings.md`
66
+ - Agent memory that contradicts another agent's memory (e.g., Szabo says "auth uses sessions" but Voss says "auth uses JWT")
67
+ - Agent memory that contradicts `CLAUDE.md`
68
+
69
+ ### Coverage gaps
70
+ - Installed agents (from `config.json`) with no meaningful memory — suggests the agent has not been calibrated
71
+ - Agents referenced in learnings but missing a memory file
72
+
73
+ ## Phase 3: CLAUDE.md audit
74
+
75
+ Check the project's `CLAUDE.md` for:
76
+
77
+ ### Accuracy
78
+ - Instructions that do not match actual project behavior (verify claims against code)
79
+ - Workflow descriptions that reference tools, commands, or patterns not present in the repo
80
+ - Agent descriptions or hook triggers that are outdated
81
+
82
+ ### Completeness
83
+ - Important patterns from `.dev-team/learnings.md` that should be in `CLAUDE.md` but are not
84
+ - Missing sections that a new developer would need (build commands, test commands, architecture overview)
85
+ - Installed agents or hooks not mentioned in `CLAUDE.md`
86
+
87
+ ### Staleness
88
+ - Content outside the `<!-- dev-team:begin/end -->` markers that references old patterns
89
+ - References to removed dependencies, deprecated APIs, or old file paths
90
+
91
+ ### Learnings promotion
92
+ - Mature learnings that have been stable for multiple sessions and should be promoted to `CLAUDE.md` instructions
93
+
94
+ ## Report
95
+
96
+ Produce a structured health report:
97
+
98
+ ### Executive summary
99
+
100
+ One paragraph: overall knowledge base health, number of issues found by severity.
101
+
102
+ ### Findings by area
103
+
104
+ For each area (learnings, agent memory, CLAUDE.md), list findings using classified severity:
105
+
106
+ ```
107
+ **[DEFECT]** area — description
108
+ Concrete impact: what goes wrong if this is not fixed.
109
+ Suggested fix: specific action to take.
110
+ ```
111
+
112
+ ```
113
+ **[RISK]** area — description
114
+ Why this matters and what could go wrong.
115
+ ```
116
+
117
+ ```
118
+ **[SUGGESTION]** area — description
119
+ Specific improvement with expected benefit.
120
+ ```
121
+
122
+ ### Cross-cutting issues
123
+
124
+ Issues that span multiple files:
125
+ - Contradictions between learnings and agent memory
126
+ - Information that exists in the wrong file
127
+ - Patterns documented in multiple places with divergent descriptions
128
+
129
+ ### Recommended actions
130
+
131
+ Numbered list of concrete actions, ordered by priority:
132
+
133
+ 1. **Fix [DEFECT] items** — these represent actively wrong information
134
+ 2. **Address [RISK] items** — these will cause problems soon
135
+ 3. **Consider [SUGGESTION] items** — these improve overall health
136
+
137
+ For each action, specify which file to edit and what change to make.
138
+
139
+ ### Health score
140
+
141
+ Provide a simple health score:
142
+
143
+ | Area | Status | Issues |
144
+ |------|--------|--------|
145
+ | Learnings | healthy / needs attention / unhealthy | count by severity |
146
+ | Agent Memory | healthy / needs attention / unhealthy | count by severity |
147
+ | CLAUDE.md | healthy / needs attention / unhealthy | count by severity |
148
+ | **Overall** | **status** | **total** |
149
+
150
+ Thresholds:
151
+ - **Healthy**: 0 defects, 0-2 risks
152
+ - **Needs attention**: 0 defects, 3+ risks OR 1 defect
153
+ - **Unhealthy**: 2+ defects
154
+
155
+ ## Completion
156
+
157
+ After the health report is delivered:
158
+ 1. Spawn **@dev-team-borges** (Librarian) to review memory freshness and capture any learnings from the assessment findings. This is mandatory.
159
+ 2. Include Borges's recommendations in the final report.
160
+
161
+ ## When to run
162
+
163
+ - **Periodically** — monthly or after a burst of activity
164
+ - **After major refactors** — code changes may invalidate learnings
165
+ - **Before onboarding** — ensure the knowledge base is accurate for new team members
166
+ - **After resolving many review findings** — learnings and memory may need cleanup
167
+ - **On request** — `/dev-team:assess`
@@ -22,7 +22,7 @@ Run a comprehensive audit of: $ARGUMENTS
22
22
  1. Spawn all three agents as **parallel background subagents** using the Agent tool with `subagent_type: "general-purpose"`.
23
23
 
24
24
  2. Each agent's prompt must include:
25
- - The agent's full definition (read from `.claude/agents/<agent>.md`)
25
+ - The agent's full definition (read from `.dev-team/agents/<agent>.md`)
26
26
  - The scope (directory/pattern or "full codebase")
27
27
  - Instruction to produce classified findings: `[DEFECT]`, `[RISK]`, `[QUESTION]`, `[SUGGESTION]`
28
28
  - Instruction to read the actual code and tests for full context
@@ -84,8 +84,13 @@ Same grouping. Include actionable recommendations.
84
84
 
85
85
  Numbered list of concrete actions, ordered by priority. Each action should reference the specific finding it addresses.
86
86
 
87
+ ### Security preamble
88
+
89
+ Before starting the audit, check for open security alerts: run `/dev-team:security-status` if available, or check `gh api repos/{owner}/{repo}/code-scanning/alerts?state=open` and `gh api repos/{owner}/{repo}/dependabot/alerts?state=open`. Include these in the audit scope.
90
+
87
91
  ### Completion
88
92
 
89
93
  After the audit report is delivered:
90
- 1. Spawn **@dev-team-borges** (Librarian) to review memory freshness and capture learnings from the audit findings. This is mandatory.
91
- 2. Include Borges's recommendations in the final report.
94
+ 1. You MUST spawn **@dev-team-borges** (Librarian) as the final step to review memory freshness and capture learnings from the audit findings. Do NOT skip this.
95
+ 2. If Borges was not spawned, the audit is INCOMPLETE.
96
+ 3. Include Borges's recommendations in the final report.