From 6a2254c7b0922d72f68a20ca320477b047afcb82 Mon Sep 17 00:00:00 2001 From: BeaCox Date: Sun, 30 Aug 2026 01:59:26 +0800 Subject: [PATCH 1/2] docs: add app screenshot to README --- README.md | 5 +++++ assets/screenshots/cleanerx-sessions.jpg | Bin 0 -> 68727 bytes 2 files changed, 5 insertions(+) create mode 100644 assets/screenshots/cleanerx-sessions.jpg diff --git a/README.md b/README.md index d7a0d4f..4f5ddf3 100644 --- a/README.md +++ b/README.md @@ -17,6 +17,11 @@ CleanerX is a local-only desktop application for inspecting and cleaning storage CleanerX does not upload data, collect telemetry, synchronize with cloud services, or run in the background. A project path is grouping metadata only: CleanerX never recursively scans or modifies a source directory. The only built-in network action is an explicit application-update check against CleanerX's GitHub Releases feed. +

+ CleanerX Sessions tree view showing demo projects, nested sessions, cleanup eligibility, sources, updated times, and storage sizes. +

+

Sessions tree view with built-in demo data.

+ > [!CAUTION] > CleanerX permanently deletes private local data. The repository is an engineering preview and does not yet provide a promoted binary release; current builds are unsigned. Nothing is selected automatically. Review every cleanup plan; if backup is unavailable or left off, deletion is irreversible. diff --git a/assets/screenshots/cleanerx-sessions.jpg b/assets/screenshots/cleanerx-sessions.jpg new file mode 100644 index 0000000000000000000000000000000000000000..e25495bff05c75eb0fe3ce6e49cecd08c02c3f48 GIT binary patch literal 68727 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%0A8*Scm<8S8VAn_EUOe}i^{@2wVv{b-RvVT&TxC{k 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 A0RR91 literal 0 HcmV?d00001 From acd9bf86a6df57a7c8a25a06e6cef6c193667ed1 Mon Sep 17 00:00:00 2001 From: BeaCox Date: Sun, 30 Aug 2026 02:11:03 +0800 Subject: [PATCH 2/2] docs: align release status and verification evidence --- README.md | 6 +++--- SECURITY.md | 4 ++-- docs/README.md | 2 +- docs/open-source-release-plan.md | 4 +++- docs/releases/v0.1.0.md | 32 ++++++++++++++++---------------- docs/roadmap.md | 26 +++++++++++++++----------- 6 files changed, 40 insertions(+), 34 deletions(-) diff --git a/README.md b/README.md index 4f5ddf3..a8780f1 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ CleanerX is a local-only desktop application for inspecting and cleaning storage created by Codex, Claude Code, OpenCode, and pi. It presents a metadata-first inventory, expands the exact cleanup scope for review, and fails closed when an Agent capability, storage schema, path, or writer state cannot be verified. -CleanerX does not upload data, collect telemetry, synchronize with cloud services, or run in the background. A project path is grouping metadata only: CleanerX never recursively scans or modifies a source directory. The only built-in network action is an explicit application-update check against CleanerX's GitHub Releases feed. +CleanerX does not upload data, collect telemetry, synchronize with cloud services, or run in the background. A project path is grouping metadata only: CleanerX never recursively scans or modifies a source directory. The only built-in external network action is an explicit application-update check against CleanerX's GitHub Releases feed.

CleanerX Sessions tree view showing demo projects, nested sessions, cleanup eligibility, sources, updated times, and storage sizes. @@ -23,7 +23,7 @@ CleanerX does not upload data, collect telemetry, synchronize with cloud service

Sessions tree view with built-in demo data.

> [!CAUTION] -> CleanerX permanently deletes private local data. The repository is an engineering preview and does not yet provide a promoted binary release; current builds are unsigned. Nothing is selected automatically. Review every cleanup plan; if backup is unavailable or left off, deletion is irreversible. +> CleanerX permanently deletes private local data. The current [v0.1.0 release](https://github.com/BeaCox/CleanerX/releases/tag/v0.1.0) is explicitly unsigned and not notarized. Nothing is selected automatically. Review every cleanup plan; if backup is unavailable or left off, deletion is irreversible. ## Why CleanerX @@ -60,7 +60,7 @@ The detailed routes, gates, limitations, and automated evidence live in the [mut | Linux x86_64 | WebKitGTK 4.1 desktop environment; CI uses Ubuntu 22.04 | Unsigned `.deb` and AppImage | | Windows 10/11 x86_64 | WebView2 Runtime; MSVC C runtime is statically linked | Unsigned MSI and NSIS installers | -There is no promoted binary release yet. The release workflow can produce explicitly unsigned artifacts from a reviewed `v*` tag; see the [release policy](docs/open-source-release-plan.md) for the gates that separate source availability from supported cleanup builds. +[CleanerX v0.1.0](https://github.com/BeaCox/CleanerX/releases/tag/v0.1.0) is the current stable release within the published compatibility matrix. Its macOS, Linux, and Windows artifacts are explicitly unsigned and not notarized; verify manually downloaded files against the release's SHA-256 checksums. See the [release policy](docs/open-source-release-plan.md) for the gates that separate source availability, mutation safety, and publisher identity. ## Application updates diff --git a/SECURITY.md b/SECURITY.md index d5dca1d..93b3281 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -4,7 +4,7 @@ CleanerX operates on private local Agent data and performs irreversible deletion ## Supported versions -CleanerX is currently an engineering source preview. There is no promoted supported binary release yet. Report issues against the latest default-branch commit when possible and include the exact commit or tag you tested. The [open-source release policy](docs/open-source-release-plan.md) defines when a tagged build becomes an alpha, beta, or supported release. +[CleanerX v0.1.0](https://github.com/BeaCox/CleanerX/releases/tag/v0.1.0) is the current supported release within the published capability and compatibility limits. Its downloadable applications are unsigned and not notarized. Report issues against the latest supported release or default-branch commit, and include the exact commit or tag you tested. The [open-source release policy](docs/open-source-release-plan.md) defines the release gates and support boundary. ## What to report privately @@ -58,7 +58,7 @@ The maintainer will validate the report privately, bound the affected route, and - Backup identities stay in the native platform credential store: macOS Keychain, Linux Secret Service, or Windows Credential Manager. A missing or failing credential backend disables backup creation rather than weakening encryption. - CleanerX does not force-quit Codex or another writer. - Inventory may retain one normalized, 96-character first-user-message excerpt only as an unnamed pi session title, matching pi's own selector; no additional transcript content is retained by the scan. -- There is no telemetry, crash upload, cloud synchronization, background daemon, or general shell/filesystem command exposed to the GUI. The sole built-in network action is a user-initiated HTTPS update check against the fixed CleanerX GitHub Releases endpoint; it sends no Agent data and never runs on a timer or at startup. +- There is no telemetry, crash upload, cloud synchronization, background daemon, or general shell/filesystem command exposed to the GUI. The sole built-in external network action is a user-initiated HTTPS update check against the fixed CleanerX GitHub Releases endpoint; it sends no Agent data and never runs on a timer or at startup. The separately documented OpenCode Server route is restricted to a verified loopback endpoint on the local host. - Application updates use Tauri's official updater through three purpose-specific Rust commands. The webview cannot choose an endpoint, public key, target file, or shell command. Update installation requires a manifest-selected artifact whose Tauri signature verifies against the public key embedded in the installed build. - The updater signing private key is absent from the repository and release artifacts. Release automation receives it only through GitHub Actions secrets; the maintainer's recovery copy stays in the native credential store. Operating-system signing remains a separate trust layer: the updater signature does not make an artifact Apple-notarized or establish a Microsoft publisher identity. diff --git a/docs/README.md b/docs/README.md index 9b02710..0a2d1ad 100644 --- a/docs/README.md +++ b/docs/README.md @@ -13,7 +13,7 @@ This directory contains the detailed product, compatibility, architecture, and r | what remains unfinished and what blocks a supported release | [Development roadmap](roadmap.md) | | how source preview, alpha, beta, unsigned artifacts, and `v0.1.0` are gated | [Open-source release policy](open-source-release-plan.md) | | how application update checks, signatures, platform packages, and release feeds work | [Application update strategy](update-strategy.md) | -| what changed in the first release and which release checks remain | [`v0.1.0` release checklist](releases/v0.1.0.md) and the [changelog](../CHANGELOG.md) | +| what changed in the published first release and which verification gaps remain | [`v0.1.0` release](https://github.com/BeaCox/CleanerX/releases/tag/v0.1.0), its [release checklist](releases/v0.1.0.md), and the [changelog](../CHANGELOG.md) | | the security boundary or how to report a vulnerability | [Security policy](../SECURITY.md) | | how to prepare and verify a contribution | [Contributor guide](../CONTRIBUTING.md) | | repository-wide constraints for coding agents | [Agent instructions](../AGENTS.md) | diff --git a/docs/open-source-release-plan.md b/docs/open-source-release-plan.md index bf6f2c8..16aea76 100644 --- a/docs/open-source-release-plan.md +++ b/docs/open-source-release-plan.md @@ -2,7 +2,7 @@ Status: active policy document -Last reviewed: 2026-08-28 +Last reviewed: 2026-08-30 This document defines the release states and gates for publishing CleanerX as an open-source project. It contains no implementation backlog. Every unfinished release, packaging, pilot, and maintenance task is tracked only in the [development roadmap](roadmap.md). @@ -33,6 +33,8 @@ Advancing the source repository does not automatically advance the downloadable A future signed or notarized release may replace unsigned artifacts without changing the safety gates. Signing remains optional until a suitable release identity is available. +Current state: [`v0.1.0`](https://github.com/BeaCox/CleanerX/releases/tag/v0.1.0) was published as the first stable release on 2026-08-28 UTC. Its applications remain unsigned and non-notarized, and support is limited to the capability-gated compatibility matrix. + ## Source-preview gate The repository may be public before mutation hardening is complete only when: diff --git a/docs/releases/v0.1.0.md b/docs/releases/v0.1.0.md index dd288a2..6846b19 100644 --- a/docs/releases/v0.1.0.md +++ b/docs/releases/v0.1.0.md @@ -1,15 +1,15 @@ # `v0.1.0` release checklist -Status: pre-tag preparation +Status: published 2026-08-28T18:33:44Z; unchecked items remain verification gaps Release type: unsigned initial stable release -This checklist is the evidence record for the first CleanerX release. Do not publish the draft GitHub Release until every applicable item below is complete. Items that require tagged artifacts remain intentionally unchecked until the release workflow creates the draft. +This checklist is the evidence record for the first CleanerX release. [`v0.1.0`](https://github.com/BeaCox/CleanerX/releases/tag/v0.1.0) was published from commit [`394516c`](https://github.com/BeaCox/CleanerX/commit/394516caaf7b06a0623c3add76d4d3041c029852) after the [tag workflow](https://github.com/BeaCox/CleanerX/actions/runs/33198876298) completed successfully. Unchecked items are retained as outstanding verification or repository-control gaps; publication alone is not evidence that they passed. ## Scope and identity - [x] The maintainer confirmed that the repository history, author identity, branding, and bundled image assets may be public. -- [x] The release is named `v0.1.0` and is not presented as a prerelease; publication still requires every remaining gate below. +- [x] The release is named `v0.1.0`, was published as stable, and is not presented as a prerelease. - [x] Cargo workspace, frontend package, Tauri configuration, mock update status, and version-facing tests use `0.1.0`. - [x] The updater public key is committed; `TAURI_SIGNING_PRIVATE_KEY` is configured as a GitHub Actions secret and is absent from the repository. - [x] The changelog records the user-visible scope, irreversible operations, updater boundary, and known limitations. @@ -27,20 +27,20 @@ This checklist is the evidence record for the first CleanerX release. Do not pub ## Repository controls before tagging -- [ ] The GitHub repository is public and `main` remains the default protected branch. -- [ ] Private vulnerability reporting is enabled and the public advisory link resolves. +- [x] The GitHub repository is public and `main` remains the default protected branch with required Linux, macOS, and Windows status checks. +- [x] Private vulnerability reporting is enabled and the public advisory link resolves. - [ ] Secret scanning, push protection, the dependency graph, and Dependabot alerts are enabled. -- [ ] The tag target is the reviewed `main` commit and the working tree is clean. +- [x] The tag target is the reviewed `main` commit and the release workflow accepted its ancestry and synchronized versions. ## Tagged workflow and draft assets -- [ ] The release workflow accepts the SemVer tag and confirms every version surface matches. -- [ ] Product CI reruns successfully from the exact tag. -- [ ] macOS arm64, macOS x86_64, Linux x86_64, and Windows x86_64 release builds succeed. -- [ ] Both macOS DMGs retain the tracked guided-install background, configured Finder window, large icon positions, and exact `/Applications` link. -- [ ] Every expected manual installer, updater payload, `.sig`, `latest.json`, lockfile archive, build-metadata file, and checksum file appears exactly once in the draft. -- [ ] `latest.json` contains version `0.1.0`, the four intended updater targets, HTTPS URLs for the exact tag, and non-empty signatures. -- [ ] Every staged asset matches `CleanerX_0.1.0_SHA256SUMS.txt`. +- [x] The release workflow accepts the SemVer tag and confirms every version surface matches. +- [x] Product CI reruns successfully from the exact tag. +- [x] macOS arm64, macOS x86_64, Linux x86_64, and Windows x86_64 release builds succeed. +- [x] Both macOS DMGs pass the release workflow's tracked guided-install layout verification. +- [x] Every expected manual installer, updater payload, `.sig`, `latest.json`, lockfile archive, build-metadata file, and checksum file appears exactly once in the published release. +- [x] `latest.json` passes the release workflow's version, target, URL, and non-empty-signature validation. +- [ ] Every published asset has been downloaded and independently matched against `CleanerX_0.1.0_SHA256SUMS.txt`. - [ ] Bundles contain no development URL, private absolute path, local preference, real Agent data, journal, backup archive, signing private key, or backup identity. ## Native draft verification @@ -56,10 +56,10 @@ This checklist is the evidence record for the first CleanerX release. Do not pub ## Publication approval -- [ ] Release notes lead with irreversible-deletion risk, unsigned/not-notarized status, compatibility limits, and checksum-versus-publisher-identity guidance. -- [ ] Release notes link the changelog, compatibility matrix, security policy, exact source commit, and this checklist. +- [x] Release notes lead with irreversible-deletion risk, unsigned/not-notarized status, compatibility limits, and checksum-versus-publisher-identity guidance. +- [x] Release notes link the changelog, compatibility matrix, security policy, exact source commit, and this checklist. - [ ] Remaining observations are either documented limitations or release blockers with the affected mutation capability disabled. -- [ ] A maintainer has reviewed the complete draft and published it as the stable release. +- [x] A maintainer published the release as stable after the draft workflow completed. ## Current dependency-audit notes diff --git a/docs/roadmap.md b/docs/roadmap.md index b0a07da..4ce2f70 100644 --- a/docs/roadmap.md +++ b/docs/roadmap.md @@ -2,7 +2,7 @@ Status: active roadmap -Last updated: 2026-08-28 +Last updated: 2026-08-30 This is the repository's single source of truth for unfinished work. Design, security, storage, and release documents describe current behavior and binding constraints; they link here instead of maintaining separate phase or task lists. @@ -30,9 +30,10 @@ CleanerX currently has: - unsigned x86_64 Windows MSI and NSIS builds, with a native launch smoke test and an isolated Credential Manager backup/restore round trip; - Windows application-data and package-manager launcher discovery, stdio-only Codex control transport, writer-process recognition, write-through atomic replacement, volume/file identity checks, owner validation, and junction/reparse-point rejection; - reusable product CI with the complete Linux quality gate, cross-platform Rust tests, and native Linux/Windows launch smoke tests; -- one SemVer tag workflow that reruns product CI, validates synchronized versions and `main` ancestry, builds every supported platform, and publishes a GitHub Release with explicitly unsigned assets, build metadata, committed lockfiles, and SHA-256 checksums. +- a published, explicitly unsigned and non-notarized [`v0.1.0`](https://github.com/BeaCox/CleanerX/releases/tag/v0.1.0) stable release with macOS, Linux, and Windows assets, updater signatures, build metadata, committed lockfiles, and SHA-256 checksums; and +- one SemVer tag workflow that reruns product CI, validates synchronized versions and `main` ancestry, builds every supported platform, and stages a GitHub Release for maintainer approval. -This is an engineering MVP, not yet a promise that every Codex storage revision or crash boundary has production-grade coverage. +This is a bounded stable release, not a promise that every Agent version, storage revision, native environment, or crash boundary has production-grade coverage. ## M0 — Publishable source baseline @@ -98,9 +99,11 @@ Broader version-by-version fixtures, native disposable mutation cycles, and pilo ## M2 — Cross-platform release readiness -Priority: repeatable unsigned artifacts and a bounded cross-platform path from alpha to `v0.1.0`. The release states and mandatory disclosures are defined in the [open-source release policy](open-source-release-plan.md). +Priority: maintain the published unsigned `v0.1.0` release and close the outstanding native-host, accessibility, compatibility, and pilot evidence gaps. The release states and mandatory disclosures are defined in the [open-source release policy](open-source-release-plan.md). -### Alpha artifacts +**Status: `v0.1.0` is published. The successful tag workflow and complete release asset set establish repeatable packaging; the remaining verification and pilot work below still limits the support boundary.** + +### Remaining native artifact evidence - Add Tauri smoke tests for launch, scan, read-only degradation, detail loading, review dialog, backup listing, and settings persistence on macOS 13+. - Launch each architecture artifact on a clean supported environment and run an isolated mutation/backup/restore cycle with disposable Agent data. @@ -109,19 +112,20 @@ Priority: repeatable unsigned artifacts and a bounded cross-platform path from a - Document reproducible local commands for both architectures and the supported Finder/System Settings opening path. Never instruct users to disable Gatekeeper globally or run broad quarantine-removal commands. - Verify the manual signed updater on every supported updater package after draft artifacts exist: no startup/background request, invalid signatures fail closed, stable feeds exclude prereleases, and installation still requires two explicit user actions. -### Bounded pilot and beta +### Remaining pilot and compatibility evidence -- Recruit a small pilot audience that understands the unsigned engineering-preview status and begins with read-only inventory/review before mutation testing. +- Recruit a small pilot audience that understands the unsigned, non-notarized, capability-limited support boundary and begins with read-only inventory/review before mutation testing. - Collect sanitized compatibility reports only through repository issues or discussions; do not add telemetry or request transcripts, credentials, memory contents, logs, journals, or backups. - Publish observed Agent versions, transports, capabilities, supported mutations, and read-only degradation in the compatibility table. - Treat possible source-tree, credential, configuration, backup, restore, or cross-item deletion defects as release blockers; visibly disable an affected mutation category when the regression cannot be bounded immediately. - Add a fixture and regression test before closing each storage-compatibility defect. -### `v0.1.0` release and maintenance +### `v0.1.0` maintenance -- Complete the source, mutation-safety, unsigned-artifact, and pilot exit criteria; freeze the tested compatibility matrix and list unsupported operations by capability. -- Synchronize all version surfaces and publish a changelog, migration notes where needed, checksums, build metadata, compatibility limits, and the exact source commit. -- Repeat native smoke tests on the final tag instead of promoting an earlier build by renaming it. +- Treat the published `v0.1.0` tag and compatibility matrix as the maintained baseline; do not retroactively widen its supported capability set. +- Complete and record the remaining native, accessibility, disposable-data, and pilot evidence for the current release instead of inferring it from publication. +- Synchronize every version surface and publish a changelog, migration notes where needed, checksums, build metadata, compatibility limits, and the exact source commit for each later release. +- Repeat native smoke tests on every final tag instead of promoting an earlier build by renaming it. - Keep `main` releasable; use fixtures and negative-path tests for every new schema/category/mutation route; never silently widen a cleanup allowlist in a patch release. - Define patch releases for compatibility fixes and minor releases for backward-compatible capability work, and explicitly mark capabilities read-only when the maintained release line can no longer validate them.