Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
5df276b
test(DEN-2923): pin offline tool-profile candidate
ORESoftware Aug 8, 2026
79ec4cf
test(DEN-2923): add black-box offline tool-profile canary
ORESoftware Aug 8, 2026
fc65c5e
ci(DEN-2923): certify offline tool profiles on three platforms
ORESoftware Aug 8, 2026
1d041d4
docs(DEN-2923): document independent offline tool-profile gate
ORESoftware Aug 8, 2026
f0c1243
test(DEN-2923): ignore durable operation-lock rendezvous bytes
ORESoftware Aug 8, 2026
4170145
test(DEN-2923): keep certification checkout byte-clean
ORESoftware Aug 8, 2026
a98ed79
ci(DEN-2923): run semantic project-state wrapper
ORESoftware Aug 8, 2026
4855935
test(DEN-2923): assemble fake token at runtime
ORESoftware Aug 8, 2026
60b9799
ci(DEN-2923): use setup-python command across platforms
ORESoftware Aug 8, 2026
515cddc
test(DEN-2923): pin rustfmt-clean product candidate
ORESoftware Aug 8, 2026
3ad2b6e
test(DEN-2923): pin failure-atomic profile candidate
ORESoftware Aug 8, 2026
3da9c5f
test(DEN-2923): pin rustfmt-clean rollback candidate
ORESoftware Aug 8, 2026
ca181a4
ci(DEN-2923): materialize Windows executable sync repair
ORESoftware Aug 8, 2026
ce8680d
test(DEN-2923): invoke Windows batch tools without literal quotes
ORESoftware Aug 8, 2026
f25d26a
ci(DEN-2923): certify complete Windows tool-profile repair
ORESoftware Aug 8, 2026
a31c698
test(DEN-2923): pin certified Windows tool-profile repair
ORESoftware Aug 8, 2026
b959881
test(DEN-2923): remove temporary Windows repair materializer
ORESoftware Aug 8, 2026
808daad
test(DEN-2923): pin connector-authored exact candidate
ORESoftware Aug 8, 2026
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
270 changes: 270 additions & 0 deletions .github/workflows/zed-tool-offline-profile.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,270 @@
name: zed-tool frozen offline profile

on:
pull_request:
paths:
- ".github/workflows/zed-tool-offline-profile.yml"
- ".zed-tool-candidate-ref"
- "scripts/zed_tool_offline_profile.py"
- "scripts/run_zed_tool_offline_profile.py"
- "docs/zed-tool-offline-profile.md"
push:
branches: [main]
paths:
- ".github/workflows/zed-tool-offline-profile.yml"
- ".zed-tool-candidate-ref"
- "scripts/zed_tool_offline_profile.py"
- "scripts/run_zed_tool_offline_profile.py"
- "docs/zed-tool-offline-profile.md"
workflow_dispatch:
inputs:
zed_cli_ref:
description: Optional full zed-cli commit override
required: false
default: ""

permissions:
contents: read

concurrency:
group: zed-tool-offline-profile-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true

env:
ZED_INTERFACES_REF: a23cdd2ac509a39ca6fd6d21a3774fdd3a0f7660

jobs:
quality:
name: exact candidate Rust quality
runs-on: ubuntu-24.04
timeout-minutes: 40
steps:
- name: Check out certification harness
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
path: harness
fetch-depth: 1
persist-credentials: false
show-progress: false

- name: Load immutable candidate pin
id: pin
shell: bash
run: |
set -euo pipefail
override="${{ github.event.inputs.zed_cli_ref || '' }}"
if [[ -n "$override" ]]; then
ref="$override"
else
ref="$(tr -d '[:space:]' < harness/.zed-tool-candidate-ref)"
fi
[[ "$ref" =~ ^[0-9a-f]{40}$ ]]
printf 'ref=%s\n' "$ref" >> "$GITHUB_OUTPUT"

- name: Check out exact zed-cli candidate
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
repository: zed-pkg/zed-cli
ref: ${{ steps.pin.outputs.ref }}
path: zed-cli
fetch-depth: 1
persist-credentials: false
show-progress: false

- name: Check out exact shared interfaces
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
repository: zed-pkg/zed-interfaces
ref: ${{ env.ZED_INTERFACES_REF }}
path: zed-interfaces
fetch-depth: 1
persist-credentials: false
show-progress: false

- name: Install pinned Rust toolchain action
uses: dtolnay/rust-toolchain@4be7066ada62dd38de10e7b70166bc74ed198c30
with:
toolchain: stable
components: rustfmt,clippy

- name: Restore Rust build cache
uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32
with:
workspaces: zed-cli
shared-key: den-2923-quality

- name: Verify pins, formatting, focused tests, and strict Clippy
shell: bash
run: |
set -euo pipefail
test "$(git -C zed-cli rev-parse HEAD)" = "${{ steps.pin.outputs.ref }}"
test "$(git -C zed-interfaces rev-parse HEAD)" = "$ZED_INTERFACES_REF"
grep -F "rev = \"$ZED_INTERFACES_REF\"" zed-cli/Cargo.toml
grep -F "#$ZED_INTERFACES_REF" zed-cli/Cargo.lock
python3 - <<'PY'
from pathlib import Path
for source in (
Path('harness/scripts/zed_tool_offline_profile.py'),
Path('harness/scripts/run_zed_tool_offline_profile.py'),
):
compile(source.read_text(encoding='utf-8'), str(source), 'exec')
PY
cargo fmt --all --check --manifest-path zed-cli/Cargo.toml
cargo test --locked --manifest-path zed-cli/Cargo.toml --lib tool_profile::tests
cargo test --locked --manifest-path zed-cli/Cargo.toml --test tool_profile_cli
cargo clippy --locked --manifest-path zed-cli/Cargo.toml \
--bin zed-tool --test tool_profile_cli -- -D warnings

blackbox:
name: offline profile / ${{ matrix.os }}
runs-on: ${{ matrix.os }}
timeout-minutes: 45
strategy:
fail-fast: false
matrix:
include:
- os: ubuntu-24.04
target: x86_64-unknown-linux-gnu
platform_os: linux
arch: x86_64
- os: macos-15
target: aarch64-apple-darwin
platform_os: macos
arch: aarch64
- os: windows-2025
target: x86_64-pc-windows-msvc
platform_os: windows
arch: x86_64
steps:
- name: Check out certification harness
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
path: harness
fetch-depth: 1
persist-credentials: false
show-progress: false

- name: Load immutable candidate pin
id: pin
shell: bash
run: |
set -euo pipefail
override="${{ github.event.inputs.zed_cli_ref || '' }}"
if [[ -n "$override" ]]; then
ref="$override"
else
ref="$(tr -d '[:space:]' < harness/.zed-tool-candidate-ref)"
fi
[[ "$ref" =~ ^[0-9a-f]{40}$ ]]
printf 'ref=%s\n' "$ref" >> "$GITHUB_OUTPUT"

- name: Check out exact zed-cli candidate
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
repository: zed-pkg/zed-cli
ref: ${{ steps.pin.outputs.ref }}
path: zed-cli
fetch-depth: 1
persist-credentials: false
show-progress: false

- name: Check out exact shared interfaces
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
repository: zed-pkg/zed-interfaces
ref: ${{ env.ZED_INTERFACES_REF }}
path: zed-interfaces
fetch-depth: 1
persist-credentials: false
show-progress: false

- name: Install pinned Python runtime
uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
with:
python-version: "3.12"
cache: ""

- name: Install pinned Rust toolchain action
uses: dtolnay/rust-toolchain@4be7066ada62dd38de10e7b70166bc74ed198c30
with:
toolchain: stable

- name: Restore Rust build cache
uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32
with:
workspaces: zed-cli
shared-key: den-2923-${{ matrix.os }}

- name: Build exact zed-tool binary
shell: bash
run: |
set -euo pipefail
test "$(git -C zed-cli rev-parse HEAD)" = "${{ steps.pin.outputs.ref }}"
test "$(git -C zed-interfaces rev-parse HEAD)" = "$ZED_INTERFACES_REF"
cargo build --locked --release --manifest-path zed-cli/Cargo.toml --bin zed-tool
binary="zed-cli/target/release/zed-tool"
if [[ "${{ runner.os }}" == Windows ]]; then
binary="${binary}.exe"
fi
test -f "$binary"
printf 'binary=%s\n' "$binary" >> "$GITHUB_ENV"

- name: Run independent frozen/offline profile contract
shell: bash
env:
WORK_ROOT: ${{ runner.temp }}/zed-tool-offline-profile
run: |
set -euo pipefail
test ! -e "$WORK_ROOT"
python harness/scripts/run_zed_tool_offline_profile.py \
--zed-tool "$binary" \
--work-root "$WORK_ROOT" \
--target "${{ matrix.target }}" \
--os "${{ matrix.platform_os }}" \
--arch "${{ matrix.arch }}" \
--candidate "${{ steps.pin.outputs.ref }}" \
2>&1 | tee "$RUNNER_TEMP/zed-tool-offline-profile.log"

- name: Prove all source checkouts remain immutable
shell: bash
run: |
set -euo pipefail
test -z "$(git -C harness status --porcelain=v1 --untracked-files=all)"
test -z "$(git -C zed-cli status --porcelain=v1 --untracked-files=all)"
test -z "$(git -C zed-interfaces status --porcelain=v1 --untracked-files=all)"

- name: Collect bounded diagnostics
if: failure()
shell: bash
env:
WORK_ROOT: ${{ runner.temp }}/zed-tool-offline-profile
run: |
set +e
diagnostics="$RUNNER_TEMP/zed-tool-offline-diagnostics"
mkdir -p "$diagnostics"
cp "$RUNNER_TEMP/zed-tool-offline-profile.log" "$diagnostics/workflow.log" 2>/dev/null || true
cp "$WORK_ROOT/evidence/transcript.log" "$diagnostics/transcript.log" 2>/dev/null || true
cp "$WORK_ROOT/evidence/result.json" "$diagnostics/result.json" 2>/dev/null || true
git -C harness status --porcelain=v1 --untracked-files=all > "$diagnostics/harness-status.txt" 2>&1
git -C zed-cli status --porcelain=v1 --untracked-files=all > "$diagnostics/zed-cli-status.txt" 2>&1
git -C zed-interfaces status --porcelain=v1 --untracked-files=all > "$diagnostics/interfaces-status.txt" 2>&1

- name: Upload pass evidence
if: success()
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: zed-tool-offline-profile-${{ runner.os }}-${{ steps.pin.outputs.ref }}
path: ${{ runner.temp }}/zed-tool-offline-profile/evidence
if-no-files-found: error
retention-days: 7
include-hidden-files: false

- name: Upload failure diagnostics
if: failure()
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: zed-tool-offline-profile-failure-${{ runner.os }}-${{ github.run_id }}
path: ${{ runner.temp }}/zed-tool-offline-diagnostics
if-no-files-found: warn
retention-days: 7
include-hidden-files: false
1 change: 1 addition & 0 deletions .zed-tool-candidate-ref
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
77a19fe3be0520b29e0c2fef2072518a0f6d043b
73 changes: 73 additions & 0 deletions docs/zed-tool-offline-profile.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
# `zed-tool` frozen offline profile certification

Tracking: DEN-2923, DEN-1437, DEN-1482, DEN-1442

This repository independently certifies the staged product command from
`zed-pkg/zed-cli`:

```console
zed-tool --lock .zed/environment.lock.json --json verify --portable
zed-tool --lock .zed/environment.lock.json --json list --target <target>
zed-tool --lock .zed/environment.lock.json --json install \
--target <target> --offline --home <zed-home>
```

The exact candidate commit is stored in `.zed-tool-candidate-ref`. Manual
workflow overrides must also be full 40-character commits. The workflow checks
out the exact shared `zed-interfaces` revision recorded by the candidate and
rejects disagreement between `Cargo.toml`, `Cargo.lock`, and the certification
pin.

## Black-box boundary

`scripts/zed_tool_offline_profile.py` imports no implementation module from
`zed-cli` or `zed-interfaces`. It constructs:

- one deterministic `tar.gz` containing a small platform-native command;
- one exact manager-neutral `EnvironmentLock` JSON document;
- one content-addressed local cache entry; and
- disposable project, Zed home, profile, and store roots.

It then drives only the compiled `zed-tool` executable. Ubuntu 24.04, macOS 15,
and Windows Server 2025 each certify:

- portable lock verification and exact-target listing;
- frozen installation from authenticated local cache bytes;
- execution of the installed command and alias;
- byte-stable `unchanged` replay;
- a second project reusing the same cache and content-addressed store;
- missing-cache, changed-hash, wrong-size, executable-collision, online-mode,
plan-digest, and unsafe-target rejection before profile creation;
- a project-relative, secret-free `profile.json`; and
- immutable harness, product, and interface checkouts.

A malformed credentials file, fake Zed token, unreachable registry, and failing
HTTP/HTTPS/ALL proxy are present during the black-box run. Success therefore
cannot depend on credential parsing, registry discovery, or network fallback.
The harness executes the installed fixture command itself only after product
installation succeeds; `zed-tool` remains responsible solely for verification,
safe extraction, store publication, and profile activation.

## Product-quality gate

A separate Ubuntu job runs candidate formatting, the focused library and
compiled CLI tests, and strict Clippy against `zed-tool` and its integration
target. The external gate complements rather than replaces the candidate's own
permanent product workflow.

## Security and evidence

The workflow has `contents: read` only, uses full-SHA Action pins, disables
persisted checkout credentials, and owns all mutable state below runner-temporary
directories. It receives no GitHub PAT, Linear token, Cloudflare/R2 credential,
registry credential, signing material, or OIDC permission.

Successful platform jobs retain only `result.json` and the command transcript
for seven days. Failed jobs retain bounded logs and checkout status; they do not
upload cache archives, store contents, credentials files, or tool-profile
payloads.

The current slice does not certify downloads, version discovery, signatures,
multiple active versions, backend plugins, global PATH mutation, lazy shims,
update/prune, or `zed dev` activation. Those remain separate product and
certification slices.
Loading