@letterblack/lbe-core 1.3.1 → 1.3.2
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 +6 -0
- package/README.md +12 -12
- package/Release-README.md +51 -325
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
package/README.md
CHANGED
|
@@ -10,7 +10,7 @@ control direct actions outside its execution boundary.
|
|
|
10
10
|
## Install and start
|
|
11
11
|
|
|
12
12
|
```bash
|
|
13
|
-
npm install @letterblack/lbe-
|
|
13
|
+
npm install @letterblack/lbe-core
|
|
14
14
|
npx lbe init
|
|
15
15
|
npx lbe status
|
|
16
16
|
npx lbe logs
|
|
@@ -44,8 +44,8 @@ egress control.
|
|
|
44
44
|
# Internal source workspace
|
|
45
45
|
|
|
46
46
|
This workspace is not the public npm package. It contains readable source,
|
|
47
|
-
tests, and release tooling. The public package is generated into
|
|
48
|
-
`release-public/` as `@letterblack/lbe-
|
|
47
|
+
tests, and release tooling. The public package is generated into
|
|
48
|
+
`release-public/` as `@letterblack/lbe-core`.
|
|
49
49
|
|
|
50
50
|
Every AI action passes through a local gate before it can execute.
|
|
51
51
|
|
|
@@ -93,7 +93,7 @@ pushes this private source repository, its history, or its internal files.
|
|
|
93
93
|
|
|
94
94
|
Set `PUBLIC_REPO_TOKEN` and `NPM_TOKEN` as Actions secrets in this repository.
|
|
95
95
|
The former needs Contents read/write permission to the public repository; the
|
|
96
|
-
latter needs npm publish permission for `@letterblack/lbe-
|
|
96
|
+
latter needs npm publish permission for `@letterblack/lbe-core`. Push a matching
|
|
97
97
|
`v<package-version>` tag from current `main` to release automatically, or run
|
|
98
98
|
the workflow manually with the same tag value. The workflow verifies the
|
|
99
99
|
artifact and tests first, publishes npm, replaces the public repository working
|
|
@@ -140,8 +140,8 @@ npm install @letterblack/lbe-core
|
|
|
140
140
|
|
|
141
141
|
Public users install:
|
|
142
142
|
|
|
143
|
-
```bash
|
|
144
|
-
npm install @letterblack/lbe-
|
|
143
|
+
```bash
|
|
144
|
+
npm install @letterblack/lbe-core
|
|
145
145
|
```
|
|
146
146
|
|
|
147
147
|
Requires Node.js ≥ 20.9.0.
|
|
@@ -171,7 +171,7 @@ cat input.json | npx lbe execute
|
|
|
171
171
|
|
|
172
172
|
```js
|
|
173
173
|
import crypto from 'node:crypto';
|
|
174
|
-
import { execute } from '@letterblack/lbe-
|
|
174
|
+
import { execute } from '@letterblack/lbe-core';
|
|
175
175
|
|
|
176
176
|
const buildRequest = (name, payload = {}) => ({
|
|
177
177
|
version: '1.0',
|
|
@@ -188,9 +188,9 @@ const output = execute(JSON.stringify(buildRequest('status')));
|
|
|
188
188
|
console.log(JSON.parse(output));
|
|
189
189
|
```
|
|
190
190
|
|
|
191
|
-
The public contract is `execute(input: string): string`. This repo still
|
|
192
|
-
contains the private source package and its internal SDK helpers below, but the
|
|
193
|
-
published surface is the generated `@letterblack/lbe-
|
|
191
|
+
The public contract is `execute(input: string): string`. This repo still
|
|
192
|
+
contains the private source package and its internal SDK helpers below, but the
|
|
193
|
+
published surface is the generated `@letterblack/lbe-core` package.
|
|
194
194
|
|
|
195
195
|
---
|
|
196
196
|
|
|
@@ -402,7 +402,7 @@ The controller is the only authority. Adapters execute — they do not decide.
|
|
|
402
402
|
|
|
403
403
|
## Public SDK surface
|
|
404
404
|
|
|
405
|
-
The published package (`@letterblack/lbe-
|
|
405
|
+
The published package (`@letterblack/lbe-core`) exposes one function:
|
|
406
406
|
|
|
407
407
|
```ts
|
|
408
408
|
export function execute(input: string): string;
|
|
@@ -427,7 +427,7 @@ interface LBEExecuteOutput {
|
|
|
427
427
|
|
|
428
428
|
These helpers exist in `@letterblack/lbe-core` (this package) for
|
|
429
429
|
repository development and testing. They are **not** exported from the public
|
|
430
|
-
`@letterblack/lbe-
|
|
430
|
+
`@letterblack/lbe-core` package.
|
|
431
431
|
|
|
432
432
|
### `sandbox(root, opts?)` → `{ write, read, patch, lbe }`
|
|
433
433
|
|
package/Release-README.md
CHANGED
|
@@ -1,13 +1,17 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @letterblack/lbe-core
|
|
2
2
|
|
|
3
3
|
LBE is local execution control for AI agents. It evaluates file and shell
|
|
4
|
-
actions routed through its execution boundary
|
|
5
|
-
|
|
4
|
+
actions routed through its execution boundary, records local evidence, and
|
|
5
|
+
returns an allow/deny outcome before the governed action runs.
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
This release documents the decision-only package. If you need the in-process
|
|
8
|
+
controller that performs governed file and shell operations, that is a separate
|
|
9
|
+
legacy/internal surface.
|
|
10
|
+
|
|
11
|
+
## Install and start
|
|
8
12
|
|
|
9
13
|
```bash
|
|
10
|
-
npm install
|
|
14
|
+
npm install @letterblack/lbe-core
|
|
11
15
|
npx lbe init
|
|
12
16
|
npx lbe status
|
|
13
17
|
npx lbe logs
|
|
@@ -15,325 +19,47 @@ npx lbe proof --public
|
|
|
15
19
|
npx lbe open-state
|
|
16
20
|
```
|
|
17
21
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
+
`init` creates project policy material. `status` shows the local central state
|
|
23
|
+
for the current workspace; `logs` reads its event history; `proof` shows the
|
|
24
|
+
latest proof result; and `open-state` opens the central state folder.
|
|
25
|
+
|
|
26
|
+
## Local state and proof
|
|
27
|
+
|
|
28
|
+
LBE keeps state locally in a central per-user state folder. Each workspace has
|
|
29
|
+
a stable workspace ID and its own event log. In v1.3, an existing
|
|
30
|
+
`.lbe/events.jsonl` remains local fallback truth and is imported into central
|
|
31
|
+
state once; the source file is preserved.
|
|
32
|
+
|
|
33
|
+
Proof combines an intent, optional target, file index, LBE events, and
|
|
34
|
+
`proof/latest.json`. Use `lbe proof --public` for a redacted proof summary.
|
|
35
|
+
Non-inspectable targets can produce `WEAK_PROOF` rather than a stronger claim.
|
|
36
|
+
|
|
37
|
+
## CLI reference
|
|
38
|
+
|
|
39
|
+
| Command | Purpose |
|
|
40
|
+
|---|---|
|
|
41
|
+
| `npx lbe init` | Create project-local policy and key state |
|
|
42
|
+
| `npx lbe status` | Show workspace ID and central state paths |
|
|
43
|
+
| `npx lbe logs` | Read the central event history |
|
|
44
|
+
| `npx lbe open-state` | Open the local central state folder |
|
|
45
|
+
| `npx lbe proof` | Show the latest proof result |
|
|
46
|
+
| `npx lbe proof --public` | Show a redacted proof summary |
|
|
47
|
+
|
|
48
|
+
## What ships
|
|
49
|
+
|
|
50
|
+
```
|
|
51
|
+
bin/lbe.js CLI entrypoint
|
|
52
|
+
dist/cli/lbe.js Packaged CLI runtime
|
|
53
|
+
dist/hooks/register.cjs Packaged hook bridge
|
|
54
|
+
dist/state/index.cjs Packaged central-state resolver
|
|
55
|
+
dist/state/appendCentral.cjs Packaged central event appender
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
Source code, controller implementation, adapters, tests, keys, and runtime
|
|
59
|
+
state are not included.
|
|
22
60
|
|
|
23
|
-
|
|
24
|
-
are best-effort, logs remain local, and non-inspectable targets may produce
|
|
25
|
-
`WEAK_PROOF`.
|
|
61
|
+
## Limits
|
|
26
62
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
The risky part is not only what the model thinks.
|
|
32
|
-
|
|
33
|
-
The risky part is what happens **after the agent decides to act**.
|
|
34
|
-
|
|
35
|
-
LBE is a local execution boundary for AI agents. It sits between an agent and the workspace, validates the requested action, applies policy, records evidence, and returns a structured allow/deny result before anything reaches the filesystem, terminal, or tool layer.
|
|
36
|
-
|
|
37
|
-
```text
|
|
38
|
-
Agent wants to act
|
|
39
|
-
↓
|
|
40
|
-
LBE validates identity, scope, replay, rate limits, and policy
|
|
41
|
-
↓
|
|
42
|
-
allow / deny / error
|
|
43
|
-
↓
|
|
44
|
-
Host executes only if LBE approved
|
|
45
|
-
↓
|
|
46
|
-
Audit evidence is written locally
|
|
47
|
-
```
|
|
48
|
-
|
|
49
|
-
No hosted service. No cloud control plane. No remote dependency.
|
|
50
|
-
|
|
51
|
-
> **Used in production:** LBE is the safety engine inside [Letterblack for After Effects](https://letterblack.net), where AI-generated scripts and automation commands are checked before touching a live creative project.
|
|
52
|
-
|
|
53
|
-
---
|
|
54
|
-
|
|
55
|
-
## The problem LBE is built for
|
|
56
|
-
|
|
57
|
-
A user asks an agent to do one thing:
|
|
58
|
-
|
|
59
|
-
```text
|
|
60
|
-
"Move the Save button 20px to the right."
|
|
61
|
-
```
|
|
62
|
-
|
|
63
|
-
The agent may correctly understand the task, but still attempt extra actions:
|
|
64
|
-
|
|
65
|
-
```text
|
|
66
|
-
edit settings-panel.jsx expected
|
|
67
|
-
edit navbar.jsx unexpected
|
|
68
|
-
edit sidebar.jsx unexpected
|
|
69
|
-
run shell command unexpected
|
|
70
|
-
```
|
|
71
|
-
|
|
72
|
-
Most systems treat this as:
|
|
73
|
-
|
|
74
|
-
```text
|
|
75
|
-
agent output → approval dialog → execution
|
|
76
|
-
```
|
|
77
|
-
|
|
78
|
-
LBE treats approval as only one signal.
|
|
79
|
-
|
|
80
|
-
```text
|
|
81
|
-
user claim is not truth
|
|
82
|
-
agent claim is not truth
|
|
83
|
-
approval dialog is not truth
|
|
84
|
-
runtime evidence is truth
|
|
85
|
-
```
|
|
86
|
-
|
|
87
|
-
LBE asks a different question before execution:
|
|
88
|
-
|
|
89
|
-
```text
|
|
90
|
-
Is this action authentic?
|
|
91
|
-
Is it fresh, or replayed?
|
|
92
|
-
Is the requester allowed?
|
|
93
|
-
Is the target inside scope?
|
|
94
|
-
Does policy allow it?
|
|
95
|
-
Can the result be audited?
|
|
96
|
-
```
|
|
97
|
-
|
|
98
|
-
That is the execution boundary.
|
|
99
|
-
|
|
100
|
-
---
|
|
101
|
-
|
|
102
|
-
## What LBE is not
|
|
103
|
-
|
|
104
|
-
LBE is **not** another AI agent framework.
|
|
105
|
-
|
|
106
|
-
It does not replace:
|
|
107
|
-
|
|
108
|
-
- the model
|
|
109
|
-
- the IDE
|
|
110
|
-
- the chat UI
|
|
111
|
-
- Git
|
|
112
|
-
- human review
|
|
113
|
-
- an OS sandbox
|
|
114
|
-
|
|
115
|
-
Git can revert source history after a change. Approval dialogs ask a human for permission. LBE exists earlier in the chain: between the agent's proposed action and the actual execution path.
|
|
116
|
-
|
|
117
|
-
---
|
|
118
|
-
|
|
119
|
-
## What LBE does
|
|
120
|
-
|
|
121
|
-
| Need | What LBE provides |
|
|
122
|
-
|---|---|
|
|
123
|
-
| Stop blind execution | Local allow/deny gate before execution |
|
|
124
|
-
| Avoid random tool access | Structured action proposal instead of direct tool calls |
|
|
125
|
-
| Verify requester identity | Signed requests, trusted keys, nonce checks |
|
|
126
|
-
| Block stale/replayed actions | Timestamp and single-use nonce validation |
|
|
127
|
-
| Enforce project rules | Local deny-wins policy evaluation |
|
|
128
|
-
| Understand what happened | Hash-linked audit log |
|
|
129
|
-
| Integrate without cloud | Runs locally through SDK / CLI / runtime package |
|
|
130
|
-
|
|
131
|
-
---
|
|
132
|
-
|
|
133
|
-
## Package choice
|
|
134
|
-
|
|
135
|
-
| I want… | Package |
|
|
136
|
-
|---|---|
|
|
137
|
-
| LBE to handle file writes and shell commands for me | `@letterblack/lbe-exec` |
|
|
138
|
-
| Just the allow/deny decision — my app executes after approval | `{{PACKAGE_NAME}}` |
|
|
139
|
-
|
|
140
|
-
This package documents the SDK boundary. For the in-process controller that performs governed file and shell operations, use `@letterblack/lbe-exec`.
|
|
141
|
-
|
|
142
|
-
---
|
|
143
|
-
|
|
144
|
-
## Install
|
|
145
|
-
|
|
146
|
-
```bash
|
|
147
|
-
npm install {{PACKAGE_NAME}}
|
|
148
|
-
```
|
|
149
|
-
|
|
150
|
-
Requires Node.js >= 20.9.0.
|
|
151
|
-
|
|
152
|
-
For the full local execution controller:
|
|
153
|
-
|
|
154
|
-
```bash
|
|
155
|
-
npm install @letterblack/lbe-exec
|
|
156
|
-
npx lbe init
|
|
157
|
-
```
|
|
158
|
-
|
|
159
|
-
---
|
|
160
|
-
|
|
161
|
-
## Quick start: decision boundary
|
|
162
|
-
|
|
163
|
-
```js
|
|
164
|
-
import { execute } from '{{PACKAGE_NAME}}';
|
|
165
|
-
|
|
166
|
-
const request = {
|
|
167
|
-
version: '1.0',
|
|
168
|
-
request_id: 'req-001',
|
|
169
|
-
timestamp: Math.floor(Date.now() / 1000),
|
|
170
|
-
actor: { id: 'agent:local', role: 'agent' },
|
|
171
|
-
intent: {
|
|
172
|
-
type: 'command',
|
|
173
|
-
name: 'write_file',
|
|
174
|
-
payload: { target: 'out.txt' }
|
|
175
|
-
},
|
|
176
|
-
context: {
|
|
177
|
-
workspace: process.cwd(),
|
|
178
|
-
env: {},
|
|
179
|
-
history: []
|
|
180
|
-
},
|
|
181
|
-
constraints: {
|
|
182
|
-
policy_mode: 'strict',
|
|
183
|
-
timeout_ms: 5000
|
|
184
|
-
},
|
|
185
|
-
auth: {
|
|
186
|
-
signature: '<host-signed>',
|
|
187
|
-
nonce: '<unique-per-request>'
|
|
188
|
-
}
|
|
189
|
-
};
|
|
190
|
-
|
|
191
|
-
const result = JSON.parse(execute(JSON.stringify(request)));
|
|
192
|
-
|
|
193
|
-
if (result.ok && result.decision === 'allow') {
|
|
194
|
-
// Host executes the action here.
|
|
195
|
-
// The SDK decides; your host acts.
|
|
196
|
-
}
|
|
197
|
-
```
|
|
198
|
-
|
|
199
|
-
`execute(input: string): string` accepts JSON and returns JSON. The SDK validates and returns a decision. It does not perform the file write or shell command itself.
|
|
200
|
-
|
|
201
|
-
---
|
|
202
|
-
|
|
203
|
-
## Observer mode
|
|
204
|
-
|
|
205
|
-
Not ready to block yet? Start in observer mode.
|
|
206
|
-
|
|
207
|
-
Observer mode validates and logs requests as if enforcement were active, but does not block. This lets you see what the agent is doing before deciding what to deny.
|
|
208
|
-
|
|
209
|
-
```bash
|
|
210
|
-
npx lbe init # create project-local policy and key state
|
|
211
|
-
npx lbe observe # advisory / log-only mode
|
|
212
|
-
npx lbe enforce # blocking mode
|
|
213
|
-
```
|
|
214
|
-
|
|
215
|
-
---
|
|
216
|
-
|
|
217
|
-
## CLI reference
|
|
218
|
-
|
|
219
|
-
| Command | Purpose |
|
|
220
|
-
|---|---|
|
|
221
|
-
| `npx lbe init` | Create project-local policy and key state |
|
|
222
|
-
| `npx lbe policy-add` | Add a rule to the active policy |
|
|
223
|
-
| `npx lbe observe` | Set advisory / log-only mode |
|
|
224
|
-
| `npx lbe enforce` | Set blocking mode |
|
|
225
|
-
| `npx lbe run` | Validate and execute a proposal from `--in <file>` |
|
|
226
|
-
| `npx lbe verify` | Validate a proposal without executing |
|
|
227
|
-
| `npx lbe dryrun` | Validate and simulate without executing |
|
|
228
|
-
| `npx lbe health` | Check required files are present and readable |
|
|
229
|
-
| `npx lbe audit-verify` | Verify the audit log hash chain |
|
|
230
|
-
|
|
231
|
-
---
|
|
232
|
-
|
|
233
|
-
## Gate pipeline
|
|
234
|
-
|
|
235
|
-

|
|
236
|
-
|
|
237
|
-
Every request enters the same local gate pipeline. A failure at any gate returns a structured denial. The remaining gates are not evaluated.
|
|
238
|
-
|
|
239
|
-
```text
|
|
240
|
-
[1] Schema required fields and structural validity
|
|
241
|
-
↓
|
|
242
|
-
[2] Timestamp permitted clock-skew window
|
|
243
|
-
↓
|
|
244
|
-
[3] Key lifecycle trusted key, active, not expired
|
|
245
|
-
↓
|
|
246
|
-
[4] Signature Ed25519 request authenticity
|
|
247
|
-
↓
|
|
248
|
-
[5] Rate limit per-requester sliding-window limit
|
|
249
|
-
↓
|
|
250
|
-
[6] Nonce single-use replay protection
|
|
251
|
-
↓
|
|
252
|
-
[7] Policy configured authorization, deny-wins
|
|
253
|
-
↓
|
|
254
|
-
allow / deny / error
|
|
255
|
-
```
|
|
256
|
-
|
|
257
|
-
The WASM runtime owns the gate decisions. The host receives the decision and acts on it.
|
|
258
|
-
|
|
259
|
-
---
|
|
260
|
-
|
|
261
|
-
## Approved path
|
|
262
|
-
|
|
263
|
-

|
|
264
|
-
|
|
265
|
-
1. Agent or host creates a signed action proposal.
|
|
266
|
-
2. LBE verifies request structure, identity, freshness, nonce, rate limit, and policy.
|
|
267
|
-
3. The result is `allow`.
|
|
268
|
-
4. The host executes the write or command inside the allowed workspace.
|
|
269
|
-
5. A hash-linked audit entry records the decision and result.
|
|
270
|
-
6. The host receives structured evidence: decision, matched rules, result, and audit identifier.
|
|
271
|
-
|
|
272
|
-
---
|
|
273
|
-
|
|
274
|
-
## Blocked path
|
|
275
|
-
|
|
276
|
-

|
|
277
|
-
|
|
278
|
-
1. Agent attempts an action that is malformed, stale, replayed, unsigned, too frequent, or not allowed by policy.
|
|
279
|
-
2. LBE returns `deny` before any adapter is reached.
|
|
280
|
-
3. The shell is untouched.
|
|
281
|
-
4. The filesystem is unchanged.
|
|
282
|
-
5. The denial is written to the audit chain.
|
|
283
|
-
|
|
284
|
-
Denial is not a crash. It is a valid controlled outcome.
|
|
285
|
-
|
|
286
|
-
---
|
|
287
|
-
|
|
288
|
-
## What this covers
|
|
289
|
-
|
|
290
|
-
| Threat / failure mode | Gate / mechanism |
|
|
291
|
-
|---|---|
|
|
292
|
-
| Malformed or incomplete request | Schema |
|
|
293
|
-
| Stale request | Timestamp |
|
|
294
|
-
| Replayed request | Nonce |
|
|
295
|
-
| Unknown or expired key | Key lifecycle |
|
|
296
|
-
| Tampered request | Signature |
|
|
297
|
-
| Request burst from one actor | Rate limit |
|
|
298
|
-
| Action not permitted by project rules | Policy |
|
|
299
|
-
| Agent writing outside project root | Host scope check after decision |
|
|
300
|
-
| Later dispute over what happened | Hash-linked audit log |
|
|
301
|
-
|
|
302
|
-
---
|
|
303
|
-
|
|
304
|
-
## What ships
|
|
305
|
-
|
|
306
|
-
```text
|
|
307
|
-
dist/index.js WebAssembly runtime loader and execute()
|
|
308
|
-
dist/cli.js Local CLI, npx lbe
|
|
309
|
-
dist/lbe_engine.wasm Verified runtime binary
|
|
310
|
-
dist/wasm.lock.json Runtime integrity lock, SHA-256 of wasm binary
|
|
311
|
-
assets/lbe-gates.jpg Gate sequence diagram
|
|
312
|
-
assets/story-allow.jpg Approved-request storyboard
|
|
313
|
-
assets/story-deny.jpg Blocked-request storyboard
|
|
314
|
-
assets/runtime-boundary.svg Runtime boundary diagram
|
|
315
|
-
assets/lbe-gates.png Gate sequence diagram, full resolution
|
|
316
|
-
assets/story-allow.png Approved-request storyboard, full resolution
|
|
317
|
-
assets/story-deny.png Blocked-request storyboard, full resolution
|
|
318
|
-
types.d.ts TypeScript declarations
|
|
319
|
-
```
|
|
320
|
-
|
|
321
|
-
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.
|
|
322
|
-
|
|
323
|
-
Source code, controller implementation, adapters, tests, keys, and runtime state are not included in this package.
|
|
324
|
-
|
|
325
|
-
---
|
|
326
|
-
|
|
327
|
-
## Limits
|
|
328
|
-
|
|
329
|
-
LBE validates requests routed through its runtime. It is not a kernel-level sandbox and does not provide OS process isolation, network-egress control, multi-tenant separation, or a hosted control plane.
|
|
330
|
-
|
|
331
|
-
If a tool writes directly to disk outside the LBE execution boundary, that write
|
|
332
|
-
is outside this package's control. Place LBE on the execution path between the
|
|
333
|
-
agent and the tools it uses.
|
|
334
|
-
|
|
335
|
-
---
|
|
336
|
-
|
|
337
|
-
## One-sentence summary
|
|
338
|
-
|
|
339
|
-
LBE does not make the agent smarter. It makes the agent's execution path controlled, evidence-backed, and locally auditable.
|
|
63
|
+
Only actions routed through LBE are controlled. Central writes are best-effort,
|
|
64
|
+
logs remain local, and LBE does not provide process isolation or network
|
|
65
|
+
egress control.
|
package/package.json
CHANGED