@det-acp/core 0.2.0 → 0.2.1
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 +264 -207
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -1,30 +1,67 @@
|
|
|
1
1
|
# Deterministic Agent Control Protocol
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
[](https://github.com/elliot35/deterministic-agent-control-protocol/stargazers)
|
|
4
|
+
[](https://github.com/elliot35/deterministic-agent-control-protocol/network/members)
|
|
5
|
+
[](https://github.com/elliot35/deterministic-agent-control-protocol/graphs/contributors)
|
|
6
|
+
[](LICENSE)
|
|
7
|
+
[](https://www.npmjs.com/package/deterministic-agent-control-protocol)
|
|
8
|
+

|
|
9
|
+

|
|
4
10
|
|
|
5
|
-
|
|
11
|
+
**A governance gateway for AI agents — making every action bounded, auditable, reversible, and explainable.**
|
|
12
|
+
|
|
13
|
+
Works transparently with **Cursor**, **Claude Code**, **Codex**, and any MCP-compatible agent. Also supports shell command governance and a language-agnostic HTTP API.
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## Table of Contents
|
|
18
|
+
|
|
19
|
+
- [How It Works](#how-it-works)
|
|
20
|
+
- [Core Principles](#core-principles)
|
|
21
|
+
- [Quick Start](#quick-start)
|
|
22
|
+
- [Agent Integrations](#agent-integrations)
|
|
23
|
+
- [Built-in Policies](#built-in-policies)
|
|
24
|
+
- [Integration Modes](#integration-modes)
|
|
25
|
+
- [Architecture](#architecture)
|
|
26
|
+
- [Policy DSL Reference](#policy-dsl-reference)
|
|
27
|
+
- [Built-in Tool Adapters](#built-in-tool-adapters)
|
|
28
|
+
- [Custom Tool Adapters](#custom-tool-adapters)
|
|
29
|
+
- [Development](#development)
|
|
30
|
+
- [Contributing](#contributing)
|
|
31
|
+
- [License](#license)
|
|
32
|
+
|
|
33
|
+
---
|
|
6
34
|
|
|
7
35
|
## How It Works
|
|
8
36
|
|
|
9
|
-
|
|
37
|
+
Agents never execute tools directly. Every action flows through the control plane for evaluation, enforcement, and audit:
|
|
10
38
|
|
|
11
|
-
```
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
39
|
+
```mermaid
|
|
40
|
+
flowchart LR
|
|
41
|
+
A["Agent"] -->|"action request"| CP["Control Protocol"]
|
|
42
|
+
CP -->|"evaluate against policy"| D{"Decision"}
|
|
43
|
+
D -->|"allow"| E["Agent Executes Action"]
|
|
44
|
+
D -->|"deny"| F["Blocked + Reason Logged"]
|
|
45
|
+
D -->|"gate"| G["Human Approval Required"]
|
|
46
|
+
E -->|"record result"| L["Evidence Ledger"]
|
|
47
|
+
G -->|"approved"| E
|
|
17
48
|
```
|
|
18
49
|
|
|
19
|
-
The
|
|
50
|
+
The protocol **does not execute** actions itself. It evaluates them against a policy, enforces session-level budgets, requires human approval for risky operations, and records everything in a tamper-evident audit ledger.
|
|
51
|
+
|
|
52
|
+
---
|
|
20
53
|
|
|
21
54
|
## Core Principles
|
|
22
55
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
56
|
+
| Principle | Description |
|
|
57
|
+
|-----------|-------------|
|
|
58
|
+
| **Bounded** | Agents can only perform allowed actions within allowed scopes |
|
|
59
|
+
| **Session-Aware** | Budget, rate limits, and escalation rules across the full interaction |
|
|
60
|
+
| **Auditable** | Every action logged in a tamper-evident ledger with SHA-256 hash chaining |
|
|
61
|
+
| **Reversible** | Compensation plans for undoing executed actions |
|
|
62
|
+
| **Explainable** | Full reporting — what was allowed, denied, gated, and why |
|
|
63
|
+
|
|
64
|
+
---
|
|
28
65
|
|
|
29
66
|
## Quick Start
|
|
30
67
|
|
|
@@ -36,32 +73,24 @@ npm install deterministic-agent-control-protocol
|
|
|
36
73
|
|
|
37
74
|
### Set Up Governance (One Command)
|
|
38
75
|
|
|
39
|
-
The fastest way to add governance to your AI agent:
|
|
40
|
-
|
|
41
76
|
```bash
|
|
42
|
-
# Cursor
|
|
43
|
-
npx det-acp init
|
|
44
|
-
|
|
45
|
-
# Codex CLI
|
|
46
|
-
npx det-acp init codex
|
|
47
|
-
|
|
48
|
-
# Claude Code
|
|
49
|
-
npx det-acp init claude-code
|
|
77
|
+
npx det-acp init cursor # Cursor
|
|
78
|
+
npx det-acp init codex # Codex CLI
|
|
79
|
+
npx det-acp init claude-code # Claude Code
|
|
50
80
|
```
|
|
51
81
|
|
|
52
|
-
This generates all required files (policy, MCP config, governance rules) with sensible defaults.
|
|
53
|
-
|
|
54
|
-
To use your own policy instead of the default:
|
|
82
|
+
This generates all required files (policy, MCP config, governance rules) with sensible defaults. Edit `policy.yaml` to customize — everything else is handled automatically.
|
|
55
83
|
|
|
56
84
|
```bash
|
|
85
|
+
# Use your own policy instead of the default
|
|
57
86
|
npx det-acp init cursor --policy ./my-policy.yaml
|
|
58
87
|
```
|
|
59
88
|
|
|
60
|
-
After running `init`, restart your agent
|
|
89
|
+
> After running `init`, restart your agent to pick up the MCP server.
|
|
61
90
|
|
|
62
91
|
### Define a Policy
|
|
63
92
|
|
|
64
|
-
Create
|
|
93
|
+
Create `agent.policy.yaml`:
|
|
65
94
|
|
|
66
95
|
```yaml
|
|
67
96
|
version: "1.0"
|
|
@@ -129,7 +158,7 @@ const verdict = await gateway.evaluate(session.id, {
|
|
|
129
158
|
});
|
|
130
159
|
|
|
131
160
|
if (verdict.decision === 'allow') {
|
|
132
|
-
// Execute the action yourself
|
|
161
|
+
// Execute the action yourself
|
|
133
162
|
const content = fs.readFileSync('./src/index.ts', 'utf-8');
|
|
134
163
|
|
|
135
164
|
// Record the result
|
|
@@ -140,7 +169,7 @@ if (verdict.decision === 'allow') {
|
|
|
140
169
|
});
|
|
141
170
|
}
|
|
142
171
|
|
|
143
|
-
//
|
|
172
|
+
// Terminate and get report
|
|
144
173
|
const report = await gateway.terminateSession(session.id, 'task complete');
|
|
145
174
|
console.log(`Allowed: ${report.allowed}, Denied: ${report.denied}`);
|
|
146
175
|
```
|
|
@@ -149,42 +178,68 @@ console.log(`Allowed: ${report.allowed}, Denied: ${report.denied}`);
|
|
|
149
178
|
|
|
150
179
|
## Agent Integrations
|
|
151
180
|
|
|
152
|
-
Ready-to-use
|
|
181
|
+
Ready-to-use guides for popular AI agents. Each integration includes policy, config templates, governance rules, test sandbox, and step-by-step instructions.
|
|
153
182
|
|
|
154
|
-
| Agent
|
|
155
|
-
|
|
156
|
-
| **Cursor**
|
|
157
|
-
| **Codex CLI**
|
|
183
|
+
| Agent | Integration Mode | Governance Level | Guide |
|
|
184
|
+
|-------|-----------------|-----------------|-------|
|
|
185
|
+
| **Cursor** | MCP Proxy + Cursor Rules | Soft | [integrations/cursor/](integrations/cursor/) |
|
|
186
|
+
| **Codex CLI** | MCP Proxy + AGENTS.md + OS Sandbox | Soft + Sandbox | [integrations/codex/](integrations/codex/) |
|
|
158
187
|
| **Claude Code** | MCP Proxy + CLAUDE.md + settings.json | Soft + Semi-Hard | [integrations/claude-code/](integrations/claude-code/) |
|
|
159
|
-
| **OpenClaw**
|
|
188
|
+
| **OpenClaw** | HTTP API + Skill + Docker Sandbox | Hard | [integrations/openclaw/](integrations/openclaw/) |
|
|
189
|
+
|
|
190
|
+
<details>
|
|
191
|
+
<summary><strong>Governance Levels Explained</strong></summary>
|
|
160
192
|
|
|
161
|
-
|
|
193
|
+
- **Soft** — The LLM is instructed (via rules/instructions files) to prefer governed tools. Effective in practice, but a creative prompt could theoretically bypass it.
|
|
194
|
+
- **Semi-Hard** — Soft instructions combined with the agent's built-in permission system that can deny direct tool access (e.g., Claude Code's `settings.json`).
|
|
195
|
+
- **Hard** — The agent physically cannot access tools outside the governance layer. Achieved via Docker sandboxing, tool allow/deny lists, or custom agent harnesses.
|
|
162
196
|
|
|
163
|
-
|
|
164
|
-
- **Semi-Hard**: Soft instructions combined with the agent's built-in permission system that can deny direct tool access (e.g., Claude Code's `settings.json`).
|
|
165
|
-
- **Hard**: The agent physically cannot access tools outside the governance layer. Achieved via Docker sandboxing, tool allow/deny lists, or custom agent harnesses.
|
|
197
|
+
</details>
|
|
166
198
|
|
|
167
|
-
For any MCP-compatible agent not listed above, see
|
|
199
|
+
For any MCP-compatible agent not listed above, see [MCP Proxy (General)](#mcp-proxy-general).
|
|
168
200
|
|
|
169
201
|
---
|
|
170
202
|
|
|
171
|
-
##
|
|
203
|
+
## Built-in Policies
|
|
204
|
+
|
|
205
|
+
Production-ready policies in `examples/` — usable out of the box:
|
|
206
|
+
|
|
207
|
+
| Policy | File | Use Case |
|
|
208
|
+
|--------|------|----------|
|
|
209
|
+
| Coding Agent | [`coding-agent.policy.yaml`](examples/coding-agent.policy.yaml) | AI coding agents operating on a project |
|
|
210
|
+
| DevOps Deploy | [`devops-deploy.policy.yaml`](examples/devops-deploy.policy.yaml) | Deployment agents that build, test, and deploy code |
|
|
211
|
+
| Video Upscaler | [`video-upscaler.policy.yaml`](examples/video-upscaler.policy.yaml) | Media processing agents running upscaling pipelines |
|
|
212
|
+
|
|
213
|
+
> Validate any policy with: `npx det-acp validate ./policy.yaml`
|
|
214
|
+
|
|
215
|
+
---
|
|
216
|
+
|
|
217
|
+
## Integration Modes
|
|
218
|
+
|
|
219
|
+
| Mode | How It Works | Best For |
|
|
220
|
+
|------|-------------|----------|
|
|
221
|
+
| **MCP Proxy** | Transparent proxy between agent and MCP servers | Cursor, Claude Code, any MCP client |
|
|
222
|
+
| **Shell Proxy** | Command wrapper that validates before executing | CLI agents, shell-based workflows |
|
|
223
|
+
| **HTTP API** | REST endpoints for session management | Any language, custom integrations |
|
|
224
|
+
| **Library SDK** | TypeScript API for in-process governance | Custom TypeScript agents |
|
|
172
225
|
|
|
173
226
|
### MCP Proxy (General)
|
|
174
227
|
|
|
175
|
-
|
|
228
|
+
Works with any MCP-compatible client.
|
|
176
229
|
|
|
177
|
-
**Simplified mode** —
|
|
230
|
+
**Simplified mode** — point at a policy file, auto-configures filesystem backend:
|
|
178
231
|
|
|
179
232
|
```bash
|
|
180
233
|
npx det-acp proxy --policy ./policy.yaml
|
|
181
|
-
npx det-acp proxy --policy ./policy.yaml --dir /path/to/project
|
|
234
|
+
npx det-acp proxy --policy ./policy.yaml --dir /path/to/project
|
|
182
235
|
```
|
|
183
236
|
|
|
184
|
-
|
|
237
|
+
<details>
|
|
238
|
+
<summary><strong>Full config mode</strong></summary>
|
|
239
|
+
|
|
240
|
+
For advanced setups with multiple backends, SSE transport, etc.:
|
|
185
241
|
|
|
186
242
|
```bash
|
|
187
|
-
# Create a proxy config
|
|
188
243
|
cat > mcp-proxy.config.yaml << 'EOF'
|
|
189
244
|
policy: ./agent.policy.yaml
|
|
190
245
|
ledger_dir: ./.det-acp/ledgers
|
|
@@ -196,28 +251,30 @@ backends:
|
|
|
196
251
|
args: ["-y", "@modelcontextprotocol/server-filesystem", "./src"]
|
|
197
252
|
EOF
|
|
198
253
|
|
|
199
|
-
# Start the proxy
|
|
200
254
|
npx det-acp proxy ./mcp-proxy.config.yaml
|
|
201
255
|
```
|
|
202
256
|
|
|
257
|
+
</details>
|
|
258
|
+
|
|
203
259
|
### Shell Proxy
|
|
204
260
|
|
|
205
261
|
Execute commands through the policy gateway:
|
|
206
262
|
|
|
207
263
|
```bash
|
|
208
|
-
# Allowed
|
|
209
|
-
npx det-acp exec ./agent.policy.yaml
|
|
210
|
-
|
|
211
|
-
# Denied (rm -rf is forbidden)
|
|
212
|
-
npx det-acp exec ./agent.policy.yaml rm -rf /tmp
|
|
264
|
+
npx det-acp exec ./agent.policy.yaml echo "hello" # Allowed
|
|
265
|
+
npx det-acp exec ./agent.policy.yaml rm -rf /tmp # Denied (forbidden)
|
|
213
266
|
```
|
|
214
267
|
|
|
215
268
|
### HTTP Session Server
|
|
216
269
|
|
|
217
270
|
```bash
|
|
218
|
-
# Start the server
|
|
219
271
|
npx det-acp serve --port 3100
|
|
272
|
+
```
|
|
220
273
|
|
|
274
|
+
<details>
|
|
275
|
+
<summary><strong>HTTP API Examples</strong></summary>
|
|
276
|
+
|
|
277
|
+
```bash
|
|
221
278
|
# Create a session
|
|
222
279
|
curl -X POST http://localhost:3100/sessions \
|
|
223
280
|
-H "Content-Type: application/json" \
|
|
@@ -237,97 +294,88 @@ curl -X POST http://localhost:3100/sessions/<session-id>/record \
|
|
|
237
294
|
curl -X POST http://localhost:3100/sessions/<session-id>/terminate
|
|
238
295
|
```
|
|
239
296
|
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
```bash
|
|
243
|
-
# Set up governance for an integration (generates all config files)
|
|
244
|
-
npx det-acp init cursor # or codex, claude-code
|
|
245
|
-
npx det-acp init cursor --policy ./my-policy.yaml # use custom policy
|
|
246
|
-
|
|
247
|
-
# Validate a policy
|
|
248
|
-
npx det-acp validate ./agent.policy.yaml
|
|
249
|
-
|
|
250
|
-
# Start MCP proxy (simplified — just a policy file)
|
|
251
|
-
npx det-acp proxy --policy ./policy.yaml
|
|
252
|
-
|
|
253
|
-
# Start MCP proxy (full config file for advanced use)
|
|
254
|
-
npx det-acp proxy ./mcp-proxy.config.yaml
|
|
297
|
+
</details>
|
|
255
298
|
|
|
256
|
-
|
|
257
|
-
npx det-acp exec ./agent.policy.yaml echo "hello"
|
|
299
|
+
### CLI Reference
|
|
258
300
|
|
|
259
|
-
|
|
260
|
-
npx det-acp
|
|
261
|
-
|
|
262
|
-
#
|
|
263
|
-
npx det-acp
|
|
301
|
+
```bash
|
|
302
|
+
npx det-acp init <agent> # Set up governance (cursor, codex, claude-code)
|
|
303
|
+
npx det-acp init <agent> --policy <file> # Use custom policy
|
|
304
|
+
npx det-acp validate <policy-file> # Validate a policy
|
|
305
|
+
npx det-acp proxy --policy <policy-file> # Start MCP proxy (simplified)
|
|
306
|
+
npx det-acp proxy <config-file> # Start MCP proxy (full config)
|
|
307
|
+
npx det-acp exec <policy-file> <command> # Execute via shell proxy
|
|
308
|
+
npx det-acp report <ledger-file> # View audit report
|
|
309
|
+
npx det-acp serve [--port <port>] # Start HTTP session server
|
|
264
310
|
```
|
|
265
311
|
|
|
312
|
+
---
|
|
313
|
+
|
|
266
314
|
## Architecture
|
|
267
315
|
|
|
268
316
|
### Component Architecture
|
|
269
317
|
|
|
270
318
|
```mermaid
|
|
271
319
|
graph TB
|
|
272
|
-
subgraph
|
|
320
|
+
subgraph External["External Systems"]
|
|
273
321
|
BackendMCP["Backend MCP Servers"]
|
|
274
|
-
|
|
322
|
+
Approvers["Human / Webhook Approvers"]
|
|
275
323
|
end
|
|
276
324
|
|
|
277
|
-
subgraph
|
|
278
|
-
MCPProxy["
|
|
279
|
-
|
|
280
|
-
HTTPServer["HTTP Server
|
|
281
|
-
LibrarySDK["Library SDK
|
|
325
|
+
subgraph Integration["Integration Layer"]
|
|
326
|
+
MCPProxy["MCP Proxy Server"]
|
|
327
|
+
ShellProxy["Shell Proxy"]
|
|
328
|
+
HTTPServer["HTTP Server"]
|
|
329
|
+
LibrarySDK["Library SDK"]
|
|
282
330
|
end
|
|
283
331
|
|
|
284
|
-
subgraph
|
|
285
|
-
Gateway["
|
|
286
|
-
SessionMgr["
|
|
287
|
-
PolicyEval["
|
|
288
|
-
GateMgr["
|
|
289
|
-
|
|
332
|
+
subgraph Core["Core Engine"]
|
|
333
|
+
Gateway["Agent Gateway"]
|
|
334
|
+
SessionMgr["Session Manager"]
|
|
335
|
+
PolicyEval["Policy Evaluator"]
|
|
336
|
+
GateMgr["Gate Manager"]
|
|
337
|
+
ActionReg["Action Registry"]
|
|
290
338
|
end
|
|
291
339
|
|
|
292
|
-
subgraph
|
|
293
|
-
Ledger["
|
|
294
|
-
Rollback["
|
|
340
|
+
subgraph Infra["Infrastructure"]
|
|
341
|
+
Ledger["Evidence Ledger<br/>(JSONL + SHA-256)"]
|
|
342
|
+
Rollback["Rollback Manager"]
|
|
295
343
|
end
|
|
296
344
|
|
|
297
|
-
subgraph
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
345
|
+
subgraph Tools["Tool Adapters"]
|
|
346
|
+
FR["file:read"]
|
|
347
|
+
FW["file:write"]
|
|
348
|
+
CR["command:run"]
|
|
349
|
+
HR["http:request"]
|
|
350
|
+
GD["git:diff"]
|
|
351
|
+
GA["git:apply"]
|
|
304
352
|
end
|
|
305
353
|
|
|
306
354
|
MCPProxy --> Gateway
|
|
307
|
-
|
|
355
|
+
ShellProxy --> Gateway
|
|
308
356
|
HTTPServer --> Gateway
|
|
309
357
|
LibrarySDK --> Gateway
|
|
310
358
|
|
|
311
359
|
Gateway --> SessionMgr
|
|
312
|
-
Gateway -->
|
|
360
|
+
Gateway --> ActionReg
|
|
313
361
|
Gateway --> GateMgr
|
|
314
362
|
|
|
315
363
|
SessionMgr --> PolicyEval
|
|
316
364
|
SessionMgr --> GateMgr
|
|
317
365
|
SessionMgr --> Ledger
|
|
318
366
|
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
367
|
+
ActionReg --> FR
|
|
368
|
+
ActionReg --> FW
|
|
369
|
+
ActionReg --> CR
|
|
370
|
+
ActionReg --> HR
|
|
371
|
+
ActionReg --> GD
|
|
372
|
+
ActionReg --> GA
|
|
325
373
|
|
|
326
|
-
Rollback -->
|
|
374
|
+
Rollback --> ActionReg
|
|
327
375
|
Rollback --> Ledger
|
|
328
376
|
|
|
329
377
|
MCPProxy --> BackendMCP
|
|
330
|
-
GateMgr -->
|
|
378
|
+
GateMgr --> Approvers
|
|
331
379
|
```
|
|
332
380
|
|
|
333
381
|
### Action Evaluation Flow
|
|
@@ -335,83 +383,76 @@ graph TB
|
|
|
335
383
|
```mermaid
|
|
336
384
|
sequenceDiagram
|
|
337
385
|
participant Agent
|
|
338
|
-
participant Integration
|
|
339
|
-
participant Gateway as
|
|
340
|
-
participant Session as
|
|
341
|
-
participant Policy as
|
|
342
|
-
participant Gate as
|
|
343
|
-
participant Ledger as
|
|
344
|
-
|
|
345
|
-
Agent->>Integration: Action request (tool, input)
|
|
346
|
-
Integration->>Gateway: evaluate(sessionId, action)
|
|
347
|
-
Gateway->>Session: evaluate(sessionId, action)
|
|
348
|
-
|
|
349
|
-
Session->>Policy: evaluateSessionAction(action
|
|
350
|
-
|
|
351
|
-
Policy
|
|
352
|
-
|
|
353
|
-
Session
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
Gate-->>Session:
|
|
361
|
-
|
|
386
|
+
participant Integration
|
|
387
|
+
participant Gateway as Agent Gateway
|
|
388
|
+
participant Session as Session Manager
|
|
389
|
+
participant Policy as Policy Evaluator
|
|
390
|
+
participant Gate as Gate Manager
|
|
391
|
+
participant Ledger as Evidence Ledger
|
|
392
|
+
|
|
393
|
+
Agent ->> Integration: Action request (tool, input)
|
|
394
|
+
Integration ->> Gateway: evaluate(sessionId, action)
|
|
395
|
+
Gateway ->> Session: evaluate(sessionId, action)
|
|
396
|
+
|
|
397
|
+
Session ->> Policy: evaluateSessionAction(action)
|
|
398
|
+
|
|
399
|
+
Note right of Policy: 1. Session state check<br/>2. Rate limits & escalation<br/>3. Forbidden patterns<br/>4. Capability & scope match<br/>5. Budget limits<br/>6. Gate lookup
|
|
400
|
+
|
|
401
|
+
Policy -->> Session: allow / deny / gate
|
|
402
|
+
|
|
403
|
+
Session ->> Ledger: append(action:evaluate)
|
|
404
|
+
|
|
405
|
+
alt Gate required
|
|
406
|
+
Session ->> Gate: requestApproval(action, gate)
|
|
407
|
+
alt Approved
|
|
408
|
+
Gate -->> Session: approved
|
|
409
|
+
else Pending
|
|
410
|
+
Gate -->> Session: pending
|
|
411
|
+
Note over Agent, Gate: Session paused until resolved
|
|
362
412
|
end
|
|
363
413
|
end
|
|
364
414
|
|
|
365
|
-
Session-->>Gateway: EvaluateResponse
|
|
366
|
-
Gateway-->>Integration: decision + reasons
|
|
367
|
-
Integration-->>Agent: allow / deny / gate
|
|
368
|
-
|
|
369
|
-
alt
|
|
370
|
-
Note over Agent:
|
|
371
|
-
Agent->>Integration: recordResult(actionId, result)
|
|
372
|
-
Integration->>Gateway: recordResult(sessionId, actionId, result)
|
|
373
|
-
Gateway->>Session: recordResult(
|
|
374
|
-
Session->>Session: Update budget
|
|
375
|
-
Session->>Ledger: append(
|
|
415
|
+
Session -->> Gateway: EvaluateResponse
|
|
416
|
+
Gateway -->> Integration: decision + reasons
|
|
417
|
+
Integration -->> Agent: allow / deny / gate
|
|
418
|
+
|
|
419
|
+
alt Allowed
|
|
420
|
+
Note over Agent: Executes action externally
|
|
421
|
+
Agent ->> Integration: recordResult(actionId, result)
|
|
422
|
+
Integration ->> Gateway: recordResult(sessionId, actionId, result)
|
|
423
|
+
Gateway ->> Session: recordResult(result)
|
|
424
|
+
Session ->> Session: Update budget tracking
|
|
425
|
+
Session ->> Ledger: append(action:result)
|
|
376
426
|
end
|
|
377
427
|
|
|
378
428
|
opt Session complete
|
|
379
|
-
Agent->>Integration: terminateSession()
|
|
380
|
-
Integration->>Gateway:
|
|
381
|
-
Gateway->>Session: terminate(sessionId)
|
|
382
|
-
Session->>Ledger: append(
|
|
383
|
-
Session-->>
|
|
384
|
-
Gateway-->>Integration: SessionReport
|
|
385
|
-
Integration-->>Agent: SessionReport
|
|
429
|
+
Agent ->> Integration: terminateSession()
|
|
430
|
+
Integration ->> Gateway: terminate(sessionId)
|
|
431
|
+
Gateway ->> Session: terminate(sessionId)
|
|
432
|
+
Session ->> Ledger: append(session:terminate)
|
|
433
|
+
Session -->> Agent: Session Report
|
|
386
434
|
end
|
|
387
435
|
```
|
|
388
436
|
|
|
389
437
|
### Session Lifecycle
|
|
390
438
|
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
439
|
+
```mermaid
|
|
440
|
+
stateDiagram-v2
|
|
441
|
+
[*] --> Created: createSession()
|
|
442
|
+
Created --> Evaluating: evaluate(action)
|
|
443
|
+
Evaluating --> Allowed: policy allows
|
|
444
|
+
Evaluating --> Denied: policy denies
|
|
445
|
+
Evaluating --> Gated: gate required
|
|
446
|
+
Gated --> Allowed: approved
|
|
447
|
+
Gated --> Denied: rejected
|
|
448
|
+
Allowed --> Recording: recordResult()
|
|
449
|
+
Recording --> Evaluating: next action
|
|
450
|
+
Denied --> Evaluating: next action
|
|
451
|
+
Recording --> Terminated: terminateSession()
|
|
452
|
+
Evaluating --> Terminated: terminateSession()
|
|
453
|
+
Terminated --> [*]
|
|
397
454
|
```
|
|
398
455
|
|
|
399
|
-
Sessions track:
|
|
400
|
-
|
|
401
|
-
- Cumulative budget (runtime, files changed, cost)
|
|
402
|
-
- Action history (for rate limiting and escalation)
|
|
403
|
-
- Pending gates (human approval required)
|
|
404
|
-
- Evidence ledger (tamper-evident audit trail)
|
|
405
|
-
|
|
406
|
-
### Integration Modes
|
|
407
|
-
|
|
408
|
-
| Mode | How it works | Best for |
|
|
409
|
-
| --------------------- | ----------------------------------------------- | ----------------------------------- |
|
|
410
|
-
| **MCP Proxy** | Transparent proxy between agent and MCP servers | Cursor, Claude Code, any MCP client |
|
|
411
|
-
| **Shell Proxy** | Command wrapper that validates before executing | CLI agents, shell-based workflows |
|
|
412
|
-
| **HTTP API** | REST endpoints for session management | Any language, custom integrations |
|
|
413
|
-
| **Library SDK** | TypeScript API for in-process governance | Custom TypeScript agents |
|
|
414
|
-
|
|
415
456
|
### Evidence Ledger
|
|
416
457
|
|
|
417
458
|
Every action produces an immutable audit record in JSONL format with SHA-256 hash chaining:
|
|
@@ -424,34 +465,40 @@ Every action produces an immutable audit record in JSONL format with SHA-256 has
|
|
|
424
465
|
|
|
425
466
|
If any entry is tampered with, the hash chain breaks and integrity verification fails.
|
|
426
467
|
|
|
427
|
-
|
|
468
|
+
---
|
|
428
469
|
|
|
429
|
-
|
|
470
|
+
## Policy DSL Reference
|
|
430
471
|
|
|
431
|
-
| Section
|
|
432
|
-
|
|
433
|
-
| `capabilities` |
|
|
434
|
-
| `limits`
|
|
435
|
-
| `gates`
|
|
436
|
-
| `evidence`
|
|
437
|
-
| `forbidden`
|
|
438
|
-
| `session`
|
|
439
|
-
| `remediation`
|
|
472
|
+
| Section | Purpose |
|
|
473
|
+
|---------|---------|
|
|
474
|
+
| `capabilities` | Allowed tools and their scoped paths, binaries, or domains |
|
|
475
|
+
| `limits` | Runtime, cost, file change, and retry budgets |
|
|
476
|
+
| `gates` | Actions requiring human or webhook approval |
|
|
477
|
+
| `evidence` | Artifacts that must be recorded (checksums, diffs) |
|
|
478
|
+
| `forbidden` | Patterns that are always blocked |
|
|
479
|
+
| `session` | Max actions, rate limits, escalation rules |
|
|
480
|
+
| `remediation` | Error handling rules and fallback chains |
|
|
440
481
|
|
|
441
|
-
|
|
482
|
+
See [examples/](examples/) for complete policy files.
|
|
442
483
|
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
|
448
|
-
|
|
449
|
-
| `
|
|
450
|
-
| `
|
|
484
|
+
---
|
|
485
|
+
|
|
486
|
+
## Built-in Tool Adapters
|
|
487
|
+
|
|
488
|
+
| Tool | Description |
|
|
489
|
+
|------|-------------|
|
|
490
|
+
| `file:read` | Read files within scoped paths |
|
|
491
|
+
| `file:write` | Write files with backup for rollback |
|
|
492
|
+
| `command:run` | Execute allow-listed binaries with timeout |
|
|
493
|
+
| `http:request` | HTTP requests to allow-listed domains |
|
|
494
|
+
| `git:diff` | Get git diff output |
|
|
495
|
+
| `git:apply` | Apply git patches with stash-based rollback |
|
|
496
|
+
|
|
497
|
+
---
|
|
451
498
|
|
|
452
|
-
|
|
499
|
+
## Custom Tool Adapters
|
|
453
500
|
|
|
454
|
-
Extend the `ToolAdapter` base class:
|
|
501
|
+
Extend the `ToolAdapter` base class to add your own tools:
|
|
455
502
|
|
|
456
503
|
```typescript
|
|
457
504
|
import { ToolAdapter } from 'deterministic-agent-control-protocol';
|
|
@@ -471,22 +518,32 @@ class MyCustomTool extends ToolAdapter {
|
|
|
471
518
|
gateway.getRegistry().register(new MyCustomTool());
|
|
472
519
|
```
|
|
473
520
|
|
|
521
|
+
---
|
|
522
|
+
|
|
474
523
|
## Development
|
|
475
524
|
|
|
476
525
|
```bash
|
|
477
|
-
# Install dependencies
|
|
478
|
-
npm
|
|
526
|
+
npm install # Install dependencies
|
|
527
|
+
npm run lint # Type check (TypeScript strict)
|
|
528
|
+
npm test # Run tests (Vitest)
|
|
529
|
+
npm run build # Build
|
|
530
|
+
```
|
|
531
|
+
|
|
532
|
+
---
|
|
479
533
|
|
|
480
|
-
|
|
481
|
-
npm run lint
|
|
534
|
+
## Contributing
|
|
482
535
|
|
|
483
|
-
|
|
484
|
-
npm test
|
|
536
|
+
Contributions are welcome! Please follow these guidelines:
|
|
485
537
|
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
538
|
+
1. **Fork** the repository and create a feature branch
|
|
539
|
+
2. **Follow** the coding standards (TypeScript strict, ESM, Zod validation)
|
|
540
|
+
3. **Write tests** mirroring `src/` structure under `tests/`
|
|
541
|
+
4. **Run** `npm test && npm run lint` before submitting
|
|
542
|
+
5. **Use** [Conventional Commits](https://www.conventionalcommits.org/) for commit messages
|
|
543
|
+
6. **Open a PR** with a clear description of changes
|
|
544
|
+
|
|
545
|
+
---
|
|
489
546
|
|
|
490
547
|
## License
|
|
491
548
|
|
|
492
|
-
MIT
|
|
549
|
+
[MIT](LICENSE)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@det-acp/core",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"description": "Agent Governance Gateway — bounded, auditable, session-aware control for AI agents with MCP proxy, shell proxy, and HTTP API",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -60,11 +60,11 @@
|
|
|
60
60
|
"license": "MIT",
|
|
61
61
|
"repository": {
|
|
62
62
|
"type": "git",
|
|
63
|
-
"url": "https://github.com/
|
|
63
|
+
"url": "https://github.com/elliot35/deterministic-agent-control-protocol.git"
|
|
64
64
|
},
|
|
65
|
-
"homepage": "https://github.com/
|
|
65
|
+
"homepage": "https://github.com/elliot35/deterministic-agent-control-protocol#readme",
|
|
66
66
|
"bugs": {
|
|
67
|
-
"url": "https://github.com/
|
|
67
|
+
"url": "https://github.com/elliot35/deterministic-agent-control-protocol/issues"
|
|
68
68
|
},
|
|
69
69
|
"publishConfig": {
|
|
70
70
|
"access": "public"
|