@letterblack/lbe-core 1.3.2 → 1.3.4
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/LICENSE +1 -1
- package/README.md +130 -442
- package/assets/runtime-boundary.svg +36 -36
- package/dist/cli.js +141 -0
- package/dist/index.js +52 -0
- package/{release-exec/dist → dist}/wasm.lock.json +5 -4
- package/package.json +23 -54
- package/types.d.ts +2 -175
- package/.githooks/pre-commit +0 -2
- package/.githooks/pre-push +0 -2
- package/CHANGELOG.md +0 -69
- package/Release-README.md +0 -65
- package/WORKSPACE.md +0 -422
- package/_proof.mjs +0 -246
- package/bin/lbe.js +0 -12
- package/config/identity.config.json +0 -3
- package/config/policy.default.json +0 -24
- package/dist/cli/lbe.js +0 -4274
- package/dist/hooks/register.cjs +0 -505
- package/dist/state/appendCentral.cjs +0 -87
- package/dist/state/index.cjs +0 -101
- package/exec/cli.js +0 -472
- package/exec/index.js +0 -2
- package/index.js +0 -24
- package/lbe.audit.jsonl +0 -46
- package/release/README.md +0 -216
- package/release/TRUST.md +0 -90
- package/release/exec-README.md +0 -215
- package/release/exec-types.d.ts +0 -50
- package/release-exec/LICENSE +0 -1
- package/release-exec/README.md +0 -215
- package/release-exec/assets/lbe-gates.jpg +0 -0
- package/release-exec/assets/lbe-gates.png +0 -0
- package/release-exec/assets/runtime-boundary.svg +0 -36
- package/release-exec/assets/story-allow.jpg +0 -0
- package/release-exec/assets/story-allow.png +0 -0
- package/release-exec/assets/story-deny.jpg +0 -0
- package/release-exec/assets/story-deny.png +0 -0
- package/release-exec/dist/cli.js +0 -2841
- package/release-exec/dist/index.js +0 -1835
- package/release-exec/hooks/register.cjs +0 -473
- package/release-exec/package.json +0 -35
- package/release-exec/types.d.ts +0 -50
- package/runtime/engine.js +0 -322
- package/runtime/lbe_engine.wasm +0 -0
- package/src/cli/commands/auditVerify.js +0 -36
- package/src/cli/commands/dryrun.js +0 -175
- package/src/cli/commands/health.js +0 -153
- package/src/cli/commands/init.js +0 -306
- package/src/cli/commands/integrityCheck.js +0 -57
- package/src/cli/commands/logs.js +0 -53
- package/src/cli/commands/openState.js +0 -44
- package/src/cli/commands/policyAdd.js +0 -8
- package/src/cli/commands/policyMode.js +0 -7
- package/src/cli/commands/policySign.js +0 -72
- package/src/cli/commands/proof.js +0 -122
- package/src/cli/commands/run.js +0 -342
- package/src/cli/commands/status.js +0 -73
- package/src/cli/commands/verify.js +0 -144
- package/src/cli/main.js +0 -176
- package/src/cli/parseArgs.js +0 -114
- package/src/exec/localExecutor.js +0 -289
- package/src/hooks/register.cjs +0 -505
- package/src/state/appendCentral.cjs +0 -87
- package/src/state/fileIndex.js +0 -140
- package/src/state/index.cjs +0 -101
- package/src/state/index.js +0 -65
- package/src/state/intentRegistry.js +0 -83
- package/src/state/migration.js +0 -112
- package/src/state/proofRunner.js +0 -246
- package/src/state/stateRoot.js +0 -40
- package/src/state/targetRegistry.js +0 -108
- package/src/state/workspaceId.js +0 -40
- package/src/state/workspaceRegistry.js +0 -65
- /package/{release-exec/dist → dist}/lbe_engine.wasm +0 -0
package/Release-README.md
DELETED
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
# @letterblack/lbe-core
|
|
2
|
-
|
|
3
|
-
LBE is local execution control for AI agents. It evaluates file and shell
|
|
4
|
-
actions routed through its execution boundary, records local evidence, and
|
|
5
|
-
returns an allow/deny outcome before the governed action runs.
|
|
6
|
-
|
|
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
|
|
12
|
-
|
|
13
|
-
```bash
|
|
14
|
-
npm install @letterblack/lbe-core
|
|
15
|
-
npx lbe init
|
|
16
|
-
npx lbe status
|
|
17
|
-
npx lbe logs
|
|
18
|
-
npx lbe proof --public
|
|
19
|
-
npx lbe open-state
|
|
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.
|
|
60
|
-
|
|
61
|
-
## Limits
|
|
62
|
-
|
|
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/WORKSPACE.md
DELETED
|
@@ -1,422 +0,0 @@
|
|
|
1
|
-
# LetterBlack LBE — Workspace Instructions
|
|
2
|
-
|
|
3
|
-
This document covers every aspect of the private workspace:
|
|
4
|
-
structure, development, testing, build, release, and governance.
|
|
5
|
-
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
## What this is
|
|
9
|
-
|
|
10
|
-
**LBE (Local-first execution Governance Engine)** puts a deterministic
|
|
11
|
-
validation gate between what an AI agent proposes and what the host system
|
|
12
|
-
actually executes. Every action — file write, shell command, anything — passes
|
|
13
|
-
a 7-gate pipeline before execution. Nothing runs unless the gate passes.
|
|
14
|
-
|
|
15
|
-
There are two published packages and one private source workspace:
|
|
16
|
-
|
|
17
|
-
| Package | npm | What it is |
|
|
18
|
-
|---|---|---|
|
|
19
|
-
| `@letterblack/lbe-sdk` | published | WASM runtime + CLI only. Raw `execute()` function, no controller. |
|
|
20
|
-
| `@letterblack/lbe-exec` | published | Full in-process controller. `createLocalExecutor()`, policy, audit, sandbox. |
|
|
21
|
-
| `letterblack-lbe-core` | private | This workspace. Source for both packages. Never published. |
|
|
22
|
-
|
|
23
|
-
---
|
|
24
|
-
|
|
25
|
-
## Workspace layout
|
|
26
|
-
|
|
27
|
-
```
|
|
28
|
-
letterblack-sentinel/
|
|
29
|
-
│
|
|
30
|
-
├── assets/ Visual assets (source of truth — built into both packages)
|
|
31
|
-
│ ├── lbe-gates.png Gate sequence diagram (Request → Policy → Identity → Scope → Action)
|
|
32
|
-
│ ├── story-allow.png Happy-path storyboard (6 panels)
|
|
33
|
-
│ ├── story-deny.png Deny-path storyboard (6 panels)
|
|
34
|
-
│ └── runtime-boundary.svg WASM boundary diagram
|
|
35
|
-
│
|
|
36
|
-
├── src/
|
|
37
|
-
│ ├── core/ Private controller internals
|
|
38
|
-
│ │ ├── validator.js 7-gate orchestrator — extracts flags, calls WASM
|
|
39
|
-
│ │ ├── localPolicy.js lbe.policy.json read/write, deny-wins evaluation
|
|
40
|
-
│ │ ├── auditLog.js SHA-256 hash-chained JSONL append
|
|
41
|
-
│ │ ├── signature.js Ed25519 sign/verify (tweetnacl)
|
|
42
|
-
│ │ ├── atomicWrite.js Write-then-rename for all state files
|
|
43
|
-
│ │ ├── policyEngine.js Deployment policy evaluation
|
|
44
|
-
│ │ ├── policySignature.js Policy signing and tamper detection
|
|
45
|
-
│ │ ├── policyVersionGuard.js Version bump / rollback protection
|
|
46
|
-
│ │ ├── nonceStore.js Single-use nonce registry
|
|
47
|
-
│ │ ├── requestRateLimiter.js Per-requester rate limiting
|
|
48
|
-
│ │ ├── invariants.js Invariant gate (key present? policy signed?)
|
|
49
|
-
│ │ ├── backup.js Pre-write backup and restore
|
|
50
|
-
│ │ ├── trustedKeys.js Key store management
|
|
51
|
-
│ │ ├── integrity.js Workspace integrity manifest
|
|
52
|
-
│ │ ├── workspaceScanner.js Workspace file enumeration
|
|
53
|
-
│ │ ├── schema.js Request schema constants
|
|
54
|
-
│ │ ├── logger.js Structured logger
|
|
55
|
-
│ │ ├── deepFreeze.js Freeze policy/config objects
|
|
56
|
-
│ │ └── approval-token.js Short-lived approval tokens
|
|
57
|
-
│ │
|
|
58
|
-
│ ├── adapters/ Execution adapters (decide nothing, only execute)
|
|
59
|
-
│ │ ├── fileAdapter.js read / write / patch / delete inside rootDir
|
|
60
|
-
│ │ ├── shellAdapter.js run an allowlisted shell command
|
|
61
|
-
│ │ ├── noopAdapter.js dry-run / observer sink
|
|
62
|
-
│ │ └── index.js Adapter router
|
|
63
|
-
│ │
|
|
64
|
-
│ ├── exec/
|
|
65
|
-
│ │ └── localExecutor.js createLocalExecutor() — in-process controller
|
|
66
|
-
│ │ (source for @letterblack/lbe-exec)
|
|
67
|
-
│ │
|
|
68
|
-
│ └── cli/
|
|
69
|
-
│ ├── parseArgs.js Argument parser
|
|
70
|
-
│ └── commands/ One file per CLI command
|
|
71
|
-
│ ├── init.js npx lbe init
|
|
72
|
-
│ ├── policyMode.js npx lbe observe / enforce
|
|
73
|
-
│ ├── policyAdd.js npx lbe policy add
|
|
74
|
-
│ ├── run.js npx lbe execute
|
|
75
|
-
│ ├── dryrun.js npx lbe dryrun
|
|
76
|
-
│ ├── verify.js npx lbe verify
|
|
77
|
-
│ ├── health.js npx lbe health
|
|
78
|
-
│ ├── auditVerify.js npx lbe audit-verify
|
|
79
|
-
│ ├── integrityCheck.js npx lbe integrity-check
|
|
80
|
-
│ └── policySign.js npx lbe policy-sign
|
|
81
|
-
│
|
|
82
|
-
├── exec/
|
|
83
|
-
│ └── index.js Public entrypoint for @letterblack/lbe-exec
|
|
84
|
-
│
|
|
85
|
-
├── runtime/
|
|
86
|
-
│ ├── lbe_engine.wasm Compiled WASM binary (output of build:engine)
|
|
87
|
-
│ └── engine.js JS WASM loader — exposes validate_pipeline etc.
|
|
88
|
-
│
|
|
89
|
-
├── native/
|
|
90
|
-
│ └── lbe-engine/ Rust crate — compiled to lbe_engine.wasm
|
|
91
|
-
│ ├── Cargo.toml crate-type = cdylib, publish = false
|
|
92
|
-
│ └── src/lib.rs All governance decision logic lives here
|
|
93
|
-
│
|
|
94
|
-
├── bin/
|
|
95
|
-
│ └── lbe.js CLI entry (private — never ships in public packages)
|
|
96
|
-
│
|
|
97
|
-
├── config/
|
|
98
|
-
│ ├── policy.default.json Default policy template (ships in lbe-sdk)
|
|
99
|
-
│ └── identity.config.json Workspace identity config (private)
|
|
100
|
-
│
|
|
101
|
-
├── test/
|
|
102
|
-
│ ├── local-executor.test.js 40 tests — observe/enforce/deny-wins/sandbox/audit
|
|
103
|
-
│ ├── local-policy.test.js Policy file read/write/evaluate
|
|
104
|
-
│ ├── public-api.test.js WASM execute() contract
|
|
105
|
-
│ ├── security-invariants.test.js Key lifecycle, policy signature, version guard
|
|
106
|
-
│ ├── invariant-backup.test.js Backup and rollback
|
|
107
|
-
│ └── shell-adapter.test.js Shell metacharacter safety
|
|
108
|
-
│
|
|
109
|
-
├── scripts/
|
|
110
|
-
│ ├── build-engine.js cargo build → runtime/lbe_engine.wasm
|
|
111
|
-
│ ├── build-public-sdk.mjs Builds release-public/ (@letterblack/lbe-sdk)
|
|
112
|
-
│ ├── build-public-exec.mjs Builds release-exec/ (@letterblack/lbe-exec)
|
|
113
|
-
│ ├── check-public-artifact.mjs Validates release-public/ before publish
|
|
114
|
-
│ ├── check-public-exec.mjs Validates release-exec/ before publish
|
|
115
|
-
│ ├── mainhead-guard.mjs Blocks commits/pushes from non-main branches
|
|
116
|
-
│ └── install-git-hooks.mjs Installs pre-commit and pre-push hooks
|
|
117
|
-
│
|
|
118
|
-
├── docs/
|
|
119
|
-
│ ├── decisions/
|
|
120
|
-
│ │ ├── ADR-001-remove-mcp-execution-surface.md
|
|
121
|
-
│ │ ├── ADR-002-remove-http-server-surface.md
|
|
122
|
-
│ │ └── ADR-003-sdk-only-product-boundary.md
|
|
123
|
-
│ └── governance/
|
|
124
|
-
│ └── mainhead.md Branch authority rules
|
|
125
|
-
│
|
|
126
|
-
├── release/ README and type templates (source for builds)
|
|
127
|
-
│ ├── README.md Template for @letterblack/lbe-sdk README
|
|
128
|
-
│ ├── exec-README.md Template for @letterblack/lbe-exec README
|
|
129
|
-
│ └── exec-types.d.ts Type declarations for @letterblack/lbe-exec
|
|
130
|
-
│
|
|
131
|
-
├── release-public/ Built artifact — @letterblack/lbe-sdk (never edit directly)
|
|
132
|
-
├── release-exec/ Built artifact — @letterblack/lbe-exec (never edit directly)
|
|
133
|
-
│
|
|
134
|
-
├── types.d.ts Private full type declarations
|
|
135
|
-
├── index.js Private package entry
|
|
136
|
-
├── package.json Private workspace package (letterblack-lbe-core)
|
|
137
|
-
├── CHANGELOG.md
|
|
138
|
-
└── WORKSPACE.md This file
|
|
139
|
-
```
|
|
140
|
-
|
|
141
|
-
---
|
|
142
|
-
|
|
143
|
-
## Prerequisites
|
|
144
|
-
|
|
145
|
-
| Tool | Version | Purpose |
|
|
146
|
-
|---|---|---|
|
|
147
|
-
| Node.js | ≥ 20.9.0 | Runtime and test runner |
|
|
148
|
-
| Rust / cargo | stable | Compile WASM engine |
|
|
149
|
-
| rustup target | `wasm32-unknown-unknown` | WASM build target (auto-added by build:engine) |
|
|
150
|
-
| npm | any | Package management and publish |
|
|
151
|
-
|
|
152
|
-
```bash
|
|
153
|
-
npm install
|
|
154
|
-
npm run hooks:install # installs pre-commit and pre-push git hooks — do this once after clone
|
|
155
|
-
```
|
|
156
|
-
|
|
157
|
-
---
|
|
158
|
-
|
|
159
|
-
## Development commands
|
|
160
|
-
|
|
161
|
-
### Daily workflow
|
|
162
|
-
|
|
163
|
-
```bash
|
|
164
|
-
npm test # run all 40 tests
|
|
165
|
-
npm run lint # ESLint on src/ and bin/
|
|
166
|
-
npm run validate:all # mainhead guard + engine check + lint + test (full gate)
|
|
167
|
-
```
|
|
168
|
-
|
|
169
|
-
### WASM engine
|
|
170
|
-
|
|
171
|
-
```bash
|
|
172
|
-
npm run build:engine # compile native/lbe-engine → runtime/lbe_engine.wasm
|
|
173
|
-
npm run engine:check # verify the WASM binary loads and exports the expected functions
|
|
174
|
-
```
|
|
175
|
-
|
|
176
|
-
Only needed when `native/lbe-engine/src/lib.rs` changes. The compiled binary
|
|
177
|
-
`runtime/lbe_engine.wasm` is committed and ships in both packages.
|
|
178
|
-
|
|
179
|
-
### CLI (local development)
|
|
180
|
-
|
|
181
|
-
```bash
|
|
182
|
-
node bin/lbe.js init # create lbe.policy.json in observer mode
|
|
183
|
-
node bin/lbe.js status # mode, rule count, audit entry count
|
|
184
|
-
node bin/lbe.js policy # list rules
|
|
185
|
-
node bin/lbe.js observe # switch to observer mode
|
|
186
|
-
node bin/lbe.js enforce # switch to enforcement mode
|
|
187
|
-
node bin/lbe.js health --json true
|
|
188
|
-
node bin/lbe.js audit-verify
|
|
189
|
-
```
|
|
190
|
-
|
|
191
|
-
Or via npm aliases: `npm run init`, `npm run verify`, `npm run health`.
|
|
192
|
-
|
|
193
|
-
---
|
|
194
|
-
|
|
195
|
-
## Test suite
|
|
196
|
-
|
|
197
|
-
**40 tests, 0 failures.** Run with `npm test` (uses native Node.js test runner).
|
|
198
|
-
|
|
199
|
-
| File | Coverage |
|
|
200
|
-
|---|---|
|
|
201
|
-
| `local-executor.test.js` | observe mode, enforce mode, deny-wins, sandbox, advisory vs controller split, shell allowlist, symlink escape, dryRun, audit |
|
|
202
|
-
| `local-policy.test.js` | policy load/write/evaluate, deny-wins, observer/enforce defaults |
|
|
203
|
-
| `public-api.test.js` | raw WASM `execute()` input/output contract |
|
|
204
|
-
| `security-invariants.test.js` | Ed25519 key lifecycle, policy signature tamper, version rollback guard |
|
|
205
|
-
| `invariant-backup.test.js` | backup creation, restore on failure, atomic write |
|
|
206
|
-
| `shell-adapter.test.js` | metacharacter arguments treated as data, not shell syntax |
|
|
207
|
-
|
|
208
|
-
---
|
|
209
|
-
|
|
210
|
-
## Architecture — the 7-gate pipeline
|
|
211
|
-
|
|
212
|
-
Every request to `execute()` passes these gates in order. A failure at any
|
|
213
|
-
gate returns a structured deny — the remaining gates are not evaluated.
|
|
214
|
-
|
|
215
|
-
```
|
|
216
|
-
[1] Schema — required fields, structural validity
|
|
217
|
-
[2] Timestamp — permitted clock-skew window (±10 minutes)
|
|
218
|
-
[3] Key lifecycle — trusted key, active, not expired
|
|
219
|
-
[4] Signature — Ed25519 signature verified against key store
|
|
220
|
-
[5] Rate limit — per-requester sliding-window limit
|
|
221
|
-
[6] Nonce — single-use commandId replay protection
|
|
222
|
-
[7] Policy — configured authorization decision (deny-wins)
|
|
223
|
-
```
|
|
224
|
-
|
|
225
|
-
The WASM engine (`runtime/lbe_engine.wasm`) owns all gate decisions.
|
|
226
|
-
`src/core/validator.js` extracts boolean flag sets from the command object
|
|
227
|
-
and calls the WASM functions. The JS layer does IO; the Rust layer decides.
|
|
228
|
-
|
|
229
|
-
### Local policy layer (lbe-exec only)
|
|
230
|
-
|
|
231
|
-
Before the 7-gate pipeline runs, `createLocalExecutor()` evaluates
|
|
232
|
-
`lbe.policy.json`. This is a separate, simpler rule ledger:
|
|
233
|
-
|
|
234
|
-
- Rules have `effect: 'allow' | 'deny'`, `type: 'path' | 'command'`, `pattern`
|
|
235
|
-
- **Deny always wins** over allow regardless of rule order
|
|
236
|
-
- Only the host application writes rules (`addRule()`). Agents may only call
|
|
237
|
-
`proposeRule()` which returns a proposal object — it never writes to disk.
|
|
238
|
-
|
|
239
|
-
### Observer vs enforce mode
|
|
240
|
-
|
|
241
|
-
| Mode | Gates run | Audit written | Mutations |
|
|
242
|
-
|---|---|---|---|
|
|
243
|
-
| `observe` | yes | yes | **no** — short-circuits before adapter |
|
|
244
|
-
| `enforce` | yes | yes | yes — adapter executes on pass |
|
|
245
|
-
|
|
246
|
-
Default when no `lbe.policy.json` exists: **enforce**.
|
|
247
|
-
`npx lbe init` creates `lbe.policy.json` in **observe** mode.
|
|
248
|
-
|
|
249
|
-
### Project-root sandbox
|
|
250
|
-
|
|
251
|
-
All file operations are constrained to `rootDir`. The check resolves
|
|
252
|
-
symlinks before comparing paths (`physicalPath()`), so symlink escapes and
|
|
253
|
-
`../` traversal are blocked before policy is consulted.
|
|
254
|
-
|
|
255
|
-
---
|
|
256
|
-
|
|
257
|
-
## Key security properties
|
|
258
|
-
|
|
259
|
-
| Property | Implementation |
|
|
260
|
-
|---|---|
|
|
261
|
-
| Ed25519 signatures | Every proposal signed; WASM verifies before any gate runs |
|
|
262
|
-
| Nonce replay protection | Each `commandId` is single-use |
|
|
263
|
-
| Rate limiting | Per-requester sliding window, configurable |
|
|
264
|
-
| Timestamp skew guard | Rejects proposals outside ±10 minutes |
|
|
265
|
-
| Policy signature verification | Policy file is signed; tampering fails the invariant gate |
|
|
266
|
-
| Immutable audit trail | SHA-256 hash-chained JSONL; deletion or edit is detectable |
|
|
267
|
-
| Atomic writes | All state files use write-then-rename; no partial state |
|
|
268
|
-
| Project-root sandbox | Symlink-safe path resolution in `physicalPath()` |
|
|
269
|
-
| Deny-wins conflict resolution | When allow + deny both match, deny always takes precedence |
|
|
270
|
-
|
|
271
|
-
---
|
|
272
|
-
|
|
273
|
-
## Build system
|
|
274
|
-
|
|
275
|
-
### @letterblack/lbe-sdk
|
|
276
|
-
|
|
277
|
-
```bash
|
|
278
|
-
npm run build:public-sdk # → release-public/
|
|
279
|
-
npm run verify:public-sdk # build + validate + npm pack --dry-run
|
|
280
|
-
```
|
|
281
|
-
|
|
282
|
-
What the build does:
|
|
283
|
-
1. Bundles `index.js` and `bin/lbe.js` with esbuild → `release-public/dist/`
|
|
284
|
-
2. Copies `runtime/lbe_engine.wasm` and generates `wasm.lock.json`
|
|
285
|
-
3. Copies `assets/` from workspace root → `release-public/assets/`
|
|
286
|
-
4. Copies `release/README.md` (replaces `{{PACKAGE_NAME}}` placeholder) → `release-public/README.md`
|
|
287
|
-
5. Copies `config/policy.default.json` and `types.d.ts`
|
|
288
|
-
6. Writes `release-public/package.json` from workspace `package.json`
|
|
289
|
-
|
|
290
|
-
The validator (`check-public-artifact.mjs`) confirms:
|
|
291
|
-
- No `src/`, `test/`, `scripts/`, `keys/`, `data/` paths in the artifact
|
|
292
|
-
- No private path markers in the bundled JS
|
|
293
|
-
- WASM SHA-256 matches `wasm.lock.json`
|
|
294
|
-
- All required files present
|
|
295
|
-
|
|
296
|
-
### @letterblack/lbe-exec
|
|
297
|
-
|
|
298
|
-
```bash
|
|
299
|
-
npm run build:public-exec # → release-exec/
|
|
300
|
-
npm run verify:public-exec # build + validate + npm pack --dry-run
|
|
301
|
-
```
|
|
302
|
-
|
|
303
|
-
What the build does:
|
|
304
|
-
1. Bundles `exec/index.js` with esbuild → `release-exec/dist/index.js`
|
|
305
|
-
(external: tweetnacl, json-canonicalize — these are runtime dependencies)
|
|
306
|
-
2. Copies `runtime/lbe_engine.wasm` and generates `wasm.lock.json`
|
|
307
|
-
3. Copies `assets/` from workspace root → `release-exec/assets/`
|
|
308
|
-
4. Copies `release/exec-README.md` → `release-exec/README.md`
|
|
309
|
-
5. Copies `release/exec-types.d.ts` → `release-exec/types.d.ts`
|
|
310
|
-
6. Writes `release-exec/package.json` from workspace `package.json`
|
|
311
|
-
|
|
312
|
-
The validator (`check-public-exec.mjs`) confirms:
|
|
313
|
-
- No private paths or markers in the bundle
|
|
314
|
-
- WASM SHA-256 matches `wasm.lock.json`
|
|
315
|
-
- All required files present
|
|
316
|
-
|
|
317
|
-
### What never ships
|
|
318
|
-
|
|
319
|
-
Neither package contains: `src/`, `test/`, `scripts/`, `keys/`, `data/`,
|
|
320
|
-
`node_modules/`, source maps, or private adapters.
|
|
321
|
-
|
|
322
|
-
---
|
|
323
|
-
|
|
324
|
-
## Release process
|
|
325
|
-
|
|
326
|
-
Both packages are published from their respective `release-*/` directories.
|
|
327
|
-
**Never publish from the workspace root.**
|
|
328
|
-
|
|
329
|
-
### Full release checklist
|
|
330
|
-
|
|
331
|
-
```bash
|
|
332
|
-
# 1. All gates pass
|
|
333
|
-
npm run validate:all
|
|
334
|
-
|
|
335
|
-
# 2. Version bump — update in package.json (single source of truth)
|
|
336
|
-
# Build scripts read this version for both release packages.
|
|
337
|
-
|
|
338
|
-
# 3. Build and validate both artifacts
|
|
339
|
-
npm run verify:public-sdk
|
|
340
|
-
npm run verify:public-exec
|
|
341
|
-
|
|
342
|
-
# 4. Commit and push to main
|
|
343
|
-
git add -p
|
|
344
|
-
git commit -m "release: vX.Y.Z"
|
|
345
|
-
git push
|
|
346
|
-
|
|
347
|
-
# 5. Tag
|
|
348
|
-
git tag vX.Y.Z
|
|
349
|
-
git push --tags
|
|
350
|
-
|
|
351
|
-
# 6. Publish (from release directories, not workspace root)
|
|
352
|
-
cd release-public && npm publish
|
|
353
|
-
cd ../release-exec && npm publish
|
|
354
|
-
```
|
|
355
|
-
|
|
356
|
-
**Version is set once** in `package.json` at the workspace root.
|
|
357
|
-
Both build scripts read `sourcePackage.version` from there — no manual
|
|
358
|
-
sync needed between the two release `package.json` files.
|
|
359
|
-
|
|
360
|
-
### Auth
|
|
361
|
-
|
|
362
|
-
```bash
|
|
363
|
-
npm login # or set NPM_TOKEN environment variable
|
|
364
|
-
# registry: https://registry.npmjs.org/
|
|
365
|
-
```
|
|
366
|
-
|
|
367
|
-
### Current published versions
|
|
368
|
-
|
|
369
|
-
| Package | Version |
|
|
370
|
-
|---|---|
|
|
371
|
-
| `@letterblack/lbe-sdk` | 1.2.3 |
|
|
372
|
-
| `@letterblack/lbe-exec` | 1.2.3 |
|
|
373
|
-
|
|
374
|
-
---
|
|
375
|
-
|
|
376
|
-
## Branch governance
|
|
377
|
-
|
|
378
|
-
`main` is the only authoritative branch. The pre-commit and pre-push hooks
|
|
379
|
-
run `scripts/mainhead-guard.mjs` and will block any commit or push from a
|
|
380
|
-
non-main branch or linked worktree.
|
|
381
|
-
|
|
382
|
-
Rules:
|
|
383
|
-
- Never commit from a feature branch — commit directly to `main`
|
|
384
|
-
- Never use `--no-verify` to skip hooks — fix the underlying issue
|
|
385
|
-
- Never publish from a branch, tag, or worktree other than `main`
|
|
386
|
-
- The `mainhead-guard` check is also run at the start of the build scripts
|
|
387
|
-
|
|
388
|
-
Install the hooks once after cloning:
|
|
389
|
-
|
|
390
|
-
```bash
|
|
391
|
-
npm run hooks:install
|
|
392
|
-
```
|
|
393
|
-
|
|
394
|
-
---
|
|
395
|
-
|
|
396
|
-
## README authoring
|
|
397
|
-
|
|
398
|
-
Source files (edit these — never edit the built outputs directly):
|
|
399
|
-
|
|
400
|
-
| Source | Builds into |
|
|
401
|
-
|---|---|
|
|
402
|
-
| `release/README.md` | `release-public/README.md` (with `{{PACKAGE_NAME}}` replaced) |
|
|
403
|
-
| `release/exec-README.md` | `release-exec/README.md` |
|
|
404
|
-
| `release/exec-types.d.ts` | `release-exec/types.d.ts` |
|
|
405
|
-
| `types.d.ts` | private package only |
|
|
406
|
-
|
|
407
|
-
Images live in `assets/` at the workspace root and are copied into both
|
|
408
|
-
release packages during build. Reference them in READMEs as `assets/<file>`.
|
|
409
|
-
|
|
410
|
-
---
|
|
411
|
-
|
|
412
|
-
## What is not in scope
|
|
413
|
-
|
|
414
|
-
LBE governs actions routed through its runtime. It does not provide:
|
|
415
|
-
|
|
416
|
-
- Kernel-level process isolation
|
|
417
|
-
- Network egress control
|
|
418
|
-
- Multi-tenant workload separation
|
|
419
|
-
- A hosted control plane, daemon, or HTTP API
|
|
420
|
-
- An MCP server surface (see ADR-001)
|
|
421
|
-
|
|
422
|
-
See `docs/decisions/` for the rationale behind each removed surface.
|