@mrciphersmith/keryx 0.2.154 → 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
@@ -253,19 +258,55 @@ What is in it today:
253
258
  over stdio — so an ACP client (an editor, typically) can launch keryx as a
254
259
  subprocess, open a session bound to a project, and drive a real harness turn
255
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.
256
271
  A gated tool call is asked through `session/request_permission` rather than
257
272
  approved locally — only an explicit allow runs it, and an `allow_always`
258
273
  answer is remembered by the client, never persisted by keryx — and
259
274
  `session/cancel`, `session/list`, and `session/load` (replaying a session
260
275
  created anywhere, including one from `keryx shell`) are all implemented.
261
- Writes and shell execution stay local unconditionally (no `fs/write_text_file`
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`
262
286
  or `terminal/*` calls, whatever the client advertises), and there is no
263
287
  HTTP/WebSocket transport, no authentication over this wire, and no
264
- `session/resume`/`close`/`delete`/`set_mode`/`set_config_option`. Verified
265
- against the published v1 schema and this repo's own scripted test client,
266
- not yet against a shipping IDE. See [the CLI
267
- reference](docs/docs/cli-reference.md#acp) for the full method table and
268
- what keryx does when a capability is absent.
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).
269
310
  - **Plans that survive the turn.** For multi-step work, the agent can keep a
270
311
  structured execution plan in the session's own `plan.json` — beside the
271
312
  transcript, not inside the Slate — so closing a Slate (or a Flow reporting
@@ -394,15 +435,38 @@ Grouped by what you are trying to do, not by internal module layout.
394
435
  **Operate agents**
395
436
 
396
437
  - **tasks** — an agent-first Task Manager driven by `keryx flow`, with frozen
397
- 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).
398
444
  - **triggers** — declared automation over `.metaproject/triggers.json` (a
399
445
  repository event or a cron/systemd schedule): `reconcile`/`rebuild` keep the
400
- graph and wiki current, `open-flow`/`flow-next` open or report on Task
401
- Manager work. `keryx trigger install` extends the same hook files `sync
402
- install-hooks` and `update` already write into, rather than owning its own;
403
- `keryx trigger schedule` prints a cron line or systemd unit pair and runs no
404
- daemon of its own. Every fired run is recorded and gated by a project-wide
405
- spend ceiling and a run lock. See the [CLI reference](docs/docs/cli-reference.md#trigger).
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).
406
470
  - **security** — deterministic secrets / PII / prompt-injection / egress
407
471
  scanning, redaction, and a policy gate at agent write seams, with a committed
408
472
  evaluation corpus.
@@ -580,9 +644,12 @@ graph falls back to its deterministic resolver when a grammar is absent.
580
644
  | ripgrep is external | `keryx ctx rg` needs `rg` on `PATH` | Install ripgrep, or let the agent read files directly |
581
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 |
582
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 |
583
- | `keryx trigger`'s `flow-next` action only reports | It records the next task's status into the run record; it never dispatches an agent turn to work it | Dispatch the reported task yourself, or through a flow orchestrator |
584
- | Trigger spend ceiling is project-wide | `open-flow`/`flow-next` triggers share one ceiling with every other recorded trigger cost; there is no per-trigger override | Watch `keryx trigger status`'s recorded cost |
585
- | Trigger-run lock does not cover interactive commands | A person running `keryx sync --apply` / `keryx gdgraph build` by hand can still race a triggered `reconcile`/`rebuild` | Avoid running those by hand while triggers may be firing |
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 |
586
653
 
587
654
  Full detail, including known defects and platform caveats:
588
655
  [limitations](docs/docs/limitations.md).