Skip to content
Closed
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
232 changes: 135 additions & 97 deletions .github/workflows/release.yml

Large diffs are not rendered by default.

7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,16 @@ The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and

### Changed

- Bind Tauri packaging to a fail-closed cross-manifest release-version verifier so `package.json`, `Cargo.toml`, `tauri.conf.json`, and any `v*` release tag must agree on one valid Semantic Version before a bundle is built.
- Add retry-safe release concurrency: fresh first attempts may supersede stale runs, while explicit GitHub rerun attempts do not self-cancel inside the same concurrency group.
- Replace generator-era Cargo package metadata with the DiskSage product description, MIT license expression, canonical source repository URL, and `publish = false` registry-publication boundary; deliberately omit Cargo's deprecated `authors` field, verify publication refusal through Cargo's versioned parsed metadata rather than substring matching, and regression-test commented/out-of-table decoys together with the retained acquisition metadata and doctoring evidence.
- Require a fresh, exact, human-attributed approval and rationale for cloud copy-only and existing-copy adoption actions, with a 15-minute authorization lifetime bound to the candidate, destination, provider, account scope, and review fingerprint.
- Return the candidate-specific cloud copy approval action, exact confirmation phrase, and maximum approval age from the Rust plan contract; the frontend only displays and submits that backend-authored phrase and fails closed when it is missing or does not match the candidate action.
- Align the frontend toolchain on Vite 8.2 and `@sveltejs/vite-plugin-svelte` 7.2 so the declared peer dependency graph is installable and reproducible.
- Declare the supported Node.js runtime floor as Node.js 20.19 or Node.js 22.12 and later, matching Vite 8 requirements.
- Pin the primary test workflow to Node.js 20.19.0 so the minimum supported runtime is continuously verified.
- Document the iCloud batch operation's local-only versus path-free shareable evidence boundary and map its fail-closed controls to NIST SP 800-53 Release 5.2.0, ISO/IEC 27040:2024, and primary secure-design literature with APA 7th references and deterministic documentation contract tests.
- Refresh the Tauri CSP standards evidence to the current July 29, 2026 W3C Content Security Policy Level 3 Working Draft and regression-test its exact publication URL so future doctoring cannot silently drift back to an older draft.

### Fixed

Expand All @@ -22,6 +26,9 @@ The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and

### Security

- Add buyer-verifiable release artifact provenance with read-only platform build jobs, a tag-only least-privilege attestation job, exact 17-file admission, adjacent operational-CLI SHA-256 verification, preserved artifact namespaces, non-regular-entry rejection, and a separate publication job that cannot publish before attestation succeeds.
- Require explicit organization-tenant authority when either the destination account scope is organization-owned or the canonical organization-sensitive review reason is present; fail closed in both frontend projection and durable Rust transfer authorization even when the ordinary review flag is absent, and regression-test contradictory signal combinations.
- Enable an explicit fail-closed Tauri Content Security Policy to keep executable scripts and fonts local, grant production network authority only to the Tauri IPC transport, confine Vite WebSocket HMR to a separate development-only CSP, deny object/frame/base-URI authority, deny form submissions with explicit `form-action 'none'`, deny unused worker, media, and web-app-manifest fetch authority with explicit `'none'` directives, and regression-test against null, wildcard, remote-script/style, eval, and development-authority leakage.
- Re-verify the installed GGUF immediately before llama.cpp initialization and retain the verified model handle through llama.cpp loading: reject missing, linked, non-regular, identity-raced, short, oversized, unreadable, or SHA-256-mismatched artifacts with stable path-free errors; use a stable descriptor path on Unix and a Windows read-sharing guard so the mutable source pathname cannot be substituted between verification and model parsing.
- Bind the default on-device GGUF model to an immutable upstream revision, exact byte count, and SHA-256 digest; replace whole-model buffering and named sibling staging with bounded streaming into an unnamed same-directory temporary file; ignore and preserve unrelated legacy `.part` paths; refuse destination overwrite with create-new semantics; capture destination ownership from the returned open file handle; re-read and rehash the still-open staging source while copying; flush, sync, re-read, and rehash the destination before final acceptance; reject same-file source or destination mutation; preserve foreign destination replacements through identity-bound cleanup; and keep model installation inside the Rust coverage surface with privacy-safe stable errors and deterministic race regressions.
- Persist copy-approval provenance in immutable receipt lineage, reject stale, generic, mismatched, or tampered approvals, and retain explicit backward readability for pre-approval receipt formats.
Expand Down
102 changes: 102 additions & 0 deletions docs/doctoring/release-artifact-provenance.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
# Release artifact provenance

## Decision

DiskSage treats provenance as a release gate rather than optional release metadata. A tagged release may be published only after all operating-system build jobs finish, the exact uploaded artifact set is downloaded into a clean tag-only job, every shipped operational CLI checksum is verified, and GitHub creates signed build-provenance attestations for the files that will be published.

This design keeps three authorities separate:

1. `build` compiles and tests release candidates with read-only repository access, then uploads ephemeral workflow artifacts.
2. `attest-release` receives only `contents: read`, `id-token: write`, and `attestations: write`. It verifies the expected platform and CLI set before generating provenance.
3. `publish-release` receives `contents: write` only after `attest-release` succeeds. It cannot publish an unattested build because it has a durable `needs: attest-release` dependency.

Pull requests and manual non-tag builds still produce inspectable artifacts, but they cannot request an OpenID Connect identity, create durable attestations, or publish a GitHub Release through these jobs.

## Evidence contract

The authoritative implementation is `.github/workflows/release.yml`.

The release contract requires all of the following:

- checkout binds every platform build to `github.event.pull_request.head.sha` for pull requests and `github.sha` for tags or manual runs, rather than silently treating a generated pull-request merge ref as exact-head evidence;
- release concurrency uses `github.run_attempt == 1`, so a fresh first attempt supersedes stale work while explicit rerun attempts do not cancel themselves inside the same concurrency group;
- the three platform builds upload the exact bundle and operational CLI paths that later jobs consume;
- release workflow artifacts use the `release-disksage-*` namespace, which excludes concurrently uploaded `disksage-gpu-*` diagnostic bundles;
- attestation and publication downloads preserve each workflow artifact in its own directory instead of flattening archives, so duplicate basenames remain observable and last-writer-wins extraction cannot erase evidence before admission;
- release publication is absent from the matrix build job, preventing any matrix member from publishing before the complete set exists;
- the attestation and publication jobs run only for `refs/tags/`;
- the attestation job depends on the complete build matrix;
- Linux `.deb` and `.AppImage`, Windows `.msi` and NSIS `.exe`, and macOS `.dmg` bundles are present exactly once in their expected bundle paths;
- all six platform-specific operational CLIs and all six corresponding `.sha256` files are each present exactly once;
- the preserved release tree contains exactly 17 regular files and no symlink, device, socket, FIFO, or other non-regular entry, so unreviewed debug output, logs, dumps, or unrelated executables cannot become attested release subjects;
- every checksum file contains exactly one SHA-256 record naming its adjacent expected CLI basename, so alternate, absolute, traversing, or decoy filenames are rejected before digest verification;
- each checksum is verified before provenance generation;
- `actions/download-artifact` is immutably pinned to commit `37930b1c2abaa49bbe596cd826c3c89aef350131`, the upstream `v7.0.0` tag commit;
- `actions/attest` is immutably pinned to commit `59d89421af93a897026c735860bf21b6eb4f7b26`, the upstream `v4.1.0` tag commit;
- every published file is a subject of the generated attestation; and
- publication depends on successful attestation rather than merely running in parallel with it.

GitHub's action emits an in-toto Statement v1 containing a SLSA Provenance v1 predicate. SLSA specification version 1.2 is the current approved framework version, while the stable build-provenance predicate URI remains `https://slsa.dev/provenance/v1`.

## Buyer and operator verification

Download one release artifact without renaming or modifying it, install a current GitHub CLI, authenticate if the repository visibility requires it, and run:

```bash
gh attestation verify PATH/TO/ARTIFACT -R ContextualWisdomLab/disksage
```

The verifier must bind the artifact digest to `ContextualWisdomLab/disksage`. A successful result demonstrates that GitHub Actions produced an attestation for those exact bytes; it does not independently prove that the software is defect-free, that every dependency is trustworthy, or that the build platform satisfies a claimed SLSA level. Those are separate review and assurance questions.

For offline evidence collection, download the attestation bundle while network access is available:

```bash
gh attestation download PATH/TO/ARTIFACT -R ContextualWisdomLab/disksage
```

Retain the artifact, the downloaded bundle, the release tag, the source commit SHA, and the successful release workflow URL together. Do not substitute an attestation for a differently named or older artifact, even when the version string appears identical.

## Failure and stale-evidence behavior

The pipeline fails closed when an expected platform bundle, operational CLI, or checksum file is absent or duplicated. Artifact namespaces remain separate during download, so the same required filename contributed by two platform archives remains two filesystem entries and is rejected rather than silently overwritten. It validates checksum-record semantics and digests first so an invalid or redirected record receives the specific actionable diagnostic, then rejects any eighteenth regular file and every non-regular filesystem entry before attestation or publication. This exact-set rule prevents a build step from silently adding an unreviewed diagnostic archive, crash dump, log, secret-bearing output, or unrelated executable to the release. Path-scoped checks distinguish the Windows NSIS installer from the two separately shipped Windows operational CLI executables. The pipeline also fails when a checksum record names a file other than its adjacent operational CLI, contains additional fields or records, or presents a malformed digest. A checksum mismatch stops the attestation job. A failed, cancelled, skipped, neutral, missing, or stale-head attestation job cannot satisfy the publication dependency.

Concurrency cancellation applies only to a first workflow attempt. A newer first attempt may cancel stale work for the same ref, but an explicit rerun has `github.run_attempt > 1` and therefore cannot cancel itself. A rerun remains non-authoritative until every required exact-head job in that attempt completes successfully.

Attestations bind artifact digests, not mutable filenames. Rebuilding the same version produces different bytes and therefore requires new exact-build attestations. Evidence from an earlier workflow run or commit must never authorize publication of a later head.

## Privacy and security boundaries

The attestation describes build provenance and artifact digests. It must not include API keys, user data, local disk inventory, file paths from an operator workstation, model prompts, cleanup plans, or dynamic command output containing private host information. GitHub Secrets remain unavailable to pull-request-controlled release tests unless a separately reviewed workflow explicitly requires them. The exact 17-file allowlist is also a privacy boundary: unexpected diagnostics and transient build outputs are rejected rather than made durable through an attestation or GitHub Release.

All third-party actions in the release path use immutable 40-character commit SHAs. The attestation job receives no `contents: write` permission, and the publication job receives neither `id-token: write` nor `attestations: write`. This separation limits the impact of a compromised publication or attestation step.

## Rollback and migration

Rollback is a workflow-source revert, not deletion or reuse of old attestations:

1. revert the provenance workflow commit through an independently reviewed pull request;
2. rerun all exact-current-head test, security, packaging, and release-acceptance checks;
3. do not publish a replacement tag until the approved workflow state is on the protected branch; and
4. document why provenance was removed or changed in `CHANGELOG.md` and the release notes.

Already published attestations remain historical evidence for their original artifact digests. They must not be presented as evidence for replacement binaries. If a release artifact is withdrawn, mark the GitHub Release accordingly and publish a new version with new provenance rather than silently replacing assets under the same tag.

## MSA compatibility

Provenance is attached at the DiskSage release boundary and does not require `naruon`, `contextual-orchestrator`, or organization-central services at runtime. CWL services may consume the same verification contract as a module integration gate: verify the artifact against `ContextualWisdomLab/disksage`, bind the verified digest in deployment metadata, and preserve that digest across promotion and rollback.

## APA 7th references

GitHub. (n.d.). *Using artifact attestations to establish provenance for builds*. GitHub Docs. Retrieved August 6, 2026, from https://docs.github.com/en/actions/how-tos/secure-your-work/use-artifact-attestations/use-artifact-attestations

GitHub. (n.d.). *Verifying attestations offline*. GitHub Docs. Retrieved August 6, 2026, from https://docs.github.com/en/actions/how-tos/secure-your-work/use-artifact-attestations/verify-attestations-offline

in-toto Project. (n.d.). *in-toto attestation framework specification (Version 1.2)*. GitHub. Retrieved August 6, 2026, from https://github.com/in-toto/attestation/blob/v1.2.0/spec/README.md

Supply-chain Levels for Software Artifacts. (n.d.). *SLSA specification (Version 1.2)*. The Linux Foundation. Retrieved August 6, 2026, from https://slsa.dev/spec/v1.2/

Supply-chain Levels for Software Artifacts. (n.d.). *Build: Verifying artifacts (Version 1.2)*. The Linux Foundation. Retrieved August 6, 2026, from https://slsa.dev/spec/v1.2/verifying-artifacts

## Reference verification note

The sources above were rechecked against their authoritative upstream locations on August 6, 2026. GitHub documentation was used for the supported action permissions and verification commands; upstream tag comparisons established the immutable action commits; the SLSA and in-toto specifications were used for provenance semantics and attestation structure. This document makes no unsupported claim that the workflow alone certifies a particular SLSA level.
50 changes: 50 additions & 0 deletions docs/doctoring/release-version-contract.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# Release version contract

## Decision

DiskSage fails closed before packaging when its buyer-visible release versions are not identical. `package.json`, `src-tauri/Cargo.toml`, and `src-tauri/tauri.conf.json` must each expose one identical Semantic Versioning value. A tag-triggered release must additionally use the exact tag `v<manifest version>`.

The authoritative executable policy is `scripts/ci/release-version.mjs`. The package `build` command runs that policy before Vite compilation. Tauri executes `npm run build` through `beforeBuildCommand`, so the same check precedes Linux, Windows, and macOS bundle creation without relying on one operating system's shell syntax. Exact production coverage remains an independent CI authority owned by the coverage workflow contract; the release-version gate does not duplicate or weaken it.

## Evidence contract

The verifier:

- reads each JSON manifest as UTF-8 and requires one non-empty string `version`;
- reads exactly one literal `version = "..."` from Cargo's `[package]` section and refuses absent, duplicated, or workspace-inherited ambiguity;
- requires all three values to be identical;
- requires the shared value to satisfy Semantic Versioning 2.0.0, including rejection of leading zeroes in numeric prerelease identifiers such as `1.0.0-01` and `1.0.0-alpha.01`;
- treats branch and pull-request builds as version-consistency checks without inventing a release tag;
- when `GITHUB_REF` is a tag reference, requires `GITHUB_REF_NAME` to equal `v<manifest version>` exactly;
- emits stable privacy-safe diagnostics containing only repository-controlled version values; and
- runs under ordinary read-only build authority before attestation or publication authority exists.

`src/lib/releaseVersionContract.test.ts` verifies valid releases, prerelease/build metadata, Cargo section parsing, invalid JSON, missing and empty versions, duplicate Cargo versions, each manifest-disagreement path, malformed Semantic Versioning including numeric prerelease leading zeroes, tag drift, repository-root loading, and stable CLI success and failure behavior.

## Failure and stale-evidence behavior

A mismatch terminates `npm run build`; therefore Tauri cannot create a bundle and downstream provenance or publication jobs cannot receive release artifacts. A successful check from another commit, branch, tag, or workflow attempt is not reusable. Any manifest edit changes the exact current head and requires the complete Test, Release, security, review, packaging, provenance, and release-acceptance gates to run again.

The contract does not bump versions automatically. Version changes remain explicit reviewed source changes across all three manifests and `CHANGELOG.md`. Release automation must never rewrite a tag or manifest to make a mismatch pass.

## Rollback and migration

Rollback requires a reviewed source revert. After a revert, run the exact-current-head coverage and packaging gates and confirm that all three manifests still agree. Do not reuse or replace assets under an existing tag; publish a new version with new provenance when replacement binaries are necessary.

## MSA compatibility

The verifier is standalone and requires no Naruon, contextual-orchestrator, model API, user data, or network access. CWL services that embed DiskSage may invoke the same package build contract or independently compare the three version sources and the deployment artifact digest before promotion.

## APA 7th references

npm, Inc. (n.d.). *Creating a package.json file*. npm Docs. Retrieved August 6, 2026, from https://docs.npmjs.com/creating-a-package-json-file/

Rust Project. (n.d.). *The manifest format*. The Cargo Book. Retrieved August 6, 2026, from https://doc.rust-lang.org/cargo/reference/manifest.html

Semantic Versioning. (n.d.). *Semantic Versioning 2.0.0*. Retrieved August 6, 2026, from https://semver.org/spec/v2.0.0.html

Tauri Programme within The Commons Conservancy. (n.d.). *Distribute*. Tauri. Retrieved August 6, 2026, from https://v2.tauri.app/distribute/

## Reference verification note

The authoritative publisher sources above were rechecked on August 6, 2026. They support the manifest locations, package version semantics, including the prohibition on leading zeroes in numeric prerelease identifiers, and distribution boundary used by this contract; they do not imply external certification of DiskSage.
Loading
Loading