@det-acp/core 0.2.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 +21 -0
- package/README.md +492 -0
- package/dist/cli/index.d.ts +15 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +308 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/init.d.ts +32 -0
- package/dist/cli/init.d.ts.map +1 -0
- package/dist/cli/init.js +234 -0
- package/dist/cli/init.js.map +1 -0
- package/dist/cli/templates.d.ts +27 -0
- package/dist/cli/templates.d.ts.map +1 -0
- package/dist/cli/templates.js +266 -0
- package/dist/cli/templates.js.map +1 -0
- package/dist/engine/action-registry.d.ts +49 -0
- package/dist/engine/action-registry.d.ts.map +1 -0
- package/dist/engine/action-registry.js +95 -0
- package/dist/engine/action-registry.js.map +1 -0
- package/dist/engine/gate.d.ts +57 -0
- package/dist/engine/gate.d.ts.map +1 -0
- package/dist/engine/gate.js +145 -0
- package/dist/engine/gate.js.map +1 -0
- package/dist/engine/runtime.d.ts +98 -0
- package/dist/engine/runtime.d.ts.map +1 -0
- package/dist/engine/runtime.js +138 -0
- package/dist/engine/runtime.js.map +1 -0
- package/dist/engine/session.d.ts +74 -0
- package/dist/engine/session.d.ts.map +1 -0
- package/dist/engine/session.js +343 -0
- package/dist/engine/session.js.map +1 -0
- package/dist/index.d.ts +48 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +56 -0
- package/dist/index.js.map +1 -0
- package/dist/ledger/ledger.d.ts +58 -0
- package/dist/ledger/ledger.d.ts.map +1 -0
- package/dist/ledger/ledger.js +188 -0
- package/dist/ledger/ledger.js.map +1 -0
- package/dist/ledger/query.d.ts +29 -0
- package/dist/ledger/query.d.ts.map +1 -0
- package/dist/ledger/query.js +61 -0
- package/dist/ledger/query.js.map +1 -0
- package/dist/ledger/types.d.ts +27 -0
- package/dist/ledger/types.d.ts.map +1 -0
- package/dist/ledger/types.js +5 -0
- package/dist/ledger/types.js.map +1 -0
- package/dist/policy/evaluator.d.ts +21 -0
- package/dist/policy/evaluator.d.ts.map +1 -0
- package/dist/policy/evaluator.js +383 -0
- package/dist/policy/evaluator.js.map +1 -0
- package/dist/policy/loader.d.ts +27 -0
- package/dist/policy/loader.d.ts.map +1 -0
- package/dist/policy/loader.js +69 -0
- package/dist/policy/loader.js.map +1 -0
- package/dist/policy/schema.d.ts +168 -0
- package/dist/policy/schema.d.ts.map +1 -0
- package/dist/policy/schema.js +107 -0
- package/dist/policy/schema.js.map +1 -0
- package/dist/proxy/mcp-proxy.d.ts +43 -0
- package/dist/proxy/mcp-proxy.d.ts.map +1 -0
- package/dist/proxy/mcp-proxy.js +240 -0
- package/dist/proxy/mcp-proxy.js.map +1 -0
- package/dist/proxy/mcp-types.d.ts +79 -0
- package/dist/proxy/mcp-types.d.ts.map +1 -0
- package/dist/proxy/mcp-types.js +28 -0
- package/dist/proxy/mcp-types.js.map +1 -0
- package/dist/proxy/shell-proxy.d.ts +52 -0
- package/dist/proxy/shell-proxy.d.ts.map +1 -0
- package/dist/proxy/shell-proxy.js +92 -0
- package/dist/proxy/shell-proxy.js.map +1 -0
- package/dist/rollback/manager.d.ts +62 -0
- package/dist/rollback/manager.d.ts.map +1 -0
- package/dist/rollback/manager.js +151 -0
- package/dist/rollback/manager.js.map +1 -0
- package/dist/server/server.d.ts +24 -0
- package/dist/server/server.d.ts.map +1 -0
- package/dist/server/server.js +200 -0
- package/dist/server/server.js.map +1 -0
- package/dist/tools/base.d.ts +58 -0
- package/dist/tools/base.d.ts.map +1 -0
- package/dist/tools/base.js +48 -0
- package/dist/tools/base.js.map +1 -0
- package/dist/tools/command-run.d.ts +30 -0
- package/dist/tools/command-run.d.ts.map +1 -0
- package/dist/tools/command-run.js +87 -0
- package/dist/tools/command-run.js.map +1 -0
- package/dist/tools/file-read.d.ts +34 -0
- package/dist/tools/file-read.d.ts.map +1 -0
- package/dist/tools/file-read.js +67 -0
- package/dist/tools/file-read.js.map +1 -0
- package/dist/tools/file-write.d.ts +39 -0
- package/dist/tools/file-write.d.ts.map +1 -0
- package/dist/tools/file-write.js +158 -0
- package/dist/tools/file-write.js.map +1 -0
- package/dist/tools/git.d.ts +48 -0
- package/dist/tools/git.d.ts.map +1 -0
- package/dist/tools/git.js +193 -0
- package/dist/tools/git.js.map +1 -0
- package/dist/tools/http-request.d.ts +48 -0
- package/dist/tools/http-request.d.ts.map +1 -0
- package/dist/tools/http-request.js +91 -0
- package/dist/tools/http-request.js.map +1 -0
- package/dist/types.d.ts +257 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +8 -0
- package/dist/types.js.map +1 -0
- package/examples/coding-agent.policy.yaml +80 -0
- package/examples/devops-deploy.policy.yaml +107 -0
- package/examples/mcp-proxy.config.yaml +34 -0
- package/examples/simple-session.ts +161 -0
- package/examples/video-upscaler.policy.yaml +86 -0
- package/package.json +92 -0
- package/schemas/generate.ts +18 -0
- package/schemas/policy.schema.json +7 -0
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
version: "1.0"
|
|
2
|
+
name: "coding-agent"
|
|
3
|
+
description: "Policy for AI coding agents (Cursor, Claude Code, Codex) operating on a project"
|
|
4
|
+
|
|
5
|
+
capabilities:
|
|
6
|
+
- tool: "file:read"
|
|
7
|
+
scope:
|
|
8
|
+
paths:
|
|
9
|
+
- "./src/**"
|
|
10
|
+
- "./tests/**"
|
|
11
|
+
- "./package.json"
|
|
12
|
+
- "./tsconfig.json"
|
|
13
|
+
- "./README.md"
|
|
14
|
+
- tool: "file:write"
|
|
15
|
+
scope:
|
|
16
|
+
paths:
|
|
17
|
+
- "./src/**"
|
|
18
|
+
- "./tests/**"
|
|
19
|
+
- tool: "command:run"
|
|
20
|
+
scope:
|
|
21
|
+
binaries:
|
|
22
|
+
- "npm"
|
|
23
|
+
- "npx"
|
|
24
|
+
- "node"
|
|
25
|
+
- "tsc"
|
|
26
|
+
- "git"
|
|
27
|
+
- "echo"
|
|
28
|
+
- "cat"
|
|
29
|
+
- "ls"
|
|
30
|
+
- tool: "git:diff"
|
|
31
|
+
scope:
|
|
32
|
+
repos: ["."]
|
|
33
|
+
- tool: "git:apply"
|
|
34
|
+
scope:
|
|
35
|
+
repos: ["."]
|
|
36
|
+
|
|
37
|
+
limits:
|
|
38
|
+
max_runtime_ms: 1800000 # 30 minutes
|
|
39
|
+
max_files_changed: 30
|
|
40
|
+
max_output_bytes: 10485760 # 10MB
|
|
41
|
+
max_cost_usd: 5.0
|
|
42
|
+
|
|
43
|
+
gates:
|
|
44
|
+
- action: "command:run"
|
|
45
|
+
approval: "human"
|
|
46
|
+
risk_level: "high"
|
|
47
|
+
condition: "outside_scope"
|
|
48
|
+
|
|
49
|
+
evidence:
|
|
50
|
+
require: ["checksums", "diffs"]
|
|
51
|
+
format: "jsonl"
|
|
52
|
+
|
|
53
|
+
forbidden:
|
|
54
|
+
- pattern: "**/.env"
|
|
55
|
+
- pattern: "**/.env.*"
|
|
56
|
+
- pattern: "**/credentials*"
|
|
57
|
+
- pattern: "**/secrets*"
|
|
58
|
+
- pattern: "curl | sh"
|
|
59
|
+
- pattern: "wget | sh"
|
|
60
|
+
- pattern: "npm publish"
|
|
61
|
+
- pattern: "git push --force"
|
|
62
|
+
|
|
63
|
+
session:
|
|
64
|
+
max_actions: 200
|
|
65
|
+
max_denials: 20
|
|
66
|
+
rate_limit:
|
|
67
|
+
max_per_minute: 60
|
|
68
|
+
escalation:
|
|
69
|
+
- after_actions: 50
|
|
70
|
+
require: human_checkin
|
|
71
|
+
- after_minutes: 15
|
|
72
|
+
require: human_checkin
|
|
73
|
+
|
|
74
|
+
remediation:
|
|
75
|
+
rules:
|
|
76
|
+
- match: "ENOENT"
|
|
77
|
+
action: "retry"
|
|
78
|
+
- match: "EACCES"
|
|
79
|
+
action: "abort"
|
|
80
|
+
fallback_chain: ["retry", "skip", "abort"]
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
# DevOps Deployment Agent Policy
|
|
2
|
+
# Constrains a deployment agent to operate within safe boundaries.
|
|
3
|
+
|
|
4
|
+
version: "1.0"
|
|
5
|
+
name: "devops-deploy"
|
|
6
|
+
description: "Policy for a deployment agent that builds, tests, and deploys application code."
|
|
7
|
+
|
|
8
|
+
capabilities:
|
|
9
|
+
- tool: "file:read"
|
|
10
|
+
scope:
|
|
11
|
+
paths:
|
|
12
|
+
- "/app/**"
|
|
13
|
+
- "/config/**"
|
|
14
|
+
|
|
15
|
+
- tool: "file:write"
|
|
16
|
+
scope:
|
|
17
|
+
paths:
|
|
18
|
+
- "/app/dist/**"
|
|
19
|
+
- "/tmp/deploy-work/**"
|
|
20
|
+
|
|
21
|
+
- tool: "command:run"
|
|
22
|
+
scope:
|
|
23
|
+
binaries:
|
|
24
|
+
- "npm"
|
|
25
|
+
- "node"
|
|
26
|
+
- "docker"
|
|
27
|
+
- "kubectl"
|
|
28
|
+
- "git"
|
|
29
|
+
- "curl"
|
|
30
|
+
|
|
31
|
+
- tool: "git:diff"
|
|
32
|
+
scope:
|
|
33
|
+
repos:
|
|
34
|
+
- "/app"
|
|
35
|
+
|
|
36
|
+
- tool: "git:apply"
|
|
37
|
+
scope:
|
|
38
|
+
repos:
|
|
39
|
+
- "/app"
|
|
40
|
+
|
|
41
|
+
- tool: "http:request"
|
|
42
|
+
scope:
|
|
43
|
+
domains:
|
|
44
|
+
- "registry.npmjs.org"
|
|
45
|
+
- "api.github.com"
|
|
46
|
+
- "k8s.internal.yourcompany.com"
|
|
47
|
+
methods:
|
|
48
|
+
- "GET"
|
|
49
|
+
- "POST"
|
|
50
|
+
|
|
51
|
+
limits:
|
|
52
|
+
max_runtime_ms: 600000 # 10 minutes
|
|
53
|
+
max_output_bytes: 1073741824 # 1 GB
|
|
54
|
+
max_files_changed: 200
|
|
55
|
+
max_retries: 2
|
|
56
|
+
max_cost_usd: 5.0
|
|
57
|
+
|
|
58
|
+
gates:
|
|
59
|
+
- action: "command:run"
|
|
60
|
+
approval: "human"
|
|
61
|
+
risk_level: "high"
|
|
62
|
+
condition: "outside_scope"
|
|
63
|
+
|
|
64
|
+
- action: "http:request"
|
|
65
|
+
approval: "human"
|
|
66
|
+
risk_level: "high"
|
|
67
|
+
|
|
68
|
+
- action: "file:delete"
|
|
69
|
+
approval: "human"
|
|
70
|
+
risk_level: "critical"
|
|
71
|
+
|
|
72
|
+
evidence:
|
|
73
|
+
require:
|
|
74
|
+
- "diffs"
|
|
75
|
+
- "checksums"
|
|
76
|
+
- "exit_codes"
|
|
77
|
+
- "logs"
|
|
78
|
+
format: "jsonl"
|
|
79
|
+
|
|
80
|
+
forbidden:
|
|
81
|
+
- pattern: "rm -rf /"
|
|
82
|
+
- pattern: "**/.env"
|
|
83
|
+
- pattern: "**/credentials*"
|
|
84
|
+
- pattern: "**/secrets/**"
|
|
85
|
+
- pattern: "kubectl delete namespace"
|
|
86
|
+
|
|
87
|
+
session:
|
|
88
|
+
max_actions: 100
|
|
89
|
+
max_denials: 10
|
|
90
|
+
rate_limit:
|
|
91
|
+
max_per_minute: 30
|
|
92
|
+
escalation:
|
|
93
|
+
- after_actions: 30
|
|
94
|
+
require: human_checkin
|
|
95
|
+
- after_minutes: 5
|
|
96
|
+
require: human_checkin
|
|
97
|
+
|
|
98
|
+
remediation:
|
|
99
|
+
rules:
|
|
100
|
+
- match: "npm ERR!"
|
|
101
|
+
action: "retry"
|
|
102
|
+
- match: "docker: Error"
|
|
103
|
+
action: "abort"
|
|
104
|
+
- match: "kubectl error"
|
|
105
|
+
action: "abort"
|
|
106
|
+
- match: "ECONNREFUSED"
|
|
107
|
+
action: "retry"
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# MCP Proxy Configuration
|
|
2
|
+
#
|
|
3
|
+
# This config file tells the MCP proxy how to connect to backend MCP servers
|
|
4
|
+
# and which policy to enforce on all tool calls.
|
|
5
|
+
#
|
|
6
|
+
# Usage: det-acp proxy ./mcp-proxy.config.yaml
|
|
7
|
+
|
|
8
|
+
# Policy to enforce on all proxied tool calls
|
|
9
|
+
policy: ./coding-agent.policy.yaml
|
|
10
|
+
|
|
11
|
+
# Directory for evidence ledger files
|
|
12
|
+
ledger_dir: ./.det-acp/ledgers
|
|
13
|
+
|
|
14
|
+
# Transport to expose to the agent (stdio for local, sse for remote)
|
|
15
|
+
transport: stdio
|
|
16
|
+
|
|
17
|
+
# Backend MCP servers to proxy tool calls to
|
|
18
|
+
backends:
|
|
19
|
+
- name: filesystem
|
|
20
|
+
transport: stdio
|
|
21
|
+
command: npx
|
|
22
|
+
args: ["-y", "@modelcontextprotocol/server-filesystem", "./src"]
|
|
23
|
+
|
|
24
|
+
- name: github
|
|
25
|
+
transport: stdio
|
|
26
|
+
command: npx
|
|
27
|
+
args: ["-y", "@modelcontextprotocol/server-github"]
|
|
28
|
+
env:
|
|
29
|
+
GITHUB_TOKEN: "${GITHUB_TOKEN}"
|
|
30
|
+
|
|
31
|
+
# Optional metadata attached to every session
|
|
32
|
+
session_metadata:
|
|
33
|
+
source: mcp-proxy
|
|
34
|
+
project: my-project
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Example: Simple Session Gateway Usage
|
|
3
|
+
*
|
|
4
|
+
* Demonstrates the core gateway API — creating a session, evaluating actions,
|
|
5
|
+
* recording results, and terminating with a report.
|
|
6
|
+
*
|
|
7
|
+
* Run: npx tsx examples/simple-session.ts
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { AgentGateway } from '../src/index.js';
|
|
11
|
+
|
|
12
|
+
const POLICY_YAML = `
|
|
13
|
+
version: "1.0"
|
|
14
|
+
name: "simple-session-example"
|
|
15
|
+
|
|
16
|
+
capabilities:
|
|
17
|
+
- tool: "file:read"
|
|
18
|
+
scope:
|
|
19
|
+
paths: ["/tmp/det-acp-demo/**"]
|
|
20
|
+
- tool: "file:write"
|
|
21
|
+
scope:
|
|
22
|
+
paths: ["/tmp/det-acp-demo/**"]
|
|
23
|
+
- tool: "command:run"
|
|
24
|
+
scope:
|
|
25
|
+
binaries: ["echo", "ls", "cat"]
|
|
26
|
+
|
|
27
|
+
limits:
|
|
28
|
+
max_runtime_ms: 60000
|
|
29
|
+
max_files_changed: 10
|
|
30
|
+
|
|
31
|
+
gates: []
|
|
32
|
+
|
|
33
|
+
evidence:
|
|
34
|
+
require: ["checksums"]
|
|
35
|
+
format: "jsonl"
|
|
36
|
+
|
|
37
|
+
forbidden:
|
|
38
|
+
- pattern: "**/.env"
|
|
39
|
+
- pattern: "rm -rf"
|
|
40
|
+
|
|
41
|
+
session:
|
|
42
|
+
max_actions: 20
|
|
43
|
+
max_denials: 5
|
|
44
|
+
`;
|
|
45
|
+
|
|
46
|
+
async function main() {
|
|
47
|
+
// 1. Create the gateway
|
|
48
|
+
const gateway = await AgentGateway.create({
|
|
49
|
+
ledgerDir: '/tmp/det-acp-demo/ledgers',
|
|
50
|
+
onStateChange: (sessionId, from, to) => {
|
|
51
|
+
console.log(` [${sessionId.slice(0, 8)}] ${from} → ${to}`);
|
|
52
|
+
},
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
console.log('=== Deterministic Agent Control Protocol — Session Gateway Demo ===\n');
|
|
56
|
+
|
|
57
|
+
// 2. Create a session
|
|
58
|
+
const session = await gateway.createSession(POLICY_YAML, {
|
|
59
|
+
agent: 'demo-agent',
|
|
60
|
+
purpose: 'demonstrate session API',
|
|
61
|
+
});
|
|
62
|
+
console.log(`Session created: ${session.id}`);
|
|
63
|
+
console.log(`Policy: ${session.policy.name}\n`);
|
|
64
|
+
|
|
65
|
+
// 3. Evaluate some actions
|
|
66
|
+
console.log('--- Evaluating actions ---\n');
|
|
67
|
+
|
|
68
|
+
// Allowed: read within scope
|
|
69
|
+
const read = await gateway.evaluate(session.id, {
|
|
70
|
+
tool: 'file:read',
|
|
71
|
+
input: { path: '/tmp/det-acp-demo/data.txt' },
|
|
72
|
+
});
|
|
73
|
+
console.log(`file:read /tmp/det-acp-demo/data.txt → ${read.decision}`);
|
|
74
|
+
|
|
75
|
+
// Record result (simulating external execution)
|
|
76
|
+
if (read.decision === 'allow') {
|
|
77
|
+
await gateway.recordResult(session.id, read.actionId, {
|
|
78
|
+
success: true,
|
|
79
|
+
output: 'Hello from data.txt',
|
|
80
|
+
durationMs: 5,
|
|
81
|
+
});
|
|
82
|
+
console.log(` Result recorded: success\n`);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// Allowed: write within scope
|
|
86
|
+
const write = await gateway.evaluate(session.id, {
|
|
87
|
+
tool: 'file:write',
|
|
88
|
+
input: { path: '/tmp/det-acp-demo/output.txt', content: 'Agent wrote this' },
|
|
89
|
+
});
|
|
90
|
+
console.log(`file:write /tmp/det-acp-demo/output.txt → ${write.decision}`);
|
|
91
|
+
|
|
92
|
+
if (write.decision === 'allow') {
|
|
93
|
+
await gateway.recordResult(session.id, write.actionId, {
|
|
94
|
+
success: true,
|
|
95
|
+
output: { path: '/tmp/det-acp-demo/output.txt', bytesWritten: 15 },
|
|
96
|
+
durationMs: 3,
|
|
97
|
+
});
|
|
98
|
+
console.log(` Result recorded: success\n`);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// Denied: read outside scope
|
|
102
|
+
const deniedRead = await gateway.evaluate(session.id, {
|
|
103
|
+
tool: 'file:read',
|
|
104
|
+
input: { path: '/etc/passwd' },
|
|
105
|
+
});
|
|
106
|
+
console.log(`file:read /etc/passwd → ${deniedRead.decision}`);
|
|
107
|
+
console.log(` Reasons: ${deniedRead.reasons.join('; ')}\n`);
|
|
108
|
+
|
|
109
|
+
// Denied: forbidden command
|
|
110
|
+
const deniedCmd = await gateway.evaluate(session.id, {
|
|
111
|
+
tool: 'command:run',
|
|
112
|
+
input: { command: 'rm -rf /tmp' },
|
|
113
|
+
});
|
|
114
|
+
console.log(`command:run "rm -rf /tmp" → ${deniedCmd.decision}`);
|
|
115
|
+
console.log(` Reasons: ${deniedCmd.reasons.join('; ')}\n`);
|
|
116
|
+
|
|
117
|
+
// Allowed: safe command
|
|
118
|
+
const echoCmd = await gateway.evaluate(session.id, {
|
|
119
|
+
tool: 'command:run',
|
|
120
|
+
input: { command: 'echo "hello from agent"' },
|
|
121
|
+
});
|
|
122
|
+
console.log(`command:run "echo hello" → ${echoCmd.decision}`);
|
|
123
|
+
|
|
124
|
+
if (echoCmd.decision === 'allow') {
|
|
125
|
+
await gateway.recordResult(session.id, echoCmd.actionId, {
|
|
126
|
+
success: true,
|
|
127
|
+
output: 'hello from agent',
|
|
128
|
+
durationMs: 10,
|
|
129
|
+
});
|
|
130
|
+
console.log(` Result recorded: success\n`);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// 4. Get intermediate report
|
|
134
|
+
console.log('--- Session Report ---\n');
|
|
135
|
+
const report = gateway.getSessionReport(session.id);
|
|
136
|
+
console.log(`Total actions: ${report.totalActions}`);
|
|
137
|
+
console.log(` Allowed: ${report.allowed}`);
|
|
138
|
+
console.log(` Denied: ${report.denied}`);
|
|
139
|
+
console.log(` Gated: ${report.gated}`);
|
|
140
|
+
console.log(`Budget used:`);
|
|
141
|
+
console.log(` Actions evaluated: ${report.budgetUsed.actionsEvaluated}`);
|
|
142
|
+
console.log(` Actions denied: ${report.budgetUsed.actionsDenied}`);
|
|
143
|
+
console.log('');
|
|
144
|
+
|
|
145
|
+
// 5. Terminate the session
|
|
146
|
+
const finalReport = await gateway.terminateSession(session.id, 'Demo complete');
|
|
147
|
+
console.log(`Session terminated: ${finalReport.state}`);
|
|
148
|
+
console.log(`Duration: ${finalReport.durationMs}ms`);
|
|
149
|
+
|
|
150
|
+
// 6. Verify ledger integrity
|
|
151
|
+
const ledger = gateway.getSessionLedger(session.id);
|
|
152
|
+
if (ledger) {
|
|
153
|
+
const { EvidenceLedger } = await import('../src/ledger/ledger.js');
|
|
154
|
+
const integrity = EvidenceLedger.verifyIntegrity(ledger.getFilePath());
|
|
155
|
+
console.log(`\nLedger integrity: ${integrity.valid ? 'VALID' : 'BROKEN'}`);
|
|
156
|
+
console.log(`Ledger entries: ${integrity.totalEntries}`);
|
|
157
|
+
console.log(`Ledger path: ${ledger.getFilePath()}`);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
main().catch(console.error);
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
# Video Upscaler Agent Policy
|
|
2
|
+
# This policy constrains a video upscaling agent to operate safely.
|
|
3
|
+
|
|
4
|
+
version: "1.0"
|
|
5
|
+
name: "video-upscaler"
|
|
6
|
+
description: "Policy for a video upscaling agent that reads input video files, runs upscaling binaries, and writes output files."
|
|
7
|
+
|
|
8
|
+
capabilities:
|
|
9
|
+
- tool: "file:read"
|
|
10
|
+
scope:
|
|
11
|
+
paths:
|
|
12
|
+
- "/data/in/**"
|
|
13
|
+
- "/data/models/**"
|
|
14
|
+
|
|
15
|
+
- tool: "file:write"
|
|
16
|
+
scope:
|
|
17
|
+
paths:
|
|
18
|
+
- "/data/out/**"
|
|
19
|
+
- "/tmp/agent-work/**"
|
|
20
|
+
|
|
21
|
+
- tool: "command:run"
|
|
22
|
+
scope:
|
|
23
|
+
binaries:
|
|
24
|
+
- "ffmpeg"
|
|
25
|
+
- "realesrgan-ncnn-vulkan"
|
|
26
|
+
- "video2x"
|
|
27
|
+
- "ffprobe"
|
|
28
|
+
|
|
29
|
+
- tool: "http:request"
|
|
30
|
+
scope:
|
|
31
|
+
domains:
|
|
32
|
+
- "downloads.yourcompany.com"
|
|
33
|
+
- "models.yourcompany.com"
|
|
34
|
+
methods:
|
|
35
|
+
- "GET"
|
|
36
|
+
|
|
37
|
+
limits:
|
|
38
|
+
max_runtime_ms: 1800000 # 30 minutes
|
|
39
|
+
max_output_bytes: 5368709120 # 5 GB
|
|
40
|
+
max_files_changed: 50
|
|
41
|
+
max_retries: 3
|
|
42
|
+
|
|
43
|
+
gates:
|
|
44
|
+
- action: "file:delete"
|
|
45
|
+
approval: "human"
|
|
46
|
+
risk_level: "high"
|
|
47
|
+
|
|
48
|
+
- action: "command:run"
|
|
49
|
+
approval: "auto"
|
|
50
|
+
risk_level: "medium"
|
|
51
|
+
|
|
52
|
+
evidence:
|
|
53
|
+
require:
|
|
54
|
+
- "diffs"
|
|
55
|
+
- "checksums"
|
|
56
|
+
- "exit_codes"
|
|
57
|
+
format: "jsonl"
|
|
58
|
+
|
|
59
|
+
forbidden:
|
|
60
|
+
- pattern: "rm -rf"
|
|
61
|
+
- pattern: "**/.env"
|
|
62
|
+
- pattern: "**/secrets/**"
|
|
63
|
+
- pattern: "/etc/**"
|
|
64
|
+
- pattern: "/usr/**"
|
|
65
|
+
|
|
66
|
+
session:
|
|
67
|
+
max_actions: 50
|
|
68
|
+
max_denials: 5
|
|
69
|
+
escalation:
|
|
70
|
+
- after_minutes: 15
|
|
71
|
+
require: human_checkin
|
|
72
|
+
|
|
73
|
+
remediation:
|
|
74
|
+
rules:
|
|
75
|
+
- match: "CUDA out of memory"
|
|
76
|
+
action: "fallback:vulkan"
|
|
77
|
+
- match: "Vulkan device not found"
|
|
78
|
+
action: "fallback:cpu"
|
|
79
|
+
- match: "disk full"
|
|
80
|
+
action: "abort"
|
|
81
|
+
- match: "permission denied"
|
|
82
|
+
action: "abort"
|
|
83
|
+
fallback_chain:
|
|
84
|
+
- "cuda"
|
|
85
|
+
- "vulkan"
|
|
86
|
+
- "cpu"
|
package/package.json
ADDED
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@det-acp/core",
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "Agent Governance Gateway — bounded, auditable, session-aware control for AI agents with MCP proxy, shell proxy, and HTTP API",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"import": "./dist/index.js"
|
|
12
|
+
},
|
|
13
|
+
"./policy": {
|
|
14
|
+
"types": "./dist/policy/loader.d.ts",
|
|
15
|
+
"import": "./dist/policy/loader.js"
|
|
16
|
+
},
|
|
17
|
+
"./server": {
|
|
18
|
+
"types": "./dist/server/server.d.ts",
|
|
19
|
+
"import": "./dist/server/server.js"
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
"bin": {
|
|
23
|
+
"det-acp": "dist/cli/index.js"
|
|
24
|
+
},
|
|
25
|
+
"files": [
|
|
26
|
+
"dist/",
|
|
27
|
+
"schemas/",
|
|
28
|
+
"examples/",
|
|
29
|
+
"LICENSE",
|
|
30
|
+
"README.md"
|
|
31
|
+
],
|
|
32
|
+
"scripts": {
|
|
33
|
+
"build": "tsc",
|
|
34
|
+
"dev": "tsc --watch",
|
|
35
|
+
"test": "vitest run",
|
|
36
|
+
"test:watch": "vitest",
|
|
37
|
+
"lint": "tsc --noEmit",
|
|
38
|
+
"start:server": "node dist/server/server.js",
|
|
39
|
+
"generate:schema": "node dist/schemas/generate.js",
|
|
40
|
+
"prepare": "npm run build",
|
|
41
|
+
"prepublishOnly": "npm run build && npm run test"
|
|
42
|
+
},
|
|
43
|
+
"keywords": [
|
|
44
|
+
"agent",
|
|
45
|
+
"governance",
|
|
46
|
+
"safety",
|
|
47
|
+
"control-protocol",
|
|
48
|
+
"audit",
|
|
49
|
+
"policy",
|
|
50
|
+
"mcp",
|
|
51
|
+
"cursor",
|
|
52
|
+
"claude-code",
|
|
53
|
+
"gateway",
|
|
54
|
+
"session",
|
|
55
|
+
"ai-agent",
|
|
56
|
+
"model-context-protocol",
|
|
57
|
+
"deterministic"
|
|
58
|
+
],
|
|
59
|
+
"author": "det-acp",
|
|
60
|
+
"license": "MIT",
|
|
61
|
+
"repository": {
|
|
62
|
+
"type": "git",
|
|
63
|
+
"url": "https://github.com/det-acp/agent-control-plane.git"
|
|
64
|
+
},
|
|
65
|
+
"homepage": "https://github.com/det-acp/agent-control-plane#readme",
|
|
66
|
+
"bugs": {
|
|
67
|
+
"url": "https://github.com/det-acp/agent-control-plane/issues"
|
|
68
|
+
},
|
|
69
|
+
"publishConfig": {
|
|
70
|
+
"access": "public"
|
|
71
|
+
},
|
|
72
|
+
"engines": {
|
|
73
|
+
"node": ">=20.0.0"
|
|
74
|
+
},
|
|
75
|
+
"dependencies": {
|
|
76
|
+
"@modelcontextprotocol/sdk": "^1.26.0",
|
|
77
|
+
"commander": "^14.0.3",
|
|
78
|
+
"fastify": "^5.7.4",
|
|
79
|
+
"js-yaml": "^4.1.1",
|
|
80
|
+
"minimatch": "^10.1.2",
|
|
81
|
+
"nanoid": "^3.3.11",
|
|
82
|
+
"pino": "^10.3.0",
|
|
83
|
+
"zod": "^4.3.6"
|
|
84
|
+
},
|
|
85
|
+
"devDependencies": {
|
|
86
|
+
"@types/js-yaml": "^4.0.9",
|
|
87
|
+
"@types/node": "^25.2.1",
|
|
88
|
+
"typescript": "^5.9.3",
|
|
89
|
+
"vitest": "^4.0.18",
|
|
90
|
+
"zod-to-json-schema": "^3.25.1"
|
|
91
|
+
}
|
|
92
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generate JSON Schema from Zod policy schema.
|
|
3
|
+
* Run: npx tsx schemas/generate.ts
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { zodToJsonSchema } from 'zod-to-json-schema';
|
|
7
|
+
import { PolicySchema } from '../src/policy/schema.js';
|
|
8
|
+
import fs from 'node:fs';
|
|
9
|
+
import path from 'node:path';
|
|
10
|
+
|
|
11
|
+
const jsonSchema = zodToJsonSchema(PolicySchema, {
|
|
12
|
+
name: 'AgentPolicy',
|
|
13
|
+
$refStrategy: 'none',
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
const outputPath = path.resolve(import.meta.dirname, 'policy.schema.json');
|
|
17
|
+
fs.writeFileSync(outputPath, JSON.stringify(jsonSchema, null, 2) + '\n');
|
|
18
|
+
console.log(`Generated JSON Schema at ${outputPath}`);
|