@openlatch/client 0.2.2 → 0.4.0
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 +82 -257
- package/package.json +6 -6
package/README.md
CHANGED
|
@@ -6,216 +6,48 @@
|
|
|
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
|
-
|
|
19
|
-
|
|
20
|
-
|
|
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
|
-
|
|
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.
|
|
73
24
|
|
|
74
|
-
|
|
75
|
-
git clone https://github.com/OpenLatch/openlatch-client && cd openlatch-client
|
|
76
|
-
cargo build
|
|
77
|
-
cargo test
|
|
78
|
-
```
|
|
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**.
|
|
79
26
|
|
|
80
|
-
|
|
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.
|
|
81
28
|
|
|
82
|
-
|
|
83
|
-
|
|
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.
|
|
85
|
-
|
|
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
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
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 system 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
|
|
35
|
+
codex # … and the other one, under the same policy on the same host
|
|
95
36
|
```
|
|
96
37
|
|
|
97
|
-
|
|
98
|
-
|
|
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.
|
|
100
|
-
|
|
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) |
|
|
38
|
+
`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/).
|
|
108
39
|
|
|
109
|
-
|
|
40
|
+
The installer runs on Node.js. macOS, Windows and Linux are supported.
|
|
110
41
|
|
|
111
|
-
|
|
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.
|
|
42
|
+
## How it works
|
|
211
43
|
|
|
212
44
|
```
|
|
213
45
|
┌─────────────────────────────────────────────────────────────────┐
|
|
214
|
-
│
|
|
46
|
+
│ Developer's machine │
|
|
215
47
|
│ │
|
|
216
48
|
│ ┌──────────┐ hook event ┌──────────────────────────────┐ │
|
|
217
|
-
│ │
|
|
218
|
-
│ │
|
|
49
|
+
│ │ Coding │──────────────▶│ OpenLatch client │ │
|
|
50
|
+
│ │ agent │ │ (127.0.0.1) │ │
|
|
219
51
|
│ │ │ │ │ │
|
|
220
52
|
│ │ │ │ 1. Wrap in envelope │ │
|
|
221
53
|
│ │ │ │ 2. Evaluate resident │ │
|
|
@@ -223,83 +55,85 @@ Hooks live inside the agent, the client decides locally, the platform authors ru
|
|
|
223
55
|
│ │ │ ◀─ verdict ──│ 3. Redact credentials │ │
|
|
224
56
|
│ └──────────┘ │ 4. Write local audit log │ │
|
|
225
57
|
│ │ 5. Batch → forward │────┼──▶ OpenLatch platform
|
|
226
|
-
│ │ ◀── policy bundle │◀───┼── (
|
|
227
|
-
│ └──────────────────────────────┘ │
|
|
58
|
+
│ │ ◀── policy bundle │◀───┼── (policies, analysis,
|
|
59
|
+
│ └──────────────────────────────┘ │ dashboard)
|
|
228
60
|
└─────────────────────────────────────────────────────────────────┘
|
|
229
61
|
```
|
|
230
62
|
|
|
231
|
-
- **
|
|
232
|
-
- **Local-authoritative
|
|
233
|
-
- **
|
|
234
|
-
- **
|
|
235
|
-
- **Privacy-first** — credentials are redacted locally before anything leaves the machine.
|
|
63
|
+
- **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.
|
|
64
|
+
- **Local-authoritative.** The resident policy bundle is the authority, not a cache of one. Evaluation reads an in-memory handle and returns.
|
|
65
|
+
- **Fail-static, not fail-open.** A resident bundle keeps enforcing offline, forever. A failed refresh keeps the last known good.
|
|
66
|
+
- **Privacy-first.** Credentials are redacted locally before anything leaves the machine.
|
|
236
67
|
|
|
237
|
-
|
|
68
|
+
## What a verdict does
|
|
238
69
|
|
|
239
|
-
The
|
|
70
|
+
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.
|
|
240
71
|
|
|
241
|
-
|
|
72
|
+
| Verdict | On the wire / in the bundle | What this client does today |
|
|
73
|
+
| ------- | --------------------------- | ------------------------- |
|
|
74
|
+
| **Allow** | `allow`, `approve` | The action proceeds. `approve` is a user-confirmed allow |
|
|
75
|
+
| **Ask** | No wire variant — an `allow` / `approve` carrying `context` | It **allows and flags**; it does not hold the agent waiting on a human. Claude Code renders it as `permissionDecision: "ask"` with the alert as its reason; Codex CLI has no `ask` tier, so it degrades to a `systemMessage` carrying that same reason. It prevents recurrence, not the first occurrence |
|
|
76
|
+
| **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 |
|
|
77
|
+
| **Optimize** | `kind=request` rules: `prefix_reorder`, `history_trim`, `prompt_edit` | **Measurement only.** Out of the box the model relay observes, reports what a transform *would* have saved, and forwards the original bytes |
|
|
242
78
|
|
|
243
|
-
|
|
79
|
+
Each rule runs in Monitor (record the match, allow the action) or Enforce (apply the verdict). Most restrictive wins across matching rules.
|
|
244
80
|
|
|
245
|
-
|
|
81
|
+
## Supported agents
|
|
246
82
|
|
|
247
|
-
|
|
83
|
+
**Two agents are wired end-to-end: [Claude Code](https://claude.ai/code) and [OpenAI Codex CLI](https://developers.openai.com/codex/cli).** `init` detects every agent on the host and wires **all** of them — coverage is the default, and `--agent <type>` is how you opt one out. `doctor`, `status` and `uninstall` each report and tear down every agent they find.
|
|
248
84
|
|
|
249
|
-
|
|
85
|
+
Coverage is stated per agent **and per plane**. An unqualified "Enforced" would round an enforced command plane and an observe-only request plane back up to green, and that is the one arithmetic this table refuses.
|
|
250
86
|
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
|
254
|
-
|
|
|
255
|
-
| `
|
|
256
|
-
|
|
|
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.
|
|
87
|
+
| Agent | Delivery | Command plane | Request plane | Control level |
|
|
88
|
+
| ----- | -------- | ------------- | ------------- | ------------- |
|
|
89
|
+
| **Claude Code** | any | **Enforced** | Observed *(runtime-checked)* | **Enforced** *(command plane)* |
|
|
90
|
+
| **Codex CLI** | managed (MDM / system / cloud) | **Enforced**, and **not disableable by the developer** | Observed *(runtime-checked)* | **Enforced** *(command plane)* |
|
|
91
|
+
| **Codex CLI** | self-serve (`npx init`) | **Monitored** until `/hooks` trust; **Enforced** after | Observed *(runtime-checked)* | Monitored → Enforced |
|
|
92
|
+
| Cursor · Windsurf · GitHub Copilot · Gemini CLI · Cline · OpenClaw | — | Not wired | Not wired | Known |
|
|
280
93
|
|
|
281
|
-
|
|
94
|
+
**The vocabulary is closed.** *Enforced* — the verdict reaches the agent and is obeyed. *Monitored* — the integration is installed and events flow, but a verdict cannot yet be delivered, so nothing is prevented. *Observed* — capture and would-have measurement only, by design for this phase. *Known* — identified and classified, with the limits stated.
|
|
95
|
+
|
|
96
|
+
**Why Codex has two rows.** A user-level Codex hook is *marked for review and skipped until trusted*, so a fresh self-serve install is Monitored — not Enforced — until you run `/hooks` in Codex and trust the OpenLatch hook. Any re-install that changes the hook command re-arms that review. On the managed path the hook is trusted by policy and cannot be switched off by the developer, which is a stronger claim than we can make on Claude Code. `openlatch doctor` proves the hook by **invoking** it rather than by observing that a file exists, and reports the trust state per agent — an untrusted hook is never spawned, and that is the one failure that looks identical to working from the outside.
|
|
97
|
+
|
|
98
|
+
Making an agent **Enforced** is a hook binding plus a verdict translator. Both are contributions we welcome — see [Contributing](#contributing).
|
|
99
|
+
|
|
100
|
+
## Behind a corporate proxy
|
|
101
|
+
|
|
102
|
+
`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.
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
openlatch init --proxy http://proxy.corp:8080 --ca-bundle /etc/ssl/corp-root.pem
|
|
106
|
+
openlatch system proxy test # walks the chain hop by hop and names the failing one
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
The hosts to open, every `[proxy]` key and every `OL-122x` code: [docs/egress.md](docs/egress.md).
|
|
282
110
|
|
|
283
|
-
##
|
|
111
|
+
## Configuration
|
|
112
|
+
|
|
113
|
+
`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
114
|
|
|
285
|
-
|
|
115
|
+
## Documentation
|
|
286
116
|
|
|
287
|
-
|
|
|
288
|
-
|
|
|
289
|
-
|
|
|
290
|
-
|
|
|
117
|
+
| Where | What |
|
|
118
|
+
| ----- | ---- |
|
|
119
|
+
| [openlatch.ai/docs](https://openlatch.ai/docs/) | Installation, getting started, how it works, FAQ, privacy |
|
|
120
|
+
| [docs/configuration.md](docs/configuration.md) | Environment variables, `config.toml`, what the daemon writes into the agent's config |
|
|
121
|
+
| [docs/egress.md](docs/egress.md) | Proxies, the hosts to open, Kerberos, troubleshooting codes |
|
|
122
|
+
| [docs/cli.md](docs/cli.md) | Command reference, health reports, exit codes |
|
|
123
|
+
| [docs/evaluate-protocol.md](docs/evaluate-protocol.md) | Evaluation process frames, caller-owned session state, errors and diagnostics |
|
|
124
|
+
| [CHANGELOG.md](CHANGELOG.md) | What changed in each release |
|
|
291
125
|
|
|
292
|
-
|
|
126
|
+
## Contributing
|
|
293
127
|
|
|
294
|
-
|
|
128
|
+
```bash
|
|
129
|
+
git clone https://github.com/OpenLatch/openlatch-client && cd openlatch-client
|
|
130
|
+
cargo build # Rust 1.88+, no other prerequisites
|
|
131
|
+
cargo test
|
|
132
|
+
```
|
|
295
133
|
|
|
296
|
-
The
|
|
134
|
+
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
135
|
|
|
298
|
-
|
|
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. |
|
|
136
|
+
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
137
|
|
|
304
138
|
## Security
|
|
305
139
|
|
|
@@ -307,15 +141,6 @@ The platform is closed; this node is Apache-2.0, for three enterprise reasons.
|
|
|
307
141
|
- Releases are built with SLSA provenance via GitHub Actions
|
|
308
142
|
- Full policy: [SECURITY.md](SECURITY.md)
|
|
309
143
|
|
|
310
|
-
##
|
|
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).
|
|
144
|
+
## License
|
|
315
145
|
|
|
316
|
-
|
|
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) |
|
|
146
|
+
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.
|
|
3
|
+
"version": "0.4.0",
|
|
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.
|
|
24
|
-
"@openlatch/client-darwin-x64": "0.
|
|
25
|
-
"@openlatch/client-linux-x64": "0.
|
|
26
|
-
"@openlatch/client-linux-arm64": "0.
|
|
27
|
-
"@openlatch/client-win32-x64": "0.
|
|
23
|
+
"@openlatch/client-darwin-arm64": "0.4.0",
|
|
24
|
+
"@openlatch/client-darwin-x64": "0.4.0",
|
|
25
|
+
"@openlatch/client-linux-x64": "0.4.0",
|
|
26
|
+
"@openlatch/client-linux-arm64": "0.4.0",
|
|
27
|
+
"@openlatch/client-win32-x64": "0.4.0"
|
|
28
28
|
}
|
|
29
29
|
}
|