@letterblack/lbe-core 1.3.26 → 1.3.28
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 +144 -145
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 1.3.28 — 2026-06-25
|
|
4
|
+
|
|
5
|
+
### Fixed
|
|
6
|
+
- 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.
|
|
7
|
+
|
|
8
|
+
## 1.3.27 — 2026-06-25
|
|
9
|
+
|
|
10
|
+
### Changed
|
|
11
|
+
- Rewrote public mirror README to accurately reflect the 6 real CLI commands, programmatic API, request/response shape, and what ships in the package. Removed all phantom commands and stale package references.
|
|
12
|
+
|
|
3
13
|
## 1.3.26 — 2026-06-25
|
|
4
14
|
|
|
5
15
|
### Fixed
|
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.28",
|
|
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": "3ab9a74084e1e4f067d65223d4a3d632b3a8a3e7"
|
|
78
78
|
}
|
package/release/README.md
CHANGED
|
@@ -1,216 +1,215 @@
|
|
|
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
|
+
**Local execution control for AI agents.**
|
|
6
4
|
|
|
7
|
-
|
|
5
|
+
LBE sits between what an AI agent proposes and what your system executes. Every action is validated against a local policy before it runs. No cloud service. No daemon. Evidence stays on your machine.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Install
|
|
8
10
|
|
|
9
11
|
```bash
|
|
10
12
|
npm install {{PACKAGE_NAME}}
|
|
11
|
-
npx lbe init
|
|
12
|
-
npx lbe status
|
|
13
|
-
npx lbe logs
|
|
14
|
-
npx lbe proof --public
|
|
15
|
-
npx lbe open-state
|
|
16
13
|
```
|
|
17
14
|
|
|
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.
|
|
22
|
-
|
|
23
|
-
LBE controls only actions routed through its execution boundary. Central writes
|
|
24
|
-
are best-effort, logs remain local, and non-inspectable targets may produce
|
|
25
|
-
`WEAK_PROOF`.
|
|
15
|
+
Requires Node.js >= 20.9.0.
|
|
26
16
|
|
|
27
17
|
---
|
|
28
18
|
|
|
29
|
-
|
|
19
|
+
## Quick start
|
|
30
20
|
|
|
31
|
-
|
|
21
|
+
```bash
|
|
22
|
+
npx lbe init # create policy file in observer mode
|
|
23
|
+
npx lbe status # show current policy and workspace state
|
|
24
|
+
npx lbe enforce # switch to blocking mode when ready
|
|
25
|
+
```
|
|
32
26
|
|
|
33
27
|
---
|
|
34
28
|
|
|
35
|
-
##
|
|
36
|
-
|
|
37
|
-
| I want… | Package |
|
|
38
|
-
|---|---|
|
|
39
|
-
| LBE to handle file writes and shell commands for me (full controller) | `@letterblack/lbe-exec` |
|
|
40
|
-
| Just the allow/deny decision — I'll execute it myself | `@letterblack/lbe-sdk` ← you are here |
|
|
29
|
+
## How it works
|
|
41
30
|
|
|
42
|
-
|
|
31
|
+
Every request passes through a 7-gate validation pipeline inside a local WASM runtime. If any gate fails, the request is denied before anything executes.
|
|
43
32
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
33
|
+
```
|
|
34
|
+
[1] Schema required fields and structure
|
|
35
|
+
[2] Timestamp clock-skew within ±10 minutes
|
|
36
|
+
[3] Key lifecycle trusted key, active, not expired
|
|
37
|
+
[4] Signature Ed25519 request authenticity
|
|
38
|
+
[5] Rate limit per-requester sliding-window limit
|
|
39
|
+
[6] Nonce single-use replay protection
|
|
40
|
+
[7] Policy configured rules — deny always wins
|
|
41
|
+
↓
|
|
42
|
+
allow / deny — structured result returned to your host
|
|
48
43
|
```
|
|
49
44
|
|
|
50
|
-
|
|
45
|
+
Your host receives the decision and acts on it. Nothing executes inside the runtime.
|
|
51
46
|
|
|
52
47
|
---
|
|
53
48
|
|
|
54
|
-
##
|
|
49
|
+
## CLI reference
|
|
55
50
|
|
|
56
|
-
|
|
57
|
-
|
|
51
|
+
| Command | What it does |
|
|
52
|
+
|---|---|
|
|
53
|
+
| `npx lbe init` | Create `lbe.policy.json` in observer mode |
|
|
54
|
+
| `npx lbe status` | Show policy mode, rules, and workspace state |
|
|
55
|
+
| `npx lbe policy` | Print the current policy file |
|
|
56
|
+
| `npx lbe observe` | Switch to advisory mode — logs but does not block |
|
|
57
|
+
| `npx lbe enforce` | Switch to blocking mode — denies policy violations |
|
|
58
|
+
| `npx lbe execute` | Validate a JSON proposal from stdin |
|
|
59
|
+
| `npx lbe execute --input <file>` | Validate a JSON proposal from a file |
|
|
58
60
|
|
|
59
|
-
|
|
60
|
-
version: '1.0',
|
|
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
|
-
};
|
|
69
|
-
|
|
70
|
-
const result = JSON.parse(execute(JSON.stringify(request)));
|
|
71
|
-
// Approved: { ok: true, decision: 'allow', ... }
|
|
72
|
-
// Blocked: { ok: false, decision: 'deny', error: { stage, message } }
|
|
73
|
-
```
|
|
61
|
+
Start in observer mode. Watch what your agent proposes. Add deny rules. Switch to enforce when you are confident in the policy.
|
|
74
62
|
|
|
75
|
-
|
|
63
|
+
---
|
|
64
|
+
|
|
65
|
+
## Observer mode
|
|
76
66
|
|
|
77
|
-
|
|
67
|
+
Not ready to block? `init` creates the policy in observer mode. LBE validates every request and writes audit entries — but nothing is blocked. You see exactly what the agent is doing before you decide what to deny.
|
|
78
68
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
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` |
|
|
69
|
+
```bash
|
|
70
|
+
npx lbe init # observer mode on by default
|
|
71
|
+
npx lbe status # confirm mode: observe
|
|
72
|
+
npx lbe enforce # block when ready
|
|
73
|
+
npx lbe observe # back to advisory if needed
|
|
74
|
+
```
|
|
89
75
|
|
|
90
76
|
---
|
|
91
77
|
|
|
92
|
-
##
|
|
78
|
+
## Validating a request
|
|
93
79
|
|
|
94
|
-
|
|
80
|
+
`execute` accepts a JSON proposal on stdin or via `--input <file>` and returns a structured decision.
|
|
95
81
|
|
|
96
82
|
```bash
|
|
97
|
-
|
|
98
|
-
npx lbe
|
|
99
|
-
|
|
83
|
+
# from a file
|
|
84
|
+
npx lbe execute --input proposal.json
|
|
85
|
+
|
|
86
|
+
# from stdin
|
|
87
|
+
echo '{"version":"1.0",...}' | npx lbe execute
|
|
100
88
|
```
|
|
101
89
|
|
|
102
|
-
|
|
90
|
+
Exit code `0` = allowed. Exit code `1` = denied. Exit code `2` = bad input.
|
|
91
|
+
|
|
92
|
+
### Minimal request shape
|
|
93
|
+
|
|
94
|
+
```json
|
|
95
|
+
{
|
|
96
|
+
"version": "1.0",
|
|
97
|
+
"request_id": "req-001",
|
|
98
|
+
"timestamp": 1700000000,
|
|
99
|
+
"actor": { "id": "agent:local", "role": "agent" },
|
|
100
|
+
"intent": {
|
|
101
|
+
"type": "command",
|
|
102
|
+
"name": "write_file",
|
|
103
|
+
"payload": { "target": "out.txt" }
|
|
104
|
+
},
|
|
105
|
+
"context": { "workspace": "/your/project", "env": {}, "history": [] },
|
|
106
|
+
"constraints": { "policy_mode": "strict", "timeout_ms": 5000 },
|
|
107
|
+
"auth": { "signature": "<host-signed>", "nonce": "<unique-per-request>" }
|
|
108
|
+
}
|
|
109
|
+
```
|
|
103
110
|
|
|
104
|
-
|
|
111
|
+
### Decision response
|
|
105
112
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
113
|
+
```json
|
|
114
|
+
{
|
|
115
|
+
"ok": true,
|
|
116
|
+
"decision": "allow",
|
|
117
|
+
"request_id": "req-001",
|
|
118
|
+
"result": { "type": "allowed" }
|
|
119
|
+
}
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
```json
|
|
123
|
+
{
|
|
124
|
+
"ok": false,
|
|
125
|
+
"decision": "deny",
|
|
126
|
+
"request_id": "req-001",
|
|
127
|
+
"error": { "stage": "policy", "message": "rule:deny_outside_workspace" }
|
|
128
|
+
}
|
|
129
|
+
```
|
|
117
130
|
|
|
118
131
|
---
|
|
119
132
|
|
|
120
|
-
##
|
|
133
|
+
## Programmatic API
|
|
121
134
|
|
|
122
|
-
|
|
135
|
+
```js
|
|
136
|
+
import { execute } from '{{PACKAGE_NAME}}';
|
|
123
137
|
|
|
124
|
-
|
|
138
|
+
const result = JSON.parse(execute(JSON.stringify(proposal)));
|
|
125
139
|
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
[3] Key lifecycle trusted key, active, not expired
|
|
132
|
-
↓
|
|
133
|
-
[4] Signature Ed25519 request authenticity
|
|
134
|
-
↓
|
|
135
|
-
[5] Rate limit per-requester sliding-window limit
|
|
136
|
-
↓
|
|
137
|
-
[6] Nonce single-use replay protection
|
|
138
|
-
↓
|
|
139
|
-
[7] Policy configured authorization (deny-wins)
|
|
140
|
-
↓
|
|
141
|
-
allow / deny / error — structured result returned to host
|
|
140
|
+
if (result.decision === 'allow') {
|
|
141
|
+
// safe to act
|
|
142
|
+
} else {
|
|
143
|
+
// blocked — result.error has the gate and reason
|
|
144
|
+
}
|
|
142
145
|
```
|
|
143
146
|
|
|
144
|
-
|
|
147
|
+
`execute(input: string): string` — accepts JSON, returns JSON. Synchronous. The WASM runtime owns all gate decisions.
|
|
145
148
|
|
|
146
149
|
---
|
|
147
150
|
|
|
148
|
-
##
|
|
151
|
+
## What ships in this package
|
|
149
152
|
|
|
150
|
-
|
|
153
|
+
```
|
|
154
|
+
dist/index.js WebAssembly runtime loader — exports execute()
|
|
155
|
+
dist/cli.js CLI (npx lbe)
|
|
156
|
+
dist/lbe_engine.wasm Verified runtime binary
|
|
157
|
+
dist/wasm.lock.json Runtime integrity lock (SHA-256 of wasm binary)
|
|
158
|
+
assets/lbe-gates.jpg Gate sequence diagram
|
|
159
|
+
assets/story-allow.jpg Approved-request flow
|
|
160
|
+
assets/story-deny.jpg Blocked-request flow
|
|
161
|
+
assets/runtime-boundary.svg Runtime boundary diagram
|
|
162
|
+
types.d.ts TypeScript declarations
|
|
163
|
+
LICENSE
|
|
164
|
+
```
|
|
151
165
|
|
|
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.
|
|
166
|
+
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.
|
|
158
167
|
|
|
159
|
-
|
|
168
|
+
Source code, tests, keys, internal adapters, and workspace state are not included.
|
|
160
169
|
|
|
161
170
|
---
|
|
162
171
|
|
|
163
|
-
##
|
|
172
|
+
## Gate pipeline — approved request
|
|
164
173
|
|
|
165
|
-

|
|
166
175
|
|
|
167
|
-
1.
|
|
168
|
-
2.
|
|
169
|
-
3.
|
|
170
|
-
4.
|
|
171
|
-
|
|
172
|
-
No partial execution. No silent failures. Denial is a first-class outcome, not an error.
|
|
176
|
+
1. Agent produces a signed action proposal.
|
|
177
|
+
2. Identity confirmed against a locally held key — no network call.
|
|
178
|
+
3. Policy evaluated. Request approved.
|
|
179
|
+
4. Host executes inside the allowed workspace.
|
|
180
|
+
5. Audit entry appended to local hash-linked log.
|
|
173
181
|
|
|
174
182
|
---
|
|
175
183
|
|
|
176
|
-
##
|
|
184
|
+
## Gate pipeline — denied request
|
|
177
185
|
|
|
178
|
-
|
|
179
|
-
|---|---|
|
|
180
|
-
| Malformed or incomplete request | Schema |
|
|
181
|
-
| Stale or replayed request | Timestamp + Nonce |
|
|
182
|
-
| Tampered or expired key | Key lifecycle + Signature |
|
|
183
|
-
| Excessive requests from one actor | Rate limit |
|
|
184
|
-
| Action not permitted by project policy | Policy — deny-wins |
|
|
185
|
-
| Agent writing outside project root | Scope check in host after decision |
|
|
186
|
+

|
|
186
187
|
|
|
187
|
-
|
|
188
|
+
1. Agent proposes an action outside the permitted policy.
|
|
189
|
+
2. Policy gate closes. WASM runtime returns denied before any adapter runs.
|
|
190
|
+
3. Shell untouched. Filesystem unchanged.
|
|
191
|
+
4. Denial written to audit log — chain sealed.
|
|
188
192
|
|
|
189
|
-
|
|
193
|
+
No partial execution. Denial is a first-class outcome.
|
|
190
194
|
|
|
191
|
-
|
|
192
|
-
dist/index.js WebAssembly runtime loader and execute()
|
|
193
|
-
dist/cli.js Local CLI (npx lbe)
|
|
194
|
-
dist/lbe_engine.wasm Verified runtime binary
|
|
195
|
-
dist/wasm.lock.json Runtime integrity lock (SHA-256 of wasm binary)
|
|
196
|
-
assets/lbe-gates.jpg Gate sequence diagram
|
|
197
|
-
assets/story-allow.jpg Approved-request storyboard
|
|
198
|
-
assets/story-deny.jpg Blocked-request storyboard
|
|
199
|
-
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
|
-
types.d.ts TypeScript declarations
|
|
204
|
-
```
|
|
195
|
+
---
|
|
205
196
|
|
|
206
|
-
|
|
197
|
+
## What LBE does not do
|
|
198
|
+
|
|
199
|
+
- Kernel-level process isolation
|
|
200
|
+
- Network-egress control
|
|
201
|
+
- Multi-tenant separation
|
|
202
|
+
- Cloud monitoring or hosted control plane
|
|
203
|
+
- Universal control over tools not routed through LBE
|
|
207
204
|
|
|
208
|
-
|
|
205
|
+
LBE controls only actions that pass through its execution boundary.
|
|
209
206
|
|
|
210
207
|
---
|
|
211
208
|
|
|
212
209
|
## Limits
|
|
213
210
|
|
|
214
|
-
|
|
211
|
+
Central writes are best-effort. Local logs remain local. Non-inspectable targets may produce `WEAK_PROOF`. Rate and nonce state is per-process unless you supply a shared database path.
|
|
212
|
+
|
|
213
|
+
---
|
|
215
214
|
|
|
216
|
-
|
|
215
|
+
**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.
|