@rightkit/release 0.4.0 → 0.5.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.
- package/README.md +59 -7
- package/adhoc-entitlements.mjs +8 -0
- package/adoption-evidence.mjs +650 -0
- package/advisory-exceptions.mjs +371 -0
- package/apple-profile-create.mjs +113 -10
- package/bin/darwin/rightkit-swap +0 -0
- package/bin/rightkit-gate.mjs +1079 -0
- package/binary-license-notices.mjs +161 -0
- package/cargo-license-notices.mjs +111 -0
- package/cli/right-release.mjs +39 -0
- package/deterministic-scans.mjs +966 -0
- package/development-signing.mjs +2 -1
- package/host-upload-refusal.mjs +90 -0
- package/local-publish.mjs +142 -19
- package/local-qualify.mjs +728 -0
- package/local-runtime.mjs +319 -0
- package/lock-graph.mjs +51 -0
- package/managed-cargo.mjs +4 -1
- package/ownership-approval.mjs +23 -6
- package/ownership-dependency-allowlist.json +2 -0
- package/ownership-mandatory-set.json +158 -68
- package/ownership-mandatory-set.mjs +82 -6
- package/package.json +6 -2
- package/pipeline-admission.mjs +375 -0
- package/pipeline-config.mjs +100 -0
- package/pipeline-generators.json +4 -0
- package/pipeline-generators.mjs +137 -0
- package/pipeline-receipts.mjs +302 -0
- package/pipeline-scan.mjs +285 -0
- package/pipeline-tools.mjs +171 -0
- package/production-mode.mjs +42 -0
- package/publication-gate.mjs +94 -32
- package/publish-cargo.mjs +24 -7
- package/publish-swift.mjs +12 -3
- package/qa-control-scan.mjs +4 -0
- package/release-config.mjs +330 -0
- package/release-switch-scan.mjs +44 -5
- package/release.mjs +14 -4
- package/rightkit-ownership.json +57 -0
- package/rightkit-sync.mjs +8 -0
- package/rightkit-versions.json +191 -131
- package/runtime-budget-classes.json +8 -0
- package/runtime-budget-crates.mjs +14 -0
- package/runtime-budgets.mjs +128 -31
- package/scan-digest.mjs +107 -0
- package/sign-qa-bundle.mjs +210 -0
- package/stage-sidecar.mjs +99 -15
- package/swap-helper-bundle.mjs +7 -3
- package/workflow-yaml.mjs +177 -0
- package/bin/darwin/rightkit-swap.sign.json +0 -6
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schema": 1,
|
|
3
3
|
"source": {
|
|
4
|
-
"table": "private-audits/TABLE1-MANDATORY.md:56-78 (M1-M23 requirement catalog)",
|
|
5
|
-
"versions": "
|
|
6
|
-
"note": "min =
|
|
4
|
+
"table": "private-audits/TABLE1-MANDATORY.md:56-78 (M1-M23 requirement catalog; M24-M25 added 2026-10-21, pending)",
|
|
5
|
+
"versions": "registry readback 2026-10-19 after the mandatory-set publish (#790): min = registryMax = the live version",
|
|
6
|
+
"note": "min = registryMax = the required version: the live registry version of the published mandatory set (#790). Raise both with each mandatory-set publish."
|
|
7
7
|
},
|
|
8
8
|
"defaultProfile": "desktop",
|
|
9
9
|
"defaultApps": [
|
|
@@ -37,18 +37,20 @@
|
|
|
37
37
|
{
|
|
38
38
|
"name": "rightkit-tauri-shell",
|
|
39
39
|
"ecosystem": "cargo",
|
|
40
|
-
"min": "0.
|
|
40
|
+
"min": "0.4.0",
|
|
41
|
+
"registryMax": "0.4.0"
|
|
41
42
|
},
|
|
42
43
|
{
|
|
43
44
|
"name": "rightkit-device",
|
|
44
45
|
"ecosystem": "cargo",
|
|
45
|
-
"min": "0.
|
|
46
|
+
"min": "0.3.0",
|
|
47
|
+
"registryMax": "0.3.0"
|
|
46
48
|
},
|
|
47
49
|
{
|
|
48
50
|
"name": "@rightkit/tauri",
|
|
49
51
|
"ecosystem": "npm",
|
|
50
|
-
"min": "0.2.
|
|
51
|
-
"registryMax": "0.2.
|
|
52
|
+
"min": "0.2.3",
|
|
53
|
+
"registryMax": "0.2.3"
|
|
52
54
|
}
|
|
53
55
|
]
|
|
54
56
|
},
|
|
@@ -60,19 +62,20 @@
|
|
|
60
62
|
{
|
|
61
63
|
"name": "@rightkit/react-shell",
|
|
62
64
|
"ecosystem": "npm",
|
|
63
|
-
"min": "0.
|
|
65
|
+
"min": "0.7.1",
|
|
66
|
+
"registryMax": "0.7.1"
|
|
64
67
|
},
|
|
65
68
|
{
|
|
66
69
|
"name": "@rightkit/platform-ui",
|
|
67
70
|
"ecosystem": "npm",
|
|
68
|
-
"min": "0.
|
|
69
|
-
"registryMax": "0.
|
|
71
|
+
"min": "0.4.0",
|
|
72
|
+
"registryMax": "0.4.0"
|
|
70
73
|
},
|
|
71
74
|
{
|
|
72
75
|
"name": "@rightkit/theme",
|
|
73
76
|
"ecosystem": "npm",
|
|
74
|
-
"min": "0.
|
|
75
|
-
"registryMax": "0.
|
|
77
|
+
"min": "0.3.1",
|
|
78
|
+
"registryMax": "0.3.1"
|
|
76
79
|
}
|
|
77
80
|
]
|
|
78
81
|
},
|
|
@@ -84,12 +87,14 @@
|
|
|
84
87
|
{
|
|
85
88
|
"name": "rightkit-job-queue",
|
|
86
89
|
"ecosystem": "cargo",
|
|
87
|
-
"min": "0.
|
|
90
|
+
"min": "0.4.0",
|
|
91
|
+
"registryMax": "0.4.0"
|
|
88
92
|
},
|
|
89
93
|
{
|
|
90
94
|
"name": "rightkit-child-process",
|
|
91
95
|
"ecosystem": "cargo",
|
|
92
|
-
"min": "0.
|
|
96
|
+
"min": "0.5.2",
|
|
97
|
+
"registryMax": "0.5.2"
|
|
93
98
|
}
|
|
94
99
|
]
|
|
95
100
|
},
|
|
@@ -101,12 +106,14 @@
|
|
|
101
106
|
{
|
|
102
107
|
"name": "rightkit-job-queue",
|
|
103
108
|
"ecosystem": "cargo",
|
|
104
|
-
"min": "0.
|
|
109
|
+
"min": "0.4.0",
|
|
110
|
+
"registryMax": "0.4.0"
|
|
105
111
|
},
|
|
106
112
|
{
|
|
107
113
|
"name": "rightkit-sidecar",
|
|
108
114
|
"ecosystem": "cargo",
|
|
109
|
-
"min": "0.
|
|
115
|
+
"min": "0.3.0",
|
|
116
|
+
"registryMax": "0.3.0"
|
|
110
117
|
}
|
|
111
118
|
]
|
|
112
119
|
},
|
|
@@ -118,7 +125,8 @@
|
|
|
118
125
|
{
|
|
119
126
|
"name": "rightkit-child-process",
|
|
120
127
|
"ecosystem": "cargo",
|
|
121
|
-
"min": "0.
|
|
128
|
+
"min": "0.5.2",
|
|
129
|
+
"registryMax": "0.5.2"
|
|
122
130
|
}
|
|
123
131
|
]
|
|
124
132
|
},
|
|
@@ -130,7 +138,8 @@
|
|
|
130
138
|
{
|
|
131
139
|
"name": "rightkit-daemon",
|
|
132
140
|
"ecosystem": "cargo",
|
|
133
|
-
"min": "0.
|
|
141
|
+
"min": "0.3.0",
|
|
142
|
+
"registryMax": "0.3.0"
|
|
134
143
|
}
|
|
135
144
|
]
|
|
136
145
|
},
|
|
@@ -142,7 +151,8 @@
|
|
|
142
151
|
{
|
|
143
152
|
"name": "rightkit-daemon",
|
|
144
153
|
"ecosystem": "cargo",
|
|
145
|
-
"min": "0.
|
|
154
|
+
"min": "0.3.0",
|
|
155
|
+
"registryMax": "0.3.0"
|
|
146
156
|
}
|
|
147
157
|
]
|
|
148
158
|
},
|
|
@@ -154,8 +164,8 @@
|
|
|
154
164
|
{
|
|
155
165
|
"name": "rightkit-fs",
|
|
156
166
|
"ecosystem": "cargo",
|
|
157
|
-
"min": "0.4.
|
|
158
|
-
"registryMax": "0.4.
|
|
167
|
+
"min": "0.4.4",
|
|
168
|
+
"registryMax": "0.4.4"
|
|
159
169
|
}
|
|
160
170
|
]
|
|
161
171
|
},
|
|
@@ -167,8 +177,8 @@
|
|
|
167
177
|
{
|
|
168
178
|
"name": "rightkit-db",
|
|
169
179
|
"ecosystem": "cargo",
|
|
170
|
-
"min": "0.
|
|
171
|
-
"registryMax": "0.
|
|
180
|
+
"min": "0.5.0",
|
|
181
|
+
"registryMax": "0.5.0"
|
|
172
182
|
}
|
|
173
183
|
]
|
|
174
184
|
},
|
|
@@ -180,13 +190,14 @@
|
|
|
180
190
|
{
|
|
181
191
|
"name": "rightkit-app-settings",
|
|
182
192
|
"ecosystem": "cargo",
|
|
183
|
-
"min": "0.2.
|
|
193
|
+
"min": "0.2.4",
|
|
194
|
+
"registryMax": "0.2.4"
|
|
184
195
|
},
|
|
185
196
|
{
|
|
186
197
|
"name": "@rightkit/settings-ui",
|
|
187
198
|
"ecosystem": "npm",
|
|
188
|
-
"min": "0.
|
|
189
|
-
"registryMax": "0.
|
|
199
|
+
"min": "0.7.0",
|
|
200
|
+
"registryMax": "0.7.0"
|
|
190
201
|
}
|
|
191
202
|
]
|
|
192
203
|
},
|
|
@@ -198,7 +209,8 @@
|
|
|
198
209
|
{
|
|
199
210
|
"name": "rightkit-credentials",
|
|
200
211
|
"ecosystem": "cargo",
|
|
201
|
-
"min": "0.2
|
|
212
|
+
"min": "0.4.2",
|
|
213
|
+
"registryMax": "0.4.2"
|
|
202
214
|
}
|
|
203
215
|
]
|
|
204
216
|
},
|
|
@@ -210,19 +222,20 @@
|
|
|
210
222
|
{
|
|
211
223
|
"name": "rightkit-license",
|
|
212
224
|
"ecosystem": "cargo",
|
|
213
|
-
"min": "0.2.
|
|
214
|
-
"registryMax": "0.2.
|
|
225
|
+
"min": "0.2.3",
|
|
226
|
+
"registryMax": "0.2.3"
|
|
215
227
|
},
|
|
216
228
|
{
|
|
217
229
|
"name": "rightkit-device",
|
|
218
230
|
"ecosystem": "cargo",
|
|
219
|
-
"min": "0.
|
|
231
|
+
"min": "0.3.0",
|
|
232
|
+
"registryMax": "0.3.0"
|
|
220
233
|
},
|
|
221
234
|
{
|
|
222
235
|
"name": "@rightkit/license",
|
|
223
236
|
"ecosystem": "npm",
|
|
224
|
-
"min": "0.2.
|
|
225
|
-
"registryMax": "0.2.
|
|
237
|
+
"min": "0.2.1",
|
|
238
|
+
"registryMax": "0.2.1"
|
|
226
239
|
}
|
|
227
240
|
]
|
|
228
241
|
},
|
|
@@ -234,8 +247,8 @@
|
|
|
234
247
|
{
|
|
235
248
|
"name": "rightkit-license",
|
|
236
249
|
"ecosystem": "cargo",
|
|
237
|
-
"min": "0.2.
|
|
238
|
-
"registryMax": "0.2.
|
|
250
|
+
"min": "0.2.3",
|
|
251
|
+
"registryMax": "0.2.3"
|
|
239
252
|
}
|
|
240
253
|
]
|
|
241
254
|
},
|
|
@@ -247,20 +260,20 @@
|
|
|
247
260
|
{
|
|
248
261
|
"name": "@rightkit/legal",
|
|
249
262
|
"ecosystem": "npm",
|
|
250
|
-
"min": "0.
|
|
251
|
-
"registryMax": "0.
|
|
263
|
+
"min": "0.6.1",
|
|
264
|
+
"registryMax": "0.6.1"
|
|
252
265
|
},
|
|
253
266
|
{
|
|
254
267
|
"name": "@rightkit/legal-ui",
|
|
255
268
|
"ecosystem": "npm",
|
|
256
|
-
"min": "0.
|
|
257
|
-
"registryMax": "0.
|
|
269
|
+
"min": "0.4.0",
|
|
270
|
+
"registryMax": "0.4.0"
|
|
258
271
|
},
|
|
259
272
|
{
|
|
260
273
|
"name": "@rightkit/onboarding",
|
|
261
274
|
"ecosystem": "npm",
|
|
262
|
-
"min": "0.
|
|
263
|
-
"registryMax": "0.
|
|
275
|
+
"min": "0.6.1",
|
|
276
|
+
"registryMax": "0.6.1"
|
|
264
277
|
}
|
|
265
278
|
]
|
|
266
279
|
},
|
|
@@ -272,14 +285,14 @@
|
|
|
272
285
|
{
|
|
273
286
|
"name": "rightkit-logs",
|
|
274
287
|
"ecosystem": "cargo",
|
|
275
|
-
"min": "0.3.
|
|
276
|
-
"registryMax": "0.3.
|
|
288
|
+
"min": "0.3.3",
|
|
289
|
+
"registryMax": "0.3.3"
|
|
277
290
|
},
|
|
278
291
|
{
|
|
279
292
|
"name": "@rightkit/logs",
|
|
280
293
|
"ecosystem": "npm",
|
|
281
|
-
"min": "0.1.
|
|
282
|
-
"registryMax": "0.1.
|
|
294
|
+
"min": "0.1.6",
|
|
295
|
+
"registryMax": "0.1.6"
|
|
283
296
|
}
|
|
284
297
|
]
|
|
285
298
|
},
|
|
@@ -291,8 +304,8 @@
|
|
|
291
304
|
{
|
|
292
305
|
"name": "rightkit-crash",
|
|
293
306
|
"ecosystem": "cargo",
|
|
294
|
-
"min": "0.
|
|
295
|
-
"registryMax": "0.3.
|
|
307
|
+
"min": "0.3.3",
|
|
308
|
+
"registryMax": "0.3.3"
|
|
296
309
|
}
|
|
297
310
|
]
|
|
298
311
|
},
|
|
@@ -304,8 +317,8 @@
|
|
|
304
317
|
{
|
|
305
318
|
"name": "rightkit-http",
|
|
306
319
|
"ecosystem": "cargo",
|
|
307
|
-
"min": "0.3.
|
|
308
|
-
"registryMax": "0.3.
|
|
320
|
+
"min": "0.3.6",
|
|
321
|
+
"registryMax": "0.3.6"
|
|
309
322
|
}
|
|
310
323
|
]
|
|
311
324
|
},
|
|
@@ -317,7 +330,8 @@
|
|
|
317
330
|
{
|
|
318
331
|
"name": "@rightkit/app-update",
|
|
319
332
|
"ecosystem": "npm",
|
|
320
|
-
"min": "0.
|
|
333
|
+
"min": "0.4.1",
|
|
334
|
+
"registryMax": "0.4.1"
|
|
321
335
|
}
|
|
322
336
|
]
|
|
323
337
|
},
|
|
@@ -329,8 +343,8 @@
|
|
|
329
343
|
{
|
|
330
344
|
"name": "@rightkit/release",
|
|
331
345
|
"ecosystem": "npm",
|
|
332
|
-
"min": "0.
|
|
333
|
-
"registryMax": "0.
|
|
346
|
+
"min": "0.4.1",
|
|
347
|
+
"registryMax": "0.4.1",
|
|
334
348
|
"allowDev": true
|
|
335
349
|
}
|
|
336
350
|
]
|
|
@@ -343,29 +357,22 @@
|
|
|
343
357
|
{
|
|
344
358
|
"name": "rightkit-qa",
|
|
345
359
|
"ecosystem": "cargo",
|
|
346
|
-
"min": "0.
|
|
347
|
-
"registryMax": "0.
|
|
348
|
-
"allowDev": true
|
|
349
|
-
},
|
|
350
|
-
{
|
|
351
|
-
"name": "rightkit-qa-driver",
|
|
352
|
-
"ecosystem": "cargo",
|
|
353
|
-
"min": "0.3.0",
|
|
354
|
-
"note": "deprecated shim; the QA owner is rightkit-qa with the `control` feature (Ember #280)",
|
|
360
|
+
"min": "0.7.0",
|
|
361
|
+
"registryMax": "0.7.0",
|
|
355
362
|
"allowDev": true
|
|
356
363
|
},
|
|
357
364
|
{
|
|
358
365
|
"name": "@rightkit/qa",
|
|
359
366
|
"ecosystem": "npm",
|
|
360
|
-
"min": "0.
|
|
361
|
-
"registryMax": "0.
|
|
367
|
+
"min": "0.5.1",
|
|
368
|
+
"registryMax": "0.5.1",
|
|
362
369
|
"allowDev": true
|
|
363
370
|
},
|
|
364
371
|
{
|
|
365
372
|
"name": "@rightkit/qa-chrome",
|
|
366
373
|
"ecosystem": "npm",
|
|
367
|
-
"min": "0.1.
|
|
368
|
-
"registryMax": "0.1.
|
|
374
|
+
"min": "0.1.8",
|
|
375
|
+
"registryMax": "0.1.8",
|
|
369
376
|
"allowDev": true
|
|
370
377
|
}
|
|
371
378
|
]
|
|
@@ -378,8 +385,8 @@
|
|
|
378
385
|
{
|
|
379
386
|
"name": "rightkit-agent-tools",
|
|
380
387
|
"ecosystem": "cargo",
|
|
381
|
-
"min": "0.
|
|
382
|
-
"registryMax": "0.
|
|
388
|
+
"min": "0.2.0",
|
|
389
|
+
"registryMax": "0.2.0"
|
|
383
390
|
}
|
|
384
391
|
]
|
|
385
392
|
}
|
|
@@ -390,16 +397,99 @@
|
|
|
390
397
|
"name": "Test mode",
|
|
391
398
|
"profile": "desktop",
|
|
392
399
|
"owners": [],
|
|
393
|
-
"ownerPending": "No selected owner (D4 unratified); never fails."
|
|
400
|
+
"ownerPending": "No selected owner (D4 unratified); never fails.",
|
|
401
|
+
"pendingOwners": [
|
|
402
|
+
{
|
|
403
|
+
"name": "rightkit-fs",
|
|
404
|
+
"ecosystem": "cargo",
|
|
405
|
+
"min": "0.4.4"
|
|
406
|
+
},
|
|
407
|
+
{
|
|
408
|
+
"name": "rightkit-daemon",
|
|
409
|
+
"ecosystem": "cargo",
|
|
410
|
+
"min": "0.3.0"
|
|
411
|
+
},
|
|
412
|
+
{
|
|
413
|
+
"name": "rightkit-qa",
|
|
414
|
+
"ecosystem": "cargo",
|
|
415
|
+
"min": "0.7.0",
|
|
416
|
+
"allowDev": true
|
|
417
|
+
}
|
|
418
|
+
]
|
|
394
419
|
},
|
|
395
420
|
{
|
|
396
421
|
"id": "M23",
|
|
397
422
|
"name": "Release-time switches",
|
|
398
423
|
"profile": "desktop",
|
|
399
424
|
"owners": [],
|
|
400
|
-
"ownerPending": "No selected owner (D4 unratified); never fails."
|
|
425
|
+
"ownerPending": "No selected owner (D4 unratified); never fails.",
|
|
426
|
+
"pendingOwners": [
|
|
427
|
+
{
|
|
428
|
+
"name": "@rightkit/release",
|
|
429
|
+
"ecosystem": "npm",
|
|
430
|
+
"min": "0.4.1",
|
|
431
|
+
"allowDev": true,
|
|
432
|
+
"registryMax": "0.4.1"
|
|
433
|
+
},
|
|
434
|
+
{
|
|
435
|
+
"name": "rightkit-daemon",
|
|
436
|
+
"ecosystem": "cargo",
|
|
437
|
+
"min": "0.3.0"
|
|
438
|
+
}
|
|
439
|
+
]
|
|
440
|
+
},
|
|
441
|
+
{
|
|
442
|
+
"id": "M24",
|
|
443
|
+
"name": "Issue tracker",
|
|
444
|
+
"profile": "all",
|
|
445
|
+
"owners": [],
|
|
446
|
+
"ownerPending": "@rightkit/issues-tracker 0.1.0 is not yet published (rightkit#875); never fails.",
|
|
447
|
+
"pendingOwners": [
|
|
448
|
+
{
|
|
449
|
+
"name": "@rightkit/issues-tracker",
|
|
450
|
+
"ecosystem": "npm",
|
|
451
|
+
"min": "0.1.0",
|
|
452
|
+
"allowDev": true
|
|
453
|
+
}
|
|
454
|
+
]
|
|
455
|
+
},
|
|
456
|
+
{
|
|
457
|
+
"id": "M25",
|
|
458
|
+
"name": "End-to-end journeys",
|
|
459
|
+
"profile": [
|
|
460
|
+
"desktop",
|
|
461
|
+
"apple"
|
|
462
|
+
],
|
|
463
|
+
"owners": [],
|
|
464
|
+
"ownerPending": "Journeys capability (E2E-TESTING-STANDARD, rightkit#878) is not built or published in rightkit-qa / @rightkit/qa; never fails.",
|
|
465
|
+
"pendingOwners": [
|
|
466
|
+
{
|
|
467
|
+
"name": "rightkit-qa",
|
|
468
|
+
"ecosystem": "cargo",
|
|
469
|
+
"min": "0.7.0",
|
|
470
|
+
"allowDev": true
|
|
471
|
+
},
|
|
472
|
+
{
|
|
473
|
+
"name": "@rightkit/qa",
|
|
474
|
+
"ecosystem": "npm",
|
|
475
|
+
"min": "0.5.1",
|
|
476
|
+
"allowDev": true
|
|
477
|
+
}
|
|
478
|
+
]
|
|
401
479
|
}
|
|
402
480
|
],
|
|
481
|
+
"applicabilityRecords": {
|
|
482
|
+
"M22": {
|
|
483
|
+
"name": "Agent surface",
|
|
484
|
+
"roles": [
|
|
485
|
+
"client",
|
|
486
|
+
"host",
|
|
487
|
+
"both",
|
|
488
|
+
"absent"
|
|
489
|
+
],
|
|
490
|
+
"note": "Declared in <app>/rightkit-mandatory.json as M22: { role, entrypoints }. Report-only: a record never removes or adds a violation; only notApplicable (with a reason) removes a row."
|
|
491
|
+
}
|
|
492
|
+
},
|
|
403
493
|
"appAmendments": {
|
|
404
494
|
"ember": {
|
|
405
495
|
"issue": "Orthic-Labs/rightkit#280",
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// right-release ownership-mandatory: Table 1 mandatory-owner-set check (plan task 5.1).
|
|
3
3
|
//
|
|
4
4
|
// This evaluates declarations only; it does not establish active target/features, lock resolution or production adoption.
|
|
5
|
-
// A registered app must declare every Table 1 owner (rows M1-M23) at or above the required version,
|
|
5
|
+
// A registered app must declare every Table 1 owner (enforced rows M1-M20, M22; pending rows M21, M23-M25 never fail) at or above the required version,
|
|
6
6
|
// from the registry. Report mode (default) prints per-app findings and exits 0; --enforce exits 1
|
|
7
7
|
// on any missing owner, below-required version, or path/git/patch override ("not-on-registry").
|
|
8
8
|
// Mode switching of the ownership gate itself (Report -> Enforce) is a separate step; this check
|
|
@@ -12,7 +12,15 @@
|
|
|
12
12
|
// [--amendment v2.1] [--enforce] [--json]
|
|
13
13
|
//
|
|
14
14
|
// App-side declaration (optional): <app>/rightkit-mandatory.json
|
|
15
|
-
// { "profile": "desktop", "notApplicable": { "M16": "reason text" }
|
|
15
|
+
// { "profile": "desktop", "notApplicable": { "M16": "reason text" },
|
|
16
|
+
// "M22": { "role": "client|host|both|absent", "entrypoints": ["src-tauri/src/agent.rs#register_tools"] } }
|
|
17
|
+
//
|
|
18
|
+
// PK17.scanner (report only, never enforcement): rows M21, M23, M24 and M25 stay `ownerPending` and never fail, but each lists its
|
|
19
|
+
// `pendingOwners` (M21: rightkit-fs, rightkit-daemon, rightkit-qa; M23: @rightkit/release, rightkit-daemon; M24: @rightkit/issues-tracker,
|
|
20
|
+
// unpublished; M25: rightkit-qa, @rightkit/qa, journeys capability unbuilt) and the report shows
|
|
21
|
+
// how each app's declarations measure up (`pending[].candidateOwners`, `enforced: false`). Moving those owners into `rows` and
|
|
22
|
+
// raising minimums is the separate activation step (PK17.activation). The M22 applicability record (PK15-2) is validated and
|
|
23
|
+
// reported under `applicability.M22`; an invalid or contradictory record is a `problem`, which never changes the exit code.
|
|
16
24
|
import { existsSync, readFileSync, readdirSync, realpathSync, statSync } from "node:fs";
|
|
17
25
|
import path from "node:path";
|
|
18
26
|
import { fileURLToPath } from "node:url";
|
|
@@ -231,9 +239,50 @@ function judge(req, facts) {
|
|
|
231
239
|
return { ...base, status: "ok", declared: declaredAt, evidence: [] };
|
|
232
240
|
}
|
|
233
241
|
|
|
242
|
+
// An entrypoint is `<relative file>`, optionally `#<symbol>` or `::<symbol>`; a bare token with no path separator or extension
|
|
243
|
+
// is a symbol or command name and is recorded unverified. A file part must stay inside the app root and exist.
|
|
244
|
+
const entrypointFile = (entry) => entry.split(/#|::/)[0];
|
|
245
|
+
const looksLikePath = (text) => /[\\/]/.test(text) || /\.[A-Za-z0-9]+$/.test(text);
|
|
246
|
+
|
|
247
|
+
/** Validate one applicability record (`M22: { role, entrypoints }`); report-only, never throws. */
|
|
248
|
+
export function validateApplicabilityRecord(id, raw, { spec, root }) {
|
|
249
|
+
const result = { row: id, status: "unrecorded", role: null, entrypoints: [], unverifiedEntrypoints: 0, problems: [] };
|
|
250
|
+
if (raw === undefined) return result;
|
|
251
|
+
const bad = (reason) => result.problems.push(`${id}: ${reason}`);
|
|
252
|
+
if (!raw || typeof raw !== "object" || Array.isArray(raw)) { bad("applicability record must be an object { role, entrypoints }"); result.status = "invalid"; return result; }
|
|
253
|
+
const extra = Object.keys(raw).filter((key) => key !== "role" && key !== "entrypoints");
|
|
254
|
+
if (extra.length) bad(`unknown applicability record key(s): ${extra.join(", ")}`);
|
|
255
|
+
const roles = spec?.roles ?? [];
|
|
256
|
+
if (!roles.includes(raw.role)) bad(`role must be one of ${roles.join("|")}, got ${JSON.stringify(raw.role)}`);
|
|
257
|
+
else result.role = raw.role;
|
|
258
|
+
if (!Array.isArray(raw.entrypoints)) bad("entrypoints must be an array");
|
|
259
|
+
else {
|
|
260
|
+
const seen = new Set();
|
|
261
|
+
for (const entry of raw.entrypoints) {
|
|
262
|
+
if (typeof entry !== "string" || !entry.trim()) { bad("every entrypoint must be a non-empty string"); continue; }
|
|
263
|
+
const text = entry.trim();
|
|
264
|
+
if (seen.has(text)) { bad(`entrypoint ${JSON.stringify(text)} is listed twice`); continue; }
|
|
265
|
+
seen.add(text);
|
|
266
|
+
result.entrypoints.push(text);
|
|
267
|
+
const file = entrypointFile(text);
|
|
268
|
+
if (!file) { bad(`entrypoint ${JSON.stringify(text)} names no file or symbol`); continue; }
|
|
269
|
+
if (!looksLikePath(file)) { result.unverifiedEntrypoints += 1; continue; }
|
|
270
|
+
const normalized = file.replace(/\\/g, "/");
|
|
271
|
+
if (path.isAbsolute(file) || /^[A-Za-z]:/.test(file) || normalized.split("/").includes("..")) { bad(`entrypoint ${JSON.stringify(text)} must be a relative path inside the app`); continue; }
|
|
272
|
+
let isFile = false;
|
|
273
|
+
try { isFile = statSync(path.join(root, normalized)).isFile(); } catch { /* missing */ }
|
|
274
|
+
if (!isFile) bad(`entrypoint ${JSON.stringify(text)}: file not found under the app root`);
|
|
275
|
+
}
|
|
276
|
+
if (result.role === "absent" && raw.entrypoints.length) bad("role absent must list no entrypoints");
|
|
277
|
+
if (result.role && result.role !== "absent" && !raw.entrypoints.length) bad(`role ${result.role} needs at least one real entrypoint`);
|
|
278
|
+
}
|
|
279
|
+
result.status = result.problems.length ? "invalid" : "recorded";
|
|
280
|
+
return result;
|
|
281
|
+
}
|
|
282
|
+
|
|
234
283
|
export function loadAppDeclaration(root, data) {
|
|
235
284
|
const file = path.join(root, data.appDeclarationFile);
|
|
236
|
-
if (!existsSync(file)) return { profile: data.defaultProfile, notApplicable: {}, problems: [] };
|
|
285
|
+
if (!existsSync(file)) return { profile: data.defaultProfile, notApplicable: {}, records: {}, problems: [] };
|
|
237
286
|
const problems = [];
|
|
238
287
|
let doc = {};
|
|
239
288
|
try { doc = JSON.parse(readFileSync(file, "utf8")); } catch (error) { problems.push(`${data.appDeclarationFile} unparseable: ${error.message}`); }
|
|
@@ -242,7 +291,14 @@ export function loadAppDeclaration(root, data) {
|
|
|
242
291
|
if (typeof reason === "string" && reason.trim().length >= 10) notApplicable[id] = reason.trim();
|
|
243
292
|
else problems.push(`${id}: N/A declaration needs a reason (>= 10 chars); ignored`);
|
|
244
293
|
}
|
|
245
|
-
|
|
294
|
+
const records = {};
|
|
295
|
+
for (const id of Object.keys(data.applicabilityRecords ?? {})) if (doc && typeof doc === "object" && Object.hasOwn(doc, id)) records[id] = doc[id];
|
|
296
|
+
return { profile: doc.profile ?? data.defaultProfile, notApplicable, records, problems };
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
// A pending row's `profile` is one profile name, a list of profile names, or "all" (repository-wide: every profile, including future ones).
|
|
300
|
+
export function pendingAppliesTo(row, active) {
|
|
301
|
+
return row.profile === "all" || (Array.isArray(row.profile) ? row.profile.includes(active) : row.profile === active);
|
|
246
302
|
}
|
|
247
303
|
|
|
248
304
|
export function checkApp(root, { data = loadData(), profile, amendments = [] } = {}) {
|
|
@@ -263,11 +319,29 @@ export function checkApp(root, { data = loadData(), profile, amendments = [] } =
|
|
|
263
319
|
}
|
|
264
320
|
const notApplicable = Object.entries(declaration.notApplicable).map(([id, reason]) => ({ row: id, reason }));
|
|
265
321
|
const applicable = rows.filter((r) => !(r.id in declaration.notApplicable));
|
|
266
|
-
const pending = data.pendingRows.filter((r) => r.profile === active).map((r) => ({ row: r.id, name: r.name, status: "owner-pending", note: r.ownerPending }));
|
|
267
322
|
const manifests = findManifests(root).map((f) => readManifest(f, root));
|
|
268
323
|
resolveWorkspaceInheritance(manifests);
|
|
269
324
|
for (const m of manifests) if (m.error) problems.push(`${m.rel}: ${m.error}`);
|
|
270
325
|
const facts = manifests.flatMap((m) => m.facts);
|
|
326
|
+
// Pending rows never fail. Their `pendingOwners` are judged like any owner and listed as `candidateOwners` (`enforced: false`)
|
|
327
|
+
// so the report shows what activation would find; the result is never counted in `violations`.
|
|
328
|
+
const pending = data.pendingRows.filter((r) => pendingAppliesTo(r, active)).map((r) => ({
|
|
329
|
+
row: r.id, name: r.name, status: "owner-pending", note: r.ownerPending,
|
|
330
|
+
candidateOwners: r.id in declaration.notApplicable ? [] : (r.pendingOwners ?? []).map((o) => {
|
|
331
|
+
const judged = judge({ ...o, rows: [r.id] }, facts);
|
|
332
|
+
return { owner: judged.owner, ecosystem: judged.ecosystem, rows: judged.rows, required: judged.required, declared: judged.declared, declarationStatus: judged.status, evidence: judged.evidence, enforced: false };
|
|
333
|
+
}),
|
|
334
|
+
}));
|
|
335
|
+
// Applicability records (PK15-2): validated and reported, never enforced.
|
|
336
|
+
const applicability = {};
|
|
337
|
+
for (const [id, spec] of Object.entries(data.applicabilityRecords ?? {})) {
|
|
338
|
+
const record = validateApplicabilityRecord(id, declaration.records[id], { spec, root });
|
|
339
|
+
applicability[id] = record;
|
|
340
|
+
problems.push(...record.problems);
|
|
341
|
+
const declaredNa = id in declaration.notApplicable;
|
|
342
|
+
if (record.role === "absent" && !declaredNa) problems.push(`${id}: applicability role is absent but notApplicable.${id} is not declared; the ${id} row still applies until the app declares it not applicable with a reason`);
|
|
343
|
+
if (record.role && record.role !== "absent" && declaredNa) problems.push(`${id}: notApplicable.${id} is declared but the applicability record says role ${record.role}`);
|
|
344
|
+
}
|
|
271
345
|
const owners = [...requirements(applicable).values()].map((req) => { const result = judge(req, facts); return { ...result, declarationStatus: result.status }; });
|
|
272
346
|
// A profile that is unknown, marked unratified, or has no rows checks nothing; an app may not select it, so it fails rather than passing empty.
|
|
273
347
|
const profileStatus = !data.profiles[active] ? "unknown-profile" : (data.profiles[active].ratified === false || !data.rows.some((r) => r.profile === active)) ? "unratified" : null;
|
|
@@ -276,7 +350,7 @@ export function checkApp(root, { data = loadData(), profile, amendments = [] } =
|
|
|
276
350
|
owners.push({ owner: `profile:${active}`, ecosystem: "profile", rows: [], required: "ratified profile", status: profileStatus, declared: null, evidence: ["an app may not select a profile that is not ratified"] });
|
|
277
351
|
}
|
|
278
352
|
const violations = owners.filter((o) => o.status !== "ok").length;
|
|
279
|
-
return { app: name, root, scanned: true, profile: active, manifests: manifests.length, owners, pending, notApplicable, problems, violations };
|
|
353
|
+
return { app: name, root, scanned: true, profile: active, manifests: manifests.length, owners, pending, applicability, notApplicable, problems, violations };
|
|
280
354
|
}
|
|
281
355
|
|
|
282
356
|
export function checkApps(roots, options = {}) {
|
|
@@ -292,6 +366,8 @@ export function renderText(report) {
|
|
|
292
366
|
out.push("", `${app.app} [${app.profile}] ${app.scanned ? `ok=${count("ok")} missing=${count("missing")} below-required=${count("below-required")} not-on-registry=${count("not-on-registry")}` : "UNSCANNED"}`
|
|
293
367
|
+ (app.pending.length ? ` pending=${app.pending.map((p) => p.row).join(",")}` : "") + (app.notApplicable.length ? ` n/a=${app.notApplicable.map((n) => n.row).join(",")}` : ""));
|
|
294
368
|
for (const o of app.owners.filter((x) => x.status !== "ok")) out.push(` ${o.status.padEnd(15)} ${o.owner} (${o.rows.join(",")}) requires ${o.required}${o.declared ? `, declared ${o.declared}` : ""}${o.evidence.length ? ` — ${o.evidence.join("; ")}` : ""}`);
|
|
369
|
+
for (const p of app.pending) for (const c of p.candidateOwners ?? []) if (c.declarationStatus !== "ok") out.push(` not-enforced ${p.row} ${c.declarationStatus} ${c.owner} requires ${c.required}${c.declared ? `, declared ${c.declared}` : ""} (owner-pending: report only)`);
|
|
370
|
+
for (const record of Object.values(app.applicability ?? {})) if (record.status !== "unrecorded") out.push(` applicability ${record.row} ${record.status}${record.role ? ` role=${record.role}` : ""} entrypoints=${record.entrypoints.length}${record.unverifiedEntrypoints ? ` (${record.unverifiedEntrypoints} unverified symbol)` : ""}`);
|
|
295
371
|
for (const n of app.notApplicable) out.push(` n/a ${n.row}: ${n.reason}`);
|
|
296
372
|
for (const p of app.problems) out.push(` problem ${p}`);
|
|
297
373
|
}
|
package/package.json
CHANGED
|
@@ -1,17 +1,21 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rightkit/release",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"description": "Portable release CLI/SDK with fail-closed public GitHub Releases and private R2 + RightApps distribution.",
|
|
5
5
|
"license": "MIT OR Apache-2.0",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"bin": {
|
|
8
|
-
"right-release": "cli/right-release.mjs"
|
|
8
|
+
"right-release": "cli/right-release.mjs",
|
|
9
|
+
"rightkit-gate": "bin/rightkit-gate.mjs"
|
|
9
10
|
},
|
|
10
11
|
"rightkit": {
|
|
11
12
|
"publishCheck": {
|
|
12
13
|
"binSmoke": {
|
|
13
14
|
"right-release": [
|
|
14
15
|
"--version"
|
|
16
|
+
],
|
|
17
|
+
"rightkit-gate": [
|
|
18
|
+
"--version"
|
|
15
19
|
]
|
|
16
20
|
}
|
|
17
21
|
}
|