@letterblack/lbe-core 1.3.5 → 1.3.7
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 +181 -166
- package/RELEASE_WORKSPACE_RULES.md +179 -110
- package/Release-README.md +2 -0
- package/_proof.mjs +246 -246
- package/config/identity.config.json +2 -2
- package/config/policy.default.json +24 -24
- package/dist/cli/lbe.js +2 -3
- package/dist/hooks/register.cjs +505 -505
- package/exec/cli.js +472 -472
- package/npm-pack.json +0 -0
- package/package.json +78 -77
- package/release/TRUST.md +88 -88
- package/release-exec/dist/cli.js +2841 -2841
- package/release-exec/dist/index.js +1835 -1835
- package/release-exec/hooks/register.cjs +473 -473
- package/release-exec/package.json +35 -35
- package/src/cli/commands/assertConsumer.js +164 -164
- package/src/cli/commands/init.js +306 -306
- package/src/cli/commands/proof.js +2 -22
- package/src/cli/main.js +181 -181
- package/src/hooks/register.cjs +505 -505
- package/src/state/fileIndex.js +1 -1
- package/src/state/intentRegistry.js +3 -2
- package/src/state/proofRunner.js +1 -1
- package/src/state/targetRegistry.js +3 -2
- package/lbe.audit.jsonl +0 -46
|
@@ -1,35 +1,35 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@letterblack/lbe-exec",
|
|
3
|
-
"version": "1.2.20",
|
|
4
|
-
"description": "Local host-signed execution layer for LetterBlack LBE.",
|
|
5
|
-
"type": "module",
|
|
6
|
-
"main": "dist/index.js",
|
|
7
|
-
"types": "types.d.ts",
|
|
8
|
-
"exports": {
|
|
9
|
-
".": {
|
|
10
|
-
"types": "./types.d.ts",
|
|
11
|
-
"default": "./dist/index.js"
|
|
12
|
-
},
|
|
13
|
-
"./hooks/register.cjs": "./hooks/register.cjs"
|
|
14
|
-
},
|
|
15
|
-
"bin": {
|
|
16
|
-
"lbe-exec": "dist/cli.js"
|
|
17
|
-
},
|
|
18
|
-
"files": [
|
|
19
|
-
"dist/",
|
|
20
|
-
"hooks/",
|
|
21
|
-
"assets/",
|
|
22
|
-
"README.md",
|
|
23
|
-
"TRUST.md",
|
|
24
|
-
"types.d.ts",
|
|
25
|
-
"LICENSE"
|
|
26
|
-
],
|
|
27
|
-
"dependencies": {
|
|
28
|
-
"tweetnacl": "^1.0.3",
|
|
29
|
-
"json-canonicalize": "^1.0.4"
|
|
30
|
-
},
|
|
31
|
-
"license": "SEE LICENSE IN LICENSE",
|
|
32
|
-
"engines": {
|
|
33
|
-
"node": ">=20.9.0"
|
|
34
|
-
}
|
|
35
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "@letterblack/lbe-exec",
|
|
3
|
+
"version": "1.2.20",
|
|
4
|
+
"description": "Local host-signed execution layer for LetterBlack LBE.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"types": "types.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./types.d.ts",
|
|
11
|
+
"default": "./dist/index.js"
|
|
12
|
+
},
|
|
13
|
+
"./hooks/register.cjs": "./hooks/register.cjs"
|
|
14
|
+
},
|
|
15
|
+
"bin": {
|
|
16
|
+
"lbe-exec": "dist/cli.js"
|
|
17
|
+
},
|
|
18
|
+
"files": [
|
|
19
|
+
"dist/",
|
|
20
|
+
"hooks/",
|
|
21
|
+
"assets/",
|
|
22
|
+
"README.md",
|
|
23
|
+
"TRUST.md",
|
|
24
|
+
"types.d.ts",
|
|
25
|
+
"LICENSE"
|
|
26
|
+
],
|
|
27
|
+
"dependencies": {
|
|
28
|
+
"tweetnacl": "^1.0.3",
|
|
29
|
+
"json-canonicalize": "^1.0.4"
|
|
30
|
+
},
|
|
31
|
+
"license": "SEE LICENSE IN LICENSE",
|
|
32
|
+
"engines": {
|
|
33
|
+
"node": ">=20.9.0"
|
|
34
|
+
}
|
|
35
|
+
}
|
|
@@ -1,107 +1,107 @@
|
|
|
1
|
-
// src/cli/commands/assertConsumer.js
|
|
2
|
-
// Guard that proves a consuming project is using LBE as an installed package,
|
|
3
|
-
// not treating a copied/source repository as release authority.
|
|
4
|
-
|
|
5
|
-
import fs from 'fs';
|
|
6
|
-
import path from 'path';
|
|
7
|
-
import { createRequire } from 'module';
|
|
8
|
-
|
|
9
|
-
const PACKAGE_NAME = '@letterblack/lbe-core';
|
|
10
|
-
const DEP_SECTIONS = [
|
|
11
|
-
'dependencies',
|
|
12
|
-
'devDependencies',
|
|
13
|
-
'optionalDependencies',
|
|
14
|
-
'peerDependencies'
|
|
15
|
-
];
|
|
16
|
-
|
|
17
|
-
function readJson(filePath) {
|
|
18
|
-
try {
|
|
19
|
-
return JSON.parse(fs.readFileSync(filePath, 'utf-8'));
|
|
20
|
-
} catch {
|
|
21
|
-
return null;
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
function addCheck(checks, name, ok, details = {}) {
|
|
26
|
-
checks.push({ name, ok, ...details });
|
|
27
|
-
return ok;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
function findDependencySpec(packageJson) {
|
|
31
|
-
if (!packageJson || typeof packageJson !== 'object') return null;
|
|
32
|
-
|
|
33
|
-
for (const section of DEP_SECTIONS) {
|
|
34
|
-
const value = packageJson[section]?.[PACKAGE_NAME];
|
|
35
|
-
if (value !== undefined) {
|
|
36
|
-
return { section, spec: String(value) };
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
return null;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
function classifyDependencySpec(spec) {
|
|
44
|
-
const raw = String(spec || '').trim();
|
|
45
|
-
const lower = raw.toLowerCase();
|
|
46
|
-
|
|
47
|
-
if (!raw) {
|
|
48
|
-
return { ok: false, reason: 'EMPTY_DEPENDENCY_SPEC' };
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
const blockedPrefixes = [
|
|
52
|
-
'file:',
|
|
53
|
-
'link:',
|
|
54
|
-
'workspace:',
|
|
55
|
-
'git+',
|
|
56
|
-
'github:',
|
|
57
|
-
'git://',
|
|
58
|
-
'ssh://'
|
|
59
|
-
];
|
|
60
|
-
|
|
61
|
-
for (const prefix of blockedPrefixes) {
|
|
62
|
-
if (lower.startsWith(prefix)) {
|
|
63
|
-
return { ok: false, reason: 'LOCAL_OR_GIT_DEPENDENCY_SPEC', prefix };
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
if (/^[a-z]:[\\/]/i.test(raw) || raw.startsWith('./') || raw.startsWith('../')) {
|
|
68
|
-
return { ok: false, reason: 'PATH_DEPENDENCY_SPEC' };
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
return { ok: true };
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
function findPackageRoot(startFile) {
|
|
75
|
-
let dir = fs.statSync(startFile).isDirectory() ? startFile : path.dirname(startFile);
|
|
76
|
-
|
|
77
|
-
while (
|
|
78
|
-
const candidate = path.join(dir, 'package.json');
|
|
79
|
-
const pkg = readJson(candidate);
|
|
80
|
-
if (pkg?.name === PACKAGE_NAME) return dir;
|
|
81
|
-
|
|
82
|
-
const parent = path.dirname(dir);
|
|
83
|
-
if (parent === dir) return null;
|
|
84
|
-
dir = parent;
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
|
|
1
|
+
// src/cli/commands/assertConsumer.js
|
|
2
|
+
// Guard that proves a consuming project is using LBE as an installed package,
|
|
3
|
+
// not treating a copied/source repository as release authority.
|
|
4
|
+
|
|
5
|
+
import fs from 'fs';
|
|
6
|
+
import path from 'path';
|
|
7
|
+
import { createRequire } from 'module';
|
|
8
|
+
|
|
9
|
+
const PACKAGE_NAME = '@letterblack/lbe-core';
|
|
10
|
+
const DEP_SECTIONS = [
|
|
11
|
+
'dependencies',
|
|
12
|
+
'devDependencies',
|
|
13
|
+
'optionalDependencies',
|
|
14
|
+
'peerDependencies'
|
|
15
|
+
];
|
|
16
|
+
|
|
17
|
+
function readJson(filePath) {
|
|
18
|
+
try {
|
|
19
|
+
return JSON.parse(fs.readFileSync(filePath, 'utf-8'));
|
|
20
|
+
} catch {
|
|
21
|
+
return null;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function addCheck(checks, name, ok, details = {}) {
|
|
26
|
+
checks.push({ name, ok, ...details });
|
|
27
|
+
return ok;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function findDependencySpec(packageJson) {
|
|
31
|
+
if (!packageJson || typeof packageJson !== 'object') return null;
|
|
32
|
+
|
|
33
|
+
for (const section of DEP_SECTIONS) {
|
|
34
|
+
const value = packageJson[section]?.[PACKAGE_NAME];
|
|
35
|
+
if (value !== undefined) {
|
|
36
|
+
return { section, spec: String(value) };
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
return null;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function classifyDependencySpec(spec) {
|
|
44
|
+
const raw = String(spec || '').trim();
|
|
45
|
+
const lower = raw.toLowerCase();
|
|
46
|
+
|
|
47
|
+
if (!raw) {
|
|
48
|
+
return { ok: false, reason: 'EMPTY_DEPENDENCY_SPEC' };
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
const blockedPrefixes = [
|
|
52
|
+
'file:',
|
|
53
|
+
'link:',
|
|
54
|
+
'workspace:',
|
|
55
|
+
'git+',
|
|
56
|
+
'github:',
|
|
57
|
+
'git://',
|
|
58
|
+
'ssh://'
|
|
59
|
+
];
|
|
60
|
+
|
|
61
|
+
for (const prefix of blockedPrefixes) {
|
|
62
|
+
if (lower.startsWith(prefix)) {
|
|
63
|
+
return { ok: false, reason: 'LOCAL_OR_GIT_DEPENDENCY_SPEC', prefix };
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
if (/^[a-z]:[\\/]/i.test(raw) || raw.startsWith('./') || raw.startsWith('../')) {
|
|
68
|
+
return { ok: false, reason: 'PATH_DEPENDENCY_SPEC' };
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
return { ok: true };
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function findPackageRoot(startFile) {
|
|
75
|
+
let dir = fs.statSync(startFile).isDirectory() ? startFile : path.dirname(startFile);
|
|
76
|
+
|
|
77
|
+
while (dir) {
|
|
78
|
+
const candidate = path.join(dir, 'package.json');
|
|
79
|
+
const pkg = readJson(candidate);
|
|
80
|
+
if (pkg?.name === PACKAGE_NAME) return dir;
|
|
81
|
+
|
|
82
|
+
const parent = path.dirname(dir);
|
|
83
|
+
if (parent === dir) return null;
|
|
84
|
+
dir = parent;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
88
|
function inspectPackageLock(root) {
|
|
89
|
-
const lockPath = path.join(root, 'package-lock.json');
|
|
90
|
-
const lock = readJson(lockPath);
|
|
91
|
-
if (!lock) return { present: false };
|
|
92
|
-
|
|
93
|
-
const packageEntry = lock.packages?.[`node_modules/${PACKAGE_NAME}`];
|
|
94
|
-
if (!packageEntry) return { present: true, packageEntryPresent: false };
|
|
95
|
-
|
|
96
|
-
const resolved = String(packageEntry.resolved || '');
|
|
97
|
-
const blockedResolved =
|
|
98
|
-
packageEntry.link === true ||
|
|
99
|
-
resolved.startsWith('file:') ||
|
|
100
|
-
resolved.startsWith('git+') ||
|
|
101
|
-
resolved.startsWith('github:') ||
|
|
102
|
-
resolved.startsWith('ssh://') ||
|
|
103
|
-
/^[a-z]:[\\/]/i.test(resolved);
|
|
104
|
-
|
|
89
|
+
const lockPath = path.join(root, 'package-lock.json');
|
|
90
|
+
const lock = readJson(lockPath);
|
|
91
|
+
if (!lock) return { present: false };
|
|
92
|
+
|
|
93
|
+
const packageEntry = lock.packages?.[`node_modules/${PACKAGE_NAME}`];
|
|
94
|
+
if (!packageEntry) return { present: true, packageEntryPresent: false };
|
|
95
|
+
|
|
96
|
+
const resolved = String(packageEntry.resolved || '');
|
|
97
|
+
const blockedResolved =
|
|
98
|
+
packageEntry.link === true ||
|
|
99
|
+
resolved.startsWith('file:') ||
|
|
100
|
+
resolved.startsWith('git+') ||
|
|
101
|
+
resolved.startsWith('github:') ||
|
|
102
|
+
resolved.startsWith('ssh://') ||
|
|
103
|
+
/^[a-z]:[\\/]/i.test(resolved);
|
|
104
|
+
|
|
105
105
|
return {
|
|
106
106
|
present: true,
|
|
107
107
|
packageEntryPresent: true,
|
|
@@ -114,39 +114,39 @@ function inspectPackageLock(root) {
|
|
|
114
114
|
function getInstalledPackagePath(root) {
|
|
115
115
|
return path.join(root, 'node_modules', ...PACKAGE_NAME.split('/'));
|
|
116
116
|
}
|
|
117
|
-
|
|
118
|
-
export async function assertConsumerCommand(opts = {}) {
|
|
119
|
-
const root = path.resolve(opts.root || process.cwd());
|
|
120
|
-
const packageJsonPath = path.join(root, 'package.json');
|
|
121
|
-
const packageJson = readJson(packageJsonPath);
|
|
122
|
-
const checks = [];
|
|
123
|
-
|
|
124
|
-
addCheck(checks, 'project-package-json-present', Boolean(packageJson), { path: packageJsonPath });
|
|
125
|
-
|
|
126
|
-
const dependency = findDependencySpec(packageJson);
|
|
127
|
-
addCheck(checks, 'declares-lbe-package-dependency', Boolean(dependency), dependency || {});
|
|
128
|
-
|
|
129
|
-
const specCheck = dependency ? classifyDependencySpec(dependency.spec) : { ok: false, reason: 'DEPENDENCY_NOT_DECLARED' };
|
|
130
|
-
addCheck(checks, 'dependency-spec-is-registry-package', specCheck.ok, {
|
|
131
|
-
spec: dependency?.spec || null,
|
|
132
|
-
reason: specCheck.reason || null,
|
|
133
|
-
blockedPrefix: specCheck.prefix || null
|
|
134
|
-
});
|
|
135
|
-
|
|
136
|
-
let resolvedEntry = null;
|
|
137
|
-
let resolvedRoot = null;
|
|
138
|
-
try {
|
|
139
|
-
const req = createRequire(path.join(root, 'package.json'));
|
|
140
|
-
resolvedEntry = req.resolve(PACKAGE_NAME);
|
|
141
|
-
resolvedRoot = findPackageRoot(resolvedEntry);
|
|
142
|
-
} catch (error) {
|
|
143
|
-
addCheck(checks, 'lbe-package-resolves-from-project', false, { message: error.message });
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
if (resolvedEntry) {
|
|
147
|
-
addCheck(checks, 'lbe-package-resolves-from-project', true, { resolvedEntry });
|
|
148
|
-
}
|
|
149
|
-
|
|
117
|
+
|
|
118
|
+
export async function assertConsumerCommand(opts = {}) {
|
|
119
|
+
const root = path.resolve(opts.root || process.cwd());
|
|
120
|
+
const packageJsonPath = path.join(root, 'package.json');
|
|
121
|
+
const packageJson = readJson(packageJsonPath);
|
|
122
|
+
const checks = [];
|
|
123
|
+
|
|
124
|
+
addCheck(checks, 'project-package-json-present', Boolean(packageJson), { path: packageJsonPath });
|
|
125
|
+
|
|
126
|
+
const dependency = findDependencySpec(packageJson);
|
|
127
|
+
addCheck(checks, 'declares-lbe-package-dependency', Boolean(dependency), dependency || {});
|
|
128
|
+
|
|
129
|
+
const specCheck = dependency ? classifyDependencySpec(dependency.spec) : { ok: false, reason: 'DEPENDENCY_NOT_DECLARED' };
|
|
130
|
+
addCheck(checks, 'dependency-spec-is-registry-package', specCheck.ok, {
|
|
131
|
+
spec: dependency?.spec || null,
|
|
132
|
+
reason: specCheck.reason || null,
|
|
133
|
+
blockedPrefix: specCheck.prefix || null
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
let resolvedEntry = null;
|
|
137
|
+
let resolvedRoot = null;
|
|
138
|
+
try {
|
|
139
|
+
const req = createRequire(path.join(root, 'package.json'));
|
|
140
|
+
resolvedEntry = req.resolve(PACKAGE_NAME);
|
|
141
|
+
resolvedRoot = findPackageRoot(resolvedEntry);
|
|
142
|
+
} catch (error) {
|
|
143
|
+
addCheck(checks, 'lbe-package-resolves-from-project', false, { message: error.message });
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
if (resolvedEntry) {
|
|
147
|
+
addCheck(checks, 'lbe-package-resolves-from-project', true, { resolvedEntry });
|
|
148
|
+
}
|
|
149
|
+
|
|
150
150
|
if (resolvedRoot) {
|
|
151
151
|
const stat = fs.lstatSync(resolvedRoot);
|
|
152
152
|
addCheck(checks, 'lbe-package-is-not-symlink', !stat.isSymbolicLink(), { resolvedRoot });
|
|
@@ -168,31 +168,31 @@ export async function assertConsumerCommand(opts = {}) {
|
|
|
168
168
|
}
|
|
169
169
|
|
|
170
170
|
const lockInfo = inspectPackageLock(root);
|
|
171
|
-
if (lockInfo.present && lockInfo.packageEntryPresent) {
|
|
172
|
-
addCheck(checks, 'package-lock-does-not-link-local-lbe', !lockInfo.blockedResolved, lockInfo);
|
|
173
|
-
} else {
|
|
174
|
-
addCheck(checks, 'package-lock-does-not-link-local-lbe', true, lockInfo);
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
const ok = checks.every((check) => check.ok);
|
|
178
|
-
const result = {
|
|
179
|
-
ok,
|
|
180
|
-
command: 'assert-consumer',
|
|
181
|
-
package: PACKAGE_NAME,
|
|
182
|
-
root,
|
|
183
|
-
classification: ok
|
|
184
|
-
? 'consumer-project-using-installed-registry-dependency'
|
|
185
|
-
: 'not-proven-consumer-installed-dependency',
|
|
186
|
-
releaseClaimsAllowed: false,
|
|
187
|
-
message: ok
|
|
188
|
-
? 'This project consumes LBE as an installed package dependency. This does not certify LBE release safety.'
|
|
189
|
-
: 'This project is not proven to consume LBE only as an installed registry dependency.',
|
|
190
|
-
checks
|
|
191
|
-
};
|
|
192
|
-
|
|
193
|
-
console.log(JSON.stringify(result, null, 2));
|
|
194
|
-
|
|
195
|
-
if (!ok) {
|
|
196
|
-
process.exitCode = 7;
|
|
197
|
-
}
|
|
198
|
-
}
|
|
171
|
+
if (lockInfo.present && lockInfo.packageEntryPresent) {
|
|
172
|
+
addCheck(checks, 'package-lock-does-not-link-local-lbe', !lockInfo.blockedResolved, lockInfo);
|
|
173
|
+
} else {
|
|
174
|
+
addCheck(checks, 'package-lock-does-not-link-local-lbe', true, lockInfo);
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
const ok = checks.every((check) => check.ok);
|
|
178
|
+
const result = {
|
|
179
|
+
ok,
|
|
180
|
+
command: 'assert-consumer',
|
|
181
|
+
package: PACKAGE_NAME,
|
|
182
|
+
root,
|
|
183
|
+
classification: ok
|
|
184
|
+
? 'consumer-project-using-installed-registry-dependency'
|
|
185
|
+
: 'not-proven-consumer-installed-dependency',
|
|
186
|
+
releaseClaimsAllowed: false,
|
|
187
|
+
message: ok
|
|
188
|
+
? 'This project consumes LBE as an installed package dependency. This does not certify LBE release safety.'
|
|
189
|
+
: 'This project is not proven to consume LBE only as an installed registry dependency.',
|
|
190
|
+
checks
|
|
191
|
+
};
|
|
192
|
+
|
|
193
|
+
console.log(JSON.stringify(result, null, 2));
|
|
194
|
+
|
|
195
|
+
if (!ok) {
|
|
196
|
+
process.exitCode = 7;
|
|
197
|
+
}
|
|
198
|
+
}
|