Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions apps/public-docs/derun.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ Script installer:
./scripts/install/derun.ps1 -Version latest -Method direct
```

Direct installers verify Sigstore bundle sidecars (`*.sigstore.json`) and only support bundle-enabled releases.

## Quick start

Run a command with transcript capture:
Expand Down
2 changes: 2 additions & 0 deletions apps/public-docs/dexdex.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ Script installer:
./scripts/install/dexdex-stack.ps1 -Version latest -Method direct
```

Direct installers verify Sigstore bundle sidecars (`*.sigstore.json`) and only support bundle-enabled releases.

## Related pages

- [Projects Overview](projects-overview)
Expand Down
2 changes: 2 additions & 0 deletions apps/public-docs/nodeup.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ Script installer:
./scripts/install/nodeup.ps1 -Version latest -Method direct
```

Direct installers verify Sigstore bundle sidecars (`*.sigstore.json`) and only support bundle-enabled releases.

## Common workflows

Set a global default runtime:
Expand Down
2 changes: 2 additions & 0 deletions docs/cmds-derun-foundation.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,11 @@
- Release artifact contract for distribution tooling:
- Required asset names: `derun-linux-amd64.tar.gz`, `derun-darwin-amd64.tar.gz`, `derun-darwin-arm64.tar.gz`, `derun-windows-amd64.zip`.
- Required build matrix: `linux/amd64`, `darwin/amd64`, `darwin/arm64`, `windows/amd64`.
- Required signing sidecars: `SHA256SUMS.sigstore.json` and `<artifact>.sigstore.json`.
- Homebrew `derun` formula contract:
- Must install from GitHub release prebuilt tarballs (darwin amd64/arm64 and linux amd64).
- Linux arm64 must fail explicitly as unsupported until a dedicated artifact is added.
- Direct install scripts must verify release artifacts with `SHA256SUMS` and Sigstore bundle sidecars via `cosign verify-blob --bundle`.
- User-facing error messages must remain single-line and follow stable style contracts:
- Usage/validation: `invalid arguments: <reason>; details: <k=v,...>; hint: <how to fix>`
- Runtime: `failed to <action>: <cause>; details: <k=v,...>`
Expand Down
3 changes: 2 additions & 1 deletion docs/crates-cargo-mono-foundation.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,11 +66,12 @@
- Workspace validation baseline: `cargo test --workspace --all-targets`
- CI alignment: `.github/workflows/CI.yml` Rust jobs
- Release contract checks should align with `.github/workflows/release-cargo-mono.yml`.
- Release signing outputs must use Sigstore bundle sidecars (`SHA256SUMS.sigstore.json` and `<artifact>.sigstore.json`).

## Dependencies and Integrations
- Integrates with Cargo workspace metadata and release workflows.
- Integrates with root automation (`auto-publish`) through stable command contracts, including CI-driven tag publication.
- Integrates with tag-based binary distribution automation (`release-cargo-mono`) through stable artifact naming and signing contracts.
- Integrates with tag-based binary distribution automation (`release-cargo-mono`) through stable artifact naming and bundle-signing contracts.

## Change Triggers
- Update `docs/project-cargo-mono.md` with this file when command identifiers or ownership changes.
Expand Down
2 changes: 2 additions & 0 deletions docs/crates-nodeup-foundation.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
- Shim dispatch behavior must remain deterministic by executable name (`node`, `npm`, `npx`, `yarn`, `pnpm`).
- Install/update command surfaces must preserve backward-compatible flags and outputs.
- Homebrew installation must consume prebuilt release archives for `darwin/amd64`, `darwin/arm64`, and `linux/amd64`; Linux arm64 must fail with a clear unsupported-platform message.
- Direct install scripts must verify release artifacts with `SHA256SUMS` and Sigstore bundle sidecars (`<artifact>.sigstore.json`) via `cosign verify-blob --bundle`.
- `yarn`/`pnpm` delegated execution must honor nearest `package.json` `packageManager` when present.
- `packageManager` parsing contract is strict: `<manager>@<exact-semver>` with manager limited to `yarn|pnpm`.
- `packageManager` manager-command mismatch must fail with `conflict`; malformed values must fail with `invalid-input`.
Expand Down Expand Up @@ -53,6 +54,7 @@
- Workspace baseline: `cargo test --workspace --all-targets`
- Release contract checks should align with `release-nodeup` workflow expectations.
- Release assets must include both standalone prebuilt binaries (`nodeup-<os>-<arch>[.exe]`) and compressed archives (`nodeup-<os>-<arch>.tar.gz|zip`) for the supported release matrix.
- Release signing outputs must include `SHA256SUMS.sigstore.json` and `<artifact>.sigstore.json` sidecars; legacy `.sig`/`.pem` sidecars are out of scope for direct installation.
- Homebrew release automation must render the prebuilt formula from release asset URLs and push tap updates directly to `delinoio/homebrew-tap` `main` with a dedicated tap-write credential.
- Completion coverage must include successful script generation, invalid shell/scope validation, and JSON-mode raw output behavior.
- Output color coverage must include flag/env precedence, invalid env fallback, stream-aware auto-mode behavior, and JSON/completion ANSI exclusion.
Expand Down
2 changes: 1 addition & 1 deletion docs/project-cargo-mono.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ Provide a Cargo subcommand for Rust monorepo lifecycle management, including ver
- `publish` retry overrides must remain operator-controlled through `--max-attempts <count>` and `CARGO_MONO_PUBLISH_MAX_ATTEMPTS`, with precedence `--max-attempts` > env > default unlimited retries.
- Remote tag publication remains CI-owned: `auto-publish` pushes release tags with `git push --tags` after a successful `publish` run, with checkout credential persistence disabled and authentication bound to `secrets.GH_TOKEN` (non-`GITHUB_TOKEN`) so downstream tag-triggered workflows run.
- Publish tag configuration must be opt-in through `[workspace.metadata.cargo-mono.publish.tag].packages`, and tag naming must remain `<crate>@v<version>`.
- Tag release automation must detect `cargo-mono@v*` and produce signed multi-OS prebuilt artifacts without changing CLI command behavior.
- Tag release automation must detect `cargo-mono@v*` and produce signed multi-OS prebuilt artifacts with Sigstore bundle sidecars (`*.sigstore.json`) without changing CLI command behavior.
- Runtime failure messaging must follow the `Summary/Context/Hint` three-line contract while command behavior, output schema, and exit code semantics remain stable.
- Dependency-cycle conflicts in package ordering must identify cycle package names and dependency scope in `Context` without changing CLI flags, command behavior, or JSON output schema.
- Human output color controls must remain stable: global `--color <auto|always|never>`, `CARGO_MONO_OUTPUT_COLOR`, and `NO_COLOR` with precedence `--color` > `CARGO_MONO_OUTPUT_COLOR` > `NO_COLOR` > auto-detection.
Expand Down
2 changes: 2 additions & 0 deletions docs/project-derun.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,14 @@ Provide a Go CLI that preserves terminal fidelity for AI-agent workflows and bri
- User-facing error messages must remain single-line and include deterministic `details` segments with safe diagnostic fields only (no secrets).
- User-facing error messages must preserve compatibility tokens used by MCP/automation integrations (`session not found`, `parse <field>`, `session_id is required`, `cursor is required`).
- Release artifact matrix and names must remain stable: `derun-linux-amd64.tar.gz`, `derun-darwin-amd64.tar.gz`, `derun-darwin-arm64.tar.gz`, `derun-windows-amd64.zip`.
- Release signing must publish Sigstore bundle sidecars (`*.sigstore.json`) for each artifact and `SHA256SUMS`, and direct installers only support bundle-enabled releases.
- Homebrew distribution must install `derun` from GitHub release prebuilt archives (darwin amd64/arm64 and linux amd64) instead of source builds.

## Change Policy
- Update this index and `docs/cmds-derun-foundation.md` together whenever command shape or runtime contracts change.
- Update this index and `docs/cmds-derun-foundation.md` together whenever user-facing error message contracts or compatibility tokens change.
- Update `.github/workflows/release-derun.yml`, `scripts/release/update-homebrew.sh`, and `packaging/homebrew/templates/derun.rb.tmpl` in the same change when derun release artifact names, target matrix, or package-manager distribution contracts change.
- Keep direct installer contracts in `scripts/install/derun.sh` and `scripts/install/derun.ps1` synchronized with release signing changes.
- Align command lifecycle changes with `cmds/AGENTS.md` and root `AGENTS.md`.

## References
Expand Down
3 changes: 2 additions & 1 deletion docs/project-dexdex.md
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,8 @@ Recommended runtime environment keys:

## Release Distribution Contracts
- Release workflow: `.github/workflows/release-dexdex.yml`.
- GitHub Releases publish signed desktop and server artifacts (`SHA256SUMS` + cosign signatures).
- GitHub Releases publish signed desktop and server artifacts (`SHA256SUMS` + `.sigstore.json` bundle sidecars).
- Direct installers verify Sigstore bundle sidecars and only support bundle-enabled releases.
- Homebrew distribution:
- `dexdex` cask consumes the macOS desktop DMG release artifact.
- `dexdex-main-server` and `dexdex-worker-server` formulas consume prebuilt server release artifacts for `darwin/amd64`, `darwin/arm64`, and `linux/amd64`.
Expand Down
3 changes: 2 additions & 1 deletion docs/project-nodeup.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ Provide a Rust-based Node.js version manager with predictable channel resolution
- `package.json` `packageManager` support for `yarn|pnpm` must remain strict and deterministic.
- Shell completion generation must remain deterministic for supported shells and top-level command scopes.
- Human output styling controls (`--color`, `NODEUP_COLOR`, and `NO_COLOR` precedence) must remain stable across CLI and public documentation.
- Release automation must publish both standalone prebuilt binaries and archive assets for the supported OS/architecture matrix.
- Release automation must publish both standalone prebuilt binaries and archive assets for the supported OS/architecture matrix, plus Sigstore bundle sidecars (`*.sigstore.json`) for each artifact and `SHA256SUMS`.
- Direct installers must verify `SHA256SUMS` entries and Sigstore bundle sidecars, and only support bundle-enabled releases.
- Homebrew installation must use prebuilt `nodeup` release archives for `darwin/amd64`, `darwin/arm64`, and `linux/amd64`, while failing clearly for unsupported Linux arm64 hosts.

## Change Policy
Expand Down
2 changes: 2 additions & 0 deletions scripts/install/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ Cross-platform install scripts with the shared interface:

- `--version <semver|latest>`
- `--method package-manager|direct`
- `direct` verifies `SHA256SUMS` plus Sigstore bundle sidecars (`*.sigstore.json`)
- Older releases that only published legacy `.sig`/`.pem` files are not supported in direct mode

Scripts:

Expand Down
31 changes: 21 additions & 10 deletions scripts/install/derun.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -48,20 +48,33 @@ function Verify-Checksum {
}
}

function Verify-Signature {
function Download-Bundle {
param(
[string]$BaseUrl,
[string]$AssetName,
[string]$BundlePath
)

try {
Invoke-WebRequest -Uri "$BaseUrl/$AssetName.sigstore.json" -OutFile $BundlePath
}
catch {
throw "[install.derun] direct installs require releases published with Sigstore bundle sidecars"
}
}

function Verify-Bundle {
param(
[string]$FilePath,
[string]$SignaturePath,
[string]$CertificatePath
[string]$BundlePath
)

if (-not (Get-Command cosign -ErrorAction SilentlyContinue)) {
throw "[install.derun] cosign is required for direct installation"
}

cosign verify-blob `
--certificate $CertificatePath `
--signature $SignaturePath `
--bundle $BundlePath `
--certificate-identity-regexp $WorkflowIdentityPattern `
--certificate-oidc-issuer "https://token.actions.githubusercontent.com" `
$FilePath | Out-Null
Expand All @@ -78,17 +91,15 @@ function Install-Direct {
try {
$assetPath = Join-Path $tmpDir $assetName
$sumsPath = Join-Path $tmpDir "SHA256SUMS"
$signaturePath = "$assetPath.sig"
$certificatePath = "$assetPath.pem"
$bundlePath = "$assetPath.sigstore.json"

Write-Host "[install.derun] downloading $assetName"
Invoke-WebRequest -Uri "$baseUrl/$assetName" -OutFile $assetPath
Invoke-WebRequest -Uri "$baseUrl/SHA256SUMS" -OutFile $sumsPath
Invoke-WebRequest -Uri "$baseUrl/$assetName.sig" -OutFile $signaturePath
Invoke-WebRequest -Uri "$baseUrl/$assetName.pem" -OutFile $certificatePath
Download-Bundle -BaseUrl $baseUrl -AssetName $assetName -BundlePath $bundlePath

Verify-Checksum -FilePath $assetPath -Sha256SumsPath $sumsPath -AssetName $assetName
Verify-Signature -FilePath $assetPath -SignaturePath $signaturePath -CertificatePath $certificatePath
Verify-Bundle -FilePath $assetPath -BundlePath $bundlePath

$extractDir = Join-Path $tmpDir "extract"
Expand-Archive -Path $assetPath -DestinationPath $extractDir -Force
Expand Down
22 changes: 16 additions & 6 deletions scripts/install/derun.sh
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,19 @@ install_via_package_manager() {
return 1
}

verify_signature() {
download_bundle() {
local base_url="$1"
local artifact="$2"
local bundle_name="${artifact}.sigstore.json"

if ! curl -fsSLO "${base_url}/${bundle_name}"; then
echo "[install.derun] missing bundle sidecar: ${bundle_name}" >&2
echo "[install.derun] direct installs require releases published with Sigstore bundle sidecars" >&2
exit 1
fi
}

verify_bundle() {
local artifact="$1"

if ! command -v cosign >/dev/null 2>&1; then
Expand All @@ -99,8 +111,7 @@ verify_signature() {
fi

cosign verify-blob \
--certificate "${artifact}.pem" \
--signature "${artifact}.sig" \
--bundle "${artifact}.sigstore.json" \
--certificate-identity-regexp "$workflow_identity" \
--certificate-oidc-issuer "https://token.actions.githubusercontent.com" \
"$artifact"
Expand Down Expand Up @@ -162,12 +173,11 @@ install_direct() {
echo "[install.derun] downloading artifact: $asset_name" >&2
curl -fsSLO "${base_url}/${asset_name}"
curl -fsSLO "${base_url}/SHA256SUMS"
curl -fsSLO "${base_url}/${asset_name}.sig"
curl -fsSLO "${base_url}/${asset_name}.pem"
download_bundle "$base_url" "$asset_name"

grep " ${asset_name}$" SHA256SUMS > SHA256SUMS.derun
shasum -a 256 -c SHA256SUMS.derun
verify_signature "$asset_name"
verify_bundle "$asset_name"

tar -xzf "$asset_name"

Expand Down
31 changes: 21 additions & 10 deletions scripts/install/dexdex-stack.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -48,20 +48,33 @@ function Verify-Checksum {
}
}

function Verify-Signature {
function Download-Bundle {
param(
[string]$BaseUrl,
[string]$AssetName,
[string]$BundlePath
)

try {
Invoke-WebRequest -Uri "$BaseUrl/$AssetName.sigstore.json" -OutFile $BundlePath
}
catch {
throw "[install.dexdex] direct installs require releases published with Sigstore bundle sidecars"
}
}

function Verify-Bundle {
param(
[string]$FilePath,
[string]$SignaturePath,
[string]$CertificatePath
[string]$BundlePath
)

if (-not (Get-Command cosign -ErrorAction SilentlyContinue)) {
throw "[install.dexdex] cosign is required for direct installation"
}

cosign verify-blob `
--certificate $CertificatePath `
--signature $SignaturePath `
--bundle $BundlePath `
--certificate-identity-regexp $WorkflowIdentityPattern `
--certificate-oidc-issuer "https://token.actions.githubusercontent.com" `
$FilePath | Out-Null
Expand All @@ -76,15 +89,13 @@ function Download-AndVerify {
)

$assetPath = Join-Path $TempDir $AssetName
$signaturePath = "$assetPath.sig"
$certificatePath = "$assetPath.pem"
$bundlePath = "$assetPath.sigstore.json"

Invoke-WebRequest -Uri "$BaseUrl/$AssetName" -OutFile $assetPath
Invoke-WebRequest -Uri "$BaseUrl/$AssetName.sig" -OutFile $signaturePath
Invoke-WebRequest -Uri "$BaseUrl/$AssetName.pem" -OutFile $certificatePath
Download-Bundle -BaseUrl $BaseUrl -AssetName $AssetName -BundlePath $bundlePath

Verify-Checksum -FilePath $assetPath -Sha256SumsPath $Sha256SumsPath -AssetName $AssetName
Verify-Signature -FilePath $assetPath -SignaturePath $signaturePath -CertificatePath $certificatePath
Verify-Bundle -FilePath $assetPath -BundlePath $bundlePath

return $assetPath
}
Expand Down
22 changes: 16 additions & 6 deletions scripts/install/dexdex-stack.sh
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,19 @@ resolve_tag() {
printf '%s%s\n' "$tag_prefix" "$version"
}

verify_signature() {
download_bundle() {
local base_url="$1"
local artifact="$2"
local bundle_name="${artifact}.sigstore.json"

if ! curl -fsSLO "${base_url}/${bundle_name}"; then
echo "[install.dexdex] missing bundle sidecar: ${bundle_name}" >&2
echo "[install.dexdex] direct installs require releases published with Sigstore bundle sidecars" >&2
exit 1
fi
}

verify_bundle() {
local artifact="$1"

if ! command -v cosign >/dev/null 2>&1; then
Expand All @@ -88,8 +100,7 @@ verify_signature() {
fi

cosign verify-blob \
--certificate "${artifact}.pem" \
--signature "${artifact}.sig" \
--bundle "${artifact}.sigstore.json" \
--certificate-identity-regexp "$workflow_identity" \
--certificate-oidc-issuer "https://token.actions.githubusercontent.com" \
"$artifact"
Expand All @@ -100,12 +111,11 @@ download_and_verify() {
local asset_name="$2"

curl -fsSLO "${base_url}/${asset_name}"
curl -fsSLO "${base_url}/${asset_name}.sig"
curl -fsSLO "${base_url}/${asset_name}.pem"
download_bundle "$base_url" "$asset_name"

grep " ${asset_name}$" SHA256SUMS > "SHA256SUMS.${asset_name}"
shasum -a 256 -c "SHA256SUMS.${asset_name}"
verify_signature "$asset_name"
verify_bundle "$asset_name"
}

install_via_package_manager() {
Expand Down
31 changes: 21 additions & 10 deletions scripts/install/nodeup.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -48,20 +48,33 @@ function Verify-Checksum {
}
}

function Verify-Signature {
function Download-Bundle {
param(
[string]$BaseUrl,
[string]$AssetName,
[string]$BundlePath
)

try {
Invoke-WebRequest -Uri "$BaseUrl/$AssetName.sigstore.json" -OutFile $BundlePath
}
catch {
throw "[install.nodeup] direct installs require releases published with Sigstore bundle sidecars"
}
}

function Verify-Bundle {
param(
[string]$FilePath,
[string]$SignaturePath,
[string]$CertificatePath
[string]$BundlePath
)

if (-not (Get-Command cosign -ErrorAction SilentlyContinue)) {
throw "[install.nodeup] cosign is required for direct installation"
}

cosign verify-blob `
--certificate $CertificatePath `
--signature $SignaturePath `
--bundle $BundlePath `
--certificate-identity-regexp $WorkflowIdentityPattern `
--certificate-oidc-issuer "https://token.actions.githubusercontent.com" `
$FilePath | Out-Null
Expand All @@ -78,17 +91,15 @@ function Install-Direct {
try {
$assetPath = Join-Path $tmpDir $assetName
$sumsPath = Join-Path $tmpDir "SHA256SUMS"
$signaturePath = "$assetPath.sig"
$certificatePath = "$assetPath.pem"
$bundlePath = "$assetPath.sigstore.json"

Write-Host "[install.nodeup] downloading $assetName"
Invoke-WebRequest -Uri "$baseUrl/$assetName" -OutFile $assetPath
Invoke-WebRequest -Uri "$baseUrl/SHA256SUMS" -OutFile $sumsPath
Invoke-WebRequest -Uri "$baseUrl/$assetName.sig" -OutFile $signaturePath
Invoke-WebRequest -Uri "$baseUrl/$assetName.pem" -OutFile $certificatePath
Download-Bundle -BaseUrl $baseUrl -AssetName $assetName -BundlePath $bundlePath

Verify-Checksum -FilePath $assetPath -Sha256SumsPath $sumsPath -AssetName $assetName
Verify-Signature -FilePath $assetPath -SignaturePath $signaturePath -CertificatePath $certificatePath
Verify-Bundle -FilePath $assetPath -BundlePath $bundlePath

$extractDir = Join-Path $tmpDir "extract"
Expand-Archive -Path $assetPath -DestinationPath $extractDir -Force
Expand Down
Loading
Loading