Skip to content

Commit b034e93

Browse files
grypezclaude
andcommitted
feat(caprock): add audit CLI and slash-command skills
Adds an `audit` CLI that reports which permission rules and provisions were exercised in a given Claude session, plus SKILL.md manifests so `audit`, `setup`, and `status` are reachable as slash commands from Claude Code. - `bin/audit.ts` + `scripts/audit.sh`: cross-references the transcript's tool uses against the session-state allow/deny lists and the in-vat provision ledger (via the new `listVatProvisions` RPC), and prints a per-tool breakdown of which standing provisions were activated. - `skills/{audit,setup,status}/SKILL.md`: thin wrappers that invoke the corresponding `dist/bin/*.mjs` entry points. `setup` and `status` existed as scripts; this is the slash-command surface. - `src/rpc.ts:listVatProvisions`: queries the permission-tracker vat for its current provisions list, decoded back to JS values. - `package.json`: includes `skills/` in published files so the plugin install ships the manifests. - `bin/hook.ts:registerSkillPermissions`: adds the `audit.sh` entry to the auto-registered Bash permissions. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
1 parent 91de234 commit b034e93

8 files changed

Lines changed: 482 additions & 0 deletions

File tree

packages/caprock/bin/audit.ts

Lines changed: 419 additions & 0 deletions
Large diffs are not rendered by default.

packages/caprock/bin/hook.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,7 @@ async function registerSkillPermissions(): Promise<void> {
142142
const newEntries = [
143143
`Bash(${versionGlob}/scripts/status.sh *)`,
144144
`Bash(${versionGlob}/scripts/setup.sh)`,
145+
`Bash(${versionGlob}/scripts/audit.sh)`,
145146
].filter((entry) => !current.includes(entry));
146147

147148
if (newEntries.length === 0) {

packages/caprock/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
"dist/",
3030
"vat/",
3131
"hooks/",
32+
"skills/",
3233
".claude-plugin/"
3334
],
3435
"scripts": {

packages/caprock/scripts/audit.sh

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
#!/usr/bin/env bash
2+
PLUGIN_ROOT="$(cd "$(dirname "$0")/.." && pwd)"
3+
node "${PLUGIN_ROOT}/dist/bin/audit.mjs" "$@"
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
---
2+
description: Show which permission rules and provisions were activated by tool uses this session
3+
allowed-tools: Bash
4+
---
5+
6+
Run the caprock audit and show the output:
7+
8+
```bash
9+
node "${CLAUDE_PLUGIN_ROOT}/dist/bin/audit.mjs" "${CLAUDE_SESSION_ID}"
10+
```
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
---
2+
description: Run caprock setup diagnostics — checks tree-sitter bindings, daemon connectivity, and permissions
3+
allowed-tools: Bash
4+
---
5+
6+
Run the caprock setup diagnostic and show the output:
7+
8+
```bash
9+
node "${CLAUDE_PLUGIN_ROOT}/dist/bin/setup.mjs"
10+
```
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
---
2+
description: Show caprock authority tracking status and tool usage summary for this session
3+
allowed-tools: Bash
4+
---
5+
6+
Run the caprock status report and show the output:
7+
8+
```bash
9+
node "${CLAUDE_PLUGIN_ROOT}/dist/bin/status.mjs" "${CLAUDE_SESSION_ID}"
10+
```

packages/caprock/src/rpc.ts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -307,6 +307,34 @@ export async function recordProvisioned(
307307
await sendCommand({ socketPath, method: 'session.record', params });
308308
}
309309

310+
/**
311+
* Return all provisions currently stored in a permission-tracker vat.
312+
*
313+
* @param socketPath - The UNIX socket path.
314+
* @param rootKref - The vat's root kref.
315+
* @returns The list of provisions, oldest first, or an empty array on error.
316+
*/
317+
export async function listVatProvisions(
318+
socketPath: string,
319+
rootKref: string,
320+
): Promise<Provision[]> {
321+
try {
322+
const response = await sendCommand({
323+
socketPath,
324+
method: 'queueMessage',
325+
params: [rootKref, 'listProvisions', []],
326+
timeoutMs: 5_000,
327+
});
328+
if (isJsonRpcFailure(response)) {
329+
return [];
330+
}
331+
const raw = decodeCapData(response.result as CapData);
332+
return decodeSmallcapsStrings(raw) as Provision[];
333+
} catch {
334+
return [];
335+
}
336+
}
337+
310338
/**
311339
* Decode a CapData body to a JavaScript value.
312340
*

0 commit comments

Comments
 (0)