@rightkit/release 0.2.151 → 0.2.154
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-APACHE +201 -0
- package/LICENSE-MIT +21 -0
- package/README.md +117 -8
- package/build-release.mjs +7 -2
- package/cli/right-release.mjs +18 -5
- package/committed-source.mjs +19 -1
- package/crate-graph.mjs +121 -0
- package/deps.mjs +0 -0
- package/development-signing.mjs +8 -0
- package/development.mjs +46 -13
- package/devtools-policy.json +5 -0
- package/devtools-policy.mjs +119 -0
- package/direct-bootstrap.mjs +9 -3
- package/dmg-build.mjs +19 -5
- package/dmg-layout.mjs +2 -2
- package/dmg-spec.mjs +97 -0
- package/execution-policy.mjs +17 -1
- package/github-release.mjs +25 -7
- package/github-upload-gate.mjs +84 -0
- package/hardeningscan.mjs +3 -0
- package/inventory-check.mjs +4 -4
- package/lsclean.sh +0 -0
- package/mac-bundle-signing.mjs +1 -1
- package/mac-sign-core.mjs +97 -0
- package/mac-signing-matrix.mjs +186 -0
- package/msix-appinstaller.mjs +4 -1
- package/msix-build.mjs +3 -6
- package/msix-config.mjs +5 -1
- package/msix-repair-guard.mjs +24 -0
- package/msix-repair-guard.ps1 +356 -0
- package/msix-signer.mjs +211 -0
- package/ownership-catalog-config.json +6 -7
- package/ownership-command.mjs +69 -8
- package/ownership-evidence.mjs +1 -1
- package/ownership-key-authority.mjs +1 -1
- package/ownership-key-command.mjs +15 -3
- package/ownership-key-elevation.mjs +11 -2
- package/ownership-mandatory-set.json +420 -0
- package/ownership-mandatory-set.mjs +273 -0
- package/ownership.mjs +2 -2
- package/package.json +25 -11
- package/packaged-app-identity.mjs +88 -0
- package/preflight.mjs +25 -3
- package/prune-r2.mjs +28 -3
- package/publication-gate.mjs +49 -10
- package/publish-cargo.mjs +21 -1
- package/publish-swift.mjs +78 -141
- package/publish-update.mjs +24 -2
- package/qa-build-features.mjs +216 -0
- package/qa-control-scan.mjs +435 -0
- package/registry-parity.mjs +18 -1
- package/release-invocation.mjs +2 -1
- package/release-state.mjs +9 -0
- package/release-switch-registry.json +33 -0
- package/release-switch-scan.mjs +452 -0
- package/release.mjs +320 -26
- package/renamed-away.mjs +29 -0
- package/rightkit-ownership.json +682 -709
- package/rightkit-sync.mjs +8 -4
- package/rightkit-version-policy.mjs +18 -0
- package/rightkit-versions.json +211 -127
- package/runtime-budget-classes.json +4 -0
- package/runtime-budgets.mjs +870 -0
- package/runtime-bundle-scan.mjs +61 -0
- package/sign-macos.mjs +28 -30
- package/sign-updater.mjs +5 -2
- package/swift-mac-dmg.mjs +7 -2
- package/swift-package-command.mjs +1 -1
- package/upload-large.mjs +0 -0
- package/upload-release.mjs +10 -37
package/ownership-command.mjs
CHANGED
|
@@ -18,6 +18,7 @@ import { spawnSync } from "./background-process.mjs";
|
|
|
18
18
|
import { main as stagedMain } from "./ownership-staged.mjs";
|
|
19
19
|
import { loadTrustedExternal } from "./ownership-approval.mjs";
|
|
20
20
|
import { trustComparison } from "./ownership-policy-bundle.mjs";
|
|
21
|
+
import { isBlockingFinding } from "./ownership-verdict.mjs";
|
|
21
22
|
|
|
22
23
|
const packageRoot = path.dirname(fileURLToPath(import.meta.url));
|
|
23
24
|
|
|
@@ -37,7 +38,7 @@ export function trustCompare(args, { print, trustLoader = loadTrustedExternal }
|
|
|
37
38
|
return 0;
|
|
38
39
|
}
|
|
39
40
|
|
|
40
|
-
export async function main(args, { evidenceFactory = createOwnershipEvidence, gitRunner = spawnSync, print = (value) => console.log(value), trustLoader = loadTrustedExternal } = {}) {
|
|
41
|
+
export async function main(args, { evidenceFactory = createOwnershipEvidence, gitRunner = spawnSync, print = (value) => console.log(value), stderr = (line) => console.error(line), trustLoader = loadTrustedExternal } = {}) {
|
|
41
42
|
if (args.includes("--help")) {
|
|
42
43
|
print("right-release ownership [--app <dir>] [--json]\nright-release ownership --staged [--app <dir>] [--json] (pre-commit gate: scans the index, not the working tree)\nright-release ownership --write-manifest [--rightkit <dir>] [--approve-new-capabilities]\n--approve-new-capabilities permits new capability ids during local generation only. Existing owner conflicts are always refused. Protected installation authorization remains separate.");
|
|
43
44
|
return 0;
|
|
@@ -58,20 +59,27 @@ export async function main(args, { evidenceFactory = createOwnershipEvidence, gi
|
|
|
58
59
|
}
|
|
59
60
|
const app = path.resolve(flag(args, "--app") ?? process.cwd());
|
|
60
61
|
const top = gitRunner("git", ["-C", app, "rev-parse", "--show-toplevel"], { encoding: "utf8", windowsHide: true });
|
|
61
|
-
if (top.status !== 0) return
|
|
62
|
+
if (top.status !== 0) return refuse(args, { type: "repository", message: "could not resolve --app to a Git repository" }, { print, stderr });
|
|
62
63
|
const repoRoot = path.resolve(String(top.stdout).trim());
|
|
63
64
|
let checked;
|
|
64
65
|
try { checked = evidenceFactory(repoRoot, app); }
|
|
65
|
-
catch (error) {
|
|
66
|
+
catch (error) {
|
|
67
|
+
// A refusal from the protected checkout carries its check name and offending paths.
|
|
68
|
+
const blocked = error?.blocked ? [blockedCheck(error.blocked.check, error.message, error.blocked.paths)] : undefined;
|
|
69
|
+
return refuse(args, { type: "protected-evidence", message: error.message, blocked }, { print, stderr });
|
|
70
|
+
}
|
|
66
71
|
const result = checked.result;
|
|
67
72
|
if (args.includes("--audit-json")) return printAuditJson(result, print);
|
|
73
|
+
// A refusal names every blocking check on stderr and in the JSON `blocked` field. Advise-tier findings never refuse.
|
|
74
|
+
const blocked = checked.enrollmentPending || checked.ok ? undefined : blockingChecks(checked);
|
|
75
|
+
if (blocked) reportBlocked(blocked, stderr);
|
|
68
76
|
if (args.includes("--json")) {
|
|
69
77
|
const error = checked.enrollmentPending ? undefined : !checked.floor.ok
|
|
70
78
|
? { type: "ownership-floor", message: checked.floor.problems.join("; ") }
|
|
71
79
|
: result.coverage.length
|
|
72
80
|
? { type: "ownership-coverage", message: `${result.coverage.length} ownership coverage gap(s)` }
|
|
73
81
|
: undefined;
|
|
74
|
-
print(JSON.stringify({ ok: checked.ok, ...(checked.enrollmentPending ? { enrollmentPending: true, warning: checked.warning } : {}), ...(error ? { error } : {}), rows: result.rows, violations: result.violations, covered: result.covered, problems: [...result.problems, ...checked.floor.problems], coverage: result.coverage, metadata: result.metadata }, null, 2));
|
|
82
|
+
print(JSON.stringify({ ok: checked.ok, ...(checked.enrollmentPending ? { enrollmentPending: true, warning: checked.warning } : {}), ...(error ? { error } : {}), ...(blocked ? { blocked } : {}), rows: result.rows, violations: result.violations, covered: result.covered, problems: [...result.problems, ...checked.floor.problems], coverage: result.coverage, metadata: result.metadata }, null, 2));
|
|
75
83
|
} else {
|
|
76
84
|
print(`RightKit ownership: ${path.basename(app)}`);
|
|
77
85
|
print(formatTable(result.rows));
|
|
@@ -79,7 +87,7 @@ export async function main(args, { evidenceFactory = createOwnershipEvidence, gi
|
|
|
79
87
|
print(` OWN COPY ${v.fingerprint} (${v.package}) ${v.file}${v.line ? `:${v.line}` : ""} ${v.text}`);
|
|
80
88
|
}
|
|
81
89
|
for (const p of result.problems) print(` ${checked.enrollmentPending ? "DIAGNOSTIC" : "EXCEPTION"} ${p}`);
|
|
82
|
-
print(checked
|
|
90
|
+
print(verdictLine(checked, result, blocked));
|
|
83
91
|
}
|
|
84
92
|
// CI lanes may pass `--advisory-when-pending`: before approval keys are enrolled the scan asserts
|
|
85
93
|
// nothing, so findings print as diagnostics and the step exits 0. Release lanes never pass it.
|
|
@@ -115,9 +123,62 @@ function printAuditJson(result, print) {
|
|
|
115
123
|
}
|
|
116
124
|
}
|
|
117
125
|
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
126
|
+
// Each refusal names its blocking check and the first offending paths. Stderr and the JSON `blocked` field carry the same list.
|
|
127
|
+
const BLOCKED_PATH_LIMIT = 10;
|
|
128
|
+
|
|
129
|
+
function blockedCheck(check, message, paths = []) {
|
|
130
|
+
return { check, message, count: paths.length, paths: paths.slice(0, BLOCKED_PATH_LIMIT) };
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// The checks that refuse a scan that did not pass. Advise-tier findings are never listed here.
|
|
134
|
+
function blockingChecks(checked) {
|
|
135
|
+
const result = checked.result;
|
|
136
|
+
const checks = [];
|
|
137
|
+
const blocking = (result.violations ?? []).filter(isBlockingFinding);
|
|
138
|
+
if (blocking.length) checks.push(blockedCheck("ownership-violation", `${blocking.length} block-tier finding(s) duplicate RightKit owners`, blocking.map((entry) => entry.file).filter(Boolean)));
|
|
139
|
+
const floorProblems = checked.floor?.ok === false ? checked.floor.problems ?? [] : [];
|
|
140
|
+
if (floorProblems.length) checks.push(blockedCheck("ownership-floor", floorProblems.join("; ")));
|
|
141
|
+
const problems = (result.problems ?? []).filter((problem) => !floorProblems.includes(problem));
|
|
142
|
+
if (problems.length) checks.push(blockedCheck("ownership-problem", problems.join("; ")));
|
|
143
|
+
const gaps = result.coverage ?? [];
|
|
144
|
+
if (gaps.length) checks.push(blockedCheck("ownership-coverage", `${gaps.length} coverage gap(s): ${[...new Set(gaps.map((gap) => gap.reason))].join(", ")}`, gaps.map((gap) => gap.path)));
|
|
145
|
+
if (!checks.length) checks.push(blockedCheck("ownership-unknown", "scan reported not ok without a listed cause"));
|
|
146
|
+
return checks;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
function reportBlocked(checks, stderr) {
|
|
150
|
+
for (const check of checks) {
|
|
151
|
+
stderr(`[right-release] refused by check ${check.check}: ${check.message}`);
|
|
152
|
+
for (const file of check.paths) stderr(` - ${file}`);
|
|
153
|
+
if (check.count > check.paths.length) stderr(` ... and ${check.count - check.paths.length} more`);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
function tierCounts(violations) {
|
|
158
|
+
const counts = { block: 0, advise: 0 };
|
|
159
|
+
for (const violation of violations) counts[isBlockingFinding(violation) ? "block" : "advise"] += 1;
|
|
160
|
+
return counts;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
// The human verdict line. Advise-only results pass and say so; a refusal names its checks.
|
|
164
|
+
function verdictLine(checked, result, blocked) {
|
|
165
|
+
if (checked.enrollmentPending) return `[right-release] ${checked.warning}`;
|
|
166
|
+
if (checked.ok) {
|
|
167
|
+
const counts = tierCounts(result.violations ?? []);
|
|
168
|
+
return counts.advise
|
|
169
|
+
? `[right-release] ownership ADVISE: block ${counts.block}, advise ${counts.advise} (reported, not refused)`
|
|
170
|
+
: "[right-release] ownership passed";
|
|
171
|
+
}
|
|
172
|
+
const hint = blocked.some((entry) => entry.check === "ownership-violation") ? "; move these to RightKit or add a reviewed, dated exception" : "";
|
|
173
|
+
return `[right-release] ownership FAILED: ${blocked.map((entry) => `${entry.check}: ${entry.message}`).join("; ")}${hint}`;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
// Refusal before any verdict: unresolved repository, protected evidence, or a dirty protected checkout.
|
|
177
|
+
function refuse(args, { type, message, blocked }, { print = (value) => console.log(value), stderr = (line) => console.error(line) } = {}) {
|
|
178
|
+
const checks = blocked ?? [blockedCheck(type, message)];
|
|
179
|
+
reportBlocked(checks, stderr);
|
|
180
|
+
if (args.includes("--audit-json")) { stderr(`[right-release] ownership audit failed: ${message}`); return 1; }
|
|
181
|
+
if (args.includes("--json")) print(JSON.stringify({ ok: false, error: { type, message }, blocked: checks, rows: [], violations: [], covered: [], problems: [message], coverage: [], metadata: null }, null, 2));
|
|
121
182
|
else print(`[right-release] ownership FAILED: ${message}`);
|
|
122
183
|
return 1;
|
|
123
184
|
}
|
package/ownership-evidence.mjs
CHANGED
|
@@ -90,7 +90,7 @@ function createEvidence(repoRoot, {
|
|
|
90
90
|
: { ok: false, problems: ["protected ownership floor is unavailable until trust registry enrollment"] };
|
|
91
91
|
if (bundleProblem) { floor.ok = false; floor.problems = [bundleProblem, ...floor.problems.filter((problem) => !problem.startsWith("ownership policy bundle"))]; }
|
|
92
92
|
// Real paths on both sides: Git's root is resolved (macOS /private/var), callers may pass /var or /tmp.
|
|
93
|
-
const real = (p) => { try { return realpathSync(p); } catch { return path.resolve(p); } };
|
|
93
|
+
const real = (p) => { try { return realpathSync.native(p); } catch { return path.resolve(p); } };
|
|
94
94
|
const requestedRoot = path.relative(real(root), real(scanRoot)).replaceAll("\\", "/") || ".";
|
|
95
95
|
if (requestedRoot.startsWith("../") || requestedRoot === ".." || path.isAbsolute(requestedRoot)) throw new Error("ownership evidence scan root must be inside repository");
|
|
96
96
|
const evidenceDiagnostics = [];
|
|
@@ -37,7 +37,7 @@ function validateAuthority(authority) {
|
|
|
37
37
|
if (typeof authority.checkoutPath !== "string" || !path.isAbsolute(authority.checkoutPath) || authority.checkoutPath.includes("\0")) throw new Error("protected key authority checkoutPath must be absolute");
|
|
38
38
|
const repositoryIdentity = canonicalRepositoryIdentity(authority.repositoryIdentity);
|
|
39
39
|
if (repositoryIdentity !== authority.repositoryIdentity) throw new Error("protected key authority identity must be canonical");
|
|
40
|
-
const checkoutPath = realpathSync(authority.checkoutPath);
|
|
40
|
+
const checkoutPath = realpathSync.native(authority.checkoutPath);
|
|
41
41
|
if (!statSync(checkoutPath).isDirectory()) throw new Error("protected key authority checkoutPath must be a directory");
|
|
42
42
|
return { repositoryIdentity, checkoutPath };
|
|
43
43
|
}
|
|
@@ -41,7 +41,8 @@ function readLog(root) {
|
|
|
41
41
|
}
|
|
42
42
|
function ensureCleanMetadata(root, run, rels) {
|
|
43
43
|
for (const rel of rels) assertSafeMetadataParents(root, rel);
|
|
44
|
-
|
|
44
|
+
// Limited to the metadata paths: an unscoped status of a large checkout overflows the child's output buffer.
|
|
45
|
+
const result = run("git", ["-C", root, "status", "--porcelain=v1", "--untracked-files=all", "--", ...rels]);
|
|
45
46
|
if (result.status !== 0) throw new Error("could not inspect repository metadata status");
|
|
46
47
|
const status = String(result.stdout ?? "");
|
|
47
48
|
for (const rel of rels) {
|
|
@@ -49,7 +50,7 @@ function ensureCleanMetadata(root, run, rels) {
|
|
|
49
50
|
}
|
|
50
51
|
}
|
|
51
52
|
function metadataIsDirty(root, run) {
|
|
52
|
-
const r = run("git", ["-C", root, "status", "--porcelain=v1", "--untracked-files=all"]);
|
|
53
|
+
const r = run("git", ["-C", root, "status", "--porcelain=v1", "--untracked-files=all", "--", LOG, REQUEST_DIR]);
|
|
53
54
|
if (r.status !== 0) throw new Error("could not inspect repository metadata status");
|
|
54
55
|
return String(r.stdout ?? "").split(/\r?\n/).some((line) => {
|
|
55
56
|
const file = line.slice(3).replaceAll('"', "");
|
|
@@ -355,7 +356,7 @@ export async function main(args, deps = {}) {
|
|
|
355
356
|
try {
|
|
356
357
|
if (!platform) throw new Error(`ownership key management unsupported platform: ${process.platform}`);
|
|
357
358
|
// Delegate BEFORE taking the command lock: the desktop-session child needs that same lock.
|
|
358
|
-
if (args[0] === "trust-sync" && needsDesktopDelegation({ hostPlatform: deps.hostPlatform, env: deps.env, run, elevatedCheck: deps.elevatedCheck })) return delegateTrustSync(deps, run, print);
|
|
359
|
+
if (args[0] === "trust-sync" && !args.includes("--check") && needsDesktopDelegation({ hostPlatform: deps.hostPlatform, env: deps.env, run, elevatedCheck: deps.elevatedCheck })) return delegateTrustSync(deps, run, print);
|
|
359
360
|
const helper = deps.helper ?? helperFor(run);
|
|
360
361
|
const lockPath = deps.lockPath ?? path.join(os.tmpdir(), "rightkit-key-command.lock");
|
|
361
362
|
let lockFd;
|
|
@@ -524,6 +525,17 @@ async function trustSync(_args, d) {
|
|
|
524
525
|
if (!trust?.trust?.rootFingerprint) throw new Error("protected root trust is not enrolled on this host; run ownership enroll");
|
|
525
526
|
if (trust.trust.rootFingerprint !== pin) throw new Error("committed key log root does not match this host's protected trust");
|
|
526
527
|
const baseline = d.baseline ?? parse(readFileSync(path.join(here, "ownership-default-policy.json"), "utf8"), "ownership default policy");
|
|
528
|
+
if (_args.includes("--check")) {
|
|
529
|
+
// Read-only: say whether a sync would ask for approval, and for what. Asks nothing, elevates nothing, writes no trust.
|
|
530
|
+
const request = makeTrustRequest(log, pin, baseline, d.authority);
|
|
531
|
+
try {
|
|
532
|
+
const summary = (d.summarize ?? summarizeRequestFile)({ file: request.file, digest: request.digest, existing: trust.trust, ...(d.summaryInputs ?? {}) });
|
|
533
|
+
if (!summary.changed) { d.print("trust already current: no approval needed"); return 0; }
|
|
534
|
+
d.print(summary.lines.join("\n"));
|
|
535
|
+
d.print("approval needed: trust-sync on this host would ask for the change above");
|
|
536
|
+
return 3;
|
|
537
|
+
} finally { await import("node:fs").then(({ unlinkSync }) => unlinkSync(request.file)).catch(() => {}); }
|
|
538
|
+
}
|
|
527
539
|
const installed = await installCheckpoint(log, pin, baseline, d);
|
|
528
540
|
if (installed === false) { d.print("trust already current"); return 0; }
|
|
529
541
|
postVerify(d.root, log, d);
|
|
@@ -169,7 +169,7 @@ export function capSummary(lines, { maxLines = 16, maxChars = 1600 } = {}) {
|
|
|
169
169
|
|
|
170
170
|
export function buildMacConfirmScript(text) {
|
|
171
171
|
// The text field takes keyboard focus, so stray typing never presses a button; approval needs "yes" typed.
|
|
172
|
-
return `display dialog ${appleScriptText(`${text}\n\nType yes below, then click Approve.`)} default answer "" with title ${appleScriptText(CONFIRM_TITLE)} buttons {"Cancel","Approve\u2026"} default button "Approve\u2026" cancel button "Cancel" with icon caution`;
|
|
172
|
+
return `display dialog ${appleScriptText(`${text}\n\nType the word yes below (not your password), then click Approve.`)} default answer "" with title ${appleScriptText(CONFIRM_TITLE)} buttons {"Cancel","Approve\u2026"} default button "Approve\u2026" cancel button "Cancel" with icon caution`;
|
|
173
173
|
}
|
|
174
174
|
|
|
175
175
|
export const WINDOWS_APPROVE_PREFIX = "RK_CONFIRM_APPROVED:";
|
|
@@ -189,7 +189,16 @@ export function buildWindowsConfirmScript(text, nonce = "") {
|
|
|
189
189
|
|
|
190
190
|
function readLineSync() {
|
|
191
191
|
const buf = Buffer.alloc(1); let line = "";
|
|
192
|
-
for (;;) {
|
|
192
|
+
for (;;) {
|
|
193
|
+
let n = 0;
|
|
194
|
+
try { n = readSync(0, buf, 0, 1, null); } catch (error) {
|
|
195
|
+
// A terminal whose stdin is non-blocking reports "no input yet" as EAGAIN: wait for the human, do not treat it as an answer.
|
|
196
|
+
if (error?.code === "EAGAIN") { Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, 50); continue; }
|
|
197
|
+
return line;
|
|
198
|
+
}
|
|
199
|
+
if (n === 0 || buf[0] === 10) return line;
|
|
200
|
+
line += String.fromCharCode(buf[0]);
|
|
201
|
+
}
|
|
193
202
|
}
|
|
194
203
|
|
|
195
204
|
/**
|
|
@@ -0,0 +1,420 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schema": 1,
|
|
3
|
+
"source": {
|
|
4
|
+
"table": "private-audits/TABLE1-MANDATORY.md:56-78 (M1-M23 requirement catalog)",
|
|
5
|
+
"versions": "private-audits/inventory/REQUIRED-VERSIONS.md (source versions at rightkit HEAD a15e62fd, registry readback 2026-10-13)",
|
|
6
|
+
"note": "min = required version (source version at P1.7 HEAD). registryMax = highest registry version at readback; where registryMax < min the required version is not yet published, so every consumer fails until it ships."
|
|
7
|
+
},
|
|
8
|
+
"defaultProfile": "desktop",
|
|
9
|
+
"defaultApps": [
|
|
10
|
+
"heardright",
|
|
11
|
+
"scraperight",
|
|
12
|
+
"coderight",
|
|
13
|
+
"cutright",
|
|
14
|
+
"genright",
|
|
15
|
+
"postright",
|
|
16
|
+
"viewright",
|
|
17
|
+
"mailright",
|
|
18
|
+
"pulse",
|
|
19
|
+
"ember"
|
|
20
|
+
],
|
|
21
|
+
"appDeclarationFile": "rightkit-mandatory.json",
|
|
22
|
+
"profiles": {
|
|
23
|
+
"desktop": {
|
|
24
|
+
"description": "Default: every desktop app owes every row unless the app declares N/A with a reason."
|
|
25
|
+
},
|
|
26
|
+
"apple": {
|
|
27
|
+
"description": "Table 1-Apple is an unratified draft. Profile is supported by the data model; no Apple rows are shipped.",
|
|
28
|
+
"ratified": false
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
"rows": [
|
|
32
|
+
{
|
|
33
|
+
"id": "M1",
|
|
34
|
+
"name": "Window host",
|
|
35
|
+
"profile": "desktop",
|
|
36
|
+
"owners": [
|
|
37
|
+
{
|
|
38
|
+
"name": "rightkit-tauri-shell",
|
|
39
|
+
"ecosystem": "cargo",
|
|
40
|
+
"min": "0.3.0"
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
"name": "rightkit-device",
|
|
44
|
+
"ecosystem": "cargo",
|
|
45
|
+
"min": "0.1.3"
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
"name": "@rightkit/tauri",
|
|
49
|
+
"ecosystem": "npm",
|
|
50
|
+
"min": "0.2.0",
|
|
51
|
+
"registryMax": "0.2.0"
|
|
52
|
+
}
|
|
53
|
+
]
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
"id": "M2",
|
|
57
|
+
"name": "App frame",
|
|
58
|
+
"profile": "desktop",
|
|
59
|
+
"owners": [
|
|
60
|
+
{
|
|
61
|
+
"name": "@rightkit/react-shell",
|
|
62
|
+
"ecosystem": "npm",
|
|
63
|
+
"min": "0.6.4"
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
"name": "@rightkit/platform-ui",
|
|
67
|
+
"ecosystem": "npm",
|
|
68
|
+
"min": "0.2.8",
|
|
69
|
+
"registryMax": "0.2.7"
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
"name": "@rightkit/theme",
|
|
73
|
+
"ecosystem": "npm",
|
|
74
|
+
"min": "0.2.3",
|
|
75
|
+
"registryMax": "0.2.3"
|
|
76
|
+
}
|
|
77
|
+
]
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
"id": "M3",
|
|
81
|
+
"name": "Engine supervision",
|
|
82
|
+
"profile": "desktop",
|
|
83
|
+
"owners": [
|
|
84
|
+
{
|
|
85
|
+
"name": "rightkit-job-queue",
|
|
86
|
+
"ecosystem": "cargo",
|
|
87
|
+
"min": "0.3.0"
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
"name": "rightkit-child-process",
|
|
91
|
+
"ecosystem": "cargo",
|
|
92
|
+
"min": "0.4.0"
|
|
93
|
+
}
|
|
94
|
+
]
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
"id": "M4",
|
|
98
|
+
"name": "Window/CLI protocol",
|
|
99
|
+
"profile": "desktop",
|
|
100
|
+
"owners": [
|
|
101
|
+
{
|
|
102
|
+
"name": "rightkit-job-queue",
|
|
103
|
+
"ecosystem": "cargo",
|
|
104
|
+
"min": "0.3.0"
|
|
105
|
+
},
|
|
106
|
+
{
|
|
107
|
+
"name": "rightkit-sidecar",
|
|
108
|
+
"ecosystem": "cargo",
|
|
109
|
+
"min": "0.2.0"
|
|
110
|
+
}
|
|
111
|
+
]
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
"id": "M5",
|
|
115
|
+
"name": "Other child processes",
|
|
116
|
+
"profile": "desktop",
|
|
117
|
+
"owners": [
|
|
118
|
+
{
|
|
119
|
+
"name": "rightkit-child-process",
|
|
120
|
+
"ecosystem": "cargo",
|
|
121
|
+
"min": "0.4.0"
|
|
122
|
+
}
|
|
123
|
+
]
|
|
124
|
+
},
|
|
125
|
+
{
|
|
126
|
+
"id": "M6",
|
|
127
|
+
"name": "Data location",
|
|
128
|
+
"profile": "desktop",
|
|
129
|
+
"owners": [
|
|
130
|
+
{
|
|
131
|
+
"name": "rightkit-daemon",
|
|
132
|
+
"ecosystem": "cargo",
|
|
133
|
+
"min": "0.2.0"
|
|
134
|
+
}
|
|
135
|
+
]
|
|
136
|
+
},
|
|
137
|
+
{
|
|
138
|
+
"id": "M7",
|
|
139
|
+
"name": "Local services",
|
|
140
|
+
"profile": "desktop",
|
|
141
|
+
"owners": [
|
|
142
|
+
{
|
|
143
|
+
"name": "rightkit-daemon",
|
|
144
|
+
"ecosystem": "cargo",
|
|
145
|
+
"min": "0.2.0"
|
|
146
|
+
}
|
|
147
|
+
]
|
|
148
|
+
},
|
|
149
|
+
{
|
|
150
|
+
"id": "M8",
|
|
151
|
+
"name": "Safe file writes",
|
|
152
|
+
"profile": "desktop",
|
|
153
|
+
"owners": [
|
|
154
|
+
{
|
|
155
|
+
"name": "rightkit-fs",
|
|
156
|
+
"ecosystem": "cargo",
|
|
157
|
+
"min": "0.4.0",
|
|
158
|
+
"registryMax": "0.3.3"
|
|
159
|
+
}
|
|
160
|
+
]
|
|
161
|
+
},
|
|
162
|
+
{
|
|
163
|
+
"id": "M9",
|
|
164
|
+
"name": "Database",
|
|
165
|
+
"profile": "desktop",
|
|
166
|
+
"owners": [
|
|
167
|
+
{
|
|
168
|
+
"name": "rightkit-db",
|
|
169
|
+
"ecosystem": "cargo",
|
|
170
|
+
"min": "0.4.0",
|
|
171
|
+
"registryMax": "0.3.2"
|
|
172
|
+
}
|
|
173
|
+
]
|
|
174
|
+
},
|
|
175
|
+
{
|
|
176
|
+
"id": "M10",
|
|
177
|
+
"name": "Settings",
|
|
178
|
+
"profile": "desktop",
|
|
179
|
+
"owners": [
|
|
180
|
+
{
|
|
181
|
+
"name": "rightkit-app-settings",
|
|
182
|
+
"ecosystem": "cargo",
|
|
183
|
+
"min": "0.2.0"
|
|
184
|
+
},
|
|
185
|
+
{
|
|
186
|
+
"name": "@rightkit/settings-ui",
|
|
187
|
+
"ecosystem": "npm",
|
|
188
|
+
"min": "0.4.4",
|
|
189
|
+
"registryMax": "0.4.3"
|
|
190
|
+
}
|
|
191
|
+
]
|
|
192
|
+
},
|
|
193
|
+
{
|
|
194
|
+
"id": "M11",
|
|
195
|
+
"name": "Secrets",
|
|
196
|
+
"profile": "desktop",
|
|
197
|
+
"owners": [
|
|
198
|
+
{
|
|
199
|
+
"name": "rightkit-credentials",
|
|
200
|
+
"ecosystem": "cargo",
|
|
201
|
+
"min": "0.2.0"
|
|
202
|
+
}
|
|
203
|
+
]
|
|
204
|
+
},
|
|
205
|
+
{
|
|
206
|
+
"id": "M12",
|
|
207
|
+
"name": "Licence/device",
|
|
208
|
+
"profile": "desktop",
|
|
209
|
+
"owners": [
|
|
210
|
+
{
|
|
211
|
+
"name": "rightkit-license",
|
|
212
|
+
"ecosystem": "cargo",
|
|
213
|
+
"min": "0.2.0",
|
|
214
|
+
"registryMax": "0.1.3"
|
|
215
|
+
},
|
|
216
|
+
{
|
|
217
|
+
"name": "rightkit-device",
|
|
218
|
+
"ecosystem": "cargo",
|
|
219
|
+
"min": "0.1.3"
|
|
220
|
+
},
|
|
221
|
+
{
|
|
222
|
+
"name": "@rightkit/license",
|
|
223
|
+
"ecosystem": "npm",
|
|
224
|
+
"min": "0.2.0",
|
|
225
|
+
"registryMax": "0.1.8"
|
|
226
|
+
}
|
|
227
|
+
]
|
|
228
|
+
},
|
|
229
|
+
{
|
|
230
|
+
"id": "M13",
|
|
231
|
+
"name": "Pro entitlement",
|
|
232
|
+
"profile": "desktop",
|
|
233
|
+
"owners": [
|
|
234
|
+
{
|
|
235
|
+
"name": "rightkit-license",
|
|
236
|
+
"ecosystem": "cargo",
|
|
237
|
+
"min": "0.2.0",
|
|
238
|
+
"registryMax": "0.1.3"
|
|
239
|
+
}
|
|
240
|
+
]
|
|
241
|
+
},
|
|
242
|
+
{
|
|
243
|
+
"id": "M14",
|
|
244
|
+
"name": "Legal/onboarding",
|
|
245
|
+
"profile": "desktop",
|
|
246
|
+
"owners": [
|
|
247
|
+
{
|
|
248
|
+
"name": "@rightkit/legal",
|
|
249
|
+
"ecosystem": "npm",
|
|
250
|
+
"min": "0.3.1",
|
|
251
|
+
"registryMax": "0.3.1"
|
|
252
|
+
},
|
|
253
|
+
{
|
|
254
|
+
"name": "@rightkit/legal-ui",
|
|
255
|
+
"ecosystem": "npm",
|
|
256
|
+
"min": "0.2.2",
|
|
257
|
+
"registryMax": "0.2.2"
|
|
258
|
+
},
|
|
259
|
+
{
|
|
260
|
+
"name": "@rightkit/onboarding",
|
|
261
|
+
"ecosystem": "npm",
|
|
262
|
+
"min": "0.3.3",
|
|
263
|
+
"registryMax": "0.3.2"
|
|
264
|
+
}
|
|
265
|
+
]
|
|
266
|
+
},
|
|
267
|
+
{
|
|
268
|
+
"id": "M15",
|
|
269
|
+
"name": "Logging",
|
|
270
|
+
"profile": "desktop",
|
|
271
|
+
"owners": [
|
|
272
|
+
{
|
|
273
|
+
"name": "rightkit-logs",
|
|
274
|
+
"ecosystem": "cargo",
|
|
275
|
+
"min": "0.2.2",
|
|
276
|
+
"registryMax": "0.2.1"
|
|
277
|
+
},
|
|
278
|
+
{
|
|
279
|
+
"name": "@rightkit/logs",
|
|
280
|
+
"ecosystem": "npm",
|
|
281
|
+
"min": "0.1.4",
|
|
282
|
+
"registryMax": "0.1.4"
|
|
283
|
+
}
|
|
284
|
+
]
|
|
285
|
+
},
|
|
286
|
+
{
|
|
287
|
+
"id": "M16",
|
|
288
|
+
"name": "Crash reporting",
|
|
289
|
+
"profile": "desktop",
|
|
290
|
+
"owners": [
|
|
291
|
+
{
|
|
292
|
+
"name": "rightkit-crash",
|
|
293
|
+
"ecosystem": "cargo",
|
|
294
|
+
"min": "0.2.2",
|
|
295
|
+
"registryMax": "0.2.1"
|
|
296
|
+
}
|
|
297
|
+
]
|
|
298
|
+
},
|
|
299
|
+
{
|
|
300
|
+
"id": "M17",
|
|
301
|
+
"name": "HTTP",
|
|
302
|
+
"profile": "desktop",
|
|
303
|
+
"owners": [
|
|
304
|
+
{
|
|
305
|
+
"name": "rightkit-http",
|
|
306
|
+
"ecosystem": "cargo",
|
|
307
|
+
"min": "0.3.0",
|
|
308
|
+
"registryMax": "0.2.5"
|
|
309
|
+
}
|
|
310
|
+
]
|
|
311
|
+
},
|
|
312
|
+
{
|
|
313
|
+
"id": "M18",
|
|
314
|
+
"name": "Updates",
|
|
315
|
+
"profile": "desktop",
|
|
316
|
+
"owners": [
|
|
317
|
+
{
|
|
318
|
+
"name": "@rightkit/app-update",
|
|
319
|
+
"ecosystem": "npm",
|
|
320
|
+
"min": "0.2.5"
|
|
321
|
+
}
|
|
322
|
+
]
|
|
323
|
+
},
|
|
324
|
+
{
|
|
325
|
+
"id": "M19",
|
|
326
|
+
"name": "Release tooling",
|
|
327
|
+
"profile": "desktop",
|
|
328
|
+
"owners": [
|
|
329
|
+
{
|
|
330
|
+
"name": "@rightkit/release",
|
|
331
|
+
"ecosystem": "npm",
|
|
332
|
+
"min": "0.2.153",
|
|
333
|
+
"registryMax": "0.2.151",
|
|
334
|
+
"allowDev": true
|
|
335
|
+
}
|
|
336
|
+
]
|
|
337
|
+
},
|
|
338
|
+
{
|
|
339
|
+
"id": "M20",
|
|
340
|
+
"name": "QA",
|
|
341
|
+
"profile": "desktop",
|
|
342
|
+
"owners": [
|
|
343
|
+
{
|
|
344
|
+
"name": "rightkit-qa",
|
|
345
|
+
"ecosystem": "cargo",
|
|
346
|
+
"min": "0.2.16",
|
|
347
|
+
"registryMax": "0.2.14",
|
|
348
|
+
"allowDev": true
|
|
349
|
+
},
|
|
350
|
+
{
|
|
351
|
+
"name": "rightkit-qa-driver",
|
|
352
|
+
"ecosystem": "cargo",
|
|
353
|
+
"min": "0.3.0",
|
|
354
|
+
"allowDev": true
|
|
355
|
+
},
|
|
356
|
+
{
|
|
357
|
+
"name": "@rightkit/qa",
|
|
358
|
+
"ecosystem": "npm",
|
|
359
|
+
"min": "0.4.8",
|
|
360
|
+
"registryMax": "0.4.7",
|
|
361
|
+
"allowDev": true
|
|
362
|
+
},
|
|
363
|
+
{
|
|
364
|
+
"name": "@rightkit/qa-chrome",
|
|
365
|
+
"ecosystem": "npm",
|
|
366
|
+
"min": "0.1.6",
|
|
367
|
+
"registryMax": "0.1.6",
|
|
368
|
+
"allowDev": true
|
|
369
|
+
}
|
|
370
|
+
]
|
|
371
|
+
},
|
|
372
|
+
{
|
|
373
|
+
"id": "M22",
|
|
374
|
+
"name": "Agent surface",
|
|
375
|
+
"profile": "desktop",
|
|
376
|
+
"owners": [
|
|
377
|
+
{
|
|
378
|
+
"name": "rightkit-mcp",
|
|
379
|
+
"ecosystem": "cargo",
|
|
380
|
+
"min": "0.6.0",
|
|
381
|
+
"registryMax": "0.5.3"
|
|
382
|
+
}
|
|
383
|
+
]
|
|
384
|
+
}
|
|
385
|
+
],
|
|
386
|
+
"pendingRows": [
|
|
387
|
+
{
|
|
388
|
+
"id": "M21",
|
|
389
|
+
"name": "Test mode",
|
|
390
|
+
"profile": "desktop",
|
|
391
|
+
"owners": [],
|
|
392
|
+
"ownerPending": "No selected owner (D4 unratified); never fails."
|
|
393
|
+
},
|
|
394
|
+
{
|
|
395
|
+
"id": "M23",
|
|
396
|
+
"name": "Release-time switches",
|
|
397
|
+
"profile": "desktop",
|
|
398
|
+
"owners": [],
|
|
399
|
+
"ownerPending": "No selected owner (D4 unratified); never fails."
|
|
400
|
+
}
|
|
401
|
+
],
|
|
402
|
+
"amendments": {
|
|
403
|
+
"v2.1": {
|
|
404
|
+
"description": "TABLE1-AMENDMENT-v2.1 (draft): @rightkit/tauri-shell joins M1. Opt-in via --amendment v2.1.",
|
|
405
|
+
"rows": [
|
|
406
|
+
{
|
|
407
|
+
"id": "M1",
|
|
408
|
+
"profile": "desktop",
|
|
409
|
+
"owners": [
|
|
410
|
+
{
|
|
411
|
+
"name": "@rightkit/tauri-shell",
|
|
412
|
+
"ecosystem": "npm",
|
|
413
|
+
"min": "0.1.1"
|
|
414
|
+
}
|
|
415
|
+
]
|
|
416
|
+
}
|
|
417
|
+
]
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
}
|