@cpretzinger/boss-claude 1.0.0 → 1.0.2
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 +304 -1
- package/bin/boss-claude.js +1138 -0
- package/bin/commands/mode.js +250 -0
- package/bin/onyx-guard.js +259 -0
- package/bin/onyx-guard.sh +251 -0
- package/bin/prompts.js +284 -0
- package/bin/rollback.js +85 -0
- package/bin/setup-wizard.js +492 -0
- package/config/.env.example +17 -0
- package/lib/README.md +83 -0
- package/lib/agent-logger.js +61 -0
- package/lib/agents/memory-engineers/github-memory-engineer.js +251 -0
- package/lib/agents/memory-engineers/postgres-memory-engineer.js +633 -0
- package/lib/agents/memory-engineers/qdrant-memory-engineer.js +358 -0
- package/lib/agents/memory-engineers/redis-memory-engineer.js +383 -0
- package/lib/agents/memory-supervisor.js +526 -0
- package/lib/agents/registry.js +135 -0
- package/lib/auto-monitor.js +131 -0
- package/lib/checkpoint-hook.js +112 -0
- package/lib/checkpoint.js +319 -0
- package/lib/commentator.js +213 -0
- package/lib/context-scribe.js +120 -0
- package/lib/delegation-strategies.js +326 -0
- package/lib/hierarchy-validator.js +643 -0
- package/lib/index.js +15 -0
- package/lib/init-with-mode.js +261 -0
- package/lib/init.js +44 -6
- package/lib/memory-result-aggregator.js +252 -0
- package/lib/memory.js +35 -7
- package/lib/mode-enforcer.js +473 -0
- package/lib/onyx-banner.js +169 -0
- package/lib/onyx-identity.js +214 -0
- package/lib/onyx-monitor.js +381 -0
- package/lib/onyx-reminder.js +188 -0
- package/lib/onyx-tool-interceptor.js +341 -0
- package/lib/onyx-wrapper.js +315 -0
- package/lib/orchestrator-gate.js +334 -0
- package/lib/output-formatter.js +296 -0
- package/lib/postgres.js +1 -1
- package/lib/prompt-injector.js +220 -0
- package/lib/prompts.js +532 -0
- package/lib/session.js +153 -6
- package/lib/setup/README.md +187 -0
- package/lib/setup/env-manager.js +785 -0
- package/lib/setup/error-recovery.js +630 -0
- package/lib/setup/explain-scopes.js +385 -0
- package/lib/setup/github-instructions.js +333 -0
- package/lib/setup/github-repo.js +254 -0
- package/lib/setup/import-credentials.js +498 -0
- package/lib/setup/index.js +62 -0
- package/lib/setup/init-postgres.js +785 -0
- package/lib/setup/init-redis.js +456 -0
- package/lib/setup/integration-test.js +652 -0
- package/lib/setup/progress.js +357 -0
- package/lib/setup/rollback.js +670 -0
- package/lib/setup/rollback.test.js +452 -0
- package/lib/setup/setup-with-rollback.example.js +351 -0
- package/lib/setup/summary.js +400 -0
- package/lib/setup/test-github-setup.js +10 -0
- package/lib/setup/test-postgres-init.js +98 -0
- package/lib/setup/verify-setup.js +102 -0
- package/lib/task-agent-worker.js +235 -0
- package/lib/token-monitor.js +466 -0
- package/lib/tool-wrapper-integration.js +369 -0
- package/lib/tool-wrapper.js +387 -0
- package/lib/validators/README.md +497 -0
- package/lib/validators/config.js +583 -0
- package/lib/validators/config.test.js +175 -0
- package/lib/validators/github.js +310 -0
- package/lib/validators/github.test.js +61 -0
- package/lib/validators/index.js +15 -0
- package/lib/validators/postgres.js +525 -0
- package/package.json +98 -13
- package/scripts/benchmark-memory.js +433 -0
- package/scripts/check-secrets.sh +12 -0
- package/scripts/fetch-todos.mjs +148 -0
- package/scripts/graceful-shutdown.sh +156 -0
- package/scripts/install-onyx-hooks.js +373 -0
- package/scripts/install.js +119 -18
- package/scripts/redis-monitor.js +284 -0
- package/scripts/redis-setup.js +412 -0
- package/scripts/test-memory-retrieval.js +201 -0
- package/scripts/validate-exports.js +68 -0
- package/scripts/validate-package.js +120 -0
- package/scripts/verify-onyx-deployment.js +309 -0
- package/scripts/verify-redis-deployment.js +354 -0
- package/scripts/verify-redis-init.js +219 -0
|
@@ -0,0 +1,643 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import inquirer from 'inquirer';
|
|
3
|
+
import { AGENT_HIERARCHY } from './agents/registry.js';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* HIERARCHY ENFORCEMENT GATE CHECK
|
|
7
|
+
*
|
|
8
|
+
* Problem: Boss Claude violated hierarchy twice by accepting direct worker reports
|
|
9
|
+
* without Boss-tier validation.
|
|
10
|
+
*
|
|
11
|
+
* Solution: Hard-code gate check that prompts "Which domain Boss validated this?"
|
|
12
|
+
* before accepting any worker agent results.
|
|
13
|
+
*
|
|
14
|
+
* Enforces: AGENT-HIERARCHY-CANON.md delegation rules
|
|
15
|
+
* - Worker → Boss Review → Meta-Boss Approval
|
|
16
|
+
* - Never Worker → Meta-Boss directly
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
export class HierarchyValidator {
|
|
20
|
+
constructor() {
|
|
21
|
+
this.violations = [];
|
|
22
|
+
this.validations = [];
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* GATE CHECK: Enforces hierarchy before Boss Claude accepts work
|
|
27
|
+
*
|
|
28
|
+
* @param {Object} workResult - Result from an agent
|
|
29
|
+
* @param {string} workResult.agent - Agent name who did the work
|
|
30
|
+
* @param {string} workResult.task - Task description
|
|
31
|
+
* @param {Object} workResult.output - Work output
|
|
32
|
+
* @param {number} workResult.tokensUsed - Tokens consumed
|
|
33
|
+
* @returns {Promise<Object>} Validation result with approval status
|
|
34
|
+
*/
|
|
35
|
+
async validateChain(workResult) {
|
|
36
|
+
const { agent, task, output, tokensUsed } = workResult;
|
|
37
|
+
|
|
38
|
+
// Check if this is a worker agent
|
|
39
|
+
const agentInfo = AGENT_HIERARCHY.workers[agent];
|
|
40
|
+
|
|
41
|
+
if (!agentInfo) {
|
|
42
|
+
// Not a worker agent - could be boss or meta-boss
|
|
43
|
+
return {
|
|
44
|
+
approved: true,
|
|
45
|
+
reason: 'Not a worker agent - hierarchy validation not required',
|
|
46
|
+
agent,
|
|
47
|
+
task
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
console.log(chalk.yellow('\n⚠️ HIERARCHY GATE CHECK TRIGGERED'));
|
|
52
|
+
console.log(chalk.dim('─'.repeat(80)));
|
|
53
|
+
console.log(chalk.white(`\nWorker Agent: ${chalk.bold(agent)}`));
|
|
54
|
+
console.log(chalk.white(`Task: ${chalk.dim(task)}`));
|
|
55
|
+
console.log(chalk.white(`Assigned Boss: ${chalk.cyan(agentInfo.boss)}`));
|
|
56
|
+
console.log(chalk.white(`Domain: ${chalk.green(agentInfo.domain)}`));
|
|
57
|
+
console.log(chalk.white(`Tokens Used: ${chalk.magenta(tokensUsed.toLocaleString())}`));
|
|
58
|
+
|
|
59
|
+
console.log(chalk.yellow('\n📋 HIERARCHY CANON REQUIREMENT:'));
|
|
60
|
+
console.log(chalk.dim(' Worker creates code → Boss reviews → Meta-Boss approves'));
|
|
61
|
+
console.log(chalk.red(' NEVER: Worker → Meta-Boss directly (skips boss review)'));
|
|
62
|
+
|
|
63
|
+
console.log(chalk.dim('\n─'.repeat(80)));
|
|
64
|
+
|
|
65
|
+
// HARD GATE: Ask Boss Claude which domain Boss validated this
|
|
66
|
+
const questions = [
|
|
67
|
+
{
|
|
68
|
+
type: 'list',
|
|
69
|
+
name: 'validationStatus',
|
|
70
|
+
message: chalk.bold('Which domain Boss validated this work?'),
|
|
71
|
+
choices: [
|
|
72
|
+
{
|
|
73
|
+
name: `✅ ${agentInfo.boss} reviewed and approved`,
|
|
74
|
+
value: 'boss_approved',
|
|
75
|
+
short: `${agentInfo.boss} approved`
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
name: `❌ No boss review yet (VIOLATION - must be reviewed first)`,
|
|
79
|
+
value: 'no_boss_review',
|
|
80
|
+
short: 'No review'
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
name: `🔄 Different boss reviewed this`,
|
|
84
|
+
value: 'different_boss',
|
|
85
|
+
short: 'Different boss'
|
|
86
|
+
}
|
|
87
|
+
],
|
|
88
|
+
default: 1 // Default to violation to force conscious choice
|
|
89
|
+
}
|
|
90
|
+
];
|
|
91
|
+
|
|
92
|
+
const answers = await inquirer.prompt(questions);
|
|
93
|
+
|
|
94
|
+
// Handle different validation scenarios
|
|
95
|
+
if (answers.validationStatus === 'boss_approved') {
|
|
96
|
+
// Require additional confirmation
|
|
97
|
+
const confirmQuestions = [
|
|
98
|
+
{
|
|
99
|
+
type: 'input',
|
|
100
|
+
name: 'reviewDetails',
|
|
101
|
+
message: chalk.cyan(`What security/quality issues did ${agentInfo.boss} check?`),
|
|
102
|
+
validate: (input) => {
|
|
103
|
+
if (input.length < 10) {
|
|
104
|
+
return 'Please provide specific review details (min 10 characters)';
|
|
105
|
+
}
|
|
106
|
+
return true;
|
|
107
|
+
}
|
|
108
|
+
},
|
|
109
|
+
{
|
|
110
|
+
type: 'confirm',
|
|
111
|
+
name: 'finalApproval',
|
|
112
|
+
message: chalk.green('Confirm: Boss review was thorough and complete?'),
|
|
113
|
+
default: false
|
|
114
|
+
}
|
|
115
|
+
];
|
|
116
|
+
|
|
117
|
+
const confirmation = await inquirer.prompt(confirmQuestions);
|
|
118
|
+
|
|
119
|
+
if (!confirmation.finalApproval) {
|
|
120
|
+
return this._recordViolation(agent, task, 'Boss review incomplete');
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// SUCCESS: Proper hierarchy followed
|
|
124
|
+
return this._recordValidation(agent, task, agentInfo.boss, confirmation.reviewDetails);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
if (answers.validationStatus === 'no_boss_review') {
|
|
128
|
+
// VIOLATION: Worker output submitted directly to Meta-Boss
|
|
129
|
+
console.log(chalk.red('\n🚨 HIERARCHY VIOLATION DETECTED'));
|
|
130
|
+
console.log(chalk.red(`Worker agent "${agent}" submitted work without Boss review`));
|
|
131
|
+
console.log(chalk.yellow('\n📚 CANONICAL PROTOCOL:'));
|
|
132
|
+
console.log(chalk.dim(` 1. ${agent} creates work`));
|
|
133
|
+
console.log(chalk.dim(` 2. ${agentInfo.boss} reviews for domain security`));
|
|
134
|
+
console.log(chalk.dim(` 3. Boss Claude (Meta-Boss) does final approval`));
|
|
135
|
+
console.log(chalk.red(`\n❌ You attempted to skip step 2`));
|
|
136
|
+
|
|
137
|
+
const remedyQuestions = [
|
|
138
|
+
{
|
|
139
|
+
type: 'list',
|
|
140
|
+
name: 'remedy',
|
|
141
|
+
message: 'How do you want to proceed?',
|
|
142
|
+
choices: [
|
|
143
|
+
{
|
|
144
|
+
name: `🔄 Send to ${agentInfo.boss} for review (RECOMMENDED)`,
|
|
145
|
+
value: 'send_to_boss',
|
|
146
|
+
short: 'Send to boss'
|
|
147
|
+
},
|
|
148
|
+
{
|
|
149
|
+
name: `⚠️ Override: I will review this myself (logs violation)`,
|
|
150
|
+
value: 'override',
|
|
151
|
+
short: 'Override'
|
|
152
|
+
},
|
|
153
|
+
{
|
|
154
|
+
name: `❌ Reject: Start over with proper delegation`,
|
|
155
|
+
value: 'reject',
|
|
156
|
+
short: 'Reject'
|
|
157
|
+
}
|
|
158
|
+
],
|
|
159
|
+
default: 0
|
|
160
|
+
}
|
|
161
|
+
];
|
|
162
|
+
|
|
163
|
+
const remedy = await inquirer.prompt(remedyQuestions);
|
|
164
|
+
|
|
165
|
+
if (remedy.remedy === 'send_to_boss') {
|
|
166
|
+
console.log(chalk.green(`\n✅ Delegating to ${agentInfo.boss} for review...`));
|
|
167
|
+
return {
|
|
168
|
+
approved: false,
|
|
169
|
+
action: 'delegate_to_boss',
|
|
170
|
+
boss: agentInfo.boss,
|
|
171
|
+
agent,
|
|
172
|
+
task,
|
|
173
|
+
reason: 'Proper hierarchy enforcement - sending to boss for review'
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
if (remedy.remedy === 'override') {
|
|
178
|
+
const overrideQuestions = [
|
|
179
|
+
{
|
|
180
|
+
type: 'input',
|
|
181
|
+
name: 'justification',
|
|
182
|
+
message: chalk.yellow('Provide justification for override (will be logged):'),
|
|
183
|
+
validate: (input) => input.length >= 20 || 'Justification must be at least 20 characters'
|
|
184
|
+
}
|
|
185
|
+
];
|
|
186
|
+
|
|
187
|
+
const override = await inquirer.prompt(overrideQuestions);
|
|
188
|
+
return this._recordViolation(agent, task, `Override: ${override.justification}`);
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
if (remedy.remedy === 'reject') {
|
|
192
|
+
console.log(chalk.red('\n❌ Work rejected - hierarchy violation'));
|
|
193
|
+
return {
|
|
194
|
+
approved: false,
|
|
195
|
+
action: 'reject',
|
|
196
|
+
agent,
|
|
197
|
+
task,
|
|
198
|
+
reason: 'Hierarchy violation - must follow canonical delegation protocol'
|
|
199
|
+
};
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
if (answers.validationStatus === 'different_boss') {
|
|
204
|
+
const bossQuestion = [
|
|
205
|
+
{
|
|
206
|
+
type: 'input',
|
|
207
|
+
name: 'actualBoss',
|
|
208
|
+
message: 'Which boss reviewed this?',
|
|
209
|
+
},
|
|
210
|
+
{
|
|
211
|
+
type: 'input',
|
|
212
|
+
name: 'reason',
|
|
213
|
+
message: `Why not ${agentInfo.boss} (the assigned boss)?`,
|
|
214
|
+
validate: (input) => input.length >= 10 || 'Please explain (min 10 characters)'
|
|
215
|
+
}
|
|
216
|
+
];
|
|
217
|
+
|
|
218
|
+
const bossInfo = await inquirer.prompt(bossQuestion);
|
|
219
|
+
|
|
220
|
+
console.log(chalk.yellow(`\n⚠️ Non-standard boss assignment detected`));
|
|
221
|
+
console.log(chalk.dim(`Expected: ${agentInfo.boss}`));
|
|
222
|
+
console.log(chalk.dim(`Actual: ${bossInfo.actualBoss}`));
|
|
223
|
+
console.log(chalk.dim(`Reason: ${bossInfo.reason}`));
|
|
224
|
+
|
|
225
|
+
return this._recordValidation(agent, task, bossInfo.actualBoss, bossInfo.reason, true);
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
/**
|
|
230
|
+
* CANON RULE: Repository Boundary Check
|
|
231
|
+
* Ensures agents ONLY write to current repository, never to other repos
|
|
232
|
+
*
|
|
233
|
+
* @param {string} filePath - File path to validate
|
|
234
|
+
* @param {string} currentRepo - Current repository root path
|
|
235
|
+
* @returns {Promise<Object>} Validation result with boundary status
|
|
236
|
+
*/
|
|
237
|
+
async checkRepoBoundary(filePath, currentRepo) {
|
|
238
|
+
// Normalize paths for comparison
|
|
239
|
+
const normalizedFilePath = filePath.replace(/^~/, process.env.HOME);
|
|
240
|
+
const normalizedRepo = currentRepo.replace(/^~/, process.env.HOME);
|
|
241
|
+
|
|
242
|
+
// Check if file is within current repo
|
|
243
|
+
const isWithinRepo = normalizedFilePath.startsWith(normalizedRepo);
|
|
244
|
+
|
|
245
|
+
if (!isWithinRepo) {
|
|
246
|
+
console.log(chalk.red('\n🚨 REPOSITORY BOUNDARY VIOLATION'));
|
|
247
|
+
console.log(chalk.dim('─'.repeat(80)));
|
|
248
|
+
console.log(chalk.white(`File Path: ${chalk.yellow(filePath)}`));
|
|
249
|
+
console.log(chalk.white(`Current Repo: ${chalk.cyan(currentRepo)}`));
|
|
250
|
+
console.log(chalk.red('\n❌ CANON RULE: Agents ONLY write in current repository'));
|
|
251
|
+
console.log(chalk.dim('Never write to other repositories'));
|
|
252
|
+
|
|
253
|
+
const questions = [
|
|
254
|
+
{
|
|
255
|
+
type: 'list',
|
|
256
|
+
name: 'action',
|
|
257
|
+
message: chalk.bold('Repository boundary violation detected. How to proceed?'),
|
|
258
|
+
choices: [
|
|
259
|
+
{
|
|
260
|
+
name: `❌ Reject write operation (RECOMMENDED)`,
|
|
261
|
+
value: 'reject',
|
|
262
|
+
short: 'Reject'
|
|
263
|
+
},
|
|
264
|
+
{
|
|
265
|
+
name: `⚠️ Override with justification (logs violation)`,
|
|
266
|
+
value: 'override',
|
|
267
|
+
short: 'Override'
|
|
268
|
+
}
|
|
269
|
+
],
|
|
270
|
+
default: 0
|
|
271
|
+
}
|
|
272
|
+
];
|
|
273
|
+
|
|
274
|
+
const answer = await inquirer.prompt(questions);
|
|
275
|
+
|
|
276
|
+
if (answer.action === 'reject') {
|
|
277
|
+
return {
|
|
278
|
+
allowed: false,
|
|
279
|
+
reason: 'Repository boundary violation - file outside current repo',
|
|
280
|
+
filePath,
|
|
281
|
+
currentRepo,
|
|
282
|
+
violation: true
|
|
283
|
+
};
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
// Override path - require justification
|
|
287
|
+
const justificationQuestion = [
|
|
288
|
+
{
|
|
289
|
+
type: 'input',
|
|
290
|
+
name: 'justification',
|
|
291
|
+
message: chalk.yellow('Provide justification for cross-repo write (will be logged):'),
|
|
292
|
+
validate: (input) => {
|
|
293
|
+
if (input.length < 30) {
|
|
294
|
+
return 'Justification must be at least 30 characters and explain why this is necessary';
|
|
295
|
+
}
|
|
296
|
+
return true;
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
];
|
|
300
|
+
|
|
301
|
+
const justification = await inquirer.prompt(justificationQuestion);
|
|
302
|
+
|
|
303
|
+
// Record violation
|
|
304
|
+
this.violations.push({
|
|
305
|
+
timestamp: new Date().toISOString(),
|
|
306
|
+
type: 'repository_boundary',
|
|
307
|
+
filePath,
|
|
308
|
+
currentRepo,
|
|
309
|
+
justification: justification.justification,
|
|
310
|
+
severity: 'high'
|
|
311
|
+
});
|
|
312
|
+
|
|
313
|
+
console.log(chalk.yellow('\n⚠️ Cross-repo write override logged'));
|
|
314
|
+
console.log(chalk.dim(`Justification: ${justification.justification}`));
|
|
315
|
+
|
|
316
|
+
return {
|
|
317
|
+
allowed: true,
|
|
318
|
+
override: true,
|
|
319
|
+
reason: `Override: ${justification.justification}`,
|
|
320
|
+
filePath,
|
|
321
|
+
currentRepo,
|
|
322
|
+
violation: true
|
|
323
|
+
};
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
// File is within current repo - allowed
|
|
327
|
+
return {
|
|
328
|
+
allowed: true,
|
|
329
|
+
reason: 'File within current repository boundary',
|
|
330
|
+
filePath,
|
|
331
|
+
currentRepo,
|
|
332
|
+
violation: false
|
|
333
|
+
};
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
/**
|
|
337
|
+
* Quick gate check for interactive prompts during task execution
|
|
338
|
+
* Returns true if hierarchy is being followed, false if violation detected
|
|
339
|
+
*/
|
|
340
|
+
async quickCheck(agentName) {
|
|
341
|
+
const agentInfo = AGENT_HIERARCHY.workers[agentName];
|
|
342
|
+
|
|
343
|
+
if (!agentInfo) {
|
|
344
|
+
return { valid: true, reason: 'Not a worker agent' };
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
console.log(chalk.yellow(`\n🔍 Quick Hierarchy Check: ${agentName}`));
|
|
348
|
+
|
|
349
|
+
const answer = await inquirer.prompt([
|
|
350
|
+
{
|
|
351
|
+
type: 'confirm',
|
|
352
|
+
name: 'hasBossReview',
|
|
353
|
+
message: `Has ${chalk.cyan(agentInfo.boss)} reviewed this work?`,
|
|
354
|
+
default: false
|
|
355
|
+
}
|
|
356
|
+
]);
|
|
357
|
+
|
|
358
|
+
if (!answer.hasBossReview) {
|
|
359
|
+
console.log(chalk.red(`❌ Work from ${agentName} must be reviewed by ${agentInfo.boss} first`));
|
|
360
|
+
return {
|
|
361
|
+
valid: false,
|
|
362
|
+
reason: `Missing ${agentInfo.boss} review`,
|
|
363
|
+
requiredBoss: agentInfo.boss,
|
|
364
|
+
agent: agentName
|
|
365
|
+
};
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
return { valid: true, boss: agentInfo.boss };
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
/**
|
|
372
|
+
* Pre-task delegation check (enforces Rule #1: 10,000 Token Rule)
|
|
373
|
+
*/
|
|
374
|
+
async checkDelegation(task, estimatedTokens, currentAgent = 'Boss Claude') {
|
|
375
|
+
if (estimatedTokens < 10000) {
|
|
376
|
+
// Under threshold - no delegation check needed
|
|
377
|
+
return { shouldDelegate: false, reason: 'Under 10k token threshold' };
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
console.log(chalk.blue('\n📊 DELEGATION ANALYSIS (Rule #1: 10,000 Token Rule)'));
|
|
381
|
+
console.log(chalk.dim('─'.repeat(80)));
|
|
382
|
+
console.log(chalk.white(`Task: ${task}`));
|
|
383
|
+
console.log(chalk.white(`Estimated Tokens: ${chalk.magenta(estimatedTokens.toLocaleString())}`));
|
|
384
|
+
console.log(chalk.white(`Current Agent: ${chalk.cyan(currentAgent)}`));
|
|
385
|
+
|
|
386
|
+
// Find best specialist
|
|
387
|
+
const specialist = this._findBestSpecialist(task);
|
|
388
|
+
|
|
389
|
+
if (specialist) {
|
|
390
|
+
const savings = Math.floor((1 - (specialist.estimatedTokens / estimatedTokens)) * 100);
|
|
391
|
+
|
|
392
|
+
console.log(chalk.green(`\n✅ Specialist Found: ${specialist.agent}`));
|
|
393
|
+
console.log(chalk.white(`Domain: ${specialist.domain}`));
|
|
394
|
+
console.log(chalk.white(`Estimated Tokens: ${chalk.magenta(specialist.estimatedTokens.toLocaleString())}`));
|
|
395
|
+
console.log(chalk.white(`Savings: ${chalk.green(savings + '%')}`));
|
|
396
|
+
|
|
397
|
+
const answer = await inquirer.prompt([
|
|
398
|
+
{
|
|
399
|
+
type: 'list',
|
|
400
|
+
name: 'decision',
|
|
401
|
+
message: 'Delegation recommended. What would you like to do?',
|
|
402
|
+
choices: [
|
|
403
|
+
{
|
|
404
|
+
name: `✅ Delegate to ${specialist.agent} (RECOMMENDED - saves ${savings}%)`,
|
|
405
|
+
value: 'delegate',
|
|
406
|
+
short: 'Delegate'
|
|
407
|
+
},
|
|
408
|
+
{
|
|
409
|
+
name: `⚠️ Override: I'll do it myself (requires justification)`,
|
|
410
|
+
value: 'override',
|
|
411
|
+
short: 'Override'
|
|
412
|
+
}
|
|
413
|
+
],
|
|
414
|
+
default: 0
|
|
415
|
+
}
|
|
416
|
+
]);
|
|
417
|
+
|
|
418
|
+
if (answer.decision === 'delegate') {
|
|
419
|
+
console.log(chalk.green(`\n✅ Delegating to ${specialist.agent}...`));
|
|
420
|
+
return {
|
|
421
|
+
shouldDelegate: true,
|
|
422
|
+
agent: specialist.agent,
|
|
423
|
+
estimatedSavings: savings,
|
|
424
|
+
reason: `Specialist can complete in ${specialist.estimatedTokens} tokens vs ${estimatedTokens}`
|
|
425
|
+
};
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
// Override path
|
|
429
|
+
const justification = await inquirer.prompt([
|
|
430
|
+
{
|
|
431
|
+
type: 'input',
|
|
432
|
+
name: 'reason',
|
|
433
|
+
message: chalk.yellow('Why override delegation? (will be logged):'),
|
|
434
|
+
validate: (input) => input.length >= 20 || 'Justification required (min 20 chars)'
|
|
435
|
+
}
|
|
436
|
+
]);
|
|
437
|
+
|
|
438
|
+
console.log(chalk.yellow('\n⚠️ Delegation override logged'));
|
|
439
|
+
|
|
440
|
+
return {
|
|
441
|
+
shouldDelegate: false,
|
|
442
|
+
override: true,
|
|
443
|
+
specialist: specialist.agent,
|
|
444
|
+
wastedTokens: estimatedTokens - specialist.estimatedTokens,
|
|
445
|
+
justification: justification.reason,
|
|
446
|
+
reason: 'User override with justification'
|
|
447
|
+
};
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
return { shouldDelegate: false, reason: 'No specialist found for this task' };
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
/**
|
|
454
|
+
* Find the best specialist for a task based on domain keywords
|
|
455
|
+
*/
|
|
456
|
+
_findBestSpecialist(task) {
|
|
457
|
+
const taskLower = task.toLowerCase();
|
|
458
|
+
|
|
459
|
+
// Domain keyword matching
|
|
460
|
+
const domainMatches = {
|
|
461
|
+
'n8n': ['n8n', 'workflow', 'automation', 'webhook'],
|
|
462
|
+
'postgres': ['postgres', 'database', 'sql', 'query', 'schema'],
|
|
463
|
+
'redis': ['redis', 'cache', 'memory', 'key-value'],
|
|
464
|
+
'github': ['github', 'git', 'repository', 'pull request', 'commit'],
|
|
465
|
+
'openai': ['openai', 'gpt', 'embedding', 'completion', 'streaming']
|
|
466
|
+
};
|
|
467
|
+
|
|
468
|
+
for (const [domain, keywords] of Object.entries(domainMatches)) {
|
|
469
|
+
if (keywords.some(kw => taskLower.includes(kw))) {
|
|
470
|
+
// Find worker agent for this domain
|
|
471
|
+
const worker = Object.entries(AGENT_HIERARCHY.workers).find(
|
|
472
|
+
([name, info]) => info.domain === domain
|
|
473
|
+
);
|
|
474
|
+
|
|
475
|
+
if (worker) {
|
|
476
|
+
return {
|
|
477
|
+
agent: worker[0],
|
|
478
|
+
domain,
|
|
479
|
+
estimatedTokens: Math.floor(Math.random() * 5000) + 3000, // 3k-8k estimate
|
|
480
|
+
reason: `Specialist in ${domain}`
|
|
481
|
+
};
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
return null;
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
/**
|
|
490
|
+
* Record successful validation
|
|
491
|
+
*/
|
|
492
|
+
_recordValidation(agent, task, boss, reviewDetails, nonStandard = false) {
|
|
493
|
+
const validation = {
|
|
494
|
+
timestamp: new Date().toISOString(),
|
|
495
|
+
agent,
|
|
496
|
+
task,
|
|
497
|
+
boss,
|
|
498
|
+
reviewDetails,
|
|
499
|
+
nonStandard,
|
|
500
|
+
approved: true
|
|
501
|
+
};
|
|
502
|
+
|
|
503
|
+
this.validations.push(validation);
|
|
504
|
+
|
|
505
|
+
console.log(chalk.green('\n✅ HIERARCHY VALIDATION PASSED'));
|
|
506
|
+
console.log(chalk.dim(`Worker: ${agent}`));
|
|
507
|
+
console.log(chalk.dim(`Boss Review: ${boss}`));
|
|
508
|
+
console.log(chalk.dim(`Details: ${reviewDetails}`));
|
|
509
|
+
|
|
510
|
+
if (nonStandard) {
|
|
511
|
+
console.log(chalk.yellow('⚠️ Non-standard boss assignment logged'));
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
return {
|
|
515
|
+
approved: true,
|
|
516
|
+
agent,
|
|
517
|
+
boss,
|
|
518
|
+
task,
|
|
519
|
+
reviewDetails,
|
|
520
|
+
nonStandard,
|
|
521
|
+
validation
|
|
522
|
+
};
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
/**
|
|
526
|
+
* Record hierarchy violation
|
|
527
|
+
*/
|
|
528
|
+
_recordViolation(agent, task, reason) {
|
|
529
|
+
const violation = {
|
|
530
|
+
timestamp: new Date().toISOString(),
|
|
531
|
+
agent,
|
|
532
|
+
task,
|
|
533
|
+
reason,
|
|
534
|
+
approved: false,
|
|
535
|
+
override: true
|
|
536
|
+
};
|
|
537
|
+
|
|
538
|
+
this.violations.push(violation);
|
|
539
|
+
|
|
540
|
+
console.log(chalk.red('\n🚨 HIERARCHY VIOLATION RECORDED'));
|
|
541
|
+
console.log(chalk.dim(`Agent: ${agent}`));
|
|
542
|
+
console.log(chalk.dim(`Task: ${task}`));
|
|
543
|
+
console.log(chalk.dim(`Reason: ${reason}`));
|
|
544
|
+
console.log(chalk.yellow('\n⚠️ This violation will be logged for quarterly review'));
|
|
545
|
+
|
|
546
|
+
return {
|
|
547
|
+
approved: true, // Override allowed but logged
|
|
548
|
+
override: true,
|
|
549
|
+
agent,
|
|
550
|
+
task,
|
|
551
|
+
reason,
|
|
552
|
+
violation
|
|
553
|
+
};
|
|
554
|
+
}
|
|
555
|
+
|
|
556
|
+
/**
|
|
557
|
+
* Get violation report for quarterly review
|
|
558
|
+
*/
|
|
559
|
+
getViolationReport() {
|
|
560
|
+
return {
|
|
561
|
+
totalViolations: this.violations.length,
|
|
562
|
+
totalValidations: this.validations.length,
|
|
563
|
+
complianceRate: this.validations.length / (this.violations.length + this.validations.length) * 100,
|
|
564
|
+
violations: this.violations,
|
|
565
|
+
validations: this.validations,
|
|
566
|
+
mostViolatedAgents: this._getMostViolatedAgents()
|
|
567
|
+
};
|
|
568
|
+
}
|
|
569
|
+
|
|
570
|
+
_getMostViolatedAgents() {
|
|
571
|
+
const agentCounts = {};
|
|
572
|
+
|
|
573
|
+
this.violations.forEach(v => {
|
|
574
|
+
agentCounts[v.agent] = (agentCounts[v.agent] || 0) + 1;
|
|
575
|
+
});
|
|
576
|
+
|
|
577
|
+
return Object.entries(agentCounts)
|
|
578
|
+
.sort((a, b) => b[1] - a[1])
|
|
579
|
+
.map(([agent, count]) => ({ agent, violations: count }));
|
|
580
|
+
}
|
|
581
|
+
}
|
|
582
|
+
|
|
583
|
+
// Singleton instance
|
|
584
|
+
const validator = new HierarchyValidator();
|
|
585
|
+
|
|
586
|
+
export default validator;
|
|
587
|
+
|
|
588
|
+
/**
|
|
589
|
+
* USAGE EXAMPLES:
|
|
590
|
+
*
|
|
591
|
+
* 1. Validate worker result before acceptance:
|
|
592
|
+
*
|
|
593
|
+
* const result = await workerAgent.execute(task);
|
|
594
|
+
* const validation = await hierarchyValidator.validateChain({
|
|
595
|
+
* agent: 'n8n-workflow-architect',
|
|
596
|
+
* task: 'Create webhook processor',
|
|
597
|
+
* output: result.code,
|
|
598
|
+
* tokensUsed: result.tokens
|
|
599
|
+
* });
|
|
600
|
+
*
|
|
601
|
+
* if (validation.approved) {
|
|
602
|
+
* // Proceed with meta-boss review
|
|
603
|
+
* } else if (validation.action === 'delegate_to_boss') {
|
|
604
|
+
* // Send to domain boss for review
|
|
605
|
+
* }
|
|
606
|
+
*
|
|
607
|
+
* 2. Pre-task delegation check:
|
|
608
|
+
*
|
|
609
|
+
* const delegation = await hierarchyValidator.checkDelegation(
|
|
610
|
+
* 'Write comprehensive documentation',
|
|
611
|
+
* 57000,
|
|
612
|
+
* 'Boss Claude'
|
|
613
|
+
* );
|
|
614
|
+
*
|
|
615
|
+
* if (delegation.shouldDelegate) {
|
|
616
|
+
* // Delegate to specialist
|
|
617
|
+
* }
|
|
618
|
+
*
|
|
619
|
+
* 3. Quick check during execution:
|
|
620
|
+
*
|
|
621
|
+
* const check = await hierarchyValidator.quickCheck('postgres-n8n-specialist');
|
|
622
|
+
* if (!check.valid) {
|
|
623
|
+
* console.error('Missing boss review:', check.reason);
|
|
624
|
+
* }
|
|
625
|
+
*
|
|
626
|
+
* 4. Repository boundary check (CANON RULE):
|
|
627
|
+
*
|
|
628
|
+
* const boundaryCheck = await hierarchyValidator.checkRepoBoundary(
|
|
629
|
+
* '/Users/user/other-project/file.js',
|
|
630
|
+
* '/Users/user/current-project'
|
|
631
|
+
* );
|
|
632
|
+
*
|
|
633
|
+
* if (!boundaryCheck.allowed) {
|
|
634
|
+
* console.error('Cannot write outside current repo');
|
|
635
|
+
* return;
|
|
636
|
+
* }
|
|
637
|
+
*
|
|
638
|
+
* 5. Quarterly violation report:
|
|
639
|
+
*
|
|
640
|
+
* const report = hierarchyValidator.getViolationReport();
|
|
641
|
+
* console.log(`Compliance Rate: ${report.complianceRate.toFixed(1)}%`);
|
|
642
|
+
* console.log(`Violations: ${report.totalViolations}`);
|
|
643
|
+
*/
|
package/lib/index.js
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Boss Claude Library
|
|
3
|
+
*
|
|
4
|
+
* Main entry point for Boss Claude modules
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
export * from './identity.js';
|
|
8
|
+
export * from './session.js';
|
|
9
|
+
export * from './memory.js';
|
|
10
|
+
export * from './postgres.js';
|
|
11
|
+
export * from './validators/index.js';
|
|
12
|
+
|
|
13
|
+
export { default as validators } from './validators/index.js';
|
|
14
|
+
export { default as tokenMonitor } from './token-monitor.js';
|
|
15
|
+
export { default as hierarchyValidator } from './hierarchy-validator.js';
|