@openlatch/client 0.2.2 → 0.3.3

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.
Files changed (2) hide show
  1. package/README.md +71 -257
  2. package/package.json +6 -6
package/README.md CHANGED
@@ -6,216 +6,47 @@
6
6
 
7
7
  <p align="center">
8
8
  <a href="https://github.com/OpenLatch/openlatch-client/actions/workflows/pr-checks.yml"><img src="https://github.com/OpenLatch/openlatch-client/actions/workflows/pr-checks.yml/badge.svg" alt="PR Checks" /></a>
9
- <a href="https://codecov.io/gh/OpenLatch/openlatch-client"><img src="https://codecov.io/gh/OpenLatch/openlatch-client/graph/badge.svg" alt="codecov" /></a>
10
- <a href="https://crates.io/crates/openlatch-client"><img src="https://img.shields.io/crates/v/openlatch-client.svg" alt="crates.io" /></a>
11
9
  <a href="https://www.npmjs.com/package/@openlatch/client"><img src="https://img.shields.io/npm/v/@openlatch/client.svg" alt="npm" /></a>
12
10
  <a href="LICENSE"><img src="https://img.shields.io/badge/license-Apache--2.0-blue.svg" alt="License" /></a>
13
11
  <a href="https://openlatch.slack.com"><img src="https://img.shields.io/badge/Slack-join%20us-4A154B?logo=slack&logoColor=white" alt="Slack" /></a>
14
12
  </p>
15
13
 
16
- ---
17
-
18
- **[OpenLatch](https://openlatch.ai) is the agent-agnostic execution control layer for enterprise AI agents.** This repository is its open-source **capture-and-enforce adapter**: the node that runs inside a coding agent's own execution path, evaluates every covered action against that agent's Autonomy Zone before it runs, and is what gives an agent the control level **Enforced**.
19
-
20
- It is **Mode 1 — the native hook** — the first of three adapters onto one policy brain. It plugs into agents through their native lifecycle hooks, decides locally, and forwards what it sees to the control plane.
21
-
22
- **This README is for people working on the client.** If you want to *use* OpenLatch, start at [docs.openlatch.ai](https://docs.openlatch.ai) — `npx @openlatch/client init` and you are done.
23
-
24
- ---
25
-
26
- ## Where this node sits
27
-
28
- OpenLatch runs a five-step control loop around each agent's **Agent Autonomy Zone** — the operating envelope of what an agent may do, authored on the platform as intent policies across five dimensions (Quality, Economics, Security, Safety, Compliance) and compiled to deterministic rules. This client touches four of the five steps. None of the authoring happens here.
29
-
30
- | Step | What this node does | What it does not do |
31
- | ---- | ------------------- | ------------------- |
32
- | **1 · Identify** | Stamps every event with agent type, session, host and identity, so the platform's record of a sanctioned agent stays live rather than quarterly | Discovery. An agent arrives here by being installed onto, never by being found |
33
- | **2 · Define** | Nothing. It receives the compiled zone as a signed policy bundle and holds it resident | Author policy. Intent policies are written and compiled on the platform |
34
- | **3 · Detect** | Captures the actions the execution graph is built from — tool calls, commands, file changes, model calls, cost — and matches them against the resident bundle | Detection of its own. No models, no scanning, no cross-host correlation |
35
- | **4 · Act** | Returns the verdict at the hook boundary, before the action runs, from an in-process evaluation | Ask the network for it |
36
- | **5 · Improve** | Writes the local audit log and forwards every event, verdict and mode asynchronously | Report, alert, or render a dashboard |
37
-
38
- Four properties shape the code more than any feature does:
39
-
40
- | Property | What it means here |
41
- | -------- | ------------------ |
42
- | **Inside the agent, not a proxy in front of it** | The decision point is the agent's own hook lifecycle, so it sees the *action* rather than the traffic. It is not a sandbox — the threat model is a **misbehaving** agent, not an operator working to defeat it |
43
- | **Local-authoritative** | The resident bundle is the authority, not a cache of one. Evaluation reads an in-memory handle and returns, so the node keeps deciding with the network unplugged |
44
- | **Sanctioned agents only** | Depth over dragnet. This node makes the agents an enterprise has already blessed enforceable; it does not go looking for the ones it has not |
45
- | **Coverage is a deployment outcome** | An adapter in the execution path is what makes an agent **Enforced**. Without one an agent can still be **Monitored** (visible through an integration) or **Known** (identified and classified). The record always states which level applies |
46
-
47
- ### The three adapters
48
-
49
- | Mode | Surface | This repo |
50
- | ---- | ------- | --------- |
51
- | **Mode 1 — native hook** | Coding agents, including hosted ones | **Yes.** Ships first |
52
- | **Mode 2 — framework middleware** | LangChain / LangGraph | No. Ships second |
53
- | **Mode 3 — SDK + tool / MCP gate** | Bedrock, Azure AI Foundry, custom agents | No. Ships third, or on demand |
54
-
55
- ### Verdicts, and which ones this node enforces today
56
-
57
- The verdict vocabulary is **Allow, Ask, Block or Optimize**. What this binary can express is narrower than the vocabulary, and this is the honest map of it. A verdict is deterministic because an explicit policy produced it.
58
-
59
- | Verdict | On the wire / in the bundle | What this node does today |
60
- | ------- | --------------------------- | ------------------------- |
61
- | **Allow** | `allow`, `approve` | The action proceeds. `approve` is a user-confirmed allow |
62
- | **Ask** | No wire variant — an `allow` / `approve` carrying `context` | Rendered to Claude Code as `permissionDecision: "ask"`, the alert as its reason. It **allows and flags**; it does not hold the agent waiting on a human. It prevents recurrence, not the first occurrence |
63
- | **Block** | `deny` — the only action a `kind=command` rule may take | Reaches the agent as a native deny at `pre_tool_use`, naming the rule that produced it |
64
- | **Optimize** | `kind=request` rules: `prefix_reorder`, `history_trim`, `prompt_edit` | **Measurement only.** `history_trim` and `prompt_edit` are rewritten to `observe` at bundle load whatever the config says; `prefix_reorder` may act only behind `boundary.transforms_act`, which ships `false`. Out of the box the boundary observes, reports what a transform *would* have saved, and forwards the original bytes |
65
-
66
- Staging is per rule: `observe` records the match and allows the action, `enforce` applies the verdict — Monitor and Enforce in the product. Most restrictive wins across matching rules, and every rule is coerced to `observe` when the bundle's `enforcement_enabled` is false.
67
-
68
- Deny enforcement is event-scoped. Only pre-action events have somewhere to put a deny; on a post-action event it degrades to `{}` and survives in the record alone.
14
+ <p align="center">
15
+ <a href="https://openlatch.ai">Website</a> ·
16
+ <a href="https://openlatch.ai/docs/">Docs</a> ·
17
+ <a href="https://app.openlatch.ai">Dashboard</a> ·
18
+ <a href="https://openlatch.slack.com">Slack</a>
19
+ </p>
69
20
 
70
21
  ---
71
22
 
72
- ## Develop
73
-
74
- ```bash
75
- git clone https://github.com/OpenLatch/openlatch-client && cd openlatch-client
76
- cargo build
77
- cargo test
78
- ```
79
-
80
- Rust 1.88+, no other prerequisites. `cargo build` produces both binaries in `target/debug/`.
23
+ **[OpenLatch](https://openlatch.ai) is the execution control layer for enterprise AI agents.** It turns human intent into **Agent Intent Policies** across each agent's **Autonomy Zone** — security, safety, compliance, economics and quality — and makes a deterministic decision on every covered action before it executes: allow, ask, block or optimize.
81
24
 
82
- ### Work in a sandbox, not on your own machine
25
+ This repository is its open-source **capture-and-enforce adapter**: the node that runs inside a coding agent's own execution path, evaluates every covered action against that agent's Autonomy Zone before it runs, and is what gives an agent the control level **Enforced**.
83
26
 
84
- `openlatch init` installs into `~/.openlatch`, writes `~/.claude/settings.json`, and points every live Claude Code session on the host at its boundary listener. You do not want your work-in-progress build doing that.
27
+ It plugs into the agent's native lifecycle hooks, decides locally and in-process, and forwards what it saw to the platform afterwards. The agent never waits on the network, and the verdict never depends on it.
85
28
 
86
- `olbox` gives you a complete install that cannot touch your own — its own state directory, its own agent config, its own ports:
29
+ ## Quick start
87
30
 
88
31
  ```bash
89
- cargo install --path tools/sandbox --locked # once
90
-
91
- olbox enter dev # a shell inside the sandbox
92
- openlatch init # installs into the sandbox and nothing else
93
- claude # this session — and only this session — is routed
94
- exit # and you are back on your own machine
32
+ npx @openlatch/client init # installs the client, detects your agents, wires their hooks
33
+ openlatch auth login # links this machine to your OpenLatch account (opens the browser)
34
+ claude # use your agent as usual — every tool call is now covered
95
35
  ```
96
36
 
97
- It lives in [`tools/sandbox`](tools/sandbox/README.md) rather than in the client, because sandboxing is what *we* need and the client is what customers install. `olbox list`, `olbox exec dev -- <cmd>`, `olbox destroy dev`, and `eval "$(olbox env dev)"` if you would rather not use a subshell — the README covers all of it.
37
+ `openlatch status` shows what is captured and enforced on this host. The [dashboard](https://app.openlatch.ai) shows the events and the verdicts. Full walkthrough: [Getting started](https://openlatch.ai/docs/getting-started/).
98
38
 
99
- Under the hood it is five environment variables derived from the name, which are supported client seams you can also set by hand. Getting one wrong is not a failed test — it writes your real `~/.claude/settings.json` — which is why the tool exists.
39
+ The installer runs on Node.js. macOS, Windows and Linux are supported.
100
40
 
101
- | Variable | Role |
102
- | -------- | ---- |
103
- | `OPENLATCH_DIR` | State: config, token, logs, outbox |
104
- | `CLAUDE_CONFIG_DIR` | Agent config. **Claude Code's own variable**, so the daemon and the session it captures cannot end up pointed at different directories |
105
- | `OPENLATCH_PORT` | Daemon port (sandboxes: 17400–17499) |
106
- | `OPENLATCH_BOUNDARY_PORT` | Model-boundary port (sandboxes: 17600–17699) |
107
- | `OPENLATCH_BOUNDARY_OWN_WIRING` | Lets a non-default-port instance write *its own* agent config. Never inferred — see [`.claude/rules/isolated-instances.md`](.claude/rules/isolated-instances.md) |
108
-
109
- `openlatch uninstall --purge` works inside a sandbox and removes the install; `olbox destroy` removes the sandbox itself.
110
-
111
- A sandbox is never supervised: the OS unit is machine-global and carries no environment, so one installed from a sandbox shell would supervise your *real* install from your dev binary. `supervision enable` refuses there, `init` skips it, and `doctor` reports Persistence as not applicable. Use `openlatch start` — a sandbox is a session of work, not something that should survive a reboot.
112
-
113
- ### Verify before you push
114
-
115
- ```bash
116
- cargo fmt --all -- --check
117
- cargo clippy --all-targets --all-features -- -D warnings
118
- cargo test --all-features
119
- cargo test --lib --no-default-features # proves openlatch-hook links no `core`
120
- ```
121
-
122
- `tools/e2e` holds the end-to-end harness; it drives a real daemon, so run it under `olbox exec <name> --` or in its Docker mode — never straight against your own install. It enforces that itself and will refuse to start on a machine whose isolation seams are unset, printing the commands to fix it.
123
-
124
- ---
125
-
126
- ## The output contract
127
-
128
- Every command that reports health renders from one model (`src/cli/report.rs`) over the same eleven sections. Three rules decide what you see, and they are enforced by tests rather than by review:
129
-
130
- | State | Mark | Means |
131
- | ----- | :--: | ----- |
132
- | `Ok` | `✓` | Enabled **and proven working**. The only green. |
133
- | `Off` | `⚠` | Switched off deliberately. Always carries a code and a remedy. |
134
- | `Degraded` / `Pending` | `⚠` | Working, but not at full capability, or still verifying |
135
- | `Unknown` | `⚠` | Blocked by another section, which it names. One outage, one cross. |
136
- | `Failed` | `✗` | Enabled and not working |
137
- | `NotApplicable` | `·` | Absent from the build, or an exercised privacy opt-out |
138
-
139
- Eleven sections, always all reported, under three groups — the questions a reader asks in the order they ask them:
140
-
141
- | Group | Sections | Question |
142
- | ----- | -------- | -------- |
143
- | **Runtime** | Environment · Daemon · Persistence · Update | is it running, and will it keep running? |
144
- | **Coverage** | Hooks · Boundary · Policy · Inventory · Integrity | is it seeing everything, and enforcing? |
145
- | **Platform** | Cloud · Telemetry | is any of it leaving this machine? |
146
-
147
- A green section is one line. Anything else lists what needs attention, with its cause and its remedy. `-v` unfolds every check.
148
-
149
- ```
150
- Runtime
151
- Environment ✓ 3 passed, 1 not applicable
152
- Daemon ✓ 2 checks passed
153
- Persistence ⚠ Disabled at your request (user_opt_out) [OL-1513]
154
- The daemon will not restart after a logout, a reboot, or a crash.
155
- source : [supervision] disabled_reason = "user_opt_out"
156
- remedy : Run `openlatch supervision enable` to re-arm it.
157
- Update ✓ Daemon is serving the installed version (0.1.18)
158
-
159
- Platform
160
- Cloud ✓ Connected: http://localhost:5173 (0 event(s) forwarded)
161
- Telemetry · Disabled by user (opt-out honoured)
162
- ```
163
-
164
- `Policy` sits under Coverage, not Platform: the bundle arrives from the cloud but the evaluation is local and authoritative — it is about what this host enforces, not about what leaves it.
165
-
166
- ### Exit codes
167
-
168
- | Code | Meaning |
169
- | ---- | ------- |
170
- | 0 | Healthy |
171
- | 1 | Something enabled is not working |
172
- | 2 | Usage error (clap) |
173
- | 3 | Resource not found |
174
- | 4 | Permission denied |
175
- | 5 | Conflict — `OL-1501` only, because systemd's `RestartPreventExitStatus=5` keys off it |
176
- | **7** | **Degraded** — everything runs, but something is switched off or not at full capability |
177
- | 130 | Interrupted |
178
-
179
- `7` matters: `openlatch doctor && deploy` must not succeed on a host where nothing is captured or enforced.
180
-
181
- ---
182
-
183
- ## Commands
184
-
185
- | Command | Notes |
186
- | ------- | ----- |
187
- | `openlatch init` | Complete, idempotent reinstall. Reclaims the ports first — identifying the holder **by the port**, not by `daemon.pid` — then proves the daemon it started is the one serving (PID, version, `/health`). |
188
- | `openlatch status` | Dashboard plus the eleven-section verdict |
189
- | `openlatch start [--foreground] [--port N] [--boundary-port N]` | Refuses when a daemon already runs (`OL-1501`, exit 5) |
190
- | `openlatch stop` / `restart` | `stop` also removes the agent's boundary wiring, and says so |
191
- | `openlatch doctor` | Full diagnosis with causes and remedies |
192
- | `openlatch doctor --fix` | Heals what it can, backs up to `.bak` siblings + `~/.openlatch/fix-journal.json`. Never re-enables what you switched off. |
193
- | `openlatch doctor --restore` | Reverses the last `--fix`. Surgical merge preserves your non-OpenLatch hooks. |
194
- | `openlatch doctor --rescue [--since 24h] [--yes]` | Redacted diagnostic ZIP for support |
195
- | `openlatch boundary status` | Full classification, not a port probe |
196
- | `openlatch boundary {enable,disable} [-y] [--no-restart]` | Writes `[boundary] enabled`, then offers the restart that applies it |
197
- | `openlatch hooks status` | The Hooks section in detail |
198
- | `openlatch supervision {install,uninstall,enable,disable,status}` | OS-native supervisor (launchd / systemd --user / Task Scheduler), user-scope only |
199
- | `openlatch inventory {list,log,rescan,status,inspect,projects,ack}` | Configuration-plane monitoring |
200
- | `openlatch auth {login,logout,status}` · `openlatch telemetry {…}` · `openlatch update` · `openlatch logs` · `openlatch uninstall [--purge]` · `openlatch docs` | |
201
-
202
- Noun-verb aliases: `hooks install` = `init`, `daemon start` = `start`, and so on — identical arguments, pinned by test.
203
-
204
- Global flags: `--json`, `--verbose`/`-v`, `--debug`, `--quiet`/`-q`, `--no-color`. Every diagnostic's JSON carries the same `sections[]` the human rendering shows.
205
-
206
- ---
207
-
208
- ## Architecture
209
-
210
- Hooks live inside the agent, the client decides locally, the platform authors rules and runs analysis.
41
+ ## How it works
211
42
 
212
43
  ```
213
44
  ┌─────────────────────────────────────────────────────────────────┐
214
- │ Your Machine │
45
+ │ Developer's machine │
215
46
  │ │
216
47
  │ ┌──────────┐ hook event ┌──────────────────────────────┐ │
217
- │ │ Claude │──────────────▶│ OpenLatch Client │ │
218
- │ │ Code │ │ (localhost:7443) │ │
48
+ │ │ Coding │──────────────▶│ OpenLatch client │ │
49
+ │ │ agent │ │ (127.0.0.1) │ │
219
50
  │ │ │ │ │ │
220
51
  │ │ │ │ 1. Wrap in envelope │ │
221
52
  │ │ │ │ 2. Evaluate resident │ │
@@ -223,83 +54,75 @@ Hooks live inside the agent, the client decides locally, the platform authors ru
223
54
  │ │ │ ◀─ verdict ──│ 3. Redact credentials │ │
224
55
  │ └──────────┘ │ 4. Write local audit log │ │
225
56
  │ │ 5. Batch → forward │────┼──▶ OpenLatch platform
226
- │ │ ◀── policy bundle │◀───┼── (the policy brain:
227
- │ └──────────────────────────────┘ │ zone, rules, analysis)
57
+ │ │ ◀── policy bundle │◀───┼── (policies, analysis,
58
+ │ └──────────────────────────────┘ │ dashboard)
228
59
  └─────────────────────────────────────────────────────────────────┘
229
60
  ```
230
61
 
231
- - **Hook-native, not a proxy** — the decision point runs inside the agent's own runtime, so it evaluates the action rather than the traffic. Model-call economics additionally use a loopback listener on `127.0.0.1`.
232
- - **Local-authoritative verdicts** — the daemon evaluates a resident policy bundle in-process; the verdict path never touches the network. The cloud serves rules, it does not decide.
233
- - **The daemon owns `ANTHROPIC_BASE_URL`** — written after its bind succeeds and a synthetic round trip proves the listener can reach the provider, removed on teardown. Nothing else writes it, so the agent config can never name a listener that does not exist.
234
- - **Fail-static, not fail-open** — a resident bundle keeps enforcing offline forever. Genuine fail-open is limited to "no bundle was ever fetched" and "the hook binary cannot reach the daemon".
235
- - **Privacy-first** — credentials are redacted locally before anything leaves the machine.
62
+ - **Inside the agent, not a proxy in front of it.** The decision point is the agent's own hook lifecycle, so it sees the *action* rather than the traffic. Model calls additionally pass through a loopback listener, so cost and token usage are measured on the same host.
63
+ - **Local-authoritative.** The resident policy bundle is the authority, not a cache of one. Evaluation reads an in-memory handle and returns.
64
+ - **Fail-static, not fail-open.** A resident bundle keeps enforcing offline, forever. A failed refresh keeps the last known good.
65
+ - **Privacy-first.** Credentials are redacted locally before anything leaves the machine.
66
+
67
+ ## What a verdict does
236
68
 
237
- Two binaries ship: **`openlatch`** (<30 MB, the CLI and daemon) and **`openlatch-hook`** (<20 MB, spawned per hook event, fails open to `~/.openlatch/logs/fallback.jsonl`).
69
+ The verdict vocabulary is **Allow, Ask, Block or Optimize**. What this client can express today is narrower than the vocabulary, and this is the honest map of it. A verdict is deterministic because an explicit policy produced it.
238
70
 
239
- The product perimeter — what the client does, and what it deliberately does not — is **[AGENTS.md](AGENTS.md)**. Subsystem detail (envelope format, policy engine, subsystem supervision, the boundary's wiring invariants, releasing) lives in [`.claude/rules/`](.claude/rules/), one file per subsystem, scoped to the paths it governs.
71
+ | Verdict | On the wire / in the bundle | What this client does today |
72
+ | ------- | --------------------------- | ------------------------- |
73
+ | **Allow** | `allow`, `approve` | The action proceeds. `approve` is a user-confirmed allow |
74
+ | **Ask** | No wire variant — an `allow` / `approve` carrying `context` | Rendered to Claude Code as `permissionDecision: "ask"`, the alert as its reason. It **allows and flags**; it does not hold the agent waiting on a human. It prevents recurrence, not the first occurrence |
75
+ | **Block** | `deny` — the only action a `kind=command` rule may take | Reaches the agent as a native deny at `pre_tool_use`, naming the rule that produced it |
76
+ | **Optimize** | `kind=request` rules: `prefix_reorder`, `history_trim`, `prompt_edit` | **Measurement only.** Out of the box the boundary observes, reports what a transform *would* have saved, and forwards the original bytes |
240
77
 
241
- ### Supported agents
78
+ Each rule runs in Monitor (record the match, allow the action) or Enforce (apply the verdict). Most restrictive wins across matching rules.
242
79
 
243
- Claude Code, on macOS, Windows and Linux, across 12 hook events. It is the reference implementation, and the only agent this node can currently make **Enforced**. Other coding agents are recognised as envelope `agent_type` values — `cursor`, `windsurf`, `github-copilot`, `codex-cli`, `gemini-cli`, `cline`, `openclaw` — so their events store and attribute correctly, but `init` cannot install their hooks yet.
80
+ ## Supported agents
244
81
 
245
- Adding one means an `AgentBinding` in `src/hooks/bindings/` **and** a verdict translator in `src/hook_output/` — without the translator a `deny` is discarded before the developer ever sees it, which is worse than not enforcing. The translator comes first.
82
+ | Agent | Control level | Notes |
83
+ | ----- | ------------- | ----- |
84
+ | **Claude Code** | **Enforced** | macOS, Windows and Linux, across its 12 lifecycle hook events. Verdicts are delivered in the agent's own hook-output shape |
85
+ | Cursor · Windsurf · GitHub Copilot · Codex CLI · Gemini CLI · Cline · OpenClaw | Recognised | Their events store and attribute correctly; `init` cannot install their hooks yet |
246
86
 
247
- ---
87
+ Making an agent **Enforced** is a hook binding plus a verdict translator. Both are contributions we welcome — see [Contributing](#contributing).
248
88
 
249
- ## Configuration
89
+ ## Behind a corporate proxy
250
90
 
251
- Precedence: CLI flags → environment (`OPENLATCH_*`) → `~/.openlatch/config.toml` → defaults.
252
-
253
- | Variable | Description | Default |
254
- | -------- | ----------- | ------- |
255
- | `OPENLATCH_DIR` | State directory | `~/.openlatch` |
256
- | `OPENLATCH_PORT` | Daemon port. `init` binds this exact port; unset, it probes 7443–7543. | `7443` |
257
- | `OPENLATCH_API_URL` | Cloud API base URL | `https://app.openlatch.ai` |
258
- | `OPENLATCH_API_KEY` | API key (credential chain: environment → keychain → encrypted file) | — |
259
- | `OPENLATCH_SKIP_KEYRING` | Treat the OS keychain as unavailable, so the env var wins | unset |
260
- | `OPENLATCH_LOG` | `error` / `warn` / `info` / `debug` / `trace` | `info` |
261
- | `OPENLATCH_BOUNDARY_ENABLED` | Model-boundary listener. While on, the daemon points the agent at it — but only once a synthetic request proves the listener can reach the provider. Being wired disables Claude Code Remote Control. | `true` |
262
- | `OPENLATCH_BOUNDARY_PORT` | Boundary port. A non-default port makes the instance isolated. | `7600` |
263
- | `OPENLATCH_BOUNDARY_OWN_WIRING` | Let an isolated instance write its own agent config | derived from the port |
264
- | `OPENLATCH_BOUNDARY_UPSTREAM` | Where the boundary forwards. Every model call and provider credential goes here — change it only for a local harness. | `https://api.anthropic.com` |
265
- | `OPENLATCH_BOUNDARY_TRANSFORMS_ACT` | Whether an acting `prefix_reorder` rule may rewrite the forwarded request body. Off, the boundary measures and forwards the original bytes. See [Optimize](#verdicts-and-which-ones-this-node-enforces-today) for what it does and does not gate. | `false` |
266
- | `OPENLATCH_POLICY_ENABLED` | Local policy evaluation. `false` is a complete off switch, not observe mode. | `true` |
267
- | `OPENLATCH_INVENTORY_ENABLED` | Configuration-plane monitoring | `true` |
268
- | `OPENLATCH_CLOUD_BATCH_MAX_EVENTS` | Events per ingest batch, clamped to `1..=100` | `50` |
269
- | `OPENLATCH_CLOUD_BATCH_MAX_WAIT_MS` | Flush deadline, anchored to the first buffered event | `5000` |
270
- | `OPENLATCH_CLOUD_OUTBOX_MAX_BYTES` | Outbox cap before drop-oldest (0 disables) | `104857600` |
271
- | `OPENLATCH_CLOUD_FALLBACK_MAX_BYTES` | Fallback-log cap before drop-oldest (0 disables) | `52428800` |
272
- | `OPENLATCH_AUTO_UPDATE` | Background auto-update worker | `true` |
273
- | `OPENLATCH_UPDATE_CHECK` | Startup version check | `true` |
274
- | `OPENLATCH_NPM_REGISTRY` | Registry origin for `openlatch update` | `https://registry.npmjs.org` |
275
- | `OPENLATCH_TELEMETRY_DISABLED` | `1` opts out of anonymous usage telemetry | unset |
276
-
277
- **Cloud forwarding is not optional.** `[cloud] enabled` and `OPENLATCH_CLOUD_ENABLED` are still parsed so existing configs keep loading, but they are ignored — a client that captures events and sends them nowhere is a log rotator. Point `[cloud] api_url` elsewhere to change *where* events go.
278
-
279
- Auto-update, its quiet-window deferral and its rollback sentinel are documented in the module rustdoc of [`src/core/update.rs`](src/core/update.rs); `openlatch update --check --json` is the manual probe.
91
+ `init` finds the route on its own: it probes what is already configured, then walks the OS's own proxy settings (Windows, macOS, GNOME), and only asks if none of them reach the platform. Kerberos/Negotiate uses the logged-on identity; a TLS-inspecting proxy needs only its root CA in `ca_bundle`. Proxy credentials go to the OS keychain, never to a file.
280
92
 
281
- ---
93
+ ```bash
94
+ openlatch init --proxy http://proxy.corp:8080 --ca-bundle /etc/ssl/corp-root.pem
95
+ openlatch proxy test # walks the chain hop by hop and names the failing one
96
+ ```
97
+
98
+ The hosts to open, every `[proxy]` key and every `OL-122x` code: [docs/egress.md](docs/egress.md).
282
99
 
283
- ## Releases
100
+ ## Configuration
101
+
102
+ `openlatch init` writes `~/.openlatch/config.toml`, and every key has an `OPENLATCH_*` environment variable that overrides it. Precedence is CLI flags → environment → `config.toml` → defaults. The full list is in [docs/configuration.md](docs/configuration.md).
284
103
 
285
- Two artifacts on independent version lines, both cut by [release-please](https://github.com/googleapis/release-please) from Conventional Commits:
104
+ ## Documentation
286
105
 
287
- | Artifact | Tag | Where |
288
- | -------- | --- | ----- |
289
- | The client | `v1.2.3` | GitHub Releases, npm, crates.io |
290
- | The wire-format JSON Schemas | `schemas-v1.2.3` | npm, PyPI |
106
+ | Where | What |
107
+ | ----- | ---- |
108
+ | [openlatch.ai/docs](https://openlatch.ai/docs/) | Installation, getting started, how it works, FAQ, privacy |
109
+ | [docs/configuration.md](docs/configuration.md) | Environment variables, `config.toml`, what the daemon writes into the agent's config |
110
+ | [docs/egress.md](docs/egress.md) | Proxies, the hosts to open, Kerberos, troubleshooting codes |
111
+ | [docs/cli.md](docs/cli.md) | Command reference, health reports, exit codes |
112
+ | [docs/evaluate-protocol.md](docs/evaluate-protocol.md) | Evaluation process frames, caller-owned session state, errors and diagnostics |
113
+ | [CHANGELOG.md](CHANGELOG.md) | What changed in each release |
291
114
 
292
- The schema packages are versioned **only** by changes under `schemas/`, so a major bump means a breaking change to the events exchanged with the platform and nothing else. Pin them independently. Details in [`.claude/rules/release-lines.md`](.claude/rules/release-lines.md).
115
+ ## Contributing
293
116
 
294
- ## Why it is open source
117
+ ```bash
118
+ git clone https://github.com/OpenLatch/openlatch-client && cd openlatch-client
119
+ cargo build # Rust 1.88+, no other prerequisites
120
+ cargo test
121
+ ```
295
122
 
296
- The platform is closed; this node is Apache-2.0, for three enterprise reasons.
123
+ Never run a development build against your own install: `openlatch init` rewires every live agent session on the host. The [Contributing Guide](.github/CONTRIBUTING.md) covers the sandbox that prevents it, the checks CI runs, Conventional Commits and the PR process; [AGENTS.md](AGENTS.md) states what the client does and what it deliberately does not.
297
124
 
298
- | Reason | Why it matters |
299
- | ------ | -------------- |
300
- | **Transparency** | A node that sits in the execution path of every agent action cannot be a black box. Source access is a hard procurement gate at regulated enterprises. |
301
- | **Auditability** | Security reviews, internal AppSec and third-party testers all need to read the code that enforces policy on production agents. |
302
- | **Distribution** | The developer inside the account is who runs `npx @openlatch/client init` first. Open source removes the friction from that. |
125
+ Pick a [good first issue](https://github.com/OpenLatch/openlatch-client/labels/good%20first%20issue), or join us on [Slack](https://openlatch.slack.com).
303
126
 
304
127
  ## Security
305
128
 
@@ -307,15 +130,6 @@ The platform is closed; this node is Apache-2.0, for three enterprise reasons.
307
130
  - Releases are built with SLSA provenance via GitHub Actions
308
131
  - Full policy: [SECURITY.md](SECURITY.md)
309
132
 
310
- ## Contributing
311
-
312
- Read the [Contributing Guide](.github/CONTRIBUTING.md), pick a [good first issue](https://github.com/OpenLatch/openlatch-client/labels/good%20first%20issue), and join us on [Slack](https://openlatch.slack.com).
313
-
314
- Licensed under [Apache-2.0](LICENSE).
133
+ ## License
315
134
 
316
- | Resource | URL |
317
- | -------- | --- |
318
- | Website | [openlatch.ai](https://openlatch.ai) |
319
- | Documentation | [docs.openlatch.ai](https://docs.openlatch.ai) |
320
- | Slack | [openlatch.slack.com](https://openlatch.slack.com) |
321
- | Twitter / X | [@openlatch](https://x.com/openlatch) |
135
+ This client is licensed under [Apache-2.0](LICENSE). The OpenLatch platform — policy authoring, analysis and the dashboard — is a commercial product; see [openlatch.ai](https://openlatch.ai).
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openlatch/client",
3
- "version": "0.2.2",
3
+ "version": "0.3.3",
4
4
  "description": "OpenLatch runtime enforcement node — the capture-and-enforce adapter that evaluates every covered action against a coding agent's Autonomy Zone before it runs",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
@@ -20,10 +20,10 @@
20
20
  "postinstall": "node lib/postinstall.js"
21
21
  },
22
22
  "optionalDependencies": {
23
- "@openlatch/client-darwin-arm64": "0.2.2",
24
- "@openlatch/client-darwin-x64": "0.2.2",
25
- "@openlatch/client-linux-x64": "0.2.2",
26
- "@openlatch/client-linux-arm64": "0.2.2",
27
- "@openlatch/client-win32-x64": "0.2.2"
23
+ "@openlatch/client-darwin-arm64": "0.3.3",
24
+ "@openlatch/client-darwin-x64": "0.3.3",
25
+ "@openlatch/client-linux-x64": "0.3.3",
26
+ "@openlatch/client-linux-arm64": "0.3.3",
27
+ "@openlatch/client-win32-x64": "0.3.3"
28
28
  }
29
29
  }