@mrciphersmith/keryx 0.2.153 → 0.2.155
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
|
@@ -32,6 +32,11 @@ It also ships **an agent runtime of its own**, built directly on that context:
|
|
|
32
32
|
durable sessions, an allow/ask/deny policy engine, kernel-enforced sandboxing,
|
|
33
33
|
child agents and evidence-gated completion. Keep using Codex, Claude or Cursor,
|
|
34
34
|
run `keryx shell`, or do both — they all read the same project brain.
|
|
35
|
+
You can delegate the work, not the responsibility: a managed flow freezes its
|
|
36
|
+
acceptance criteria before the work starts, lets them change only through a
|
|
37
|
+
recorded update with a reason, and completes only when every one is confirmed
|
|
38
|
+
against recorded evidence — under a named owner, with every confirmation and
|
|
39
|
+
the completion itself signed.
|
|
35
40
|
|
|
36
41
|
```bash
|
|
37
42
|
npm install -g @mrciphersmith/keryx
|
|
@@ -248,6 +253,60 @@ What is in it today:
|
|
|
248
253
|
session that keeps its ancestry, without editing a transcript by hand.
|
|
249
254
|
`/status` is the session inspector (identity, context window and limits when
|
|
250
255
|
the provider reported them); `/session-info` and `/info` are not aliases.
|
|
256
|
+
- **Agent Client Protocol server.** `keryx acp` speaks
|
|
257
|
+
[ACP](https://agentclientprotocol.com) v1 — newline-delimited JSON-RPC 2.0
|
|
258
|
+
over stdio — so an ACP client (an editor, typically) can launch keryx as a
|
|
259
|
+
subprocess, open a session bound to a project, and drive a real harness turn
|
|
260
|
+
with streamed `session/update` notifications instead of one dump at the end.
|
|
261
|
+
The session gets keryx's own read-only project tools — graph, wiki, memory,
|
|
262
|
+
flow status, skills, repo map, related tests, health status and
|
|
263
|
+
`search_code` — wherever `keryx shell` would offer them (same gate, same
|
|
264
|
+
definitions), alongside file reads, `shell_exec` and `apply_patch`; web
|
|
265
|
+
tools, keryx's own MCP servers, subagents and bus tools are left out on
|
|
266
|
+
purpose. keryx advertises the commands it handles over ACP — `/help`,
|
|
267
|
+
`/model`, `/reasoning`, `/status` — and answers them itself. The model is
|
|
268
|
+
the editor's model picker (a `configOptions` entry of category `model`,
|
|
269
|
+
listing what keryx can run here): switch it there or with `/model`, and it
|
|
270
|
+
applies from the next turn without touching `keryx shell`'s saved choice.
|
|
271
|
+
A gated tool call is asked through `session/request_permission` rather than
|
|
272
|
+
approved locally — only an explicit allow runs it, and an `allow_always`
|
|
273
|
+
answer is remembered by the client, never persisted by keryx — and
|
|
274
|
+
`session/cancel`, `session/list`, and `session/load` (replaying a session
|
|
275
|
+
created anywhere, including one from `keryx shell`) are all implemented.
|
|
276
|
+
With no `--provider`/`--model` a session starts on the provider and model
|
|
277
|
+
`keryx shell` saved (run `keryx shell` once and pick one); with nothing configured it
|
|
278
|
+
still answers `initialize` and refuses `session/new` with a message saying
|
|
279
|
+
what to configure — it never answers with a test stand-in. The client's own
|
|
280
|
+
stdio MCP servers from `mcpServers` are started for that session, their
|
|
281
|
+
tools offered through `search_tool`/`use_tool` with every call asked, one
|
|
282
|
+
running set shared by the threads that send the same list, and stopped when
|
|
283
|
+
the connection ends or `keryx acp` is sent SIGTERM/SIGINT; `http`/`sse` entries and a server that
|
|
284
|
+
fails to start are reported to the client by name, and the session still
|
|
285
|
+
opens. Writes and shell execution stay local unconditionally (no `fs/write_text_file`
|
|
286
|
+
or `terminal/*` calls, whatever the client advertises), and there is no
|
|
287
|
+
HTTP/WebSocket transport, no authentication over this wire, and no
|
|
288
|
+
`session/resume`/`close`/`delete`/`set_mode`. Verified
|
|
289
|
+
against the published v1 schema and this repo's own scripted test client;
|
|
290
|
+
Zed has been driven against it by hand, and no shipping IDE is part of the
|
|
291
|
+
automated tests. See [the CLI
|
|
292
|
+
reference](docs/docs/cli-reference.md#acp) for the full method table, the
|
|
293
|
+
tool roster and why each exclusion, the commands, and what keryx does when a
|
|
294
|
+
capability is absent.
|
|
295
|
+
- **ACP client — foreign agents under keryx's policy.** The other direction:
|
|
296
|
+
`keryx agents external run gemini-acp --task "…"` launches an external ACP
|
|
297
|
+
agent (Gemini CLI's `--experimental-acp`) as a subprocess and drives it as
|
|
298
|
+
its client, inside a disposable git worktree. keryx advertises only what it
|
|
299
|
+
serves (`fs.readTextFile`; `fs.writeTextFile` with `--write`; never
|
|
300
|
+
`terminal`), serves every `fs/*` request itself — confined by real path to
|
|
301
|
+
the worktree — and answers every `session/request_permission` through its
|
|
302
|
+
own approval gate with the mode lowered to `ask`: only an explicit allow
|
|
303
|
+
selects `allow_once`, `allow_always` is never chosen, and an unattended run
|
|
304
|
+
refuses anything that needs a human. The agent gets keryx's context as a
|
|
305
|
+
read-only `serve-mcp` launched from the running build, and every run is a
|
|
306
|
+
keryx session with its decisions, fs requests, usage and cost (or
|
|
307
|
+
`missing`). Honest limit: an agent's own internal tools never reach ACP, so
|
|
308
|
+
keryx cannot see or gate them — the disposable worktree is what contains
|
|
309
|
+
them. See the [ACP client guide](docs/docs/guides/acp-client.md).
|
|
251
310
|
- **Plans that survive the turn.** For multi-step work, the agent can keep a
|
|
252
311
|
structured execution plan in the session's own `plan.json` — beside the
|
|
253
312
|
transcript, not inside the Slate — so closing a Slate (or a Flow reporting
|
|
@@ -376,7 +435,38 @@ Grouped by what you are trying to do, not by internal module layout.
|
|
|
376
435
|
**Operate agents**
|
|
377
436
|
|
|
378
437
|
- **tasks** — an agent-first Task Manager driven by `keryx flow`, with frozen
|
|
379
|
-
acceptance criteria and status gates.
|
|
438
|
+
acceptance criteria and status gates. Each flow can name an accountable
|
|
439
|
+
human **owner** (`flow init --owner`/`flow owner set`, never inferred), and
|
|
440
|
+
`ac confirm`/`complete` append an honest, append-only **signature** — who
|
|
441
|
+
acted, when, and what was signed, with its basis (`stated`/`derived`/
|
|
442
|
+
`unknown`) stated rather than assumed. See
|
|
443
|
+
[TM-02](docs/decisions/keryx-harness/TM-02-flow-owner-and-signed-completion.md).
|
|
444
|
+
- **triggers** — declared automation over `.metaproject/triggers.json` (a
|
|
445
|
+
repository event or a cron/systemd schedule): `reconcile`/`rebuild` keep the
|
|
446
|
+
graph and wiki current, `open-flow` opens Task Manager work, and `flow-next`
|
|
447
|
+
either reports a flow's next task or — with a `dispatch` block — dispatches a
|
|
448
|
+
keryx agent to work it unattended: in a throwaway worktree on a
|
|
449
|
+
`trigger/<flow>-<task>` branch that is never pushed, its commands and its
|
|
450
|
+
health gate inside a mandatory hardened sandbox (network off, home and
|
|
451
|
+
credentials hidden, allow-listed environment), every would-be-approval
|
|
452
|
+
denied and recorded, spend reserved before the first model call, tokens and
|
|
453
|
+
USD recorded, and a per-trigger spend ceiling on top of the project-wide one.
|
|
454
|
+
`keryx trigger install` extends the same hook files `sync install-hooks` and
|
|
455
|
+
`update` already write into; `keryx trigger schedule` prints a cron line or
|
|
456
|
+
systemd unit pair and runs no daemon of its own. Triggered runs and a manual
|
|
457
|
+
`sync --apply`/`gdgraph build` share one maintenance lock (manual waits,
|
|
458
|
+
triggered refuses). See the [CLI reference](docs/docs/cli-reference.md#trigger).
|
|
459
|
+
- **governance** — `keryx governance report`, one read-only report unifying what
|
|
460
|
+
is already recorded: review-round spend per flow (USD and tokens, with a
|
|
461
|
+
rounds-with-cost/rounds-total count for partial coverage), project-wide
|
|
462
|
+
trigger spend (never attributed to a flow — the run record carries no flow
|
|
463
|
+
reference), who confirmed each acceptance criterion and who signed
|
|
464
|
+
completion (with identity basis), and every `flow complete` attempt's gate
|
|
465
|
+
outcomes. A figure nobody recorded is reported as "not recorded", never as
|
|
466
|
+
zero. Writes `.metaproject/data/governance/artifacts/latest.{md,json}`, the
|
|
467
|
+
same convention `keryx health run` uses; `--all-projects` also covers every
|
|
468
|
+
project in the user-global registry. See the
|
|
469
|
+
[CLI reference](docs/docs/cli-reference.md#governance).
|
|
380
470
|
- **security** — deterministic secrets / PII / prompt-injection / egress
|
|
381
471
|
scanning, redaction, and a policy gate at agent write seams, with a committed
|
|
382
472
|
evaluation corpus.
|
|
@@ -554,6 +644,12 @@ graph falls back to its deterministic resolver when a grammar is absent.
|
|
|
554
644
|
| ripgrep is external | `keryx ctx rg` needs `rg` on `PATH` | Install ripgrep, or let the agent read files directly |
|
|
555
645
|
| Model commands need a credential | Four of the five commands above exit non-zero without one; `wiki enrich` exits `0` and marks the affected pages skipped | Everything else runs deterministically offline |
|
|
556
646
|
| External agents are read-only, and unproven against a live vendor process | A delegated CLI can read and search but never write; `worktree-write` is refused with a named reason. The parent gets the child's result and nothing before it — supervision of a running external child is not implemented. Everything is verified offline against recorded transcripts | Use keryx's own child agents for work that must mutate the tree |
|
|
647
|
+
| A dispatched `flow-next` task is "done" by checks, not review | `task done` means normal end + a commit on the trigger branch + `keryx health gate` passing in the worktree; nobody has read the diff | Review and merge the `trigger/<flow>-<task>` branch yourself |
|
|
648
|
+
| `trust` dispatch needs Linux + a working bubblewrap | The hardened unattended sandbox (network off, home hidden, allow-listed env) is bwrap-only; without it — or on macOS — a `trust` dispatch refuses before starting | Use `permissionMode: "ask"` (read-only), or run triggers on a Linux host with bwrap |
|
|
649
|
+
| `dispatch.network: true` is the host's full network | The agent's commands then reach the internet and every host loopback service; the model call never needs it (it is made outside the sandbox) | Leave `network` off; review the `trigger/*` branch before installing or building it |
|
|
650
|
+
| The unattended text floor is defence in depth | It can be spelled around (quoting, `$(…)`, interpreters); the boundary is the sandbox, not the floor | Keep `dispatch.network` off unless the task truly needs it |
|
|
651
|
+
| A killed dispatch keeps its spend reserved | Its reservation counts against both ceilings until closed | `keryx trigger status`, then `keryx trigger resolve <runId> --spent <usd>` |
|
|
652
|
+
| Dispatch cost is priced from your declared rates | keryx has no price table; wrong `rates` make both ceilings wrong by the same factor | Set `rates` from your provider's price list |
|
|
557
653
|
|
|
558
654
|
Full detail, including known defects and platform caveats:
|
|
559
655
|
[limitations](docs/docs/limitations.md).
|