@fredericboyer/dev-team 0.1.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 dev-team contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,22 @@
1
+ #!/usr/bin/env node
2
+
3
+ 'use strict';
4
+
5
+ const { run } = require('../lib/init');
6
+
7
+ const args = process.argv.slice(2);
8
+ const command = args[0];
9
+
10
+ if (command === 'init') {
11
+ run(process.cwd(), args.slice(1)).catch((err) => {
12
+ console.error(`Error: ${err.message}`);
13
+ process.exit(1);
14
+ });
15
+ } else {
16
+ console.log('dev-team — Adversarial AI agent team for any project\n');
17
+ console.log('Usage:');
18
+ console.log(' npx dev-team init Interactive onboarding wizard');
19
+ console.log(' npx dev-team init --all Install everything with defaults');
20
+ console.log('');
21
+ process.exit(command === '--help' || command === '-h' ? 0 : 1);
22
+ }
package/lib/files.js ADDED
@@ -0,0 +1,160 @@
1
+ 'use strict';
2
+
3
+ const fs = require('fs');
4
+ const path = require('path');
5
+
6
+ /**
7
+ * Returns the absolute path to the templates/ directory within the package.
8
+ */
9
+ function templateDir() {
10
+ return path.join(__dirname, '..', 'templates');
11
+ }
12
+
13
+ /**
14
+ * Copies a file from src to dest, creating parent directories as needed.
15
+ * Returns true if the file was written, false if skipped.
16
+ */
17
+ function copyFile(src, dest) {
18
+ const dir = path.dirname(dest);
19
+ fs.mkdirSync(dir, { recursive: true });
20
+ fs.copyFileSync(src, dest);
21
+ return true;
22
+ }
23
+
24
+ /**
25
+ * Checks if a file exists.
26
+ */
27
+ function fileExists(absPath) {
28
+ try {
29
+ return fs.statSync(absPath).isFile();
30
+ } catch {
31
+ return false;
32
+ }
33
+ }
34
+
35
+ /**
36
+ * Checks if a directory exists.
37
+ */
38
+ function dirExists(absPath) {
39
+ try {
40
+ return fs.statSync(absPath).isDirectory();
41
+ } catch {
42
+ return false;
43
+ }
44
+ }
45
+
46
+ /**
47
+ * Reads a file and returns its content, or null if it doesn't exist.
48
+ */
49
+ function readFile(absPath) {
50
+ try {
51
+ return fs.readFileSync(absPath, 'utf-8');
52
+ } catch {
53
+ return null;
54
+ }
55
+ }
56
+
57
+ /**
58
+ * Writes content to a file, creating parent directories as needed.
59
+ */
60
+ function writeFile(absPath, content) {
61
+ const dir = path.dirname(absPath);
62
+ fs.mkdirSync(dir, { recursive: true });
63
+ fs.writeFileSync(absPath, content);
64
+ }
65
+
66
+ /**
67
+ * Deep merges hook configurations from source into target settings.
68
+ * Additive only — never removes existing hooks.
69
+ */
70
+ function mergeSettings(existingPath, newFragment) {
71
+ let existing = {};
72
+ try {
73
+ existing = JSON.parse(fs.readFileSync(existingPath, 'utf-8'));
74
+ } catch {
75
+ // File doesn't exist or is invalid — start fresh
76
+ }
77
+
78
+ if (!existing.hooks) {
79
+ existing.hooks = {};
80
+ }
81
+
82
+ for (const [event, entries] of Object.entries(newFragment.hooks || {})) {
83
+ if (!existing.hooks[event]) {
84
+ existing.hooks[event] = entries;
85
+ } else {
86
+ // Add entries that don't already exist (by command string)
87
+ for (const newEntry of entries) {
88
+ const newCommands = (newEntry.hooks || []).map((h) => h.command);
89
+ const alreadyExists = existing.hooks[event].some((existingEntry) => {
90
+ const existingCommands = (existingEntry.hooks || []).map((h) => h.command);
91
+ return newCommands.every((cmd) => existingCommands.includes(cmd));
92
+ });
93
+ if (!alreadyExists) {
94
+ existing.hooks[event].push(newEntry);
95
+ }
96
+ }
97
+ }
98
+ }
99
+
100
+ fs.writeFileSync(existingPath, JSON.stringify(existing, null, 2) + '\n');
101
+ }
102
+
103
+ /**
104
+ * Appends content to a file with dev-team markers.
105
+ * If markers already exist, replaces content between them.
106
+ * If file doesn't exist, creates it with just the content.
107
+ */
108
+ function mergeClaudeMd(filePath, newContent) {
109
+ const BEGIN_MARKER = '<!-- dev-team:begin -->';
110
+ const END_MARKER = '<!-- dev-team:end -->';
111
+
112
+ const existing = readFile(filePath);
113
+
114
+ if (!existing) {
115
+ // File doesn't exist — create with content
116
+ writeFile(filePath, newContent);
117
+ return 'created';
118
+ }
119
+
120
+ if (existing.includes(BEGIN_MARKER)) {
121
+ // Markers exist — replace between them
122
+ const beforeMarker = existing.substring(0, existing.indexOf(BEGIN_MARKER));
123
+ const afterMarker = existing.substring(existing.indexOf(END_MARKER) + END_MARKER.length);
124
+ writeFile(filePath, beforeMarker + newContent + afterMarker);
125
+ return 'replaced';
126
+ }
127
+
128
+ // No markers — append
129
+ writeFile(filePath, existing.trimEnd() + '\n\n' + newContent + '\n');
130
+ return 'appended';
131
+ }
132
+
133
+ /**
134
+ * Lists all files in a directory recursively.
135
+ */
136
+ function listFilesRecursive(dir) {
137
+ const results = [];
138
+ const entries = fs.readdirSync(dir, { withFileTypes: true });
139
+ for (const entry of entries) {
140
+ const fullPath = path.join(dir, entry.name);
141
+ if (entry.isDirectory()) {
142
+ results.push(...listFilesRecursive(fullPath));
143
+ } else {
144
+ results.push(fullPath);
145
+ }
146
+ }
147
+ return results;
148
+ }
149
+
150
+ module.exports = {
151
+ templateDir,
152
+ copyFile,
153
+ fileExists,
154
+ dirExists,
155
+ readFile,
156
+ writeFile,
157
+ mergeSettings,
158
+ mergeClaudeMd,
159
+ listFilesRecursive,
160
+ };
package/lib/init.js ADDED
@@ -0,0 +1,206 @@
1
+ 'use strict';
2
+
3
+ const path = require('path');
4
+ const {
5
+ templateDir,
6
+ copyFile,
7
+ fileExists,
8
+ dirExists,
9
+ readFile,
10
+ writeFile,
11
+ mergeSettings,
12
+ mergeClaudeMd,
13
+ } = require('./files');
14
+ const prompts = require('./prompts');
15
+
16
+ const ALL_AGENTS = [
17
+ { label: 'Voss', file: 'dev-team-voss.md', description: 'Backend Engineer' },
18
+ { label: 'Mori', file: 'dev-team-mori.md', description: 'Frontend/UI Engineer' },
19
+ { label: 'Szabo', file: 'dev-team-szabo.md', description: 'Security Auditor' },
20
+ { label: 'Knuth', file: 'dev-team-knuth.md', description: 'Quality Auditor' },
21
+ { label: 'Beck', file: 'dev-team-beck.md', description: 'Test Implementer' },
22
+ { label: 'Deming', file: 'dev-team-deming.md', description: 'Tooling & DX Optimizer' },
23
+ ];
24
+
25
+ const QUALITY_HOOKS = [
26
+ { label: 'TDD enforcement', file: 'dev-team-tdd-enforce.js', description: 'Block implementation changes without tests' },
27
+ { label: 'Safety guard', file: 'dev-team-safety-guard.js', description: 'Block dangerous commands (rm -rf, force push)' },
28
+ { label: 'Post-change review', file: 'dev-team-post-change-review.js', description: 'Flag which agents should review after edits' },
29
+ { label: 'Pre-commit gate', file: 'dev-team-pre-commit-gate.js', description: 'Remind about reviews before committing' },
30
+ { label: 'Task loop', file: 'dev-team-task-loop.js', description: 'Iterative task loop with adversarial review gates' },
31
+ ];
32
+
33
+ /**
34
+ * Main init flow.
35
+ */
36
+ async function run(targetDir, flags = []) {
37
+ const isAll = flags.includes('--all');
38
+
39
+ console.log('\ndev-team — Adversarial AI agent team\n');
40
+
41
+ // Step 1: Detect existing state
42
+ const claudeDir = path.join(targetDir, '.claude');
43
+ const agentsDir = path.join(claudeDir, 'agents');
44
+ const hooksDir = path.join(claudeDir, 'hooks');
45
+ const skillsDir = path.join(claudeDir, 'skills');
46
+ const memoryDir = path.join(claudeDir, 'agent-memory');
47
+ const settingsPath = path.join(claudeDir, 'settings.json');
48
+ const claudeMdPath = path.join(targetDir, 'CLAUDE.md');
49
+ const prefsPath = path.join(claudeDir, 'dev-team.json');
50
+
51
+ console.log('Detected:');
52
+ console.log(` .claude/ directory: ${dirExists(claudeDir) ? 'exists' : 'will be created'}`);
53
+ console.log(` CLAUDE.md: ${fileExists(claudeMdPath) ? 'exists (will merge)' : 'will be created'}`);
54
+ console.log('');
55
+
56
+ // Step 2: Agent selection
57
+ let selectedAgents;
58
+ if (isAll) {
59
+ selectedAgents = ALL_AGENTS.map((a) => a.label);
60
+ } else {
61
+ selectedAgents = await prompts.checkbox(
62
+ 'Which agents would you like to install?',
63
+ ALL_AGENTS.map((a) => ({
64
+ label: a.label,
65
+ description: `${a.description}`,
66
+ defaultSelected: true,
67
+ }))
68
+ );
69
+ }
70
+
71
+ // Step 3: Hook selection
72
+ let selectedHooks;
73
+ if (isAll) {
74
+ selectedHooks = QUALITY_HOOKS.map((h) => h.label);
75
+ } else {
76
+ selectedHooks = await prompts.checkbox(
77
+ 'Which quality hooks do you want to enforce?',
78
+ QUALITY_HOOKS.map((h) => ({
79
+ label: h.label,
80
+ description: h.description,
81
+ defaultSelected: true,
82
+ }))
83
+ );
84
+ }
85
+
86
+ // Step 4: Copy agents
87
+ const templates = templateDir();
88
+ let agentCount = 0;
89
+
90
+ for (const agent of ALL_AGENTS) {
91
+ if (!selectedAgents.includes(agent.label)) continue;
92
+
93
+ const src = path.join(templates, 'agents', agent.file);
94
+ const dest = path.join(agentsDir, agent.file);
95
+
96
+ if (fileExists(dest) && !isAll) {
97
+ const overwrite = await prompts.confirm(` ${agent.file} already exists. Overwrite?`, false);
98
+ if (!overwrite) continue;
99
+ }
100
+
101
+ copyFile(src, dest);
102
+ agentCount++;
103
+ }
104
+
105
+ // Step 5: Create agent memory directories
106
+ for (const agent of ALL_AGENTS) {
107
+ if (!selectedAgents.includes(agent.label)) continue;
108
+
109
+ const agentName = agent.file.replace('.md', '');
110
+ const memorySrc = path.join(templates, 'agent-memory', agentName, 'MEMORY.md');
111
+ const memoryDest = path.join(memoryDir, agentName, 'MEMORY.md');
112
+
113
+ if (!fileExists(memoryDest)) {
114
+ copyFile(memorySrc, memoryDest);
115
+ }
116
+ }
117
+
118
+ // Step 6: Create shared team learnings
119
+ const learningsSrc = path.join(templates, 'dev-team-learnings.md');
120
+ const learningsDest = path.join(claudeDir, 'dev-team-learnings.md');
121
+ if (!fileExists(learningsDest)) {
122
+ copyFile(learningsSrc, learningsDest);
123
+ }
124
+
125
+ // Step 7: Copy hooks
126
+ let hookCount = 0;
127
+
128
+ for (const hook of QUALITY_HOOKS) {
129
+ if (!selectedHooks.includes(hook.label)) continue;
130
+
131
+ const src = path.join(templates, 'hooks', hook.file);
132
+ const dest = path.join(hooksDir, hook.file);
133
+
134
+ if (fileExists(dest) && !isAll) {
135
+ const overwrite = await prompts.confirm(` ${hook.file} already exists. Overwrite?`, false);
136
+ if (!overwrite) continue;
137
+ }
138
+
139
+ copyFile(src, dest);
140
+ hookCount++;
141
+ }
142
+
143
+ // Step 8: Merge hook settings
144
+ const settingsTemplate = JSON.parse(readFile(path.join(templates, 'settings.json')));
145
+
146
+ // Filter settings to only include selected hooks
147
+ const filteredSettings = { hooks: {} };
148
+ const selectedHookFiles = QUALITY_HOOKS
149
+ .filter((h) => selectedHooks.includes(h.label))
150
+ .map((h) => h.file);
151
+
152
+ for (const [event, entries] of Object.entries(settingsTemplate.hooks)) {
153
+ const filteredEntries = entries.map((entry) => ({
154
+ ...entry,
155
+ hooks: (entry.hooks || []).filter((h) =>
156
+ selectedHookFiles.some((f) => h.command && h.command.includes(f))
157
+ ),
158
+ })).filter((entry) => entry.hooks.length > 0);
159
+
160
+ if (filteredEntries.length > 0) {
161
+ filteredSettings.hooks[event] = filteredEntries;
162
+ }
163
+ }
164
+
165
+ mergeSettings(settingsPath, filteredSettings);
166
+
167
+ // Step 9: Copy skills
168
+ const skillsSrcDir = path.join(templates, 'skills');
169
+ const skillDirs = ['dev-team-challenge', 'dev-team-task'];
170
+ for (const skillDir of skillDirs) {
171
+ const src = path.join(skillsSrcDir, skillDir, 'SKILL.md');
172
+ const dest = path.join(skillsDir, skillDir, 'SKILL.md');
173
+ if (!fileExists(dest) || isAll) {
174
+ copyFile(src, dest);
175
+ }
176
+ }
177
+
178
+ // Step 10: Merge CLAUDE.md
179
+ const claudeMdTemplate = readFile(path.join(templates, 'CLAUDE.md'));
180
+ const claudeResult = mergeClaudeMd(claudeMdPath, claudeMdTemplate);
181
+
182
+ // Save preferences
183
+ const prefs = {
184
+ version: '0.1.0',
185
+ agents: selectedAgents,
186
+ hooks: selectedHooks,
187
+ };
188
+ writeFile(prefsPath, JSON.stringify(prefs, null, 2) + '\n');
189
+
190
+ // Step 11: Print summary
191
+ console.log('\nDone! Installed:\n');
192
+ console.log(` Agents: ${selectedAgents.join(', ')} (${agentCount} files)`);
193
+ console.log(` Hooks: ${selectedHooks.join(', ')} (${hookCount} files)`);
194
+ console.log(` Skills: challenge, task`);
195
+ console.log(` Memory: ${selectedAgents.length} agent memories + shared learnings`);
196
+ console.log(` CLAUDE.md: ${claudeResult}`);
197
+ console.log(` Settings: ${settingsPath}`);
198
+ console.log('');
199
+ console.log('Next steps:');
200
+ console.log(' 1. Review installed agents in .claude/agents/');
201
+ console.log(' 2. Customize agent personas and focus areas to fit your project');
202
+ console.log(' 3. Run @dev-team-deming to scan for additional tooling recommendations');
203
+ console.log('');
204
+ }
205
+
206
+ module.exports = { run };
package/lib/prompts.js ADDED
@@ -0,0 +1,123 @@
1
+ 'use strict';
2
+
3
+ const readline = require('readline');
4
+
5
+ /**
6
+ * Creates a readline interface for a single question, then closes it.
7
+ */
8
+ function createInterface() {
9
+ return readline.createInterface({
10
+ input: process.stdin,
11
+ output: process.stdout,
12
+ });
13
+ }
14
+
15
+ /**
16
+ * Asks a yes/no question. Returns true for yes.
17
+ */
18
+ async function confirm(question, defaultYes = true) {
19
+ const rl = createInterface();
20
+ const hint = defaultYes ? '[Y/n]' : '[y/N]';
21
+
22
+ return new Promise((resolve) => {
23
+ rl.question(`${question} ${hint} `, (answer) => {
24
+ rl.close();
25
+ const trimmed = answer.trim().toLowerCase();
26
+ if (trimmed === '') {
27
+ resolve(defaultYes);
28
+ } else {
29
+ resolve(trimmed === 'y' || trimmed === 'yes');
30
+ }
31
+ });
32
+ });
33
+ }
34
+
35
+ /**
36
+ * Asks a checkbox-style question. Returns array of selected labels.
37
+ * Items: [{ label, description, defaultSelected }]
38
+ */
39
+ async function checkbox(question, items) {
40
+ const rl = createInterface();
41
+
42
+ console.log(`\n${question}`);
43
+ items.forEach((item, i) => {
44
+ const checked = item.defaultSelected ? 'x' : ' ';
45
+ console.log(` ${i + 1}. [${checked}] ${item.label} — ${item.description}`);
46
+ });
47
+
48
+ return new Promise((resolve) => {
49
+ rl.question('\nEnter numbers to toggle (e.g., 1 3 4), or press Enter for defaults: ', (answer) => {
50
+ rl.close();
51
+ const trimmed = answer.trim();
52
+
53
+ if (trimmed === '') {
54
+ // Use defaults
55
+ resolve(items.filter((item) => item.defaultSelected).map((item) => item.label));
56
+ return;
57
+ }
58
+
59
+ const toggled = new Set(
60
+ trimmed.split(/[\s,]+/).map(Number).filter((n) => n >= 1 && n <= items.length)
61
+ );
62
+
63
+ const selected = items
64
+ .filter((item, i) => {
65
+ const isDefault = item.defaultSelected;
66
+ const wasToggled = toggled.has(i + 1);
67
+ return isDefault ? !wasToggled : wasToggled;
68
+ })
69
+ .map((item) => item.label);
70
+
71
+ resolve(selected);
72
+ });
73
+ });
74
+ }
75
+
76
+ /**
77
+ * Asks a single-choice question. Returns the selected label.
78
+ * Options: [{ label, description }]
79
+ */
80
+ async function select(question, options) {
81
+ const rl = createInterface();
82
+
83
+ console.log(`\n${question}`);
84
+ options.forEach((opt, i) => {
85
+ console.log(` ${i + 1}. ${opt.label} — ${opt.description}`);
86
+ });
87
+
88
+ return new Promise((resolve) => {
89
+ rl.question('\nEnter number (default: 1): ', (answer) => {
90
+ rl.close();
91
+ const trimmed = answer.trim();
92
+
93
+ if (trimmed === '') {
94
+ resolve(options[0].label);
95
+ return;
96
+ }
97
+
98
+ const idx = Number(trimmed) - 1;
99
+ if (idx >= 0 && idx < options.length) {
100
+ resolve(options[idx].label);
101
+ } else {
102
+ resolve(options[0].label);
103
+ }
104
+ });
105
+ });
106
+ }
107
+
108
+ /**
109
+ * Asks for free-text input.
110
+ */
111
+ async function input(question, defaultValue = '') {
112
+ const rl = createInterface();
113
+ const hint = defaultValue ? ` [${defaultValue}]` : '';
114
+
115
+ return new Promise((resolve) => {
116
+ rl.question(`${question}${hint}: `, (answer) => {
117
+ rl.close();
118
+ resolve(answer.trim() || defaultValue);
119
+ });
120
+ });
121
+ }
122
+
123
+ module.exports = { confirm, checkbox, select, input };
package/package.json ADDED
@@ -0,0 +1,35 @@
1
+ {
2
+ "name": "@fredericboyer/dev-team",
3
+ "version": "0.1.0",
4
+ "description": "Adversarial AI agent team for any project — installs Claude Code agents, hooks, and skills that enforce quality through productive friction",
5
+ "bin": {
6
+ "dev-team": "./bin/dev-team.js"
7
+ },
8
+ "files": [
9
+ "bin/",
10
+ "lib/",
11
+ "templates/"
12
+ ],
13
+ "scripts": {
14
+ "test": "node --test tests/unit/files.test.js tests/integration/fresh-project.test.js tests/integration/idempotency.test.js",
15
+ "test:unit": "node --test tests/unit/files.test.js",
16
+ "test:integration": "node --test tests/integration/fresh-project.test.js tests/integration/idempotency.test.js",
17
+ "test:scenarios": "node --test tests/scenarios/",
18
+ "lint": "eslint bin/ lib/ templates/hooks/",
19
+ "format:check": "prettier --check .",
20
+ "validate:agents": "node scripts/validate-agents.js"
21
+ },
22
+ "keywords": [
23
+ "claude-code",
24
+ "ai-agents",
25
+ "developer-tools",
26
+ "code-review",
27
+ "tdd",
28
+ "security"
29
+ ],
30
+ "author": "",
31
+ "license": "MIT",
32
+ "engines": {
33
+ "node": ">=18.0.0"
34
+ }
35
+ }
@@ -0,0 +1,31 @@
1
+ <!-- dev-team:begin -->
2
+
3
+ ## Dev Team
4
+
5
+ This project uses [dev-team](https://github.com/dev-team) — adversarial AI agents that enforce quality through productive friction.
6
+
7
+ ### Agents
8
+
9
+ | Agent | Role | When to use |
10
+ |-------|------|-------------|
11
+ | `@dev-team-voss` | Backend Engineer | API design, data modeling, system architecture, error handling |
12
+ | `@dev-team-mori` | Frontend/UI Engineer | Components, accessibility, UX patterns, state management |
13
+ | `@dev-team-szabo` | Security Auditor | Vulnerability review, auth flows, attack surface analysis |
14
+ | `@dev-team-knuth` | Quality Auditor | Coverage gaps, boundary conditions, correctness verification |
15
+ | `@dev-team-beck` | Test Implementer | Writing tests, TDD cycles, translating audit findings into test cases |
16
+ | `@dev-team-deming` | Tooling Optimizer | Linters, formatters, CI/CD, hooks, onboarding, automation |
17
+
18
+ ### Workflow
19
+
20
+ For non-trivial work: explore the area first, then implement, then review.
21
+
22
+ Agents challenge each other using classified findings:
23
+ - `[DEFECT]` blocks progress. `[RISK]`, `[QUESTION]`, `[SUGGESTION]` are advisory.
24
+ - When agents disagree, they escalate to the human after one exchange each. Human decides.
25
+
26
+ ### Skills
27
+
28
+ - `/dev-team:challenge` — critically examine a proposal or implementation
29
+ - `/dev-team:task` — start an iterative task loop with adversarial review gates
30
+
31
+ <!-- dev-team:end -->
@@ -0,0 +1,12 @@
1
+ # Agent Memory: Beck (Test Implementer)
2
+ <!-- First 200 lines are loaded into agent context. Keep concise. -->
3
+
4
+ ## Test Patterns and Conventions
5
+
6
+
7
+ ## Framework and Runner Notes
8
+
9
+
10
+ ## Calibration Log
11
+ <!-- Challenges accepted/overruled — tunes adversarial intensity over time -->
12
+
@@ -0,0 +1,12 @@
1
+ # Agent Memory: Deming (Tooling & DX Optimizer)
2
+ <!-- First 200 lines are loaded into agent context. Keep concise. -->
3
+
4
+ ## Tooling Decisions
5
+
6
+
7
+ ## Hook Effectiveness
8
+
9
+
10
+ ## Calibration Log
11
+ <!-- Challenges accepted/overruled — tunes adversarial intensity over time -->
12
+
@@ -0,0 +1,12 @@
1
+ # Agent Memory: Knuth (Quality Auditor)
2
+ <!-- First 200 lines are loaded into agent context. Keep concise. -->
3
+
4
+ ## Coverage Gaps Identified
5
+
6
+
7
+ ## Recurring Boundary Conditions
8
+
9
+
10
+ ## Calibration Log
11
+ <!-- Challenges accepted/overruled — tunes adversarial intensity over time -->
12
+
@@ -0,0 +1,12 @@
1
+ # Agent Memory: Mori (Frontend/UI Engineer)
2
+ <!-- First 200 lines are loaded into agent context. Keep concise. -->
3
+
4
+ ## Project Conventions
5
+
6
+
7
+ ## Patterns to Watch For
8
+
9
+
10
+ ## Calibration Log
11
+ <!-- Challenges accepted/overruled — tunes adversarial intensity over time -->
12
+
@@ -0,0 +1,12 @@
1
+ # Agent Memory: Szabo (Security Auditor)
2
+ <!-- First 200 lines are loaded into agent context. Keep concise. -->
3
+
4
+ ## Trust Boundaries Mapped
5
+
6
+
7
+ ## Known Attack Surfaces
8
+
9
+
10
+ ## Calibration Log
11
+ <!-- Challenges accepted/overruled — tunes adversarial intensity over time -->
12
+
@@ -0,0 +1,12 @@
1
+ # Agent Memory: Voss (Backend Engineer)
2
+ <!-- First 200 lines are loaded into agent context. Keep concise. -->
3
+
4
+ ## Project Conventions
5
+
6
+
7
+ ## Patterns to Watch For
8
+
9
+
10
+ ## Calibration Log
11
+ <!-- Challenges accepted/overruled — tunes adversarial intensity over time -->
12
+