@rightkit/release 0.2.123 → 0.2.125
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/build-release.mjs +2 -4
- package/ownership-evidence.mjs +4 -2
- package/ownership-report.mjs +2 -1
- package/ownership.mjs +26 -7
- package/package.json +1 -1
- package/rightkit-versions.json +31 -13
package/build-release.mjs
CHANGED
|
@@ -241,10 +241,8 @@ try {
|
|
|
241
241
|
}
|
|
242
242
|
const ownershipEvidence = preflight.find((check) => check.name === "ownership")?.evidence;
|
|
243
243
|
if (!ownershipEvidence) fail("ownership evidence was not produced by release preflight");
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
if (ownershipEvidence.source !== "enrollment-pending-advisory" && ownershipEvidence.commit !== commit) {
|
|
247
|
-
fail("ownership scan source differs from release commit");
|
|
244
|
+
if (ownershipEvidence.commit !== commit) {
|
|
245
|
+
fail(`ownership scan commit ${ownershipEvidence.commit ?? "(missing)"} differs from release commit ${commit}; regenerate with right-release ownership at release commit ${commit}`);
|
|
248
246
|
}
|
|
249
247
|
for (const check of preflight) {
|
|
250
248
|
if (check.status !== "ok") console.error(`[right-release] preflight ${check.name}: ${check.detail}`);
|
package/ownership-evidence.mjs
CHANGED
|
@@ -41,7 +41,7 @@ function createEvidence(repoRoot, {
|
|
|
41
41
|
let enrollmentPending = trustState.enrolled !== true;
|
|
42
42
|
if (committed && enrollmentPending && !allowPendingAdvisory && !trustState.trust?.rootFingerprint) throw new Error("protected ownership evidence requires both distinct, unrevoked approval keys to be enrolled");
|
|
43
43
|
// A valid protected registry with incomplete key enrollment can still drive
|
|
44
|
-
// a useful local backlog scan. It cannot
|
|
44
|
+
// a useful local backlog scan. It cannot assert a protected source binding or verify
|
|
45
45
|
// approval signatures, so this result is deliberately advisory.
|
|
46
46
|
const useCommittedSource = committed && (!enrollmentPending || Boolean(trustState.trust?.rootFingerprint));
|
|
47
47
|
if (useCommittedSource && requireCleanCheckout) assertCommittedCheckoutClean(root);
|
|
@@ -68,6 +68,7 @@ function createEvidence(repoRoot, {
|
|
|
68
68
|
}
|
|
69
69
|
if (useCommittedSource && requireCleanCheckout) assertCommittedCheckoutClean(root, { expectedCommit: source.commit, expectedTree: source.tree });
|
|
70
70
|
const commit = useCommittedSource ? source.commit : git(root, ["rev-parse", "HEAD"], gitRunner);
|
|
71
|
+
if (!commit) throw new Error("ownership evidence: scan source did not produce a HEAD commit");
|
|
71
72
|
const tree = useCommittedSource ? source.tree : git(root, ["rev-parse", `${commit}^{tree}`], gitRunner);
|
|
72
73
|
const scannerVersion = SCANNER_VERSION;
|
|
73
74
|
const catalogVersion = manifest.version ?? String(manifest.schema ?? "1");
|
|
@@ -154,7 +155,8 @@ function createEvidence(repoRoot, {
|
|
|
154
155
|
schema: 1,
|
|
155
156
|
repositoryIdentity: repositoryIdentity ? canonicalRepositoryIdentity(result.metadata?.repositoryIdentity) : null,
|
|
156
157
|
source: enrollmentPending ? "enrollment-pending-advisory" : useCommittedSource ? "committed-git-tree" : "mutable-checkout-test-seam",
|
|
157
|
-
|
|
158
|
+
commit,
|
|
159
|
+
...(enrollmentPending ? {} : { tree }),
|
|
158
160
|
catalogDigest,
|
|
159
161
|
catalogVersion,
|
|
160
162
|
scannerVersion,
|
package/ownership-report.mjs
CHANGED
|
@@ -37,6 +37,7 @@ function statusFor(row, report) {
|
|
|
37
37
|
if (report.enrollmentPending && (row.status === "blocked" || row.status === "blocked-by-findings")) return "enrollment-pending";
|
|
38
38
|
if (row.status === "blocked" || row.status === "blocked-by-findings") return "blocked";
|
|
39
39
|
if (row.status === "excepted") return "excepted";
|
|
40
|
+
if (row.status === "qa-only") return "qa-only";
|
|
40
41
|
if (row.status === "verified-integration") return "verified-integration";
|
|
41
42
|
if (row.status === "declared-dependency" || row.uses === true) return "declared-dependency";
|
|
42
43
|
if (report.coverage?.length) return "unscanned";
|
|
@@ -59,7 +60,7 @@ function exceptionRequests(root, app, report) {
|
|
|
59
60
|
|
|
60
61
|
function asRecord(app, root, scope, report, manifest, versions, scannedAt) {
|
|
61
62
|
const meta = report.metadata ?? {};
|
|
62
|
-
const findings = (report.findings ?? []).map((f) => ({ fingerprint: f.fingerprint, capability: f.capability, file: f.file, line: f.line ?? 0, occurrenceHash: f.occurrenceHash ?? sha256(canonicalJson(f)) }));
|
|
63
|
+
const findings = (report.findings ?? []).map((f) => ({ fingerprint: f.fingerprint, capability: f.capability, file: f.file, line: f.line ?? 0, occurrenceHash: f.occurrenceHash ?? sha256(canonicalJson(f)), ...(f.qaOnly ? { qaOnly: true } : {}) }));
|
|
63
64
|
const files = [...new Set(findings.map((f) => f.file))].sort();
|
|
64
65
|
const contentDigestSource = meta.contentDigests ? "scanner-inputs" : "finding-occurrences-only";
|
|
65
66
|
const contentDigests = meta.contentDigests ?? findings.map((f) => ({ path: f.file, digest: f.occurrenceHash, kind: "finding-occurrence" }));
|
package/ownership.mjs
CHANGED
|
@@ -15,7 +15,7 @@ export const EXCEPTIONS_FILE = path.join(".rightkit", "ownership-exceptions.json
|
|
|
15
15
|
const CODE_EXT = new Set([".rs", ".ts", ".tsx", ".js", ".mjs", ".cjs", ".jsx", ".swift", ".m", ".mm", ".c", ".cc", ".cpp", ".h", ".py", ".go", ".kt", ".java", ".cs"]);
|
|
16
16
|
// Listed installed/build inputs retain explicit coverage diagnostics.
|
|
17
17
|
const OPAQUE_DIRS = new Set(["target", ".build", "DerivedData", "Pods"]);
|
|
18
|
-
export const SCANNER_VERSION = "2.
|
|
18
|
+
export const SCANNER_VERSION = "2.3.0";
|
|
19
19
|
export const catalogDigest = (manifest) => sha256(manifest);
|
|
20
20
|
const byteDigest = (bytes) => createHash("sha256").update(bytes).digest("hex");
|
|
21
21
|
const inputDigest = (file) => file.digest ?? byteDigest(file.bytes);
|
|
@@ -249,7 +249,8 @@ function dependenciesFromInventory(appRoot, inventory) {
|
|
|
249
249
|
const alias = spec.match(/^(?:npm:)(@[^/]+\/[^@]+|[^@]+)(?:@|$)/)?.[1];
|
|
250
250
|
const localPath = spec.match(/^(?:file:|link:)(.+)$/)?.[1];
|
|
251
251
|
const isGit = /^(git\+|https?:.*\.git)/i.test(spec);
|
|
252
|
-
|
|
252
|
+
const devOnly = field === "devDependencies" && !["dependencies", "optionalDependencies", "peerDependencies"].some((section) => Object.hasOwn(pkg[section] ?? {}, name));
|
|
253
|
+
addDependency(deps, "npm", alias ?? name, rel, { alias: alias ? name : undefined, local: !!localPath, source: localPath ? spec.split(":")[0] : isGit ? "git" : spec.startsWith("workspace:") ? "workspace" : undefined, ...(devOnly ? { devOnly: true } : {}) });
|
|
253
254
|
if (localPath) {
|
|
254
255
|
resolveLocalPath(appRoot, rel, localPath, coverage, rel, inventory, "local-npm-dependency", name);
|
|
255
256
|
} else if (isGit) coverage.push({ path: rel, status: "unscanned", reason: `git-npm-dependency-source:${name}` });
|
|
@@ -359,13 +360,29 @@ function trustedProvenance(appRoot, inventory, trust, repositoryIdentity, covera
|
|
|
359
360
|
return { excluded, classifications };
|
|
360
361
|
}
|
|
361
362
|
|
|
363
|
+
function npmImportUsage(inventory) {
|
|
364
|
+
const usage = new Map(), qaSegments = new Set(["test", "tests", "__tests__", "e2e", "qa", "fixtures"]);
|
|
365
|
+
for (const { rel, bytes } of inventory.files) {
|
|
366
|
+
if (!CODE_EXT.has(path.posix.extname(rel).toLowerCase()) || !bytes) continue;
|
|
367
|
+
const qaPath = rel.split("/").some((segment) => qaSegments.has(segment)) || /(?:\.(?:test|spec)\.|^qa-.*\.)/.test(path.posix.basename(rel));
|
|
368
|
+
for (const match of bytes.toString("utf8").matchAll(/\bimport\b\s*(?:[\w$*{},\s]+?\bfrom\s*)?["']([^"']+)["']|\b(?:import|require)\s*\(\s*["']([^"']+)["']/g)) {
|
|
369
|
+
const specifier = match[1] ?? match[2];
|
|
370
|
+
const name = specifier.split("/").slice(0, specifier.startsWith("@") ? 2 : 1).join("/");
|
|
371
|
+
usage.set(name, (usage.get(name) ?? true) && qaPath);
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
return usage;
|
|
375
|
+
}
|
|
376
|
+
|
|
362
377
|
function scanInternal(appRoot, manifest, { inventory = fileInventory(appRoot), trust, repositoryIdentity, repositoryRoot = appRoot, pathPrefix = "" } = {}) {
|
|
363
378
|
const findings = [], coverage = [...inventory.coverage], deps = dependenciesFromInventory(appRoot, inventory), contentDigests = [...(deps.contentDigests ?? [])];
|
|
364
379
|
coverage.push(...(deps.coverage ?? []));
|
|
365
380
|
const provenance = trustedProvenance(appRoot, inventory, trust, repositoryIdentity, coverage, repositoryRoot, pathPrefix);
|
|
381
|
+
const npmUsage = npmImportUsage(inventory);
|
|
366
382
|
for (const c of manifest.capabilities) for (const f of c.fingerprints.filter((x) => x.type === "dependency")) for (const d of deps) {
|
|
367
383
|
if (d.ecosystem === f.ecosystem && (d.name === f.name || d.alias === f.name)) {
|
|
368
|
-
|
|
384
|
+
const qaOnly = c.capability !== "desktop-qa" && d.ecosystem === "npm" && d.devOnly && npmUsage.get(d.alias ?? d.name) === true;
|
|
385
|
+
findings.push({ fingerprint: f.id, capability: c.capability, package: c.package, file: d.file, line: 0, text: `${d.ecosystem} dependency ${d.alias ? `${d.alias} aliases ` : ""}${d.name}`, local: d.local, provenance: d.source, ...(qaOnly ? { qaOnly: true } : {}) });
|
|
369
386
|
}
|
|
370
387
|
}
|
|
371
388
|
const matchers = sourceMatchers(manifest);
|
|
@@ -469,16 +486,18 @@ export function evaluate(findings, exceptions, options = {}) {
|
|
|
469
486
|
}
|
|
470
487
|
const pending = enrollmentPending(options.trust, options.trustEnrollment);
|
|
471
488
|
if (pending) warnings.push("approval enrollment pending; detected findings remain open backlog requests until distinct Windows & macOS keys are enrolled");
|
|
472
|
-
|
|
473
|
-
|
|
489
|
+
const qaOnly = findings.filter((f) => f.qaOnly === true && f.capability !== "desktop-qa");
|
|
490
|
+
for (const f of findings) if (!qaOnly.includes(f) && !covered.some((x) => x.occurrenceHash === occurrenceHash(f))) violations.push({ ...f, occurrenceHash: occurrenceHash(f) });
|
|
491
|
+
return { violations, covered, qaOnly, problems, warnings, enrollmentPending: pending };
|
|
474
492
|
}
|
|
475
493
|
|
|
476
494
|
export function capabilityTable(manifest, deps, result) {
|
|
477
495
|
return [...new Map(manifest.capabilities.map((c) => [c.capability, c.package])).entries()].map(([capability, owner]) => {
|
|
478
496
|
const declared = deps.some((d) => d.name === owner || d.name === owner.replace(/^rightkit-/, "@rightkit/"));
|
|
479
497
|
const own = result.violations.filter((x) => x.capability === capability), covered = result.covered.filter((x) => x.capability === capability);
|
|
480
|
-
const
|
|
481
|
-
|
|
498
|
+
const qaOnly = (result.qaOnly ?? []).filter((x) => x.capability === capability && !covered.some((item) => item.occurrenceHash === x.occurrenceHash));
|
|
499
|
+
const status = own.length ? "blocked" : covered.length ? "excepted" : qaOnly.length ? "qa-only" : declared ? "declared-dependency" : result.coverage?.length ? "unscanned" : "not-detected";
|
|
500
|
+
return { capability, owner, uses: declared, status, count: own.length + covered.length + qaOnly.length };
|
|
482
501
|
});
|
|
483
502
|
}
|
|
484
503
|
export function formatTable(rows) { return ["capability owner status", ...rows.map((x) => `${x.capability} ${x.owner} ${x.status}`)].join("\n"); }
|
package/package.json
CHANGED
package/rightkit-versions.json
CHANGED
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
"@rightkit/app-shell": "0.2.1",
|
|
17
17
|
"@rightkit/ax": "0.2.4",
|
|
18
18
|
"@rightkit/doc-render": "0.1.3",
|
|
19
|
-
"@rightkit/git": "0.2.
|
|
19
|
+
"@rightkit/git": "0.2.26",
|
|
20
20
|
"@rightkit/hooks": "0.1.1",
|
|
21
21
|
"@rightkit/i18n": "0.1.0",
|
|
22
22
|
"@rightkit/legal": "0.3.1",
|
|
@@ -28,8 +28,8 @@
|
|
|
28
28
|
"@rightkit/pdf-ui": "0.1.2",
|
|
29
29
|
"@rightkit/platform-ui": "0.1.2",
|
|
30
30
|
"@rightkit/qa": "0.3.0",
|
|
31
|
-
"@rightkit/qa-chrome": "0.1.
|
|
32
|
-
"@rightkit/release": "0.2.
|
|
31
|
+
"@rightkit/qa-chrome": "0.1.3",
|
|
32
|
+
"@rightkit/release": "0.2.125",
|
|
33
33
|
"@rightkit/settings-ui": "0.2.7",
|
|
34
34
|
"@rightkit/shell": "0.1.0",
|
|
35
35
|
"@rightkit/tauri": "0.1.1",
|
|
@@ -66,7 +66,8 @@
|
|
|
66
66
|
"0.2.21",
|
|
67
67
|
"0.2.22",
|
|
68
68
|
"0.2.23",
|
|
69
|
-
"0.2.24"
|
|
69
|
+
"0.2.24",
|
|
70
|
+
"0.2.25"
|
|
70
71
|
],
|
|
71
72
|
"@rightkit/legal-ui": [
|
|
72
73
|
"0.1.0",
|
|
@@ -145,7 +146,9 @@
|
|
|
145
146
|
"0.2.119",
|
|
146
147
|
"0.2.120",
|
|
147
148
|
"0.2.121",
|
|
148
|
-
"0.2.122"
|
|
149
|
+
"0.2.122",
|
|
150
|
+
"0.2.123",
|
|
151
|
+
"0.2.124"
|
|
149
152
|
],
|
|
150
153
|
"@rightkit/qa": [
|
|
151
154
|
"0.1.0",
|
|
@@ -201,7 +204,8 @@
|
|
|
201
204
|
],
|
|
202
205
|
"@rightkit/qa-chrome": [
|
|
203
206
|
"0.1.0",
|
|
204
|
-
"0.1.1"
|
|
207
|
+
"0.1.1",
|
|
208
|
+
"0.1.2"
|
|
205
209
|
]
|
|
206
210
|
},
|
|
207
211
|
"cargo": {
|
|
@@ -224,7 +228,7 @@
|
|
|
224
228
|
"stagedCargo": {
|
|
225
229
|
"rightkit-audio": "0.1.0",
|
|
226
230
|
"rightkit-automation": "0.1.0",
|
|
227
|
-
"rightkit-browser": "0.2.
|
|
231
|
+
"rightkit-browser": "0.2.1",
|
|
228
232
|
"rightkit-cache": "0.1.0",
|
|
229
233
|
"rightkit-control": "0.1.6",
|
|
230
234
|
"rightkit-crash": "0.1.0",
|
|
@@ -238,13 +242,16 @@
|
|
|
238
242
|
"rightkit-logs": "0.2.0",
|
|
239
243
|
"rightkit-mcp": "0.1.1",
|
|
240
244
|
"rightkit-media": "0.2.2",
|
|
241
|
-
"rightkit-models": "0.2.
|
|
245
|
+
"rightkit-models": "0.2.2",
|
|
242
246
|
"rightkit-oauth": "0.2.0",
|
|
243
247
|
"rightkit-ort": "0.1.4",
|
|
244
248
|
"rightkit-pdf": "0.1.0",
|
|
245
249
|
"rightkit-playback": "0.1.0",
|
|
246
250
|
"rightkit-process": "0.2.1",
|
|
247
251
|
"rightkit-qa": "0.2.7",
|
|
252
|
+
"rightkit-qts": "0.2.0",
|
|
253
|
+
"rightkit-qts-ggml": "0.1.0",
|
|
254
|
+
"rightkit-qts-ggml-sys": "0.1.0",
|
|
248
255
|
"rightkit-sandbox": "0.1.0",
|
|
249
256
|
"rightkit-search": "0.1.0",
|
|
250
257
|
"rightkit-secrets": "0.1.0",
|
|
@@ -271,7 +278,7 @@
|
|
|
271
278
|
"registry": {
|
|
272
279
|
"cargo": {
|
|
273
280
|
"rightkit-audio": "0.1.0",
|
|
274
|
-
"rightkit-browser": "0.2.
|
|
281
|
+
"rightkit-browser": "0.2.1",
|
|
275
282
|
"rightkit-cache": "0.1.0",
|
|
276
283
|
"rightkit-control": "0.1.6",
|
|
277
284
|
"rightkit-crash": "0.1.0",
|
|
@@ -285,13 +292,16 @@
|
|
|
285
292
|
"rightkit-logs": "0.2.0",
|
|
286
293
|
"rightkit-mcp": "0.1.1",
|
|
287
294
|
"rightkit-media": "0.2.2",
|
|
288
|
-
"rightkit-models": "0.2.
|
|
295
|
+
"rightkit-models": "0.2.2",
|
|
289
296
|
"rightkit-oauth": "0.2.0",
|
|
290
297
|
"rightkit-ort": "0.1.4",
|
|
291
298
|
"rightkit-pdf": "0.1.0",
|
|
292
299
|
"rightkit-playback": "0.1.0",
|
|
293
300
|
"rightkit-process": "0.2.1",
|
|
294
301
|
"rightkit-qa": "0.2.7",
|
|
302
|
+
"rightkit-qts": "0.2.0",
|
|
303
|
+
"rightkit-qts-ggml": "0.1.0",
|
|
304
|
+
"rightkit-qts-ggml-sys": "0.1.0",
|
|
295
305
|
"rightkit-sandbox": "0.1.0",
|
|
296
306
|
"rightkit-search": "0.1.0",
|
|
297
307
|
"rightkit-secrets": "0.1.0",
|
|
@@ -306,7 +316,7 @@
|
|
|
306
316
|
"@rightkit/app-shell": "0.2.1",
|
|
307
317
|
"@rightkit/ax": "0.2.4",
|
|
308
318
|
"@rightkit/doc-render": "0.1.3",
|
|
309
|
-
"@rightkit/git": "0.2.
|
|
319
|
+
"@rightkit/git": "0.2.26",
|
|
310
320
|
"@rightkit/hooks": "0.1.1",
|
|
311
321
|
"@rightkit/i18n": "0.1.0",
|
|
312
322
|
"@rightkit/legal": "0.3.1",
|
|
@@ -318,13 +328,21 @@
|
|
|
318
328
|
"@rightkit/pdf-ui": "0.1.2",
|
|
319
329
|
"@rightkit/platform-ui": "0.1.2",
|
|
320
330
|
"@rightkit/qa": "0.3.0",
|
|
321
|
-
"@rightkit/qa-chrome": "0.1.
|
|
322
|
-
"@rightkit/release": "0.2.
|
|
331
|
+
"@rightkit/qa-chrome": "0.1.3",
|
|
332
|
+
"@rightkit/release": "0.2.124",
|
|
323
333
|
"@rightkit/settings-ui": "0.2.7",
|
|
324
334
|
"@rightkit/shell": "0.1.0",
|
|
325
335
|
"@rightkit/tauri": "0.1.1",
|
|
326
336
|
"@rightkit/theme": "0.2.1",
|
|
327
337
|
"@rightkit/updates": "0.2.4"
|
|
328
338
|
}
|
|
339
|
+
},
|
|
340
|
+
"legacyCargo": {
|
|
341
|
+
"rightkit-browser": [
|
|
342
|
+
"0.2.0"
|
|
343
|
+
],
|
|
344
|
+
"rightkit-models": [
|
|
345
|
+
"0.2.1"
|
|
346
|
+
]
|
|
329
347
|
}
|
|
330
348
|
}
|