@letterblack/lbe-core 1.3.27 → 1.3.29
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/CHANGELOG.md +10 -0
- package/Release-README.md +1 -1
- package/package.json +2 -2
- package/release/README.md +173 -128
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 1.3.29 — 2026-06-25
|
|
4
|
+
|
|
5
|
+
### Changed
|
|
6
|
+
- Expanded public mirror README with problem statement, target audience, use cases, why-local-first rationale, and scope boundaries. Previously documented only the technical surface.
|
|
7
|
+
|
|
8
|
+
## 1.3.28 — 2026-06-25
|
|
9
|
+
|
|
10
|
+
### Fixed
|
|
11
|
+
- Fixed public mirror README source: updated `release/README.md` (the template read by `build-public-sdk.mjs`) instead of `release-public/README.md` which is overwritten at build time. README now accurately documents the 6 real CLI commands, programmatic API, request/response shape, and package contents.
|
|
12
|
+
|
|
3
13
|
## 1.3.27 — 2026-06-25
|
|
4
14
|
|
|
5
15
|
### Changed
|
package/Release-README.md
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@letterblack/lbe-core",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.29",
|
|
4
4
|
"description": "Local-first execution governance SDK for AI agents. Agents propose → Controller validates → Adapters execute.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "index.js",
|
|
@@ -74,5 +74,5 @@
|
|
|
74
74
|
"directories": {
|
|
75
75
|
"doc": "docs"
|
|
76
76
|
},
|
|
77
|
-
"gitHead": "
|
|
77
|
+
"gitHead": "d1d8fededb1326ecc1490e0be1edbe606a16e0fb"
|
|
78
78
|
}
|
package/release/README.md
CHANGED
|
@@ -1,216 +1,261 @@
|
|
|
1
1
|
# {{PACKAGE_NAME}}
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
actions routed through its execution boundary and records local evidence.
|
|
5
|
-
It is not an AI model, IDE, full OS sandbox, or cloud monitor.
|
|
3
|
+
**A local policy gate between what an AI agent proposes and what your system executes.**
|
|
6
4
|
|
|
7
|
-
|
|
5
|
+
---
|
|
8
6
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
npx lbe status
|
|
13
|
-
npx lbe logs
|
|
14
|
-
npx lbe proof --public
|
|
15
|
-
npx lbe open-state
|
|
16
|
-
```
|
|
7
|
+
## The problem
|
|
8
|
+
|
|
9
|
+
AI agents write files, run shell commands, call APIs, and modify state. Most of the time they do the right thing. But they have no built-in execution boundary. When a model hallucinates a path, over-reaches its scope, or gets manipulated by injected instructions, there is nothing between the agent's decision and your filesystem.
|
|
17
10
|
|
|
18
|
-
|
|
19
|
-
In v1.3, `.lbe/events.jsonl` remains local fallback truth and is imported once
|
|
20
|
-
without changing the original file. Proof uses intent, target, file index, LBE
|
|
21
|
-
events, and `proof/latest.json`; `--public` redacts sensitive proof details.
|
|
11
|
+
You can prompt the agent to be careful. You can review outputs manually. But neither of those is enforcement.
|
|
22
12
|
|
|
23
|
-
LBE
|
|
24
|
-
are best-effort, logs remain local, and non-inspectable targets may produce
|
|
25
|
-
`WEAK_PROOF`.
|
|
13
|
+
LBE is enforcement. Every action the agent proposes is validated against a local policy before it runs. If the policy says no, the action does not execute — regardless of what the model decided.
|
|
26
14
|
|
|
27
15
|
---
|
|
28
16
|
|
|
29
|
-
|
|
17
|
+
## Who this is for
|
|
18
|
+
|
|
19
|
+
- **Developers building AI coding assistants** that write, move, or delete files on behalf of users
|
|
20
|
+
- **Developers building automation tools** where an AI generates shell commands or file operations
|
|
21
|
+
- **Teams integrating LLMs into existing applications** that need an audit trail and a hard execution boundary
|
|
22
|
+
- **Anyone who wants to know exactly what an AI agent did** and be able to prove it, not just trust it
|
|
30
23
|
|
|
31
|
-
|
|
24
|
+
You do not need to be building a safety product. If your application lets an AI agent touch the filesystem or run commands, you need an execution boundary. LBE is that boundary.
|
|
32
25
|
|
|
33
26
|
---
|
|
34
27
|
|
|
35
|
-
##
|
|
28
|
+
## Why local-first
|
|
36
29
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
30
|
+
No cloud service. No daemon. No API key. The runtime is a verified WASM binary that runs in your process. Policy is a local JSON file. Evidence stays on your machine.
|
|
31
|
+
|
|
32
|
+
This matters because:
|
|
33
|
+
- It works offline and in airgapped environments
|
|
34
|
+
- No external service can go down and break your enforcement
|
|
35
|
+
- Sensitive file paths and workspace context never leave the machine
|
|
36
|
+
- Latency is microseconds, not network round-trips
|
|
37
|
+
- You own the policy — no vendor decides what is allowed
|
|
41
38
|
|
|
42
39
|
---
|
|
43
40
|
|
|
44
|
-
##
|
|
41
|
+
## What it does
|
|
45
42
|
|
|
46
|
-
```
|
|
47
|
-
|
|
43
|
+
```
|
|
44
|
+
Agent proposes an action
|
|
45
|
+
↓
|
|
46
|
+
LBE validates it through a 7-gate pipeline
|
|
47
|
+
↓
|
|
48
|
+
allow / deny — structured result returned to your host
|
|
49
|
+
↓
|
|
50
|
+
Host executes only if LBE approved
|
|
51
|
+
↓
|
|
52
|
+
Audit entry written to a local hash-linked log
|
|
48
53
|
```
|
|
49
54
|
|
|
50
|
-
|
|
55
|
+
Your code stays in control. LBE makes the allow/deny decision and hands it back. It does not execute on your behalf.
|
|
51
56
|
|
|
52
57
|
---
|
|
53
58
|
|
|
54
|
-
##
|
|
59
|
+
## Use cases
|
|
55
60
|
|
|
56
|
-
|
|
57
|
-
|
|
61
|
+
**AI coding assistant**
|
|
62
|
+
The agent wants to write `src/auth.js`. LBE checks: is this path inside the allowed workspace? Is the operation type permitted? Does the policy allow file writes for this actor? Only if all gates pass does your host write the file.
|
|
58
63
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
request_id: 'req-001',
|
|
62
|
-
timestamp: Math.floor(Date.now() / 1000),
|
|
63
|
-
actor: { id: 'agent:local', role: 'agent' },
|
|
64
|
-
intent: { type: 'command', name: 'write_file', payload: { target: 'out.txt' } },
|
|
65
|
-
context: { workspace: process.cwd(), env: {}, history: [] },
|
|
66
|
-
constraints: { policy_mode: 'strict', timeout_ms: 5000 },
|
|
67
|
-
auth: { signature: '<host-signed>', nonce: '<unique-per-request>' }
|
|
68
|
-
};
|
|
64
|
+
**Shell command gating**
|
|
65
|
+
The agent proposes `rm -rf ./build`. Your policy allows `rm` inside `./build` but denies recursive deletes outside it. LBE returns deny before the command reaches the shell.
|
|
69
66
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
// Blocked: { ok: false, decision: 'deny', error: { stage, message } }
|
|
73
|
-
```
|
|
67
|
+
**Scope enforcement**
|
|
68
|
+
You want the agent to only touch files in `./generated/`. Write one policy rule. LBE denies every write outside that path, automatically, on every request, without you reviewing each one.
|
|
74
69
|
|
|
75
|
-
|
|
70
|
+
**Audit and proof**
|
|
71
|
+
Every allowed and denied action is written to a local hash-linked audit log. The chain is tamper-evident — removing or modifying an entry breaks the chain and is detectable. You can prove what the agent did, in order, with cryptographic evidence.
|
|
76
72
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
| Field | Required | Description |
|
|
80
|
-
|---|---:|---|
|
|
81
|
-
| `version` | Yes | `"1.0"` |
|
|
82
|
-
| `request_id` | Yes | Caller-supplied unique identifier |
|
|
83
|
-
| `timestamp` | Yes | Unix timestamp in seconds |
|
|
84
|
-
| `actor` | Yes | `{ id, role }` — identity of the requesting agent |
|
|
85
|
-
| `intent` | Yes | `{ type, name, payload }` — what the agent wants to do |
|
|
86
|
-
| `context` | Yes | Workspace path and caller context |
|
|
87
|
-
| `constraints` | Yes | `policy_mode` and `timeout_ms` |
|
|
88
|
-
| `auth` | Yes | Host-supplied `signature` and `nonce` |
|
|
73
|
+
**Observer mode for new projects**
|
|
74
|
+
Not sure what your agent is doing? Start in observer mode. Every request is validated and logged exactly as it would be in enforcement — but nothing is blocked. Watch the patterns. Write policy rules. Switch to enforce when you are confident.
|
|
89
75
|
|
|
90
76
|
---
|
|
91
77
|
|
|
92
|
-
##
|
|
93
|
-
|
|
94
|
-
Not ready to block? Start in observer mode. Every request is fully validated and logged exactly as it would be in enforcement — but nothing is blocked. Watch what the agent is doing before you decide what to deny.
|
|
78
|
+
## Install
|
|
95
79
|
|
|
96
80
|
```bash
|
|
97
|
-
|
|
98
|
-
npx lbe enforce # switch to blocking
|
|
99
|
-
npx lbe observe # switch back to advisory
|
|
81
|
+
npm install {{PACKAGE_NAME}}
|
|
100
82
|
```
|
|
101
83
|
|
|
84
|
+
Requires Node.js >= 20.9.0.
|
|
85
|
+
|
|
102
86
|
---
|
|
103
87
|
|
|
104
|
-
##
|
|
88
|
+
## Quick start
|
|
105
89
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
| `npx lbe enforce` | Set blocking mode |
|
|
112
|
-
| `npx lbe run` | Validate and execute a proposal from `--in <file>` |
|
|
113
|
-
| `npx lbe verify` | Validate a proposal without executing |
|
|
114
|
-
| `npx lbe dryrun` | Validate and simulate without executing |
|
|
115
|
-
| `npx lbe health` | Check all required files are present and readable |
|
|
116
|
-
| `npx lbe audit-verify` | Verify the audit log hash chain |
|
|
90
|
+
```bash
|
|
91
|
+
npx lbe init # create lbe.policy.json in observer mode
|
|
92
|
+
npx lbe status # show current policy and workspace state
|
|
93
|
+
npx lbe enforce # switch to blocking mode when ready
|
|
94
|
+
```
|
|
117
95
|
|
|
118
96
|
---
|
|
119
97
|
|
|
120
98
|
## How the gate pipeline works
|
|
121
99
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
Every request enters a 7-gate pipeline. A failure at any gate returns a structured denial — the remaining gates are not evaluated.
|
|
100
|
+
Every request passes through 7 gates inside the WASM runtime. If any gate fails, the request is denied and the remaining gates are not evaluated.
|
|
125
101
|
|
|
126
102
|
```
|
|
127
|
-
[1] Schema required fields and
|
|
128
|
-
|
|
129
|
-
[2] Timestamp permitted clock-skew window (±10 minutes)
|
|
130
|
-
↓
|
|
103
|
+
[1] Schema required fields and structure
|
|
104
|
+
[2] Timestamp clock-skew within ±10 minutes
|
|
131
105
|
[3] Key lifecycle trusted key, active, not expired
|
|
132
|
-
↓
|
|
133
106
|
[4] Signature Ed25519 request authenticity
|
|
134
|
-
↓
|
|
135
107
|
[5] Rate limit per-requester sliding-window limit
|
|
136
|
-
↓
|
|
137
108
|
[6] Nonce single-use replay protection
|
|
109
|
+
[7] Policy configured rules — deny always wins
|
|
138
110
|
↓
|
|
139
|
-
|
|
140
|
-
↓
|
|
141
|
-
allow / deny / error — structured result returned to host
|
|
111
|
+
allow / deny — structured result returned to your host
|
|
142
112
|
```
|
|
143
113
|
|
|
144
|
-
|
|
114
|
+
A failure at gate 2 never reaches gate 7. A denied request never reaches your execution layer.
|
|
145
115
|
|
|
146
116
|
---
|
|
147
117
|
|
|
148
|
-
##
|
|
118
|
+
## CLI reference
|
|
119
|
+
|
|
120
|
+
| Command | What it does |
|
|
121
|
+
|---|---|
|
|
122
|
+
| `npx lbe init` | Create `lbe.policy.json` in observer mode |
|
|
123
|
+
| `npx lbe status` | Show policy mode, rules, and workspace state |
|
|
124
|
+
| `npx lbe policy` | Print the current policy file |
|
|
125
|
+
| `npx lbe observe` | Switch to advisory mode — logs but does not block |
|
|
126
|
+
| `npx lbe enforce` | Switch to blocking mode — denies policy violations |
|
|
127
|
+
| `npx lbe execute` | Validate a JSON proposal from stdin |
|
|
128
|
+
| `npx lbe execute --input <file>` | Validate a JSON proposal from a file |
|
|
129
|
+
|
|
130
|
+
---
|
|
131
|
+
|
|
132
|
+
## Programmatic API
|
|
133
|
+
|
|
134
|
+
```js
|
|
135
|
+
import { execute } from '{{PACKAGE_NAME}}';
|
|
149
136
|
|
|
150
|
-
|
|
137
|
+
const proposal = {
|
|
138
|
+
version: '1.0',
|
|
139
|
+
request_id: 'req-001',
|
|
140
|
+
timestamp: Math.floor(Date.now() / 1000),
|
|
141
|
+
actor: { id: 'agent:local', role: 'agent' },
|
|
142
|
+
intent: {
|
|
143
|
+
type: 'command',
|
|
144
|
+
name: 'write_file',
|
|
145
|
+
payload: { target: 'src/output.js' }
|
|
146
|
+
},
|
|
147
|
+
context: { workspace: process.cwd(), env: {}, history: [] },
|
|
148
|
+
constraints: { policy_mode: 'strict', timeout_ms: 5000 },
|
|
149
|
+
auth: { signature: '<host-signed>', nonce: '<unique-per-request>' }
|
|
150
|
+
};
|
|
151
151
|
|
|
152
|
-
|
|
153
|
-
2. Identity is confirmed against a locally held key — no network call required.
|
|
154
|
-
3. The project policy is evaluated. The action is approved.
|
|
155
|
-
4. The host executes the write or command inside the allowed workspace.
|
|
156
|
-
5. The audit chain is extended — every approved action appends a hash-linked entry to the local log, permanently verifiable, impossible to silently remove.
|
|
157
|
-
6. A structured result returns: whether it succeeded, which rules matched, and the audit entry identifier.
|
|
152
|
+
const result = JSON.parse(execute(JSON.stringify(proposal)));
|
|
158
153
|
|
|
159
|
-
|
|
154
|
+
if (result.decision === 'allow') {
|
|
155
|
+
// LBE approved — safe to execute
|
|
156
|
+
} else {
|
|
157
|
+
// LBE denied — result.error has the gate and reason
|
|
158
|
+
console.error(result.error.stage, result.error.message);
|
|
159
|
+
}
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
`execute(input: string): string` — synchronous, accepts JSON, returns JSON. The WASM runtime owns all gate decisions.
|
|
163
|
+
|
|
164
|
+
### Decision responses
|
|
165
|
+
|
|
166
|
+
Allowed:
|
|
167
|
+
```json
|
|
168
|
+
{
|
|
169
|
+
"ok": true,
|
|
170
|
+
"decision": "allow",
|
|
171
|
+
"request_id": "req-001",
|
|
172
|
+
"result": { "type": "allowed" }
|
|
173
|
+
}
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
Denied:
|
|
177
|
+
```json
|
|
178
|
+
{
|
|
179
|
+
"ok": false,
|
|
180
|
+
"decision": "deny",
|
|
181
|
+
"request_id": "req-001",
|
|
182
|
+
"error": { "stage": "policy", "message": "rule:deny_outside_workspace" }
|
|
183
|
+
}
|
|
184
|
+
```
|
|
160
185
|
|
|
161
186
|
---
|
|
162
187
|
|
|
163
|
-
##
|
|
188
|
+
## Validating from the CLI
|
|
164
189
|
|
|
165
|
-
|
|
190
|
+
```bash
|
|
191
|
+
# from a file
|
|
192
|
+
npx lbe execute --input proposal.json
|
|
166
193
|
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
4. The denial is written to the immutable audit log — chain sealed, evidence preserved.
|
|
194
|
+
# from stdin
|
|
195
|
+
cat proposal.json | npx lbe execute
|
|
196
|
+
```
|
|
171
197
|
|
|
172
|
-
|
|
198
|
+
Exit code `0` = allowed. Exit code `1` = denied. Exit code `2` = bad input.
|
|
173
199
|
|
|
174
200
|
---
|
|
175
201
|
|
|
176
|
-
##
|
|
202
|
+
## Observer mode
|
|
177
203
|
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
204
|
+
Not ready to block? Start here.
|
|
205
|
+
|
|
206
|
+
`npx lbe init` creates the policy in observer mode. Every request is fully validated and logged — exactly as it would be in enforcement — but nothing is blocked. You see exactly what the agent is doing before you write your first deny rule.
|
|
207
|
+
|
|
208
|
+
```bash
|
|
209
|
+
npx lbe init # observer mode on by default
|
|
210
|
+
npx lbe status # confirm mode: observe
|
|
211
|
+
npx lbe enforce # block when ready
|
|
212
|
+
npx lbe observe # back to advisory any time
|
|
213
|
+
```
|
|
186
214
|
|
|
187
215
|
---
|
|
188
216
|
|
|
189
|
-
## What ships
|
|
217
|
+
## What ships in this package
|
|
190
218
|
|
|
191
219
|
```
|
|
192
|
-
dist/index.js WebAssembly runtime loader
|
|
193
|
-
dist/cli.js
|
|
220
|
+
dist/index.js WebAssembly runtime loader — exports execute()
|
|
221
|
+
dist/cli.js CLI (npx lbe)
|
|
194
222
|
dist/lbe_engine.wasm Verified runtime binary
|
|
195
223
|
dist/wasm.lock.json Runtime integrity lock (SHA-256 of wasm binary)
|
|
196
224
|
assets/lbe-gates.jpg Gate sequence diagram
|
|
197
|
-
assets/story-allow.jpg Approved-request
|
|
198
|
-
assets/story-deny.jpg Blocked-request
|
|
225
|
+
assets/story-allow.jpg Approved-request flow
|
|
226
|
+
assets/story-deny.jpg Blocked-request flow
|
|
199
227
|
assets/runtime-boundary.svg Runtime boundary diagram
|
|
200
|
-
assets/lbe-gates.png Gate sequence diagram (full resolution)
|
|
201
|
-
assets/story-allow.png Approved-request storyboard (full resolution)
|
|
202
|
-
assets/story-deny.png Blocked-request storyboard (full resolution)
|
|
203
228
|
types.d.ts TypeScript declarations
|
|
229
|
+
LICENSE
|
|
204
230
|
```
|
|
205
231
|
|
|
206
232
|
At load time the runtime verifies `lbe_engine.wasm` against `wasm.lock.json`. A missing, modified, or swapped binary fails before any request is processed.
|
|
207
233
|
|
|
208
|
-
Source code,
|
|
234
|
+
Source code, tests, keys, internal adapters, and workspace state are not included.
|
|
235
|
+
|
|
236
|
+
---
|
|
237
|
+
|
|
238
|
+
## What LBE does not do
|
|
239
|
+
|
|
240
|
+
LBE is not a sandbox, container, or OS-level isolation layer. It controls only the actions that your host routes through it.
|
|
241
|
+
|
|
242
|
+
- Does not provide kernel-level process isolation
|
|
243
|
+
- Does not control network egress
|
|
244
|
+
- Does not prevent the agent from calling external APIs directly
|
|
245
|
+
- Does not provide multi-tenant separation
|
|
246
|
+
- Does not run a hosted control plane
|
|
247
|
+
|
|
248
|
+
If the agent calls the filesystem directly without going through your host code, LBE does not see it. LBE governs actions that are explicitly routed through the `execute()` boundary.
|
|
209
249
|
|
|
210
250
|
---
|
|
211
251
|
|
|
212
252
|
## Limits
|
|
213
253
|
|
|
214
|
-
|
|
254
|
+
- Central writes are best-effort
|
|
255
|
+
- Local logs remain local
|
|
256
|
+
- Non-inspectable targets may produce `WEAK_PROOF`
|
|
257
|
+
- Rate and nonce state is per-process unless you supply a shared database path
|
|
258
|
+
|
|
259
|
+
---
|
|
215
260
|
|
|
216
|
-
|
|
261
|
+
**Used in production:** LBE is the safety engine inside [Letterblack for After Effects](https://letterblack.net) — every AI-generated script and automation command passes through it before touching a live project.
|