# BlackLang CLI Release Artifact Layout

## Purpose

This document defines the official release artifact layout for the BlackLang CLI.

The goal is to make every release predictable for humans, AI agents, package managers, and CI pipelines.

## Release Root

Release files are prepared under:

```text
artifacts/releases/<version>/
```

Example:

```text
artifacts/releases/v0.2.0/
```

## Platform Archive Names

Each platform archive must use this shape:

```text
blacklang-<version>-<os>-<arch>.<ext>
```

Examples:

```text
blacklang-v0.2.0-windows-amd64.zip
blacklang-v0.2.0-linux-amd64.tar.gz
blacklang-v0.2.0-darwin-arm64.tar.gz
```

Rules:

- `version` must match the Git tag and CLI version output.
- `os` must use Go target names: `windows`, `linux`, `darwin`.
- `arch` must use Go target names: `amd64`, `arm64`.
- Windows archives use `.zip`.
- Linux and macOS archives use `.tar.gz`.
- Archive names are lowercase except the semantic version prefix `v`.

## Archive Contents

Each archive contains a single root folder:

```text
blacklang-<version>-<os>-<arch>/
```

Inside that folder:

```text
blacklang-<version>-<os>-<arch>/
├── black or black.exe
├── README.md
├── LICENSE
└── manifest.blackdir
```

Rules:

- The executable is named `black.exe` on Windows.
- The executable is named `black` on Linux and macOS.
- `README.md` explains the minimal install and verify commands.
- `LICENSE` is copied from the repository root.
- `manifest.blackdir` is the compact machine-readable release metadata.
- `.black` source files are never included in CLI release archives.

## Release Root Files

The release root contains:

```text
artifacts/releases/<version>/
├── blacklang-<version>-windows-amd64.zip
├── blacklang-<version>-linux-amd64.tar.gz
├── blacklang-<version>-darwin-amd64.tar.gz
├── blacklang-<version>-darwin-arm64.tar.gz
├── blacklang-<version>-windows-amd64.zip.sig
├── blacklang-<version>-linux-amd64.tar.gz.sig
├── blacklang-<version>-darwin-amd64.tar.gz.sig
├── blacklang-<version>-darwin-arm64.tar.gz.sig
├── checksums.sha256
├── release.blackdir
└── transparency.blackdir
```

`checksums.sha256` contains one SHA-256 entry per archive.

`release.blackdir` contains release-level metadata for AI agents, scripts, and package managers.

`transparency.blackdir` contains append-only public release entries that tie each archive to its checksum, signature, signing key id, previous entry hash, entry hash, and publish timestamp. The policy shape is defined in `packages/registry/release-transparency.blackdir`.

Detached `.sig` files contain Ed25519 signatures for finalized archive bytes. Signing uses a private key outside this repository.

## Windows Build Script

The first release script builds the Windows CLI archive:

```powershell
.\scripts\build-release-windows.ps1
```

Optional parameters:

```powershell
.\scripts\build-release-windows.ps1 -Version v0.2.0 -Arch amd64
```

Rules:

- The script builds `dist/black.exe` from `packages/cli`.
- The default version is read from `black.exe version` and normalized with a `v` prefix.
- If `-Version` is provided, it must match the CLI version.
- The script writes `artifacts/releases/<version>/blacklang-<version>-windows-<arch>.zip`.
- The zip contains `black.exe`, `README.md`, `LICENSE`, and `manifest.blackdir`.
- Checksum files are generated by the separate checksum release step.

## release.blackdir Shape

The release manifest uses BlackLang's compact directory-data style rather than JSON for project-owned metadata.

```blackdir
release v0.2.0
channel stable
cli black

artifact windows amd64 zip blacklang-v0.2.0-windows-amd64.zip sha256 <hash>
artifact linux amd64 targz blacklang-v0.2.0-linux-amd64.tar.gz sha256 <hash>
artifact darwin amd64 targz blacklang-v0.2.0-darwin-amd64.tar.gz sha256 <hash>
artifact darwin arm64 targz blacklang-v0.2.0-darwin-arm64.tar.gz sha256 <hash>
```

Rules:

- `release` is the semantic version tag.
- `channel` is `dev`, `preview`, or `stable`.
- `cli` is the command name exposed to users.
- Each `artifact` line is append-only inside a released manifest.
- Hash values must be generated from the final archive bytes.
- Each released archive must have a sibling detached signature named `<artifact>.sig`.

## manifest.blackdir Shape

Each archive includes its own manifest:

```blackdir
package blacklang-cli
version v0.2.0
os windows
arch amd64
binary black.exe
command black
license MIT
source protected
```

Rules:

- `source protected` means the artifact is a compiled CLI release, not a source release.
- `binary` must match the executable file inside the archive.
- `command` must stay `black` even when the Windows file name is `black.exe`.

## Checksums

`checksums.sha256` uses the common checksum format:

```text
<sha256>  blacklang-v0.2.0-windows-amd64.zip
<sha256>  blacklang-v0.2.0-linux-amd64.tar.gz
```

Rules:

- Every archive listed in `release.blackdir` must have a checksum line.
- Every checksum line must point to a file in the same release root.
- Checksums are generated after archives are finalized.

## Signed Release Verification

Before public install paths are trusted, run:

```bash
node scripts/verify-release-trust.mjs artifacts/releases/<version> --json --strict
```

The verifier checks:

- `release.blackdir`
- `checksums.sha256`
- archive SHA-256 hashes
- detached Ed25519 signatures named `<artifact>.sig`
- trusted public key from `BLACKLANG_RELEASE_PUBLIC_KEY` or `BLACKLANG_RELEASE_PUBLIC_KEY_FILE`

Run `node packages/registry/scripts/validate-registry.mjs` as the companion policy check for release transparency and key rotation metadata. The verifier is read-only. It never creates signatures and never reads private keys.

## Checksum Script

Release checksums are generated with:

```powershell
.\scripts\write-release-checksums.ps1
```

Optional parameters:

```powershell
.\scripts\write-release-checksums.ps1 -Version v0.2.0 -Channel stable
```

Rules:

- The default version is read from `dist/black.exe version` and normalized with a `v` prefix.
- The script scans `artifacts/releases/<version>/` for finalized release archives.
- The script writes `checksums.sha256`.
- The script writes `release.blackdir`.
- `release.blackdir` artifact lines include OS, arch, archive type, archive name, and SHA-256 hash.
- The script does not build or modify release archives.

## Install Verification

After extracting an archive, users and CI should run:

```bash
black version
black --help
```

AI agents and CI should prefer the machine-readable version output:

```bash
black version --json
```

## Non-Goals for This Layout

This layout does not define package-manager publishing behavior.

## Editor Extension Package

The compiler-backed editor bridge source lives at:

```text
editors/vscode-blacklang/
```

It can be validated without launching VS Code:

```bash
cd editors/vscode-blacklang
npm test
```

When the VS Code packaging tool is available, build the shared local `.vsix` with:

```bash
npm run package:vsix
```

The extension must stay a thin bridge over `black ide --json` and `black ide diagnostics <file> --json`. It must not reimplement BlackLang parsing, validation, or snippets in JavaScript.

The same bridge is registered as prepared VS Code Marketplace, Open VSX, and Cursor-compatible VSIX channel metadata in `docs/editor-marketplace.md`, `packages/registry/package-index.blackdir`, and `adapters/marketplace/adapter-index.blackdir`. External publication remains a release-owner step after release trust verification.

npm, Homebrew, Scoop, Winget, Chocolatey, Docker, and GitHub Releases may reuse these archives, but their publishing rules live in separate release automation steps.

The first npm wrapper plan is documented in `docs/npm-wrapper.md`.

Install paths for local development, GitHub Releases, and npm are documented in `docs/install.md`.
