@rightkit/release 0.6.15 → 0.6.20
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 +7 -3
- package/admission-host.mjs +9 -5
- package/app-closure.mjs +9 -3
- package/bin/darwin/rightkit-swap +0 -0
- package/bin/rightkit-gate.mjs +469 -102
- package/bin/rightkit-linux-setup.mjs +15 -0
- package/broker-admission.mjs +184 -0
- package/broker-wire.mjs +15 -3
- package/build-launch.mjs +4 -1
- package/build-ownership.mjs +125 -36
- package/build-release.mjs +39 -7
- package/cargo-contract.mjs +4 -1
- package/cargo-guard.mjs +25 -5
- package/cargo-target-shim.mjs +56 -7
- package/clippy-route.mjs +8 -7
- package/crate-graph.mjs +5 -1
- package/credential-provider.mjs +174 -0
- package/deterministic-scans.mjs +256 -41
- package/development.mjs +8 -0
- package/disk-policy.mjs +2 -2
- package/gate-executor.mjs +5 -3
- package/gate-stages.mjs +34 -3
- package/gradle-lock.mjs +206 -0
- package/heavy-command.mjs +33 -2
- package/linux-artifacts.mjs +2 -1
- package/linux-setup.mjs +106 -0
- package/local-publish.mjs +21 -10
- package/local-qualify.mjs +9 -3
- package/managed-cargo.mjs +54 -18
- package/npm-license-notices.mjs +49 -1
- package/ownership-lockfiles.mjs +27 -4
- package/ownership.mjs +5 -1
- package/package.json +17 -11
- package/protected-credentials.mjs +13 -5
- package/publication-gate.mjs +9 -4
- package/python-lock.mjs +209 -0
- package/qa-admission-policy.json +32 -0
- package/qa-layout.mjs +229 -0
- package/qa-runner.mjs +156 -0
- package/release-artifact-path.mjs +29 -3
- package/release-config.mjs +1 -1
- package/release-qa-command.mjs +58 -8
- package/release-qa-policy.mjs +5 -3
- package/release-source-identity.mjs +1 -0
- package/release.mjs +10 -2
- package/rightkit-ownership.json +1465 -79
- package/rightkit-registry-resolver.mjs +7 -3
- package/rightkit-versions.json +173 -36
- package/runtime-budget-classes.json +4 -0
- package/runtime-budgets.mjs +5 -1
- package/shell-contract.mjs +1 -1
- package/snapshot-broker.mjs +107 -9
- package/snapshot-check.mjs +2 -0
- package/snapshot-request.mjs +20 -3
- package/snapshot.mjs +11 -4
- package/stage-commands.mjs +2 -1
- package/stage-ledger.mjs +15 -0
- package/stage-sidecar.mjs +17 -3
- package/suite-signing.mjs +40 -4
- package/swift-lock.mjs +334 -0
- package/test-command.mjs +13 -3
- package/tool-build.mjs +156 -0
- package/unit-gate.mjs +9 -2
- package/windows-identity-plan.mjs +119 -0
- package/windows-identity.mjs +136 -0
|
@@ -25,10 +25,14 @@
|
|
|
25
25
|
import { createHash } from "node:crypto";
|
|
26
26
|
import { existsSync, mkdirSync, readFileSync, readdirSync, renameSync, writeFileSync } from "node:fs";
|
|
27
27
|
import path from "node:path";
|
|
28
|
-
import {
|
|
28
|
+
import { createRequire } from "node:module";
|
|
29
|
+
// smol-toml loads on first parse, not at import: CI jobs whose closure reaches this module without installing
|
|
30
|
+
// @rightkit/release dependencies (publish.yml crates pack, bind) never parse TOML here (rightkit#1341).
|
|
31
|
+
let smolTomlParse;
|
|
32
|
+
const parseToml = (text) => (smolTomlParse ??= createRequire(import.meta.url)("smol-toml").parse)(text);
|
|
29
33
|
import { isExcludedScanDirectory } from "./cargo-contract.mjs";
|
|
30
34
|
import { resolveSharedCacheRoot } from "./cache-policy.mjs";
|
|
31
|
-
import { parsePnpmYaml } from "./ownership-lockfiles.mjs";
|
|
35
|
+
import { parsePnpmYaml, pnpmProjectDocument } from "./ownership-lockfiles.mjs";
|
|
32
36
|
import { UPDATE_COMMAND } from "./outdated-command.mjs";
|
|
33
37
|
import { compareVersions } from "./rightkit-sync.mjs";
|
|
34
38
|
|
|
@@ -132,7 +136,7 @@ function cargoLockEntries(file) {
|
|
|
132
136
|
|
|
133
137
|
function pnpmLockEntries(file) {
|
|
134
138
|
let lock;
|
|
135
|
-
try { lock = parsePnpmYaml(readFileSync(file, "utf8")); } catch (error) { throw new RightKitRegistryError("bad-lock", `${file} is not a readable pnpm-lock.yaml: ${error.message}`); }
|
|
139
|
+
try { lock = parsePnpmYaml(pnpmProjectDocument(readFileSync(file, "utf8"))); } catch (error) { throw new RightKitRegistryError("bad-lock", `${file} is not a readable pnpm-lock.yaml: ${error.message}`); }
|
|
136
140
|
const entries = [];
|
|
137
141
|
for (const [key, meta] of Object.entries(lock.packages ?? {})) {
|
|
138
142
|
const match = /^(@[^/]+\/[^@]+|[^@]+)@(.+)$/.exec(String(key).replace(/^\//, ""));
|
package/rightkit-versions.json
CHANGED
|
@@ -13,17 +13,34 @@
|
|
|
13
13
|
"@rightkit/updates": "0.2.3"
|
|
14
14
|
},
|
|
15
15
|
"stagedNpm": {
|
|
16
|
+
"@rightkit/agent-ui-approvals": "0.1.0",
|
|
17
|
+
"@rightkit/agent-ui-components": "0.1.0",
|
|
18
|
+
"@rightkit/agent-ui-core": "0.1.0",
|
|
19
|
+
"@rightkit/agent-ui-hooks": "0.1.0",
|
|
20
|
+
"@rightkit/agent-ui-settings": "0.1.0",
|
|
21
|
+
"@rightkit/agent-ui-web": "0.1.0",
|
|
22
|
+
"@rightkit/agent-ui-workbench": "0.1.0",
|
|
16
23
|
"@rightkit/app-update": "0.4.2",
|
|
17
24
|
"@rightkit/ax": "0.3.2",
|
|
18
25
|
"@rightkit/ci": "0.3.2",
|
|
26
|
+
"@rightkit/config": "0.1.0",
|
|
27
|
+
"@rightkit/dictation-ui": "0.1.0",
|
|
19
28
|
"@rightkit/doc-render": "0.2.1",
|
|
29
|
+
"@rightkit/document-core": "0.1.0",
|
|
30
|
+
"@rightkit/document-workspace": "0.1.0",
|
|
31
|
+
"@rightkit/docx-editor": "0.1.0",
|
|
20
32
|
"@rightkit/hooks": "0.1.2",
|
|
33
|
+
"@rightkit/html-editor": "0.1.0",
|
|
21
34
|
"@rightkit/i18n": "0.2.0",
|
|
22
35
|
"@rightkit/issues-tracker": "0.1.0",
|
|
23
36
|
"@rightkit/legal": "0.6.3",
|
|
24
37
|
"@rightkit/legal-ui": "0.4.1",
|
|
38
|
+
"@rightkit/library-ui": "0.1.0",
|
|
25
39
|
"@rightkit/license": "0.3.0",
|
|
26
40
|
"@rightkit/logs": "0.1.6",
|
|
41
|
+
"@rightkit/mail-ui": "0.1.0",
|
|
42
|
+
"@rightkit/markdown-editor": "0.1.0",
|
|
43
|
+
"@rightkit/media-gen-ui": "0.1.0",
|
|
27
44
|
"@rightkit/media-ui": "0.3.4",
|
|
28
45
|
"@rightkit/onboarding": "0.6.3",
|
|
29
46
|
"@rightkit/outdated": "0.3.0",
|
|
@@ -32,11 +49,17 @@
|
|
|
32
49
|
"@rightkit/qa": "0.6.2",
|
|
33
50
|
"@rightkit/qa-chrome": "0.1.12",
|
|
34
51
|
"@rightkit/react-shell": "0.7.2",
|
|
35
|
-
"@rightkit/release": "0.6.
|
|
52
|
+
"@rightkit/release": "0.6.20",
|
|
36
53
|
"@rightkit/settings-ui": "0.7.0",
|
|
54
|
+
"@rightkit/social-ui": "0.1.0",
|
|
55
|
+
"@rightkit/system-ui": "0.1.0",
|
|
37
56
|
"@rightkit/tauri": "0.3.0",
|
|
38
57
|
"@rightkit/tauri-shell": "0.1.3",
|
|
39
|
-
"@rightkit/
|
|
58
|
+
"@rightkit/terminal-ui": "0.1.0",
|
|
59
|
+
"@rightkit/theme": "0.3.1",
|
|
60
|
+
"@rightkit/video-ui": "0.1.0",
|
|
61
|
+
"@rightkit/waitlist-worker": "0.1.0",
|
|
62
|
+
"@rightkit/workspace-ui": "0.1.0"
|
|
40
63
|
},
|
|
41
64
|
"legacyNpm": {
|
|
42
65
|
"@rightkit/app-shell": [
|
|
@@ -455,73 +478,176 @@
|
|
|
455
478
|
"rightkit-tauri": "0.1.0"
|
|
456
479
|
},
|
|
457
480
|
"stagedCargo": {
|
|
458
|
-
"rightkit-
|
|
459
|
-
"rightkit-
|
|
481
|
+
"rightkit-adapt": "0.1.0",
|
|
482
|
+
"rightkit-adapt-taste": "0.1.0",
|
|
483
|
+
"rightkit-agent-demo": "0.1.0",
|
|
484
|
+
"rightkit-agent-engine-api-integrations": "0.1.0",
|
|
485
|
+
"rightkit-agent-engine-api-platform": "0.1.0",
|
|
486
|
+
"rightkit-agent-engine-api-sessions": "0.1.0",
|
|
487
|
+
"rightkit-agent-engine-api-workflows": "0.1.0",
|
|
488
|
+
"rightkit-agent-engine-attention": "0.1.0",
|
|
489
|
+
"rightkit-agent-engine-cli": "0.1.0",
|
|
490
|
+
"rightkit-agent-engine-core": "0.1.0",
|
|
491
|
+
"rightkit-agent-engine-history": "0.1.0",
|
|
492
|
+
"rightkit-agent-engine-mobile-runtime": "0.1.0",
|
|
493
|
+
"rightkit-agent-engine-protocol": "0.1.0",
|
|
494
|
+
"rightkit-agent-engine-runtime-middleware": "0.1.0",
|
|
495
|
+
"rightkit-agent-engine-runtime-resources": "0.1.0",
|
|
496
|
+
"rightkit-agent-engine-storage": "0.1.0",
|
|
497
|
+
"rightkit-agent-engine-tasks": "0.1.0",
|
|
498
|
+
"rightkit-agent-gateway": "0.1.0",
|
|
499
|
+
"rightkit-agent-host-traits": "0.1.0",
|
|
500
|
+
"rightkit-agent-orchestration": "0.1.1",
|
|
501
|
+
"rightkit-agent-orchestration-handoff": "0.1.0",
|
|
502
|
+
"rightkit-agent-plugins": "0.1.0",
|
|
503
|
+
"rightkit-agent-policy": "0.1.0",
|
|
504
|
+
"rightkit-agent-recipes": "0.1.0",
|
|
505
|
+
"rightkit-agent-tools": "0.3.1",
|
|
506
|
+
"rightkit-agent-transcript": "0.1.0",
|
|
507
|
+
"rightkit-agents": "0.2.1",
|
|
508
|
+
"rightkit-ai-accounts": "0.1.0",
|
|
460
509
|
"rightkit-android": "0.3.0",
|
|
461
|
-
"rightkit-app-
|
|
462
|
-
"rightkit-
|
|
510
|
+
"rightkit-app-host": "0.1.0",
|
|
511
|
+
"rightkit-app-manager": "0.1.0",
|
|
512
|
+
"rightkit-app-settings": "0.3.1",
|
|
513
|
+
"rightkit-apple-ops": "0.1.1",
|
|
514
|
+
"rightkit-approvals": "0.1.0",
|
|
515
|
+
"rightkit-asr": "0.3.4",
|
|
463
516
|
"rightkit-audio": "0.3.1",
|
|
464
|
-
"rightkit-
|
|
517
|
+
"rightkit-autoedit": "0.1.1",
|
|
518
|
+
"rightkit-automation": "0.6.4",
|
|
519
|
+
"rightkit-bench": "0.1.0",
|
|
520
|
+
"rightkit-bot-messaging": "0.1.0",
|
|
465
521
|
"rightkit-browser": "0.3.7",
|
|
466
522
|
"rightkit-cache": "0.2.3",
|
|
523
|
+
"rightkit-captions": "0.1.0",
|
|
467
524
|
"rightkit-channel-memory": "0.2.2",
|
|
525
|
+
"rightkit-chat-bridge": "0.1.0",
|
|
468
526
|
"rightkit-child-process": "0.5.7",
|
|
469
|
-
"rightkit-
|
|
527
|
+
"rightkit-code-audit-provider-sdk": "0.1.0",
|
|
528
|
+
"rightkit-color": "0.1.0",
|
|
529
|
+
"rightkit-compose": "0.2.2",
|
|
530
|
+
"rightkit-compositor": "0.1.0",
|
|
531
|
+
"rightkit-content-plan": "0.1.1",
|
|
532
|
+
"rightkit-content-proof": "0.1.0",
|
|
533
|
+
"rightkit-context": "0.1.0",
|
|
534
|
+
"rightkit-context-client": "0.1.0",
|
|
535
|
+
"rightkit-context-core": "0.1.0",
|
|
536
|
+
"rightkit-context-federation": "0.1.0",
|
|
537
|
+
"rightkit-context-protocol": "0.1.0",
|
|
538
|
+
"rightkit-context-provider-sdk": "0.1.0",
|
|
539
|
+
"rightkit-context-runtime": "0.1.0",
|
|
470
540
|
"rightkit-contracts": "0.1.8",
|
|
471
541
|
"rightkit-crash": "0.3.6",
|
|
472
|
-
"rightkit-credentials": "0.4.
|
|
542
|
+
"rightkit-credentials": "0.4.3",
|
|
473
543
|
"rightkit-crypto": "0.1.0",
|
|
474
|
-
"rightkit-daemon": "0.5.
|
|
544
|
+
"rightkit-daemon": "0.5.1",
|
|
475
545
|
"rightkit-db": "0.5.3",
|
|
476
546
|
"rightkit-device": "0.4.0",
|
|
547
|
+
"rightkit-device-link-types": "0.1.0",
|
|
548
|
+
"rightkit-dictation-app-runtime": "0.1.0",
|
|
549
|
+
"rightkit-dictation-command-host": "0.1.0",
|
|
550
|
+
"rightkit-dictation-core": "0.2.0",
|
|
551
|
+
"rightkit-dictation-engine": "0.1.0",
|
|
552
|
+
"rightkit-dictation-inference": "0.1.0",
|
|
553
|
+
"rightkit-dictation-models": "0.1.0",
|
|
554
|
+
"rightkit-dictation-runtime": "0.1.0",
|
|
555
|
+
"rightkit-dictation-telemetry": "0.1.0",
|
|
556
|
+
"rightkit-dictation-text-pipeline": "0.1.0",
|
|
557
|
+
"rightkit-disk-cleanup": "0.1.0",
|
|
477
558
|
"rightkit-docs": "0.1.3",
|
|
559
|
+
"rightkit-doctor": "0.1.0",
|
|
560
|
+
"rightkit-document-workspace": "0.1.1",
|
|
478
561
|
"rightkit-embed": "0.6.2",
|
|
479
|
-
"rightkit-
|
|
562
|
+
"rightkit-engine-host": "0.1.1",
|
|
563
|
+
"rightkit-evidence": "0.1.0",
|
|
564
|
+
"rightkit-evidence-contracts": "0.1.0",
|
|
565
|
+
"rightkit-evidence-decisions": "0.1.0",
|
|
566
|
+
"rightkit-evidence-effects": "0.1.0",
|
|
567
|
+
"rightkit-evidence-governance": "0.1.0",
|
|
568
|
+
"rightkit-evidence-report": "0.1.0",
|
|
569
|
+
"rightkit-ffmpeg": "0.2.13",
|
|
480
570
|
"rightkit-file-watch": "0.4.2",
|
|
481
|
-
"rightkit-fs": "0.4.
|
|
571
|
+
"rightkit-fs": "0.4.9",
|
|
482
572
|
"rightkit-fsindex": "0.6.0",
|
|
573
|
+
"rightkit-github": "0.1.1",
|
|
574
|
+
"rightkit-google-apis": "0.1.0",
|
|
483
575
|
"rightkit-google-identity": "0.2.0",
|
|
484
|
-
"rightkit-hooks": "0.2.
|
|
576
|
+
"rightkit-hooks": "0.2.1",
|
|
485
577
|
"rightkit-hotkeys": "0.1.2",
|
|
486
578
|
"rightkit-http": "0.3.9",
|
|
487
579
|
"rightkit-identity": "0.1.0",
|
|
488
580
|
"rightkit-job-queue": "0.5.1",
|
|
581
|
+
"rightkit-library": "0.1.1",
|
|
489
582
|
"rightkit-license": "0.2.6",
|
|
490
|
-
"rightkit-llm": "0.3.
|
|
491
|
-
"rightkit-
|
|
492
|
-
"rightkit-
|
|
493
|
-
"rightkit-
|
|
494
|
-
"rightkit-
|
|
583
|
+
"rightkit-llm": "0.3.2",
|
|
584
|
+
"rightkit-local-gen": "0.1.0",
|
|
585
|
+
"rightkit-logs": "0.3.7",
|
|
586
|
+
"rightkit-mail": "0.1.1",
|
|
587
|
+
"rightkit-mcp": "0.7.2",
|
|
588
|
+
"rightkit-media-fetch": "0.1.1",
|
|
589
|
+
"rightkit-media-gen": "0.1.0",
|
|
590
|
+
"rightkit-media-pipeline": "0.1.0",
|
|
591
|
+
"rightkit-memory": "0.1.0",
|
|
592
|
+
"rightkit-memory-core": "0.1.0",
|
|
593
|
+
"rightkit-memory-store": "0.1.0",
|
|
594
|
+
"rightkit-mesh": "0.1.1",
|
|
595
|
+
"rightkit-models": "0.5.3",
|
|
596
|
+
"rightkit-motion": "0.2.1",
|
|
495
597
|
"rightkit-oauth": "0.10.0",
|
|
496
598
|
"rightkit-ocr": "0.2.3",
|
|
497
|
-
"rightkit-onnx": "0.2.
|
|
599
|
+
"rightkit-onnx": "0.2.9",
|
|
498
600
|
"rightkit-overlay": "0.2.0",
|
|
499
601
|
"rightkit-overlay-win": "0.1.0",
|
|
500
|
-
"rightkit-
|
|
602
|
+
"rightkit-owner-approvals": "0.1.0",
|
|
603
|
+
"rightkit-ownership": "0.4.4",
|
|
501
604
|
"rightkit-pdf": "0.3.4",
|
|
605
|
+
"rightkit-pipeline": "0.1.1",
|
|
502
606
|
"rightkit-platform-rules": "0.1.0",
|
|
503
607
|
"rightkit-playback": "0.3.0",
|
|
504
|
-
"rightkit-
|
|
608
|
+
"rightkit-policy-rules": "0.1.0",
|
|
609
|
+
"rightkit-privileged-helper": "0.1.0",
|
|
610
|
+
"rightkit-qa": "0.10.1",
|
|
505
611
|
"rightkit-qa-driver": "0.7.0",
|
|
506
612
|
"rightkit-record": "0.3.3",
|
|
507
|
-
"rightkit-
|
|
508
|
-
"rightkit-
|
|
613
|
+
"rightkit-reframe": "0.1.0",
|
|
614
|
+
"rightkit-remote-compute": "0.1.0",
|
|
615
|
+
"rightkit-remote-gateway": "0.1.0",
|
|
616
|
+
"rightkit-repo-graph": "0.1.0",
|
|
617
|
+
"rightkit-repo-graph-grammars": "0.1.0",
|
|
618
|
+
"rightkit-research": "0.1.1",
|
|
619
|
+
"rightkit-review": "0.4.1",
|
|
620
|
+
"rightkit-sandbox": "0.6.2",
|
|
621
|
+
"rightkit-scheduler": "0.1.0",
|
|
509
622
|
"rightkit-search": "0.4.1",
|
|
510
623
|
"rightkit-send": "0.3.0",
|
|
624
|
+
"rightkit-shorts": "0.1.1",
|
|
511
625
|
"rightkit-sidecar": "0.3.0",
|
|
626
|
+
"rightkit-social-analytics": "0.1.1",
|
|
627
|
+
"rightkit-social-inbox": "0.1.1",
|
|
628
|
+
"rightkit-social-publish": "0.1.1",
|
|
512
629
|
"rightkit-speech-client": "0.4.1",
|
|
513
630
|
"rightkit-spend": "0.2.0",
|
|
514
631
|
"rightkit-sync": "0.2.2",
|
|
632
|
+
"rightkit-system-monitor": "0.1.0",
|
|
515
633
|
"rightkit-tauri-shell": "0.7.0",
|
|
516
|
-
"rightkit-
|
|
634
|
+
"rightkit-terminal-ui": "0.1.0",
|
|
635
|
+
"rightkit-text-polish": "0.1.0",
|
|
636
|
+
"rightkit-time": "0.1.1",
|
|
637
|
+
"rightkit-timeline": "0.1.0",
|
|
517
638
|
"rightkit-transcript": "0.4.0",
|
|
639
|
+
"rightkit-transcript-library": "0.1.0",
|
|
518
640
|
"rightkit-tts": "0.2.3",
|
|
519
641
|
"rightkit-tts-qwen": "0.2.7",
|
|
520
642
|
"rightkit-tts-qwen-sys": "0.1.2",
|
|
521
643
|
"rightkit-typeset": "0.1.0",
|
|
522
644
|
"rightkit-vad": "0.1.2",
|
|
523
645
|
"rightkit-vault": "0.2.0",
|
|
524
|
-
"rightkit-
|
|
646
|
+
"rightkit-video-project": "0.1.0",
|
|
647
|
+
"rightkit-voice-commands": "0.1.0",
|
|
648
|
+
"rightkit-web-extract": "0.1.1",
|
|
649
|
+
"rightkit-web-session": "0.1.0",
|
|
650
|
+
"rightkit-workflow": "0.2.1"
|
|
525
651
|
},
|
|
526
652
|
"swift": {
|
|
527
653
|
"rightkit-swift": {
|
|
@@ -801,7 +927,8 @@
|
|
|
801
927
|
"0.3.5",
|
|
802
928
|
"0.4.0",
|
|
803
929
|
"0.5.0",
|
|
804
|
-
"0.6.0"
|
|
930
|
+
"0.6.0",
|
|
931
|
+
"0.6.1"
|
|
805
932
|
],
|
|
806
933
|
"rightkit-shell": [
|
|
807
934
|
"0.1.0",
|
|
@@ -860,7 +987,8 @@
|
|
|
860
987
|
"0.4.3",
|
|
861
988
|
"0.4.4",
|
|
862
989
|
"0.4.5",
|
|
863
|
-
"0.4.6"
|
|
990
|
+
"0.4.6",
|
|
991
|
+
"0.4.7"
|
|
864
992
|
],
|
|
865
993
|
"rightkit-service": [
|
|
866
994
|
"0.1.0",
|
|
@@ -959,7 +1087,8 @@
|
|
|
959
1087
|
"0.1.0",
|
|
960
1088
|
"0.2.0",
|
|
961
1089
|
"0.2.1",
|
|
962
|
-
"0.3.0"
|
|
1090
|
+
"0.3.0",
|
|
1091
|
+
"0.3.1"
|
|
963
1092
|
],
|
|
964
1093
|
"rightkit-daemon": [
|
|
965
1094
|
"0.2.0",
|
|
@@ -990,7 +1119,8 @@
|
|
|
990
1119
|
"0.1.3",
|
|
991
1120
|
"0.1.4",
|
|
992
1121
|
"0.1.5",
|
|
993
|
-
"0.2.0"
|
|
1122
|
+
"0.2.0",
|
|
1123
|
+
"0.3.0"
|
|
994
1124
|
],
|
|
995
1125
|
"rightkit-automation": [
|
|
996
1126
|
"0.3.0",
|
|
@@ -998,7 +1128,8 @@
|
|
|
998
1128
|
"0.4.1",
|
|
999
1129
|
"0.4.4",
|
|
1000
1130
|
"0.5.0",
|
|
1001
|
-
"0.6.0"
|
|
1131
|
+
"0.6.0",
|
|
1132
|
+
"0.6.1"
|
|
1002
1133
|
],
|
|
1003
1134
|
"rightkit-child-process": [
|
|
1004
1135
|
"0.4.0",
|
|
@@ -1021,7 +1152,8 @@
|
|
|
1021
1152
|
"0.2.1"
|
|
1022
1153
|
],
|
|
1023
1154
|
"rightkit-compose": [
|
|
1024
|
-
"0.1.0"
|
|
1155
|
+
"0.1.0",
|
|
1156
|
+
"0.2.0"
|
|
1025
1157
|
],
|
|
1026
1158
|
"rightkit-contracts": [
|
|
1027
1159
|
"0.1.5",
|
|
@@ -1042,7 +1174,8 @@
|
|
|
1042
1174
|
"rightkit-app-settings": [
|
|
1043
1175
|
"0.2.0",
|
|
1044
1176
|
"0.2.3",
|
|
1045
|
-
"0.2.4"
|
|
1177
|
+
"0.2.4",
|
|
1178
|
+
"0.3.0"
|
|
1046
1179
|
],
|
|
1047
1180
|
"rightkit-ffmpeg": [
|
|
1048
1181
|
"0.2.6",
|
|
@@ -1061,13 +1194,16 @@
|
|
|
1061
1194
|
"0.2.1",
|
|
1062
1195
|
"0.3.0",
|
|
1063
1196
|
"0.4.0",
|
|
1064
|
-
"0.4.1"
|
|
1197
|
+
"0.4.1",
|
|
1198
|
+
"0.4.2"
|
|
1065
1199
|
],
|
|
1066
1200
|
"rightkit-review": [
|
|
1067
|
-
"0.2.0"
|
|
1201
|
+
"0.2.0",
|
|
1202
|
+
"0.4.0"
|
|
1068
1203
|
],
|
|
1069
1204
|
"rightkit-workflow": [
|
|
1070
|
-
"0.1.0"
|
|
1205
|
+
"0.1.0",
|
|
1206
|
+
"0.2.0"
|
|
1071
1207
|
],
|
|
1072
1208
|
"rightkit-device": [
|
|
1073
1209
|
"0.1.3",
|
|
@@ -1127,7 +1263,8 @@
|
|
|
1127
1263
|
"0.1.0"
|
|
1128
1264
|
],
|
|
1129
1265
|
"rightkit-motion": [
|
|
1130
|
-
"0.1.0"
|
|
1266
|
+
"0.1.0",
|
|
1267
|
+
"0.2.0"
|
|
1131
1268
|
],
|
|
1132
1269
|
"rightkit-spend": [
|
|
1133
1270
|
"0.1.1"
|
package/runtime-budgets.mjs
CHANGED
|
@@ -58,7 +58,11 @@ import os from "node:os";
|
|
|
58
58
|
import path from "node:path";
|
|
59
59
|
import { fileURLToPath } from "node:url";
|
|
60
60
|
import { spawnSync } from "./background-process.mjs";
|
|
61
|
-
import {
|
|
61
|
+
import { createRequire } from "node:module";
|
|
62
|
+
// smol-toml loads on first parse, not at import: CI jobs whose closure reaches this module without installing
|
|
63
|
+
// @rightkit/release dependencies (publish.yml crates pack, bind) never parse TOML here (rightkit#1341).
|
|
64
|
+
let smolTomlParse;
|
|
65
|
+
const parse = (text) => (smolTomlParse ??= createRequire(import.meta.url)("smol-toml").parse)(text);
|
|
62
66
|
import { RUNTIME_BUDGET_CRATES } from "./runtime-budget-crates.mjs";
|
|
63
67
|
import { singleHostOfPolicy } from "./publication-gate.mjs";
|
|
64
68
|
import { findWorkspaceRoot, lockClosure, pathDependencyDirs, readCargoPackage } from "./crate-graph.mjs";
|
package/shell-contract.mjs
CHANGED
|
@@ -26,7 +26,7 @@ import fs from "node:fs";
|
|
|
26
26
|
import path from "node:path";
|
|
27
27
|
import { fileURLToPath } from "node:url";
|
|
28
28
|
|
|
29
|
-
const SKIPPED_TREE = /(^|\/)(node_modules|vendor|target)\//;
|
|
29
|
+
const SKIPPED_TREE = /(^|\/)(node_modules|vendor|target|tests\/fixtures)\//;
|
|
30
30
|
const PLATFORMS = ["macos", "windows", "linux", "ios", "android"];
|
|
31
31
|
// The shell is a desktop plugin: a mobile window is created by the OS and shown by it, so R1 judges desktop targets only.
|
|
32
32
|
const DESKTOP = new Set(["base", "macos", "windows", "linux"]);
|
package/snapshot-broker.mjs
CHANGED
|
@@ -51,7 +51,12 @@ export const brokerOutputRoots = ({ dataRoot }) => [path.join(dataRoot, "rightki
|
|
|
51
51
|
|
|
52
52
|
/** The broker's receipt of one request, read through the RustRight client (`rustright status <id>`), synchronously. */
|
|
53
53
|
export function receiptSync({ client, requestId, env, spawn = spawnSync, platform = process.platform }) {
|
|
54
|
-
|
|
54
|
+
return receiptFromReply(spawnBrokerClient(spawn, client, ["status", requestId], statusOptions(env), { platform }), requestId);
|
|
55
|
+
}
|
|
56
|
+
const statusOptions = (env) => ({ encoding: "utf8", env, timeout: 60_000, maxBuffer: 64 * 1024 * 1024 });
|
|
57
|
+
|
|
58
|
+
/** The receipt one `rustright status <id>` reply carries, or the typed throw (shared by the synchronous and the asynchronous read). */
|
|
59
|
+
function receiptFromReply(r, requestId) {
|
|
55
60
|
const failedRun = () => new SnapshotRequestError("receipt", `rustright status ${requestId} failed (${r.error?.message ?? `exit ${r.status}`})`);
|
|
56
61
|
if (r.error) throw failedRun();
|
|
57
62
|
let doc;
|
|
@@ -165,7 +170,9 @@ function markCarriedRequest({ section, env, callHandle }) {
|
|
|
165
170
|
}
|
|
166
171
|
|
|
167
172
|
/** The spawn errors that prove the client process never started, so no byte reached the broker (GB-21). Anything else after a start is ambiguous and is never marked unsent. */
|
|
168
|
-
|
|
173
|
+
/** The code of a carried call whose abort signal fired before the client was started (the asynchronous carry): proof that no byte reached the broker. */
|
|
174
|
+
export const CLIENT_CANCELLED_BEFORE_SPAWN = "RK_CLIENT_CANCELLED_BEFORE_SPAWN";
|
|
175
|
+
const NO_SPAWN_CODES = new Set(["ENOENT", "EACCES", "EPERM", "EINVAL", "ENOEXEC", "ENOTDIR", BROKER_CLIENT_UNRESOLVED, CLIENT_CANCELLED_BEFORE_SPAWN]);
|
|
169
176
|
export const provenNoSpawn = (error) => Boolean(error) && NO_SPAWN_CODES.has(error.code);
|
|
170
177
|
|
|
171
178
|
/**
|
|
@@ -268,6 +275,8 @@ export function inheritedCarrierEnv(env) {
|
|
|
268
275
|
* handle durably complete); ACTIVE, UNKNOWN, a wait that timed out, a reader that is absent or throws all leave ownership held, and the outcome says which. Never resubmits.
|
|
269
276
|
*/
|
|
270
277
|
function reconcileAfterCancel({ section, callHandle, childEnv }) {
|
|
278
|
+
// This read BLOCKS the event loop for up to 30 s (a synchronous client call). Only the synchronous carry (carryBrokerAdapter, a stage step that blocks anyway) reaches it: the
|
|
279
|
+
// asynchronous carry (a Swift scan next to the gate's other scans) never calls it, because it must not freeze them; it reports the sub-handle UNKNOWN instead (deferredReconcile).
|
|
271
280
|
const cancelWait = Number(childEnv?.RUSTRIGHT_CANCEL_WAIT_MS);
|
|
272
281
|
const waitMs = Math.min(30_000, Number.isFinite(cancelWait) && cancelWait >= 0 ? Math.trunc(cancelWait) : 30_000);
|
|
273
282
|
if (typeof section.leaseStatus !== "function") return { reaped: false, subHandle: { handle: callHandle, state: "UNKNOWN", why: "this gate has no lease reader" }, note: `the gate cannot ask the broker about sub-handle ${callHandle}, so ownership stays UNKNOWN until every sub-handle is REAPED` };
|
|
@@ -279,6 +288,11 @@ function reconcileAfterCancel({ section, callHandle, childEnv }) {
|
|
|
279
288
|
return { reaped: false, subHandle, note: `after the cancel the broker reports sub-handle ${callHandle} still ${state}${status?.why ? ` (${status.why})` : ""}: ownership stays held until it is REAPED; the job is not resubmitted` };
|
|
280
289
|
}
|
|
281
290
|
|
|
291
|
+
/** What the asynchronous carry reports after a cancel or an operation deadline instead of the blocking lease read: ownership stays held, fail closed, and is settled when every sub-handle is REAPED. */
|
|
292
|
+
function deferredReconcile(callHandle) {
|
|
293
|
+
return { reaped: false, subHandle: { handle: callHandle, state: "UNKNOWN", why: "the asynchronous carry reads no lease: the lease reader blocks the event loop for up to 30 s" }, note: `the asynchronous carry does not read the broker's lease (that read blocks the gate for up to 30 s), so sub-handle ${callHandle} stays UNKNOWN and ownership stays held until every sub-handle is REAPED; the job is not resubmitted` };
|
|
294
|
+
}
|
|
295
|
+
|
|
282
296
|
/**
|
|
283
297
|
* GB-52, GB-78, GB-39 (BROKER-CONTRACT section 16): a carried call the broker answered with a refusal that clears on its own (RK_RECOVERY_PENDING, RK_STORAGE_BUDGET_UNAVAILABLE) or whose
|
|
284
298
|
* connection never opened (RK_BROKER_BUSY: every pipe instance busy, no byte sent) is a wait. The gate pauses (250 ms doubling to 5 s) and sends the call again within the call's own
|
|
@@ -370,7 +384,7 @@ function carryBrokerCargoOnce({ words, cwd, env, section, workspace, checkoutWor
|
|
|
370
384
|
const nonce = /^[0-9a-f]{64}$/.test(stageNonce ?? "") ? carriedCallNonce({ stageNonce, cwd: path.relative(section.checkout, checkoutCwd).split(path.sep).join("/") || ".", argv: words }) : undefined;
|
|
371
385
|
made = writeSnapshotRequest({ controlRoot: section.controlRoot, commit: section.commit, snapshot: section.snapshot, declaredInputs: inputs, handle: section.handle, primaryCwd: checkoutCwd, argv: words, nonce, requestIdFile: path.join(refDir, "request.json") });
|
|
372
386
|
} catch (e) { return refuse("RK_CARGO_BROKER_CARRIER", e.message); }
|
|
373
|
-
try { record({ ...base, status: "pending", nonce: made.carrier.nonce, ownershipHandle: made.carrier.ownership.handle, checkoutCwd, spawnCwd }); } catch (e) { removeCarrier(made.file); return refuse("RK_CARGO_LEDGER_ERROR", `the call cannot be recorded (${e.message}); it does not run`); }
|
|
387
|
+
try { record({ ...base, status: "pending", nonce: made.carrier.nonce, requestRef: path.join(refDir, "request.json"), ownershipHandle: made.carrier.ownership.handle, checkoutCwd, spawnCwd }); } catch (e) { removeCarrier(made.file); return refuse("RK_CARGO_LEDGER_ERROR", `the call cannot be recorded (${e.message}); it does not run`); }
|
|
374
388
|
// GB-52: the call's operation deadline (the caller's own cap is never replaced) and an outer guard past the client's own cancel wait.
|
|
375
389
|
const childEnv = { ...clientEnv, ...made.env, ...operationDeadlineEnv({ env: clientEnv, deadlineMs }) };
|
|
376
390
|
const guard = clientGuardMs(childEnv);
|
|
@@ -450,7 +464,82 @@ function carryBrokerCargoOnce({ words, cwd, env, section, workspace, checkoutWor
|
|
|
450
464
|
*/
|
|
451
465
|
export function carryBrokerAdapter(call) { return carryWithRetries(carryBrokerAdapterOnce, call); }
|
|
452
466
|
|
|
453
|
-
|
|
467
|
+
/**
|
|
468
|
+
* The same carried adapter call without blocking the caller's event loop (rightkit#1367 step 2: a carried Swift scan used to freeze the gate for as long as it ran or
|
|
469
|
+
* queued). One body (carryBrokerAdapterSteps) serves both: it yields each client call (`{ args, options }`) and the driver runs it, `spawnSync` for the synchronous call and
|
|
470
|
+
* an awaited asynchronous spawn here. `signal` (an AbortSignal) is handed to the client's spawn, so the scan's deadline or a cancel stops the client's process tree; a
|
|
471
|
+
* retry wait is abortable too. The lease reconciliation after an operation deadline stays synchronous (a bounded read, never reached on the normal path).
|
|
472
|
+
*/
|
|
473
|
+
export async function carryBrokerAdapterAsync(call) {
|
|
474
|
+
const { spawn, signal = null, deadlineMs = null, now = Date.now, sleep = abortableSleep, err = () => {}, record = () => {}, ...rest } = call;
|
|
475
|
+
if (typeof spawn !== "function") throw new TypeError("carryBrokerAdapterAsync needs an asynchronous spawn");
|
|
476
|
+
const window = deadlineMs !== null && Number.isFinite(deadlineMs) ? Math.max(1, Math.trunc(deadlineMs)) : DEFAULT_RETRY_WINDOW_MS;
|
|
477
|
+
const started = now();
|
|
478
|
+
const ledgerId = crypto.randomUUID();
|
|
479
|
+
const drive = async (effect) => {
|
|
480
|
+
// An abort that arrived before the client was started proves nothing was sent: the error carries the code provenNoSpawn recognises, so the sub-handle is recorded unsent.
|
|
481
|
+
if (signal?.aborted && effect.args[0] === "run") return { status: null, stdout: "", stderr: "", cancelled: true, error: Object.assign(new Error("cancelled before the client started"), { code: CLIENT_CANCELLED_BEFORE_SPAWN }) };
|
|
482
|
+
return spawnBrokerClient(spawn, rest.section.client, effect.args, { ...effect.options, ...(signal ? { signal } : {}) }, { platform: rest.section.platform });
|
|
483
|
+
};
|
|
484
|
+
let attempt = 0; let held = []; let result;
|
|
485
|
+
for (;;) {
|
|
486
|
+
attempt += 1;
|
|
487
|
+
held = [];
|
|
488
|
+
const remaining = Math.max(1, window - (now() - started));
|
|
489
|
+
result = await runStepsAsync(carryBrokerAdapterSteps({ ...rest, record, err: (m) => held.push(m), deadlineMs: deadlineMs === null ? null : remaining, ledgerId, signal, asyncCarry: true }), drive);
|
|
490
|
+
const code = result.outcome?.status === "unverified" ? result.outcome.code : null;
|
|
491
|
+
if (code === null || !RETRYABLE_OUTCOME_CODES.has(code) || signal?.aborted) break;
|
|
492
|
+
const pause = retryPauseMs(attempt);
|
|
493
|
+
if (window - (now() - started) <= pause) {
|
|
494
|
+
const elapsed = now() - started;
|
|
495
|
+
const message = `${result.outcome.message}; retried ${attempt - 1} time(s) over ${elapsed} ms and the call's ${window} ms deadline passed before the broker would take it: it is a wait that did not clear, never a result`;
|
|
496
|
+
result = { ...result, outcome: { ...result.outcome, message, attempts: attempt, retried: attempt - 1 } };
|
|
497
|
+
try { record({ id: ledgerId, mode: "broker", status: "unverified", code: result.outcome.code, message }); } catch { /* the final record above stands */ }
|
|
498
|
+
held.push(`rightkit-gate: ${result.outcome.code}: ${message}`);
|
|
499
|
+
break;
|
|
500
|
+
}
|
|
501
|
+
await sleep(pause, signal);
|
|
502
|
+
// A cancel during the wait ends the carry here: nothing is marked or sent for another attempt (the refused attempt was already recorded as settled or unsent).
|
|
503
|
+
if (signal?.aborted) break;
|
|
504
|
+
try { record({ id: ledgerId, mode: "broker", status: "pending", code: null, message: null }); } catch { /* the attempt records its own pending state */ }
|
|
505
|
+
}
|
|
506
|
+
for (const m of held) err(m);
|
|
507
|
+
return result;
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
/** A retry wait that ends at once when the abort signal fires (the default `sleep` of the asynchronous carry). */
|
|
511
|
+
function abortableSleep(ms, signal = null) {
|
|
512
|
+
return new Promise((resolve) => {
|
|
513
|
+
if (signal?.aborted) { resolve(); return; }
|
|
514
|
+
const done = () => { clearTimeout(timer); signal?.removeEventListener("abort", done); resolve(); };
|
|
515
|
+
const timer = setTimeout(done, ms);
|
|
516
|
+
signal?.addEventListener("abort", done, { once: true });
|
|
517
|
+
});
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
/** Drives a steps generator synchronously: each yielded client call runs through `drive` (spawnSync or its test double). */
|
|
521
|
+
function runStepsSync(steps, drive) {
|
|
522
|
+
let step = steps.next();
|
|
523
|
+
while (!step.done) step = steps.next(drive(step.value));
|
|
524
|
+
return step.value;
|
|
525
|
+
}
|
|
526
|
+
async function runStepsAsync(steps, drive) {
|
|
527
|
+
let step = steps.next();
|
|
528
|
+
while (!step.done) {
|
|
529
|
+
let reply;
|
|
530
|
+
try { reply = await drive(step.value); } catch (error) { step = steps.throw(error); continue; }
|
|
531
|
+
step = steps.next(reply);
|
|
532
|
+
}
|
|
533
|
+
return step.value;
|
|
534
|
+
}
|
|
535
|
+
|
|
536
|
+
function carryBrokerAdapterOnce(call) {
|
|
537
|
+
const { section, spawn = spawnSync } = call;
|
|
538
|
+
return runStepsSync(carryBrokerAdapterSteps(call), (effect) => spawnBrokerClient(spawn, section.client, effect.args, effect.options, { platform: section.platform }));
|
|
539
|
+
}
|
|
540
|
+
|
|
541
|
+
/** One carried adapter attempt as a generator: it yields `{ args, options }` for each client call (the carried run, then the receipt's status) and receives the spawn result. */
|
|
542
|
+
function* carryBrokerAdapterSteps({ adapter, words, cwd, env, section, record, err, tmp = os.tmpdir(), stdio = "inherit", deadlineMs = null, ledgerId = null, signal = null, asyncCarry = false }) {
|
|
454
543
|
const id = ledgerId ?? crypto.randomUUID();
|
|
455
544
|
words = [...words].map(String);
|
|
456
545
|
const base = { id, mode: "broker", shim: "adapter", adapter, cwd, argv: [...words] };
|
|
@@ -493,15 +582,17 @@ function carryBrokerAdapterOnce({ adapter, words, cwd, env, section, record, spa
|
|
|
493
582
|
const nonce = /^[0-9a-f]{64}$/.test(stageNonce ?? "") ? carriedCallNonce({ stageNonce, cwd: path.relative(section.checkout, checkoutCwd).split(path.sep).join("/") || ".", argv: words }) : undefined;
|
|
494
583
|
made = writeSnapshotRequest({ controlRoot: section.controlRoot, commit: section.commit, snapshot: section.snapshot, declaredInputs: inputs, handle: section.handle, primaryCwd: checkoutCwd, argv: words, nonce, requestIdFile: path.join(refDir, "request.json") });
|
|
495
584
|
} catch (e) { return refuse("RK_ADAPTER_BROKER_CARRIER", e.message); }
|
|
496
|
-
try { record({ ...base, status: "pending", nonce: made.carrier.nonce, ownershipHandle: made.carrier.ownership.handle, checkoutCwd, spawnCwd }); } catch (e) { removeCarrier(made.file); return refuse("RK_CARGO_LEDGER_ERROR", `the call cannot be recorded (${e.message}); it does not run`); }
|
|
585
|
+
try { record({ ...base, status: "pending", nonce: made.carrier.nonce, requestRef: path.join(refDir, "request.json"), ownershipHandle: made.carrier.ownership.handle, checkoutCwd, spawnCwd }); } catch (e) { removeCarrier(made.file); return refuse("RK_CARGO_LEDGER_ERROR", `the call cannot be recorded (${e.message}); it does not run`); }
|
|
497
586
|
// GB-52: the call's operation deadline (the caller's own cap is never replaced) and an outer guard past the client's own cancel wait.
|
|
498
587
|
const childEnv = { ...clientEnv, ...made.env, ...operationDeadlineEnv({ env: clientEnv, deadlineMs }) };
|
|
499
588
|
const guard = clientGuardMs(childEnv);
|
|
500
589
|
const capture = stdio === "capture";
|
|
501
590
|
// Broker work may exist from the next statement on: the ownership records this request's sub-handle first (a mark that does not land sends nothing).
|
|
502
591
|
{ const startable = clientStartable(section.client, section.platform); if (startable) { removeCarrier(made.file); return refuse("RK_ADAPTER_BROKER_CLIENT", `${startable}; nothing was marked or sent`); } }
|
|
592
|
+
// A scan cancelled before the request is marked sends nothing and marks nothing (the mark records that broker work may exist).
|
|
593
|
+
if (signal?.aborted) { removeCarrier(made.file); return refuse("RK_ADAPTER_BROKER_CANCELLED", "the scan was cancelled before the request was marked or sent; nothing was sent"); }
|
|
503
594
|
try { markCarriedRequest({ section, env, callHandle: made.carrier.ownership.handle }); } catch (e) { removeCarrier(made.file); return refuse("RK_ADAPTER_BROKER_OWNERSHIP", e.message); }
|
|
504
|
-
const r =
|
|
595
|
+
const r = yield { args: ["run", adapter, "--", ...words], options: capture ? { cwd: spawnCwd, env: childEnv, encoding: "utf8", maxBuffer: 1 << 28, windowsHide: true, ...(guard ? { timeout: guard } : {}) } : { cwd: spawnCwd, env: childEnv, stdio: "inherit", ...(guard ? { timeout: guard } : {}) } };
|
|
505
596
|
removeCarrier(made.file);
|
|
506
597
|
// GB-21: a client that provably never started sent nothing: that sub-handle is recorded unsent under the ownership lock, so it does not wedge a later reclaim. Any other
|
|
507
598
|
// failure after a start (a lost connection, a timeout, an exit before a reference) is ambiguous and stays held, reconciled by the request id.
|
|
@@ -509,7 +600,13 @@ function carryBrokerAdapterOnce({ adapter, words, cwd, env, section, record, spa
|
|
|
509
600
|
let outcome;
|
|
510
601
|
let ref = null;
|
|
511
602
|
let nativeManaged = null;
|
|
603
|
+
const cancelledRun = Boolean(r.error) && (r.cancelled === true || signal?.aborted === true);
|
|
512
604
|
try {
|
|
605
|
+
if (r.error && cancelledRun) {
|
|
606
|
+
// The scan's own signal stopped the client: a cancel, never "the client did not start" (the request may exist at the broker; its reference is kept when the client wrote it).
|
|
607
|
+
try { ref = readRequestRef(path.join(refDir, "request.json")); } catch { ref = null; }
|
|
608
|
+
throw new SnapshotRequestError("cancelled", provenNoSpawn(r.error) ? "the scan was cancelled before the RustRight client started; nothing was sent" : `the scan was cancelled: its signal stopped the RustRight client${ref ? ` (request ${ref.requestId})` : ""}; the request is not resubmitted`);
|
|
609
|
+
}
|
|
513
610
|
if (r.error) throw new SnapshotRequestError(r.error.code === BROKER_CLIENT_UNRESOLVED ? BROKER_CLIENT_UNRESOLVED : "spawn", `the RustRight client did not start (${r.error.message})`);
|
|
514
611
|
ref = readRequestRef(path.join(refDir, "request.json"));
|
|
515
612
|
// The request's workspace of a snapshot-bound adapter job is the directory the client ran in: the primary checkout's counterpart of the step's
|
|
@@ -517,7 +614,8 @@ function carryBrokerAdapterOnce({ adapter, words, cwd, env, section, record, spa
|
|
|
517
614
|
// directory in the snapshot), which must be inside that root"). It is the carrier's primaryCwd, never the toplevel for a step run from a subfolder
|
|
518
615
|
// (an app whose root is `app/`), and never a directory outside the primary checkout or one that is not this call's counterpart.
|
|
519
616
|
if (canonicalCounterpart(ref.workspace) !== canonicalCounterpart(checkoutCwd) || !inside(canonicalCounterpart(ref.workspace), section.checkout)) throw new SnapshotRequestError("workspace", `the request's workspace ${ref.workspace} is not the primary checkout counterpart ${checkoutCwd} of the step's directory ${realCwd} (primary toplevel ${section.checkout})`);
|
|
520
|
-
const
|
|
617
|
+
const statusReply = yield { args: ["status", ref.requestId], options: statusOptions(clientEnv) };
|
|
618
|
+
const receipt = receiptFromReply(statusReply, ref.requestId);
|
|
521
619
|
const { payload, evidence, attribution, toolchain, nestedChildren } = verifySnapshotReceipt(receipt, { pins: section.pins, jobId: ref.requestId, carrier: made.carrier, argv: words, workspace: ref.workspace, adapter, adapterEnv, checkout: section.checkout, outputRoots: section.outputRoots, platform: section.platform });
|
|
522
620
|
nativeManaged = signedNativeOutputs(receipt, payload);
|
|
523
621
|
outcome = { status: "verified", requestId: ref.requestId, workspace: ref.workspace, outputDir: evidence.outputDir, nestedChildren, treeAtStart: evidence.snapshot.treeAtStart, treeAtExit: evidence.snapshot.treeAtExit, attribution, toolchain };
|
|
@@ -538,8 +636,8 @@ function carryBrokerAdapterOnce({ adapter, words, cwd, env, section, record, spa
|
|
|
538
636
|
const seen = operationOutcomeInOutput(`${out.stdout}\n${out.stderr}`) ?? (r.error?.code === "ETIMEDOUT" ? { code: "operation-deadline", deadlineMs: null, requestId: ref?.requestId ?? null, cancelConfirmed: null, terminalState: null, guard: true } : null);
|
|
539
637
|
if (seen) outcome = { status: "unverified", code: seen.code, message: seen.code === "operation-deadline" ? `the operation deadline${seen.deadlineMs ? ` of ${seen.deadlineMs} ms` : ""} passed${seen.guard ? " and the client was stopped by the gate's outer guard" : ""}; request ${seen.requestId ?? ref?.requestId ?? "unknown"}: cancelConfirmed: ${seen.cancelConfirmed ?? "unknown"}, terminal state: ${seen.terminalState ?? "not observed"}; the job is neither abandoned nor resubmitted and ownership stays UNKNOWN until every sub-handle is REAPED` : seen.code === "broker-busy" ? "every broker connection was busy (RK_BROKER_BUSY: a wait, not an outage); nothing was admitted" : "the broker was unavailable (RK_BROKER_UNAVAILABLE)", ...(ref ? { requestId: ref.requestId, workspace: ref.workspace } : {}) };
|
|
540
638
|
}
|
|
541
|
-
if (outcome.status === "unverified" && outcome.code === "operation-deadline") {
|
|
542
|
-
const settled = reconcileAfterCancel({ section, callHandle: made.carrier.ownership.handle, childEnv });
|
|
639
|
+
if (outcome.status === "unverified" && (outcome.code === "operation-deadline" || (outcome.code === "cancelled" && !provenNoSpawn(r.error)))) {
|
|
640
|
+
const settled = asyncCarry ? deferredReconcile(made.carrier.ownership.handle) : reconcileAfterCancel({ section, callHandle: made.carrier.ownership.handle, childEnv });
|
|
543
641
|
outcome = { ...outcome, message: `${outcome.message}; ${settled.note}`, reaped: settled.reaped, subHandle: settled.subHandle };
|
|
544
642
|
}
|
|
545
643
|
// RK_BROKER_BUSY with no request reference: the connection never opened, so no byte reached the broker. That is the gate's own proof that this sub-handle was never sent (GB-21), recorded under
|
package/snapshot-check.mjs
CHANGED
|
@@ -231,6 +231,8 @@ export function installSnapshotDependencies({ checkout, snapshot, commit, tree,
|
|
|
231
231
|
const relative = path.relative(base, path.resolve(base, selected)).split(path.sep).join("/");
|
|
232
232
|
const actual = manifests.get(fold(relative));
|
|
233
233
|
const owner = nearestLock(fold(relative));
|
|
234
|
+
// A package under an install root that commits no pnpm-lock.yaml has nothing to install from: not an error here (the root loop below records it as skipped and the pnpm-lockfile scan judges it).
|
|
235
|
+
if (actual !== undefined && owner === undefined && [...installRoots].some((r) => !r || fold(relative) === r || fold(relative).startsWith(`${r}/`))) continue;
|
|
234
236
|
if (actual === undefined || owner === undefined || !installRoots.has(owner) || /[*?\[\]{}!^()\\]/.test(actual) || actual.includes("...")) throw new CheckError(`dependency package ${selected} is not an exact committed manifest directory owned by an install root`);
|
|
235
237
|
if (!selectedByRoot.has(owner)) selectedByRoot.set(owner, new Set());
|
|
236
238
|
selectedByRoot.get(owner).add(actual);
|