atabey 0.0.14 → 0.0.16
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 +672 -21
- package/PRIVACY.md +8 -14
- package/README.md +183 -25
- package/bin/cli.js +72 -5
- package/dist/framework-mcp/src/index.js +145 -13
- package/dist/framework-mcp/src/index.js.map +1 -1
- package/dist/framework-mcp/src/tools/control_plane/registry.d.ts +1 -1
- package/dist/framework-mcp/src/tools/control_plane/registry.js +52 -4
- package/dist/framework-mcp/src/tools/control_plane/registry.js.map +1 -1
- package/dist/framework-mcp/src/tools/definitions.js +1 -1
- package/dist/framework-mcp/src/tools/file_system/read_file.js +5 -0
- package/dist/framework-mcp/src/tools/file_system/read_file.js.map +1 -1
- package/dist/framework-mcp/src/tools/messaging/approve_operation.d.ts +10 -8
- package/dist/framework-mcp/src/tools/messaging/approve_operation.js +12 -12
- package/dist/framework-mcp/src/tools/messaging/approve_operation.js.map +1 -1
- package/dist/framework-mcp/src/tools/messaging/ask_human.d.ts +8 -8
- package/dist/framework-mcp/src/tools/messaging/ask_human.js +8 -8
- package/dist/framework-mcp/src/tools/messaging/send_message.js +19 -3
- package/dist/framework-mcp/src/tools/messaging/send_message.js.map +1 -1
- package/dist/framework-mcp/src/tools/observability/check_ports.d.ts +1 -0
- package/dist/framework-mcp/src/tools/observability/check_ports.js +21 -7
- package/dist/framework-mcp/src/tools/observability/check_ports.js.map +1 -1
- package/dist/framework-mcp/src/tools/schemas.d.ts +4 -4
- package/dist/framework-mcp/src/tools/search/grep_search.js +11 -4
- package/dist/framework-mcp/src/tools/search/grep_search.js.map +1 -1
- package/dist/framework-mcp/src/tools/search/list_dir.js +3 -0
- package/dist/framework-mcp/src/tools/search/list_dir.js.map +1 -1
- package/dist/framework-mcp/src/tools/shell/run_command.js +185 -93
- package/dist/framework-mcp/src/tools/shell/run_command.js.map +1 -1
- package/dist/framework-mcp/src/utils/auth.d.ts +26 -2
- package/dist/framework-mcp/src/utils/auth.js +74 -7
- package/dist/framework-mcp/src/utils/auth.js.map +1 -1
- package/dist/framework-mcp/src/utils/compliance.js +45 -13
- package/dist/framework-mcp/src/utils/compliance.js.map +1 -1
- package/dist/framework-mcp/src/utils/discipline.d.ts +1 -0
- package/dist/framework-mcp/src/utils/discipline.js +42 -3
- package/dist/framework-mcp/src/utils/discipline.js.map +1 -1
- package/dist/framework-mcp/src/utils/human-in-loop.d.ts +35 -2
- package/dist/framework-mcp/src/utils/human-in-loop.js +114 -10
- package/dist/framework-mcp/src/utils/human-in-loop.js.map +1 -1
- package/dist/framework-mcp/src/utils/loop-detector.js +3 -3
- package/dist/framework-mcp/src/utils/loop-detector.js.map +1 -1
- package/dist/framework-mcp/src/utils/permissions.d.ts +67 -3
- package/dist/framework-mcp/src/utils/permissions.js +179 -43
- package/dist/framework-mcp/src/utils/permissions.js.map +1 -1
- package/dist/framework-mcp/src/utils/prompt-injection.d.ts +20 -0
- package/dist/framework-mcp/src/utils/prompt-injection.js +64 -0
- package/dist/framework-mcp/src/utils/prompt-injection.js.map +1 -0
- package/dist/framework-mcp/src/utils/quality.js +4 -3
- package/dist/framework-mcp/src/utils/quality.js.map +1 -1
- package/dist/framework-mcp/src/utils/silent-router.d.ts +4 -2
- package/dist/framework-mcp/src/utils/silent-router.js +35 -9
- package/dist/framework-mcp/src/utils/silent-router.js.map +1 -1
- package/dist/framework-mcp/tests/tools/file_system/permissions.test.js +174 -71
- package/dist/framework-mcp/tests/tools/file_system/permissions.test.js.map +1 -1
- package/dist/framework-mcp/tests/tools/messaging/send_message.test.js +36 -30
- package/dist/framework-mcp/tests/tools/messaging/send_message.test.js.map +1 -1
- package/dist/framework-mcp/tests/tools/observability/check_ports.test.js +26 -12
- package/dist/framework-mcp/tests/tools/observability/check_ports.test.js.map +1 -1
- package/dist/framework-mcp/tests/tools/shell/run_command.test.js +38 -15
- package/dist/framework-mcp/tests/tools/shell/run_command.test.js.map +1 -1
- package/dist/framework-mcp/tests/utils/human-in-loop.test.js +152 -4
- package/dist/framework-mcp/tests/utils/human-in-loop.test.js.map +1 -1
- package/dist/framework-mcp/tests/utils/loop-detector.test.js +0 -2
- package/dist/framework-mcp/tests/utils/loop-detector.test.js.map +1 -1
- package/dist/framework-mcp/tests/utils/prompt-injection.test.d.ts +1 -0
- package/dist/framework-mcp/tests/utils/prompt-injection.test.js +43 -0
- package/dist/framework-mcp/tests/utils/prompt-injection.test.js.map +1 -0
- package/dist/src/cli/commands/dashboard.js +167 -2
- package/dist/src/cli/commands/dashboard.js.map +1 -1
- package/dist/src/cli/commands/init/scaffold-standards.js +1 -1
- package/dist/src/cli/commands/init/scaffold-standards.js.map +1 -1
- package/dist/src/cli/commands/init.js +14 -7
- package/dist/src/cli/commands/init.js.map +1 -1
- package/dist/src/cli/commands/log.js +8 -5
- package/dist/src/cli/commands/log.js.map +1 -1
- package/dist/src/cli/commands/mcp.js +3 -1
- package/dist/src/cli/commands/mcp.js.map +1 -1
- package/dist/src/cli/commands/orchestrate.d.ts +4 -4
- package/dist/src/cli/commands/orchestrate.js +14 -2
- package/dist/src/cli/commands/orchestrate.js.map +1 -1
- package/dist/src/cli/commands/script.js +8 -1
- package/dist/src/cli/commands/script.js.map +1 -1
- package/dist/src/cli/commands/status.js +21 -1
- package/dist/src/cli/commands/status.js.map +1 -1
- package/dist/src/cli/utils/memory.js +6 -5
- package/dist/src/cli/utils/memory.js.map +1 -1
- package/dist/src/cli/utils/schemas.d.ts +2 -2
- package/dist/src/contracts/tasks.d.ts +4 -4
- package/dist/src/modules/contracts/api.d.ts +6 -6
- package/dist/src/modules/engines/agent-executor.js +41 -20
- package/dist/src/modules/engines/agent-executor.js.map +1 -1
- package/dist/src/modules/engines/agent-loop.d.ts +5 -5
- package/dist/src/modules/engines/agent-loop.js +5 -5
- package/dist/src/modules/engines/evaluation-engine.d.ts +9 -2
- package/dist/src/modules/engines/evaluation-engine.js +77 -9
- package/dist/src/modules/engines/evaluation-engine.js.map +1 -1
- package/dist/src/modules/engines/quality-gate.js +4 -2
- package/dist/src/modules/engines/quality-gate.js.map +1 -1
- package/dist/src/modules/engines/risk-engine.d.ts +17 -1
- package/dist/src/modules/engines/risk-engine.js +98 -3
- package/dist/src/modules/engines/risk-engine.js.map +1 -1
- package/dist/src/modules/engines/routing-engine.d.ts +26 -1
- package/dist/src/modules/engines/routing-engine.js +97 -1
- package/dist/src/modules/engines/routing-engine.js.map +1 -1
- package/dist/src/modules/providers/shared.js +2 -3
- package/dist/src/modules/providers/shared.js.map +1 -1
- package/dist/src/shared/pii.js +1 -1
- package/dist/src/shared/pii.js.map +1 -1
- package/dist/src/shared/storage.d.ts +60 -0
- package/dist/src/shared/storage.js +77 -3
- package/dist/src/shared/storage.js.map +1 -1
- package/dist/tests/cli/commands/dashboard-coverage.test.js +3 -1
- package/dist/tests/cli/commands/dashboard-coverage.test.js.map +1 -1
- package/dist/tests/modules/engines/agent-executor.test.js +1 -1
- package/dist/tests/modules/engines/agent-executor.test.js.map +1 -1
- package/dist/tests/modules/engines/evaluation-engine.test.js +2 -2
- package/dist/tests/modules/engines/evaluation-engine.test.js.map +1 -1
- package/dist/tests/status-cost.test.js +2 -0
- package/dist/tests/status-cost.test.js.map +1 -1
- package/dist/tests/storage-operations.test.js +31 -4
- package/dist/tests/storage-operations.test.js.map +1 -1
- package/dist/vitest.config.js +6 -4
- package/dist/vitest.config.js.map +1 -1
- package/framework-mcp/README.md +18 -32
- package/framework-mcp/dist/dashboard/assets/index-B-Eu7_J9.js +1260 -0
- package/framework-mcp/dist/dashboard/index.html +1 -1
- package/framework-mcp/dist/framework-mcp/src/index.js +145 -13
- package/framework-mcp/dist/framework-mcp/src/tools/control_plane/registry.js +52 -4
- package/framework-mcp/dist/framework-mcp/src/tools/definitions.js +1 -1
- package/framework-mcp/dist/framework-mcp/src/tools/file_system/read_file.js +5 -0
- package/framework-mcp/dist/framework-mcp/src/tools/messaging/approve_operation.js +12 -12
- package/framework-mcp/dist/framework-mcp/src/tools/messaging/ask_human.js +8 -8
- package/framework-mcp/dist/framework-mcp/src/tools/messaging/send_message.js +19 -3
- package/framework-mcp/dist/framework-mcp/src/tools/observability/check_ports.js +21 -7
- package/framework-mcp/dist/framework-mcp/src/tools/search/grep_search.js +11 -4
- package/framework-mcp/dist/framework-mcp/src/tools/search/list_dir.js +3 -0
- package/framework-mcp/dist/framework-mcp/src/tools/shell/run_command.js +185 -93
- package/framework-mcp/dist/framework-mcp/src/utils/auth.js +74 -7
- package/framework-mcp/dist/framework-mcp/src/utils/compliance.js +45 -13
- package/framework-mcp/dist/framework-mcp/src/utils/discipline.js +42 -3
- package/framework-mcp/dist/framework-mcp/src/utils/human-in-loop.js +114 -10
- package/framework-mcp/dist/framework-mcp/src/utils/loop-detector.js +3 -3
- package/framework-mcp/dist/framework-mcp/src/utils/permissions.js +179 -43
- package/framework-mcp/dist/framework-mcp/src/utils/prompt-injection.js +63 -0
- package/framework-mcp/dist/framework-mcp/src/utils/quality.js +4 -3
- package/framework-mcp/dist/framework-mcp/src/utils/silent-router.js +35 -9
- package/framework-mcp/dist/src/cli/utils/memory.js +6 -5
- package/framework-mcp/dist/src/modules/engines/evaluation-engine.js +170 -0
- package/framework-mcp/dist/src/modules/engines/quality-gate.js +4 -2
- package/framework-mcp/dist/src/modules/engines/risk-engine.js +98 -3
- package/framework-mcp/dist/src/modules/engines/routing-engine.js +97 -1
- package/framework-mcp/dist/src/modules/providers/shared.js +2 -3
- package/framework-mcp/dist/src/shared/pii.js +1 -1
- package/framework-mcp/dist/src/shared/storage.js +77 -3
- package/framework-mcp/package.json +21 -18
- package/mcp.json +3 -2
- package/package.json +4 -5
- package/framework-mcp/dist/dashboard/assets/index-B2mYld0c.js +0 -1221
|
@@ -9,10 +9,11 @@
|
|
|
9
9
|
*
|
|
10
10
|
* Features:
|
|
11
11
|
* - Auto-agent detection from tool call context
|
|
12
|
-
* - Silent system prompt injection
|
|
12
|
+
* - Silent system prompt injection with specialty memory
|
|
13
13
|
* - Multi-agent chain support
|
|
14
14
|
* - Stealth notifications (stderr/dashboard only, never chat)
|
|
15
15
|
*/
|
|
16
|
+
import { EvaluationEngine } from "../../../src/modules/engines/evaluation-engine.js";
|
|
16
17
|
import { RoutingEngine } from "../../../src/modules/engines/routing-engine.js";
|
|
17
18
|
// ─── Configuration ────────────────────────────────────────────────
|
|
18
19
|
const CONFIG = {
|
|
@@ -22,6 +23,8 @@ const CONFIG = {
|
|
|
22
23
|
STEALTH_NOTIFY: process.env.MCP_SILENT_STEALTH !== "false",
|
|
23
24
|
/** Agent override via env (for testing/debugging) */
|
|
24
25
|
FORCE_AGENT: process.env.MCP_FORCE_AGENT || null,
|
|
26
|
+
/** Enable specialty memory injection into context */
|
|
27
|
+
INJECT_SPECIALTY_MEMORY: process.env.MCP_INJECT_SPECIALTY_MEMORY !== "false",
|
|
25
28
|
};
|
|
26
29
|
let agentRuleCache = null;
|
|
27
30
|
async function loadAgentRules() {
|
|
@@ -40,7 +43,6 @@ async function loadAgentRules() {
|
|
|
40
43
|
}
|
|
41
44
|
}
|
|
42
45
|
catch {
|
|
43
|
-
// Fallback: use discipline rules file
|
|
44
46
|
agentRuleCache = new Map();
|
|
45
47
|
}
|
|
46
48
|
return agentRuleCache;
|
|
@@ -52,9 +54,8 @@ async function loadAgentRules() {
|
|
|
52
54
|
export function detectAgent(toolName, args) {
|
|
53
55
|
if (CONFIG.FORCE_AGENT)
|
|
54
56
|
return CONFIG.FORCE_AGENT;
|
|
55
|
-
// Build context from args for routing
|
|
56
57
|
const contextParts = [toolName];
|
|
57
|
-
for (const [
|
|
58
|
+
for (const [, value] of Object.entries(args)) {
|
|
58
59
|
if (typeof value === "string") {
|
|
59
60
|
contextParts.push(value);
|
|
60
61
|
}
|
|
@@ -63,7 +64,6 @@ export function detectAgent(toolName, args) {
|
|
|
63
64
|
}
|
|
64
65
|
}
|
|
65
66
|
const context = contextParts.join(" ").substring(0, 500);
|
|
66
|
-
// Use RoutingEngine to detect the best agent
|
|
67
67
|
return RoutingEngine.resolveAgent(context);
|
|
68
68
|
}
|
|
69
69
|
/**
|
|
@@ -88,9 +88,32 @@ export async function getAgentPrompt(agentName) {
|
|
|
88
88
|
"> They supplement (not replace) your existing instructions.",
|
|
89
89
|
].join("\n");
|
|
90
90
|
}
|
|
91
|
+
/**
|
|
92
|
+
* Load specialty memory for an agent and format it for injection.
|
|
93
|
+
*/
|
|
94
|
+
function getSpecialtyMemoryContext(agentName) {
|
|
95
|
+
if (!CONFIG.INJECT_SPECIALTY_MEMORY)
|
|
96
|
+
return null;
|
|
97
|
+
try {
|
|
98
|
+
const conventions = EvaluationEngine.readLearnedConventions(agentName);
|
|
99
|
+
if (!conventions)
|
|
100
|
+
return null;
|
|
101
|
+
return [
|
|
102
|
+
"",
|
|
103
|
+
"### Previously Learned Conventions",
|
|
104
|
+
`The following lessons were learned from past tasks for @${agentName}:`,
|
|
105
|
+
"",
|
|
106
|
+
conventions,
|
|
107
|
+
"",
|
|
108
|
+
].join("\n");
|
|
109
|
+
}
|
|
110
|
+
catch {
|
|
111
|
+
return null;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
91
114
|
/**
|
|
92
115
|
* Build a silent context injection payload.
|
|
93
|
-
*
|
|
116
|
+
* Injects agent rules + specialty memory into tool responses.
|
|
94
117
|
*/
|
|
95
118
|
export async function buildSilentContext(detectedAgent, toolName, responseText) {
|
|
96
119
|
if (!CONFIG.ENABLED)
|
|
@@ -98,14 +121,17 @@ export async function buildSilentContext(detectedAgent, toolName, responseText)
|
|
|
98
121
|
const agentPrompt = await getAgentPrompt(detectedAgent);
|
|
99
122
|
if (!agentPrompt)
|
|
100
123
|
return responseText;
|
|
101
|
-
// Only inject if the response is substantial enough to warrant governance
|
|
102
124
|
if (responseText.length < 50)
|
|
103
125
|
return responseText;
|
|
104
|
-
// Inject
|
|
126
|
+
// Inject specialty memory if available
|
|
127
|
+
const specialtyContext = getSpecialtyMemoryContext(detectedAgent);
|
|
128
|
+
const fullPrompt = specialtyContext
|
|
129
|
+
? `${agentPrompt}\n${specialtyContext}`
|
|
130
|
+
: agentPrompt;
|
|
105
131
|
const injection = [
|
|
106
132
|
"",
|
|
107
133
|
`<!-- ATABEY_GOVERNANCE agent="${detectedAgent}" tool="${toolName}" -->`,
|
|
108
|
-
`${
|
|
134
|
+
`${fullPrompt}`,
|
|
109
135
|
"<!-- /ATABEY_GOVERNANCE -->",
|
|
110
136
|
"",
|
|
111
137
|
].join("\n");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"silent-router.js","sourceRoot":"","sources":["../../../../framework-mcp/src/utils/silent-router.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,gDAAgD,CAAC;AAE/E,qEAAqE;AAErE,MAAM,MAAM,GAAG;IACX,4CAA4C;IAC5C,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,kBAAkB,KAAK,OAAO;IACnD,6CAA6C;IAC7C,cAAc,EAAE,OAAO,CAAC,GAAG,CAAC,kBAAkB,KAAK,OAAO;IAC1D,qDAAqD;IACrD,WAAW,EAAE,OAAO,CAAC,GAAG,CAAC,eAAe,IAAI,IAAI;
|
|
1
|
+
{"version":3,"file":"silent-router.js","sourceRoot":"","sources":["../../../../framework-mcp/src/utils/silent-router.ts"],"names":[],"mappings":"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"}
|
|
@@ -2,91 +2,194 @@ import { describe, expect, it, beforeEach, afterEach } from "vitest";
|
|
|
2
2
|
import fs from "fs";
|
|
3
3
|
import path from "path";
|
|
4
4
|
import os from "os";
|
|
5
|
-
import { verifyWritePermission } from "../../../src/utils/permissions.js";
|
|
6
|
-
|
|
5
|
+
import { verifyWritePermission, verifyReadPermission, verifyMessagingPermission } from "../../../src/utils/permissions.js";
|
|
6
|
+
/**
|
|
7
|
+
* Permissions Matrix + RBAC test suite
|
|
8
|
+
*
|
|
9
|
+
* Tests cover:
|
|
10
|
+
* 1. Write permission enforcement (file-system matrix)
|
|
11
|
+
* 2. Read permission enforcement (read-side matrix)
|
|
12
|
+
* 3. AgentTier messaging RBAC (core → recon delegation block)
|
|
13
|
+
* 4. Recon write default-deny
|
|
14
|
+
* 5. Supreme tier omni-access
|
|
15
|
+
* 6. ATABEY_ACTIVE_AGENT env var resolution
|
|
16
|
+
*/
|
|
17
|
+
describe("Permissions Matrix + AgentTier RBAC", () => {
|
|
7
18
|
let tempDir;
|
|
8
19
|
let frameworkDir;
|
|
20
|
+
// Helper: write status.json with the given agent in EXECUTING state
|
|
21
|
+
function setExecutingAgent(agentName) {
|
|
22
|
+
const key = agentName.replace("@", "");
|
|
23
|
+
const status = {
|
|
24
|
+
[key]: { state: "EXECUTING", task: "test", lastUpdated: new Date().toISOString() }
|
|
25
|
+
};
|
|
26
|
+
fs.writeFileSync(path.join(frameworkDir, "memory", "status.json"), JSON.stringify(status, null, 2));
|
|
27
|
+
}
|
|
28
|
+
// Helper: write permission-matrix.json
|
|
29
|
+
function setMatrix(matrix) {
|
|
30
|
+
fs.writeFileSync(path.join(frameworkDir, "permission-matrix.json"), JSON.stringify(matrix, null, 2));
|
|
31
|
+
}
|
|
32
|
+
// Helper: set ATABEY_ACTIVE_AGENT env and clean up
|
|
33
|
+
function withEnvAgent(agent, fn) {
|
|
34
|
+
const prev = process.env.ATABEY_ACTIVE_AGENT;
|
|
35
|
+
process.env.ATABEY_ACTIVE_AGENT = agent;
|
|
36
|
+
try {
|
|
37
|
+
fn();
|
|
38
|
+
}
|
|
39
|
+
finally {
|
|
40
|
+
if (prev === undefined)
|
|
41
|
+
delete process.env.ATABEY_ACTIVE_AGENT;
|
|
42
|
+
else
|
|
43
|
+
process.env.ATABEY_ACTIVE_AGENT = prev;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
9
46
|
beforeEach(() => {
|
|
47
|
+
// Ensure env agent is cleared before each test
|
|
48
|
+
delete process.env.ATABEY_ACTIVE_AGENT;
|
|
10
49
|
tempDir = fs.mkdtempSync(path.join(os.tmpdir(), "atabey-perm-test-"));
|
|
11
50
|
frameworkDir = path.join(tempDir, ".atabey");
|
|
12
51
|
fs.mkdirSync(frameworkDir, { recursive: true });
|
|
13
52
|
fs.mkdirSync(path.join(frameworkDir, "memory"), { recursive: true });
|
|
14
53
|
});
|
|
15
54
|
afterEach(() => {
|
|
55
|
+
delete process.env.ATABEY_ACTIVE_AGENT;
|
|
16
56
|
fs.rmSync(tempDir, { recursive: true, force: true });
|
|
17
57
|
});
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
58
|
+
// ─── Write Permission ────────────────────────────────────────────────────
|
|
59
|
+
describe("verifyWritePermission", () => {
|
|
60
|
+
it("should allow write if no permission-matrix.json exists", () => {
|
|
61
|
+
expect(() => verifyWritePermission(tempDir, "apps/web/index.ts")).not.toThrow();
|
|
62
|
+
});
|
|
63
|
+
it("should enforce write matrix restrictions for the active executing agent", () => {
|
|
64
|
+
setMatrix({
|
|
65
|
+
"@frontend": { write: ["apps/web/**"] },
|
|
66
|
+
"@backend": { write: ["apps/backend/**"] }
|
|
67
|
+
});
|
|
68
|
+
setExecutingAgent("@frontend");
|
|
69
|
+
// ALLOW: @frontend writes within apps/web/**
|
|
70
|
+
expect(() => verifyWritePermission(tempDir, "apps/web/components/Button.tsx")).not.toThrow();
|
|
71
|
+
// DENY: @frontend writes to apps/backend/**
|
|
72
|
+
expect(() => verifyWritePermission(tempDir, "apps/backend/routes/api.ts")).toThrow(/Permission Denied/);
|
|
73
|
+
});
|
|
74
|
+
it("should allow write if the executing agent has no restrictions defined in matrix", () => {
|
|
75
|
+
setMatrix({ "@frontend": { write: ["apps/web/**"] } });
|
|
76
|
+
setExecutingAgent("@backend");
|
|
77
|
+
// @backend has no matrix entry → default-allow
|
|
78
|
+
expect(() => verifyWritePermission(tempDir, "apps/backend/schema.ts")).not.toThrow();
|
|
79
|
+
});
|
|
80
|
+
it("should default to allow if no agent is currently in EXECUTING state", () => {
|
|
81
|
+
setMatrix({ "@frontend": { write: ["apps/web/**"] } });
|
|
82
|
+
const status = { "frontend": { state: "READY", task: "Idle" } };
|
|
83
|
+
fs.writeFileSync(path.join(frameworkDir, "memory", "status.json"), JSON.stringify(status));
|
|
84
|
+
expect(() => verifyWritePermission(tempDir, "apps/backend/schema.ts")).not.toThrow();
|
|
85
|
+
});
|
|
86
|
+
it("ATABEY_ACTIVE_AGENT env var takes priority over status.json", () => {
|
|
87
|
+
setMatrix({ "@frontend": { write: ["apps/web/**"] } });
|
|
88
|
+
// status.json says backend is executing
|
|
89
|
+
setExecutingAgent("@backend");
|
|
90
|
+
// But env var says frontend
|
|
91
|
+
withEnvAgent("@frontend", () => {
|
|
92
|
+
// Should apply @frontend rules → deny backend write
|
|
93
|
+
expect(() => verifyWritePermission(tempDir, "apps/backend/schema.ts")).toThrow(/Permission Denied/);
|
|
94
|
+
});
|
|
95
|
+
});
|
|
22
96
|
});
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
"
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
"@
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
};
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
})
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
97
|
+
// ─── Read Permission ─────────────────────────────────────────────────────
|
|
98
|
+
describe("verifyReadPermission", () => {
|
|
99
|
+
it("should allow read if no permission-matrix.json exists", () => {
|
|
100
|
+
expect(() => verifyReadPermission(tempDir, "apps/backend/secret.ts")).not.toThrow();
|
|
101
|
+
});
|
|
102
|
+
it("should allow read if agent has no read rules in matrix (default-allow)", () => {
|
|
103
|
+
setMatrix({ "@frontend": { write: ["apps/web/**"] } }); // no read field
|
|
104
|
+
setExecutingAgent("@frontend");
|
|
105
|
+
expect(() => verifyReadPermission(tempDir, "apps/backend/secret.ts")).not.toThrow();
|
|
106
|
+
});
|
|
107
|
+
it("should enforce read matrix when read rules are defined", () => {
|
|
108
|
+
setMatrix({
|
|
109
|
+
"@frontend": {
|
|
110
|
+
write: ["apps/web/**"],
|
|
111
|
+
read: ["apps/web/**", "docs/**"]
|
|
112
|
+
}
|
|
113
|
+
});
|
|
114
|
+
setExecutingAgent("@frontend");
|
|
115
|
+
// ALLOW: reads within allowed read paths
|
|
116
|
+
expect(() => verifyReadPermission(tempDir, "apps/web/index.ts")).not.toThrow();
|
|
117
|
+
expect(() => verifyReadPermission(tempDir, "docs/README.md")).not.toThrow();
|
|
118
|
+
// DENY: reads outside allowed read paths
|
|
119
|
+
expect(() => verifyReadPermission(tempDir, "apps/backend/config.ts")).toThrow(/Permission Denied/);
|
|
120
|
+
});
|
|
121
|
+
it("should allow read even with no agent in EXECUTING state", () => {
|
|
122
|
+
setMatrix({ "@frontend": { write: ["apps/web/**"], read: ["apps/web/**"] } });
|
|
123
|
+
// No status.json → no active agent → default-allow
|
|
124
|
+
expect(() => verifyReadPermission(tempDir, "apps/backend/secret.ts")).not.toThrow();
|
|
125
|
+
});
|
|
51
126
|
});
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
"@frontend": {
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
"
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
}
|
|
66
|
-
};
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
127
|
+
// ─── Recon Tier Write Default-Deny ──────────────────────────────────────
|
|
128
|
+
describe("Recon tier — write default-deny", () => {
|
|
129
|
+
it("recon agent (@explorer) cannot write when no matrix entry exists", () => {
|
|
130
|
+
setMatrix({ "@frontend": { write: ["apps/web/**"] } }); // no @explorer entry
|
|
131
|
+
withEnvAgent("@explorer", () => {
|
|
132
|
+
expect(() => verifyWritePermission(tempDir, "apps/web/index.ts")).toThrow(/Permission Denied.*recon/i);
|
|
133
|
+
});
|
|
134
|
+
});
|
|
135
|
+
it("recon agent (@git) can write if explicitly allowed in matrix", () => {
|
|
136
|
+
setMatrix({ "@git": { write: ["docs/**"] } });
|
|
137
|
+
withEnvAgent("@git", () => {
|
|
138
|
+
expect(() => verifyWritePermission(tempDir, "docs/CHANGELOG.md")).not.toThrow();
|
|
139
|
+
expect(() => verifyWritePermission(tempDir, "apps/backend/api.ts")).toThrow(/Permission Denied/);
|
|
140
|
+
});
|
|
141
|
+
});
|
|
142
|
+
it("recon agent can always read (default-allow for reads)", () => {
|
|
143
|
+
setMatrix({ "@frontend": { write: ["apps/web/**"] } }); // no @explorer entry
|
|
144
|
+
withEnvAgent("@explorer", () => {
|
|
145
|
+
expect(() => verifyReadPermission(tempDir, "apps/backend/secret.ts")).not.toThrow();
|
|
146
|
+
});
|
|
147
|
+
});
|
|
71
148
|
});
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
149
|
+
// ─── Supreme Tier Omni-Access ────────────────────────────────────────────
|
|
150
|
+
describe("Supreme tier — omni-access", () => {
|
|
151
|
+
it("@manager (supreme) can write anywhere regardless of matrix", () => {
|
|
152
|
+
setMatrix({ "@manager": { write: ["docs/**"] } }); // restrictive matrix for manager
|
|
153
|
+
withEnvAgent("@manager", () => {
|
|
154
|
+
// Even with a restrictive matrix, supreme bypasses it
|
|
155
|
+
expect(() => verifyWritePermission(tempDir, "apps/backend/database.ts")).not.toThrow();
|
|
156
|
+
});
|
|
157
|
+
});
|
|
158
|
+
it("@security (supreme) can read anywhere regardless of matrix", () => {
|
|
159
|
+
setMatrix({ "@security": { read: ["docs/**"] } });
|
|
160
|
+
withEnvAgent("@security", () => {
|
|
161
|
+
expect(() => verifyReadPermission(tempDir, "apps/backend/auth/secrets.ts")).not.toThrow();
|
|
162
|
+
});
|
|
163
|
+
});
|
|
164
|
+
});
|
|
165
|
+
// ─── AgentTier Messaging RBAC ────────────────────────────────────────────
|
|
166
|
+
describe("verifyMessagingPermission — AgentTier hierarchy", () => {
|
|
167
|
+
it("core → core messaging is allowed", () => {
|
|
168
|
+
expect(() => verifyMessagingPermission("@frontend", "@backend")).not.toThrow();
|
|
169
|
+
});
|
|
170
|
+
it("recon → core messaging is allowed (escalation up)", () => {
|
|
171
|
+
expect(() => verifyMessagingPermission("@explorer", "@backend")).not.toThrow();
|
|
172
|
+
});
|
|
173
|
+
it("supreme → any messaging is allowed", () => {
|
|
174
|
+
expect(() => verifyMessagingPermission("@manager", "@explorer")).not.toThrow();
|
|
175
|
+
expect(() => verifyMessagingPermission("@security", "@git")).not.toThrow();
|
|
176
|
+
});
|
|
177
|
+
it("core → recon messaging is BLOCKED (prevents quality-gate bypass)", () => {
|
|
178
|
+
expect(() => verifyMessagingPermission("@frontend", "@explorer"))
|
|
179
|
+
.toThrow(/RBAC.*Messaging violation.*tier: core.*tier: recon/i);
|
|
180
|
+
});
|
|
181
|
+
it("core → recon: @backend cannot delegate to @git", () => {
|
|
182
|
+
expect(() => verifyMessagingPermission("@backend", "@git"))
|
|
183
|
+
.toThrow(/RBAC.*Messaging violation/i);
|
|
184
|
+
});
|
|
185
|
+
it("core → recon: @quality cannot delegate to @analyst", () => {
|
|
186
|
+
expect(() => verifyMessagingPermission("@quality", "@analyst"))
|
|
187
|
+
.toThrow(/RBAC.*Messaging violation/i);
|
|
188
|
+
});
|
|
189
|
+
it("any → supreme messaging is allowed (escalation always permitted)", () => {
|
|
190
|
+
expect(() => verifyMessagingPermission("@explorer", "@manager")).not.toThrow();
|
|
191
|
+
expect(() => verifyMessagingPermission("@git", "@security")).not.toThrow();
|
|
192
|
+
});
|
|
90
193
|
});
|
|
91
194
|
});
|
|
92
195
|
//# sourceMappingURL=permissions.test.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"permissions.test.js","sourceRoot":"","sources":["../../../../../framework-mcp/tests/tools/file_system/permissions.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AACrE,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,EAAE,qBAAqB,EAAE,MAAM,mCAAmC,CAAC;
|
|
1
|
+
{"version":3,"file":"permissions.test.js","sourceRoot":"","sources":["../../../../../framework-mcp/tests/tools/file_system/permissions.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,26 +1,32 @@
|
|
|
1
1
|
import fs from "fs";
|
|
2
2
|
import path from "path";
|
|
3
|
+
import os from "os";
|
|
3
4
|
import { afterEach, beforeEach, describe, expect, it } from "vitest";
|
|
4
5
|
import { handleSendAgentMessage } from "../../../src/tools/messaging/send_message.js";
|
|
5
6
|
import { asAgentID, asTraceID } from "../../../src/utils/types.js";
|
|
6
|
-
const TEST_DIR = path.resolve(__dirname, "../../_temp_messaging_tests");
|
|
7
|
-
const MESSAGES_DIR = path.join(TEST_DIR, ".gemini/messages");
|
|
8
|
-
const BACKEND_LOCK_FILE = path.join(MESSAGES_DIR, "backend.lock");
|
|
9
|
-
beforeEach(() => {
|
|
10
|
-
fs.mkdirSync(TEST_DIR, { recursive: true });
|
|
11
|
-
// Write a dummy package.json to test directory to lock frameworkDir as .gemini
|
|
12
|
-
const dummyPkg = {
|
|
13
|
-
name: "test-pkg",
|
|
14
|
-
atabey: {
|
|
15
|
-
frameworkDir: ".gemini"
|
|
16
|
-
}
|
|
17
|
-
};
|
|
18
|
-
fs.writeFileSync(path.join(TEST_DIR, "package.json"), JSON.stringify(dummyPkg, null, 2), "utf8");
|
|
19
|
-
});
|
|
20
|
-
afterEach(() => {
|
|
21
|
-
fs.rmSync(TEST_DIR, { recursive: true, force: true });
|
|
22
|
-
});
|
|
23
7
|
describe("Hermes Lock Protocol & Message sending", () => {
|
|
8
|
+
let testDir;
|
|
9
|
+
let messagesDir;
|
|
10
|
+
let backendLockFile;
|
|
11
|
+
beforeEach(() => {
|
|
12
|
+
testDir = fs.mkdtempSync(path.join(os.tmpdir(), "atabey-messaging-tests-"));
|
|
13
|
+
messagesDir = path.join(testDir, ".gemini/messages");
|
|
14
|
+
backendLockFile = path.join(messagesDir, "backend.lock");
|
|
15
|
+
// Write a dummy package.json to test directory to lock frameworkDir as .gemini
|
|
16
|
+
const dummyPkg = {
|
|
17
|
+
name: "test-pkg",
|
|
18
|
+
atabey: {
|
|
19
|
+
frameworkDir: ".gemini"
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
fs.writeFileSync(path.join(testDir, "package.json"), JSON.stringify(dummyPkg, null, 2), "utf8");
|
|
23
|
+
});
|
|
24
|
+
afterEach(() => {
|
|
25
|
+
try {
|
|
26
|
+
fs.rmSync(testDir, { recursive: true, force: true });
|
|
27
|
+
}
|
|
28
|
+
catch { /* ignore */ }
|
|
29
|
+
});
|
|
24
30
|
it("should successfully send message when lock is not present", async () => {
|
|
25
31
|
const args = {
|
|
26
32
|
to: asAgentID("@backend"),
|
|
@@ -31,10 +37,10 @@ describe("Hermes Lock Protocol & Message sending", () => {
|
|
|
31
37
|
priority: "HIGH",
|
|
32
38
|
requiresApproval: false,
|
|
33
39
|
};
|
|
34
|
-
const result = await handleSendAgentMessage(
|
|
40
|
+
const result = await handleSendAgentMessage(testDir, args);
|
|
35
41
|
expect(result.content[0].text).toContain("[OK] Message sent to @backend");
|
|
36
42
|
// Verify the message file contains the sent message
|
|
37
|
-
const messageFilePath = path.join(
|
|
43
|
+
const messageFilePath = path.join(messagesDir, "backend.json");
|
|
38
44
|
expect(fs.existsSync(messageFilePath)).toBe(true);
|
|
39
45
|
const content = fs.readFileSync(messageFilePath, "utf8");
|
|
40
46
|
const msg = JSON.parse(content.trim());
|
|
@@ -48,8 +54,8 @@ describe("Hermes Lock Protocol & Message sending", () => {
|
|
|
48
54
|
});
|
|
49
55
|
it("should retry and fail to send message if lock is kept busy", async () => {
|
|
50
56
|
// Prepare a busy lock file
|
|
51
|
-
fs.mkdirSync(
|
|
52
|
-
fs.writeFileSync(
|
|
57
|
+
fs.mkdirSync(messagesDir, { recursive: true });
|
|
58
|
+
fs.writeFileSync(backendLockFile, "Locked by @test at " + new Date().toISOString(), "utf8");
|
|
53
59
|
const args = {
|
|
54
60
|
to: asAgentID("@backend"),
|
|
55
61
|
from: asAgentID("@manager"),
|
|
@@ -60,7 +66,7 @@ describe("Hermes Lock Protocol & Message sending", () => {
|
|
|
60
66
|
requiresApproval: false,
|
|
61
67
|
};
|
|
62
68
|
const startTime = Date.now();
|
|
63
|
-
const result = await handleSendAgentMessage(
|
|
69
|
+
const result = await handleSendAgentMessage(testDir, args);
|
|
64
70
|
const duration = Date.now() - startTime;
|
|
65
71
|
expect(result.isError).toBe(true);
|
|
66
72
|
expect(result.content[0].text).toContain("[ERROR] Could not send message to @backend: Hermes lock is busy.");
|
|
@@ -68,11 +74,11 @@ describe("Hermes Lock Protocol & Message sending", () => {
|
|
|
68
74
|
expect(duration).toBeGreaterThanOrEqual(9000);
|
|
69
75
|
}, 15000);
|
|
70
76
|
it("should bypass and acquire lock if existing lock is stale (older than 10s)", async () => {
|
|
71
|
-
fs.mkdirSync(
|
|
77
|
+
fs.mkdirSync(messagesDir, { recursive: true });
|
|
72
78
|
// Set lock file mtime to 15 seconds ago
|
|
73
|
-
fs.writeFileSync(
|
|
79
|
+
fs.writeFileSync(backendLockFile, "Locked by @test at " + new Date().toISOString(), "utf8");
|
|
74
80
|
const fifteenSecondsAgo = new Date(Date.now() - 15000);
|
|
75
|
-
fs.utimesSync(
|
|
81
|
+
fs.utimesSync(backendLockFile, fifteenSecondsAgo, fifteenSecondsAgo);
|
|
76
82
|
const args = {
|
|
77
83
|
to: asAgentID("@backend"),
|
|
78
84
|
from: asAgentID("@manager"),
|
|
@@ -82,12 +88,12 @@ describe("Hermes Lock Protocol & Message sending", () => {
|
|
|
82
88
|
priority: "NORMAL",
|
|
83
89
|
requiresApproval: false,
|
|
84
90
|
};
|
|
85
|
-
const result = await handleSendAgentMessage(
|
|
91
|
+
const result = await handleSendAgentMessage(testDir, args);
|
|
86
92
|
expect(result.content[0].text).toContain("[OK] Message sent to @backend");
|
|
87
|
-
expect(fs.existsSync(
|
|
93
|
+
expect(fs.existsSync(backendLockFile)).toBe(false); // Lock should have been unlinked in finally
|
|
88
94
|
});
|
|
89
95
|
it("should safely resolve concurrent messages and execute them in sequence", async () => {
|
|
90
|
-
const send1Promise = handleSendAgentMessage(
|
|
96
|
+
const send1Promise = handleSendAgentMessage(testDir, {
|
|
91
97
|
to: asAgentID("@backend"),
|
|
92
98
|
from: asAgentID("@manager"),
|
|
93
99
|
category: "ACTION",
|
|
@@ -98,7 +104,7 @@ describe("Hermes Lock Protocol & Message sending", () => {
|
|
|
98
104
|
});
|
|
99
105
|
// Delay starting the second call slightly to make sure lock is acquired by Job 1 first
|
|
100
106
|
await new Promise((resolve) => setTimeout(resolve, 50));
|
|
101
|
-
const send2Promise = handleSendAgentMessage(
|
|
107
|
+
const send2Promise = handleSendAgentMessage(testDir, {
|
|
102
108
|
to: asAgentID("@backend"),
|
|
103
109
|
from: asAgentID("@frontend"),
|
|
104
110
|
category: "ACTION",
|
|
@@ -113,7 +119,7 @@ describe("Hermes Lock Protocol & Message sending", () => {
|
|
|
113
119
|
expect(res1.content[0].text).toContain("[OK] Message sent to @backend");
|
|
114
120
|
expect(res2.content[0].text).toContain("[OK] Message sent to @backend");
|
|
115
121
|
// Verify both messages exist in order in the message log file
|
|
116
|
-
const messageFilePath = path.join(
|
|
122
|
+
const messageFilePath = path.join(messagesDir, "backend.json");
|
|
117
123
|
const lines = fs.readFileSync(messageFilePath, "utf8").trim().split("\n");
|
|
118
124
|
expect(lines.length).toBe(2);
|
|
119
125
|
const msg1 = JSON.parse(lines[0]);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"send_message.test.js","sourceRoot":"","sources":["../../../../../framework-mcp/tests/tools/messaging/send_message.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AACrE,OAAO,EAAE,sBAAsB,EAAE,MAAM,8CAA8C,CAAC;AAEtF,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,6BAA6B,CAAC;AAEnE,
|
|
1
|
+
{"version":3,"file":"send_message.test.js","sourceRoot":"","sources":["../../../../../framework-mcp/tests/tools/messaging/send_message.test.ts"],"names":[],"mappings":"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"}
|