@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.
- package/README.md +12 -11
- package/dist/bin/dev-team.js +12 -12
- package/dist/bin/dev-team.js.map +1 -1
- package/dist/create-agent.js +6 -6
- package/dist/create-agent.js.map +1 -1
- package/dist/doctor.js +15 -16
- package/dist/doctor.js.map +1 -1
- package/dist/files.js +2 -0
- package/dist/files.js.map +1 -1
- package/dist/init.js +53 -40
- package/dist/init.js.map +1 -1
- package/dist/scan.js +9 -9
- package/dist/scan.js.map +1 -1
- package/dist/status.js +11 -11
- package/dist/status.js.map +1 -1
- package/dist/update.d.ts +1 -4
- package/dist/update.js +178 -59
- package/dist/update.js.map +1 -1
- package/package.json +2 -2
- package/templates/CLAUDE.md +14 -11
- package/templates/agent-memory/dev-team-hamilton/MEMORY.md +12 -0
- package/templates/agents/dev-team-beck.md +7 -0
- package/templates/agents/dev-team-borges.md +4 -4
- package/templates/agents/dev-team-brooks.md +42 -5
- package/templates/agents/dev-team-conway.md +7 -0
- package/templates/agents/dev-team-deming.md +16 -2
- package/templates/agents/dev-team-drucker.md +17 -5
- package/templates/agents/dev-team-hamilton.md +77 -0
- package/templates/agents/dev-team-mori.md +11 -2
- package/templates/agents/dev-team-tufte.md +24 -0
- package/templates/agents/dev-team-voss.md +12 -3
- package/templates/hooks/dev-team-post-change-review.js +69 -40
- package/templates/hooks/dev-team-pre-commit-gate.js +65 -52
- package/templates/hooks/dev-team-tdd-enforce.js +27 -6
- package/templates/hooks/dev-team-watch-list.js +3 -3
- package/templates/settings.json +6 -16
- package/templates/skills/dev-team-assess/SKILL.md +167 -0
- package/templates/skills/dev-team-audit/SKILL.md +8 -3
- package/templates/skills/dev-team-merge/SKILL.md +95 -0
- package/templates/skills/dev-team-review/SKILL.md +9 -4
- package/templates/skills/dev-team-security-status/SKILL.md +43 -0
- package/templates/skills/dev-team-task/SKILL.md +28 -41
- 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
|
-
//
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
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 (
|
|
90
|
-
flags.push("@dev-team-voss (
|
|
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
|
-
//
|
|
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
|
-
//
|
|
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 .
|
|
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
|
-
*
|
|
5
|
+
* Pre-commit hook — memory freshness gate.
|
|
6
6
|
*
|
|
7
|
-
*
|
|
8
|
-
* 1
|
|
9
|
-
*
|
|
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.
|
|
34
|
-
|
|
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
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
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
|
-
//
|
|
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("
|
|
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("
|
|
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
|
-
|
|
118
|
-
"Memory files were updated but not staged
|
|
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
|
-
|
|
122
|
-
"
|
|
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.
|
|
34
|
-
|
|
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
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
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 .
|
|
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
|
|
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(), ".
|
|
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 {
|
package/templates/settings.json
CHANGED
|
@@ -6,15 +6,15 @@
|
|
|
6
6
|
"hooks": [
|
|
7
7
|
{
|
|
8
8
|
"type": "command",
|
|
9
|
-
"command": "node .
|
|
9
|
+
"command": "node .dev-team/hooks/dev-team-post-change-review.js"
|
|
10
10
|
},
|
|
11
11
|
{
|
|
12
12
|
"type": "command",
|
|
13
|
-
"command": "node .
|
|
13
|
+
"command": "node .dev-team/hooks/dev-team-tdd-enforce.js"
|
|
14
14
|
},
|
|
15
15
|
{
|
|
16
16
|
"type": "command",
|
|
17
|
-
"command": "node .
|
|
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 .
|
|
28
|
+
"command": "node .dev-team/hooks/dev-team-safety-guard.js"
|
|
29
29
|
},
|
|
30
30
|
{
|
|
31
31
|
"type": "command",
|
|
32
|
-
"command": "node .
|
|
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 .
|
|
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 `.
|
|
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.
|
|
91
|
-
2.
|
|
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.
|