docket-agent 0.1.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 CHANGED
@@ -7,7 +7,10 @@
7
7
  Before your agent acts, it checks a one-page rule file you wrote: allow, ask,
8
8
  or deny. After, it leaves a tamper-evident record. Anything you didn't write
9
9
  down, the agent must ask about. Plain Markdown in your repo; works with
10
- Claude, Codex, Cursor, and any MCP client.
10
+ Claude, ChatGPT/Codex, Gemini, Cursor, OpenClaw, Hermes, and any MCP client.
11
+
12
+ **Install:** `npm install -g docket-agent` · **Docs:**
13
+ [shahcolate.github.io/docket/docs.html](https://shahcolate.github.io/docket/docs.html)
11
14
 
12
15
  Zero dependencies · plain Markdown + JSONL · MIT
13
16
 
@@ -202,6 +205,47 @@ The agent gets four tools:
202
205
  Warrant checks made by the agent land in the record too. *"Did the agent
203
206
  even ask?"* becomes a grep.
204
207
 
208
+ ## OpenClaw and Hermes
209
+
210
+ **[OpenClaw](https://docs.openclaw.ai)** injects your workspace's `AGENTS.md`
211
+ into the agent's system prompt at the start of every session — so compile
212
+ straight into the workspace (fitting, given the story that opens this README):
213
+
214
+ ```console
215
+ $ cd ~/.openclaw/workspace
216
+ $ npx docket-agent init
217
+ $ npx docket-agent new followup --template client-follow-up
218
+ $ npx docket-agent compile --target agents --write
219
+ ```
220
+
221
+ Docket only manages its own marked block inside `AGENTS.md` — your existing
222
+ rules, `SOUL.md`, and the rest of the workspace stay untouched. OpenClaw can
223
+ also run the MCP server for native checks and record entries: add `docket`
224
+ as an MCP server in your OpenClaw config with
225
+ `command: npx, args: ["-y", "docket-agent", "mcp", "--dir", "~/.openclaw/workspace"]`.
226
+
227
+ **[Hermes](https://hermes-agent.nousresearch.com/docs/)** (Nous Research)
228
+ reads `AGENTS.md` context files too — run the same three commands in the
229
+ directory Hermes works from. For native tools, add docket under the MCP
230
+ servers section of `~/.hermes/config.yaml`:
231
+
232
+ ```yaml
233
+ docket:
234
+ command: npx
235
+ args: ["-y", "docket-agent", "mcp", "--dir", "/path/to/your/project"]
236
+ ```
237
+
238
+ Any other agent that reads `AGENTS.md`, `CLAUDE.md`, `GEMINI.md`, or speaks
239
+ MCP gets the same treatment — one loop file, every agent under the same
240
+ warrant.
241
+
242
+ ## Documentation
243
+
244
+ The full guide — concepts, loop-file reference, the verdict algorithm,
245
+ matching semantics, record internals, CLI reference, and per-tool setup —
246
+ lives at **[the docs site](https://shahcolate.github.io/docket/docs.html)**.
247
+ The normative format definition is the [Loop File Spec](spec/SPEC.md).
248
+
205
249
  ## Five questions, then the loop exists
206
250
 
207
251
  `docket new <name>` interviews you:
@@ -215,6 +259,32 @@ even ask?"* becomes a grep.
215
259
  Unwritten answers get guessed at. Written answers get enforced — the
216
260
  questions *are* the schema: brief, procedure, warrant, reserved, record.
217
261
 
262
+ ## It iterates itself — with a human veto
263
+
264
+ The record knows where the warrant chafes: every time the agent hit an
265
+ unlisted action, a default-ask was logged. `docket review` mines those and
266
+ proposes the exact amendments:
267
+
268
+ ```console
269
+ $ docket review
270
+ 2 proposed amendments — from repeated asks in the record
271
+
272
+ 1. appeal — allow read: "state insurance regulations" (asked 4×)
273
+ 2. appeal — allow draft: "timeline summary" (asked 2×)
274
+
275
+ allow read: "state insurance regulations" in appeal? [y/N] y
276
+ ✓ appeal: read now covers "state insurance regulations"
277
+ ```
278
+
279
+ Three rules keep it honest: the analysis is automatic but **applying is
280
+ always a human keystroke** (an agent that widens its own permissions is the
281
+ exact failure docket exists to prevent — it's in our red-team suite);
282
+ anything on the `ask` or `never` lists is **never proposed**, however often
283
+ it recurs — those are policy, not friction; and every approved amendment is
284
+ **appended to the record**, so even the evolution of the rules is auditable.
285
+
286
+ Run it weekly, or wire it into a cron — the proposals wait for you.
287
+
218
288
  ## Starter loops
219
289
 
220
290
  Seven templates, each a complete worked example (`docket templates`):
@@ -249,7 +319,7 @@ Read the [Loop File Spec](spec/SPEC.md) — it's short on purpose.
249
319
  - [ ] `docket check` as a Claude Code PreToolUse hook recipe
250
320
  - [ ] Loop inheritance (`extends:`) for team baselines
251
321
  - [ ] Record export → human-readable work summaries
252
- - [ ] Adapters: OpenAI custom instructions, Gemini, Windsurf
322
+ - [ ] Adapters: OpenAI custom instructions, Windsurf
253
323
 
254
324
  ## Contributing
255
325
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "docket-agent",
3
- "version": "0.1.0",
3
+ "version": "0.2.1",
4
4
  "description": "The permission layer and paper trail for AI agents. Your agent checks a rule file before it acts - allow, ask, or deny - and leaves a tamper-evident record after.",
5
5
  "type": "module",
6
6
  "bin": {
package/spec/SPEC.md CHANGED
@@ -181,12 +181,14 @@ Storage: `.docket/record.jsonl`, one JSON object per line, append-only.
181
181
  {"seq":3,"ts":"2026-07-03T10:15:00.000Z","loop":"insurance-appeal","kind":"check","action":"send","target":"appeal email to insurer","verdict":"ask","rule":"ask: anything addressed to the insurer","prev":"sha256:…","hash":"sha256:…"}
182
182
  ```
183
183
 
184
- Two kinds today:
184
+ Three kinds today:
185
185
 
186
186
  - `check` — a warrant check, recorded automatically with its verdict. The
187
187
  question "did the agent even ask?" becomes answerable.
188
188
  - `note` — a work entry with any of: `saw`, `did`, `skipped`, `stopped`,
189
189
  `note`.
190
+ - `amend` — a human-approved warrant widening (`action`, `added`, `asks`),
191
+ written by `docket review`. Rule changes are evidence too.
190
192
 
191
193
  ### The hash chain
192
194
 
@@ -210,6 +212,14 @@ when the heads disagree. The chain doesn't stop tampering — it's a plain
210
212
  file — it makes tampering **visible**, which is what an audit trail is for.
211
213
  (Cryptographically signing the head is on the roadmap.)
212
214
 
215
+ ## Review
216
+
217
+ `docket review` clusters repeated default-ask checks from the record and
218
+ proposes the corresponding warrant additions. Implementations must not apply
219
+ proposals without explicit human approval, must never propose targets that
220
+ match the loop's `ask` or `never` lists, and must append an `amend` entry to
221
+ the record for every applied change.
222
+
213
223
  ## Compiled context
214
224
 
215
225
  Loops are the source of truth; assistant-specific files are build artifacts.
package/src/cli.js CHANGED
@@ -6,6 +6,7 @@ import { cmdList, cmdShow } from './commands/list.js';
6
6
  import { cmdCheck } from './commands/check.js';
7
7
  import { cmdRecord } from './commands/record.js';
8
8
  import { cmdCompile } from './commands/compile.js';
9
+ import { cmdReview } from './commands/review.js';
9
10
  import { cmdMcp } from './commands/mcp.js';
10
11
 
11
12
  const HELP = `
@@ -25,13 +26,18 @@ ${bold('Working with loops')}
25
26
  ask the warrant: allow, ask, or deny?
26
27
  (actions: read, draft, change, send)
27
28
 
29
+ ${bold('Iterating')}
30
+ ${cyan('review')} [--min 2] [--loop <name>] [--yes]
31
+ propose warrant updates from repeated asks —
32
+ you approve each one; approvals go on the record
33
+
28
34
  ${bold('The record')}
29
35
  ${cyan('record add')} <loop> [--did ..] [--saw ..] [--skipped ..] [--stopped ..] [--note ..]
30
36
  ${cyan('record log')} [loop] [--n 20]
31
37
  ${cyan('record verify')} verify the hash chain end to end
32
38
 
33
39
  ${bold('Portability')}
34
- ${cyan('compile')} [--target claude|agents|cursor|raw] [--loop <name>] [--write]
40
+ ${cyan('compile')} [--target claude|agents|gemini|cursor|raw] [--loop <name>] [--write]
35
41
  render loops into CLAUDE.md / AGENTS.md / Cursor rules
36
42
  ${cyan('mcp')} run the MCP server (stdio) for agent integration
37
43
 
@@ -70,6 +76,8 @@ export async function main(argv) {
70
76
  return cmdRecord(rest);
71
77
  case 'compile':
72
78
  return cmdCompile(rest);
79
+ case 'review':
80
+ return cmdReview(rest);
73
81
  case 'mcp':
74
82
  return cmdMcp(rest);
75
83
  default:
@@ -16,6 +16,9 @@ function formatEntry(e) {
16
16
  const style = VERDICT_STYLE[e.verdict] ?? { color: (s) => s, badge: e.verdict };
17
17
  return `${head} ${style.color(style.badge.toLowerCase())} ${e.action} → "${e.target}" ${dim(`(${e.rule})`)}`;
18
18
  }
19
+ if (e.kind === 'amend') {
20
+ return `${head} amended warrant: ${e.action} now covers "${e.added}" ${dim(`(after ${e.asks} asks)`)}`;
21
+ }
19
22
  const parts = [];
20
23
  if (e.saw) parts.push(`saw: ${e.saw}`);
21
24
  if (e.did) parts.push(`did: ${e.did}`);
Binary file