@letterblack/lbe-core 1.3.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.
Files changed (79) hide show
  1. package/.githooks/pre-commit +2 -0
  2. package/.githooks/pre-push +2 -0
  3. package/CHANGELOG.md +57 -0
  4. package/LICENSE +1 -0
  5. package/README.md +506 -0
  6. package/Release-README.md +339 -0
  7. package/WORKSPACE.md +422 -0
  8. package/_proof.mjs +246 -0
  9. package/assets/lbe-gates.jpg +0 -0
  10. package/assets/lbe-gates.png +0 -0
  11. package/assets/runtime-boundary.svg +36 -0
  12. package/assets/story-allow.jpg +0 -0
  13. package/assets/story-allow.png +0 -0
  14. package/assets/story-deny.jpg +0 -0
  15. package/assets/story-deny.png +0 -0
  16. package/bin/lbe.js +12 -0
  17. package/config/identity.config.json +3 -0
  18. package/config/policy.default.json +24 -0
  19. package/dist/cli/lbe.js +4274 -0
  20. package/dist/hooks/register.cjs +505 -0
  21. package/dist/state/appendCentral.cjs +87 -0
  22. package/dist/state/index.cjs +101 -0
  23. package/exec/cli.js +472 -0
  24. package/exec/index.js +2 -0
  25. package/index.js +24 -0
  26. package/lbe.audit.jsonl +46 -0
  27. package/package.json +76 -0
  28. package/release/README.md +216 -0
  29. package/release/TRUST.md +90 -0
  30. package/release/exec-README.md +215 -0
  31. package/release/exec-types.d.ts +50 -0
  32. package/release-exec/LICENSE +1 -0
  33. package/release-exec/README.md +215 -0
  34. package/release-exec/assets/lbe-gates.jpg +0 -0
  35. package/release-exec/assets/lbe-gates.png +0 -0
  36. package/release-exec/assets/runtime-boundary.svg +36 -0
  37. package/release-exec/assets/story-allow.jpg +0 -0
  38. package/release-exec/assets/story-allow.png +0 -0
  39. package/release-exec/assets/story-deny.jpg +0 -0
  40. package/release-exec/assets/story-deny.png +0 -0
  41. package/release-exec/dist/cli.js +2841 -0
  42. package/release-exec/dist/index.js +1835 -0
  43. package/release-exec/dist/lbe_engine.wasm +0 -0
  44. package/release-exec/dist/wasm.lock.json +4 -0
  45. package/release-exec/hooks/register.cjs +473 -0
  46. package/release-exec/package.json +35 -0
  47. package/release-exec/types.d.ts +50 -0
  48. package/runtime/engine.js +322 -0
  49. package/runtime/lbe_engine.wasm +0 -0
  50. package/src/cli/commands/auditVerify.js +36 -0
  51. package/src/cli/commands/dryrun.js +175 -0
  52. package/src/cli/commands/health.js +153 -0
  53. package/src/cli/commands/init.js +306 -0
  54. package/src/cli/commands/integrityCheck.js +57 -0
  55. package/src/cli/commands/logs.js +53 -0
  56. package/src/cli/commands/openState.js +44 -0
  57. package/src/cli/commands/policyAdd.js +8 -0
  58. package/src/cli/commands/policyMode.js +7 -0
  59. package/src/cli/commands/policySign.js +72 -0
  60. package/src/cli/commands/proof.js +122 -0
  61. package/src/cli/commands/run.js +342 -0
  62. package/src/cli/commands/status.js +73 -0
  63. package/src/cli/commands/verify.js +144 -0
  64. package/src/cli/main.js +176 -0
  65. package/src/cli/parseArgs.js +114 -0
  66. package/src/exec/localExecutor.js +289 -0
  67. package/src/hooks/register.cjs +505 -0
  68. package/src/state/appendCentral.cjs +87 -0
  69. package/src/state/fileIndex.js +140 -0
  70. package/src/state/index.cjs +101 -0
  71. package/src/state/index.js +65 -0
  72. package/src/state/intentRegistry.js +83 -0
  73. package/src/state/migration.js +112 -0
  74. package/src/state/proofRunner.js +246 -0
  75. package/src/state/stateRoot.js +40 -0
  76. package/src/state/targetRegistry.js +108 -0
  77. package/src/state/workspaceId.js +40 -0
  78. package/src/state/workspaceRegistry.js +65 -0
  79. package/types.d.ts +175 -0
@@ -0,0 +1,339 @@
1
+ # {{PACKAGE_NAME}}
2
+
3
+ LBE is local execution control for AI agents. It evaluates file and shell
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.
6
+
7
+ ## Setup
8
+
9
+ ```bash
10
+ 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
+ ```
17
+
18
+ State is stored locally in a central per-user folder, keyed by workspace ID.
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`.
26
+
27
+ ---
28
+
29
+ AI agents are starting to touch real files, terminals, tools, projects, and production workflows.
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
+ ![LBE gate sequence — Request flows through Policy, Identity, and Scope gates before reaching Action. A rejected request is routed to denial before it reaches execution.](assets/lbe-gates.png)
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
+ ![Happy path — agent proposes action, identity confirmed, policy approved, governed write executed, audit chain extended, result returned to app.](assets/story-allow.png)
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
+ ![Deny path — policy rejection before a governed action, shell untouched, filesystem unchanged, audit entry written, final state clean.](assets/story-deny.png)
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.