All notable changes to this project will be documented here. Format follows Keep a Changelog. This project uses semantic versioning.
Historical entries preserve the install and packaging guidance that was current
for that release. Use README.md, INSTALL.md, and docs/VERSIONING.md for
current uv-based install, development, and release instructions.
2.0.6 - 2026-10-23
- Release Please draft PRs using the official CLI with a reviewed, integrity- pinned dependency graph and patched Node runtime, plus a local preparation command. Signed tags and verified artifact publication retain their existing deliberate workflow.
- Reviewed repository lock inspection and stale-lock removal through the native production dispatcher. Unlock requires an exact review token, explicit approval, a confirmed quiet window, and only own-host, same-user locks whose processes are absent. Changed or uncertain lock inventories block removal.
- Optional
local_lastandlocal_weeklyretention counts, disabled by default, alongside daily retention. Counts are part of the reviewed retention policy.
- Keep dashboard forms and setup navigation reachable in short terminals, and preserve resource summaries, failure status and cancel hints in the compact legacy dashboard.
- Put getting-started instructions before detailed support history and keep the documentation index readable on narrow screens.
- Accept Restic's explicit
remove: nullkeep-all selection only when its keep group contains valid full snapshot IDs; malformed selections remain errors. - Recognize B2's read-only
readBucketLifecycleRulescapability without allowing administrative or unknown permissions or qualifying a permanent-delete key as a restricted source writer. - Preserve the resolved Restic cache policy in nested repository queries,
including execution without
HOMEorXDG_CACHE_HOME.
These source changes address issue #30. This maintenance release does not expand cloud or machine-recovery qualification.
- Refresh the reviewed Python maintenance dependencies from pull request #28 and the immutable GitHub Actions references from #20. Keep the established Ruff rule profile explicit across its default-rule migration. See the dependency evidence for exact versions, source timestamps and limits.
2.0.5 - 2026-10-22
- Central cloud retention honors an explicitly configured positive deletion grace period instead of imposing a thirty-day minimum. Thirty days remains the recommended profile; shorter grace reduces historical protection and does not establish a thirty-day recovery guarantee. Live aged reclamation remains unqualified under issue #25.
- Issues #23–#26 were canceled and closed as not planned. Their implementations remain experimental and unqualified. This release adds no new live provider qualification; the existing workstation results remain historical.
- Stable support remains at the v2.0.4 tested core scope; the retention policy change adds no provider or recovery qualification.
2.0.4 - 2026-10-21
- Experimental restricted B2 source-key metadata assessment and independently checked, separately signed central recovery acceptance. Live B2 protection and complete-machine recovery remain unqualified.
- Experimental HTTPS S3 remote-primary capture with a dedicated bounded staging filesystem, disabled cache, shared staging lease, pressure checks and structured resource failures. A small live B2 workstation source trial is recorded below; final remote-server qualification is deferred.
- Experimental central noncurrent-version retention with signed checkpoint dependencies, explicit catalog and grants, shared repository leases, lock and expiry checks, and journaled exact-version deletion without automatic replay. Schema-2 B2 policies can select a native lock-metadata reader; schema-1 generic S3 policies remain unchanged. Current-pack compaction and complete provider protection qualification remain outstanding.
- Experimental central snapshot maintenance with explicit accepted-record
enrollment, policy-selected full snapshot IDs, separate Restic credentials,
bounded staging and
prune --max-repack-size 0. Protected checkpoints and unknown snapshots remain preserved; historical-version deletion stays separate. Repacking and aged live reclamation remain unqualified. - Opt-in reviewed Linux file and transactional SQLite coverage with private inventory, exact scope and exclusions, drift checks, reviewed database identity/metadata and reconstruction evidence, and root system unit rendering. SQLite exports carry provenance in the encrypted capture manifest; live database/journal files are omitted from file-tree capture. Complete-machine recovery remains unqualified.
- Experimental manual PostgreSQL covered capture adds schema-2 private cluster
and database decisions, per-database
pg_dumparchives, digest-bound recovery artifacts, and an explicit administrator-coordinated quiet-window assertion. Database-level ownership, ACLs, and connection limits require a verified reconstruction procedure after native restore. A local covered capture and replacement rehearsal passed; stable v2.0.4 scope remains the v2.0.3 tested core scope, and ordinary PostgreSQL adapters are unchanged. - Refreshed matching 1280×640 GitHub social preview artwork, embedded ownership metadata, checked provenance, and explicit repository-settings upload instructions.
- On 2026-10-21, a local S3 emulator captured a small, compressible 2,245,463-byte logical fixture with 1,769,472 bytes of combined writable filesystem capacity. A controlled pressure failure stopped the next capture; a separate read-only check and full restore verified the earlier snapshot. The original harness stopped at a symlink-listing assertion; its failed result is preserved separately from the successful recovery continuation.
- On 2026-10-21, live B2 central maintenance completed a zero-forget plan and native no-repack prune. Both accepted snapshots restored afterward, all 32 previously observed versions survived, and the catalog remained unchanged. A separate changed-plan test rejected stale apply before maintenance-ledger entry, forget, or prune; inspection created and released two temporary locks. This small workstation result leaves aged reclamation, the protection window, and off-host recovery unqualified.
- A separate live B2 maintenance interruption drill used one zero-forget plan and one small fixture. After confirming the owned native prune process, its durable intent, and a fresh lock witness, one SIGINT reached the owned CLI. The native process stopped and the CLI exited 3. One read-only reconciliation after process quiescence recorded an abandoned plan while prune stayed uncertain; apply was not replayed. A no-lock read and two restores matched the fixture, all 69 previously observed versions and markers survived, and the catalog was unchanged. This does not claim prune completion or qualify provider protection.
- A separate new, empty File Lock-enabled B2 bucket tested overlapping native lifecycle rules at creation. Read-only S3 inspection returned the expected hide, orphan-marker, and noncurrent-delete actions, and central retention refused the enabled expiration rules. No objects were uploaded or deleted; this did not test elapsed expiry or physical reclamation. A read-only first- entry inventory observation found no versions. The v2.0.4 stable scope remains the v2.0.3 tested core scope, and requests #23–#26 remain open.
- On 2026-10-21, isolated PostgreSQL 17.11 containers passed covered capture and restore into a fresh replacement database. The encrypted snapshot omitted raw PostgreSQL files; recovered materials and their tested procedure rebuilt database ownership, ACLs, connection limits, and three UTF-8 rows. The fixture contained 10,006 logical bytes. This is local manual-path evidence, with no off-host, unattended, or whole-machine qualification.
- On 2026-10-21, a root-covered files/SQLite rehearsal passed in two fresh Ubuntu 24.04 AMD64 guests. The replacement restored encrypted data, rebuilt fixture accounts and metadata, and verified application startup. The logical fixture was 56,293 bytes; the two-guest run took 90.1 seconds. This is local emulation, with no off-host custody or complete-machine qualification.
- On 2026-10-20, a small live B2 S3 remote-primary source trial passed two captures, a repository check, restores of both snapshots, and seven denied forbidden-operation checks using a bucket- and machine-prefix-restricted source key. A separate verifier also reconstructed and checked historical versions after simulated source compromise and restored the older snapshot. The fixture, limits, and open qualification gaps are documented in version 2 development. This workstation result does not qualify B2 protection or production recovery; AWS has no live result and the v2.0.4 stable support scope remains the v2.0.3 tested core scope.
- A live central-retention rehearsal planned with a fresh thirty-day grace period, ran a guarded zero-apply, and reconciled an empty plan. It identified 10 protected versions in a 31-version inventory, which remained unchanged; no S3 delete was sent. Empty reconciliation made no provider reads. The native B2 metadata reader separately verified exact historical versions and fresh governance-locked and legally held canaries. The routine retention key was refused permanent deletion of both protected canaries, with survival confirmed independently; both canaries were subsequently cleaned up. The production CLI also passed schema-3 enrollment and schema-2 plan, zero-apply and empty reconciliation against the existing catalog with its first-seen times preserved. Aged deletion and uncertain live mutations remain unqualified.
- A fresh tiny B2 fixture measured initial/incremental capture interface TX of 221,039/22,065 bytes and stored-version growth of 199,080/2,457 bytes. Both captures, the full check and both restores passed within 1 MiB staging and zero cache. These measurements include protocol/version overhead and do not establish provider billing, large-scale performance or production savings.
- Updated the pinned CI and release-build
uvtool to 0.13.4 for GHSA-hq85-5cpj-mr62; the amd64 and arm64 wheel digests are recorded in release dependency evidence. - Updated
certifito 2026.10.19 to address GHSA-6q48-6c7w-9gw2. - Service operations disable Restic's cache when the child environment has no cache location, so verified restore also works from minimal system services.
- Remote capture reconciliation uses Restic reads without cloud lock writes, requires an acknowledged quiet window and refuses observed repository locks before and after inspection. It never retries an uncertain upload.
- Remote database captures retain completed exports after failed or uncertain
uploads and receipt failures. Read-only reconciliation verifies the matching
snapshot before cleanup; bounded discovery and digest-bound explicit disposal
replace manual edits to retained staging. Reboot survival requires persistent
staging rather than
tmpfs. - Checkpoint receipts accept an absent expiry date instead of failing after the encrypted kit is written. Known legacy receipt schemas migrate with a private backup and preserved rows; additional schema constraints fail closed.
- Covered user/root timers preserve the reviewed temporary-directory source view instead of substituting systemd private mounts; ordinary jobs retain their private temporary directories.
- Release publication locates the exact draft by release ID and refuses an existing draft or published tag before creation, including drafts hidden from lookup by tag.
2.0.3 - 2026-10-19
Existing schema-2 configurations require explicit migration and enrollment before mutating production operations. Migration preserves the original files. The wire result contract remains schema version 2; portable configuration is schema 3.
Scheduled file capture/copy/restore, missed-timer catch-up, and interruption without replay have bounded Ubuntu 24.04/26.04 AMD64 guest evidence. Both test repositories shared the guest. B2/AWS, native Docker, ARM64 backup/restore, and complete off-host disaster recovery remain unqualified.
- Guided terminal setup, labeled operation forms, inline validation, tooltips and keyboard help.
- Schema-3 portable source policy, private host bindings, explicit migration and machine/user enrollment.
- Per-stage job timeouts and explicit user-level systemd timer installation.
- Generated banner and social artwork with embedded rights metadata and checked provenance.
- Signed release provenance binding source/tag, trusted CI, build run, dependency lock, artwork, and package digests.
- Fresh exact-version dependency advisory evidence and reviewed build-tool pins.
- Operator-focused landing documentation and task-based guides for Linux administrators, homelabs, and small infrastructure teams.
- Fail-closed legacy decryption, private plaintext staging, occupied Docker restore-target refusal and trusted SFTP host keys.
- Encrypted and authenticated legacy tree inventories, opaque payload names, backward readers and explicit filesystem-fidelity limits.
- Trusted configuration snapshots and enrollment leases; interrupted operations never gain automatic replay authority.
- Pinned CI actions, complete integration selection, aggregate CI and signed exact-commit release verification.
- Archive extraction retains a private outer directory while restoring payload metadata.
- Filesystem metadata preflight follows native rsync exclusions without re-entering excluded trees.
- User timer installation honors an absolute custom XDG configuration directory.
- Non-root legacy Docker backups use checked tar ownership instead of trusting
docker cp -a; integration tests now select their helper image reliably. - Complete portable source archives with documentation, build tools and test fixtures, checked before release.
- Release publication now imports the checked-in public signing certificate rather than depending on a key server's email-verification state. The fixed fingerprint, artifact checksums, tag binding, and signature checks remain mandatory; no private key is stored in the repository.
2.0.2 - 2026-10-17
The v2.0.1 tag passed source validation and both Ubuntu 24.04 native package
jobs but failed both Ubuntu 26.04 package jobs, so it produced no release assets.
This patch keeps runtime behavior unchanged and fixes dependency export for the
Ubuntu 26.04 native build.
- The Debian package builder now runs
uv exportwith its validated native interpreter instead of letting the development.python-versionpin select an unavailable Python 3.12 interpreter on Ubuntu 26.04.
2.0.1 - 2026-10-17
The earlier v2.0.0 tag did not produce release artifacts because its native
package jobs failed. This patch keeps runtime behavior unchanged and fixes the
native-package build environment.
- Native package jobs now run the builder with system Python, making the
distribution-provided
packagingmodule available despite the pinneduvtool virtual environment appearing first onPATH.
2.0.0 - 2026-10-17
Stable tested scope: local file capture and restore; live PostgreSQL 17.11, MySQL 8.4.12, and MariaDB 11.8.9 capture/restore; headless dashboard happy paths; and AMD64 Ubuntu 24.04/26.04 packages. B2/AWS, native Docker, ARM64 backup/restore, ordinary cross-application-version upgrades or rollback, systemd boot/reboot, and cloud/off-host retention remain unqualified. The release workflow builds ARM64 packages, but package availability and install smoke do not qualify ARM64 backup/restore.
Only the paths in this tested-scope statement are production-qualified; the feature notes below also describe implemented but unqualified functionality.
- Local retention now uses immutable capture-time replica requirements and read-only, restic-policy plans with snapshot-bound approval tokens. Apply forgets only reviewed eligible snapshot IDs, validates state under the repository lease, records uncertain mutations, and never prunes pack data.
- First-run setup and revision-checked configuration editing share the machine command and dashboard operation boundary. Configuration changes retain private compressed backups; setup never initializes repositories or enables services.
- Dashboard administration forms cover repository checks, direct job execution, replication, retention, recovery, and database reconciliation. Interactive operations support cancellation and path-free numeric progress; the command interface exposes progress only through explicit JSON-lines output.
- Native MySQL/MariaDB restoration accepts trusted versioned exports only on an explicitly acknowledged empty recovery server, using the original database name. Pinned connection settings and shared uncertainty tracking prevent automatic replay after ambiguous mutations.
- An experimental, unqualified version-two native Docker path now preserves daemon-provided mask/read-only paths, validates typed bind/local-volume declarations, and ignores only added writable-layer entries exactly at mount destinations rebuilt by restore. It quiesces only selected running containers, then restores into a new directory and container using an already-local pinned image. Durable restart intentions require explicit recovery; Docker restore reconciliation records reviewed ledger outcomes without replay.
- Overview and machine diagnostics now report actual backup/copy/check/restore observations, operation outcomes, local capacity, observed active timers, and signed-checkpoint expiry without treating them as application or cloud proof.
- Receipt-schema upgrades preserve a validated, private compressed SQLite backup before migration; an unavailable private backup stops the upgrade.
- Native Ubuntu package construction now validates target Python/architecture, hash-locked dependencies, and the supplied restic executable. Disabled systemd templates share the runtime unit renderer. Release automation separates native builds from explicit fixed-fingerprint signature verification and publication.
- Database restore recognizes Unix-socket-only MySQL/MariaDB servers reporting port zero without weakening validation of configured TCP ports.
- Debian abort recovery distinguishes an active-client refusal before any package transition from a retained interrupted-transition marker. Validating the intact payload under a shared lock keeps the former package installed; the latter still requires exclusive locking before its marker can be cleared.
- Release-note extraction accepts the dated changelog headings used by actual releases and still refuses a missing release section. Readiness checks no longer require obsolete release-action tags or diagnostic wording.
- Live PostgreSQL 17.11, MySQL 8.4.12, and MariaDB 11.8.9 capture/restore drills validated transaction boundaries and recovered application data. MySQL-family drills additionally exercised DEFINER views, routines, triggers, and events.
- A million-file local capture, independent repository copy, full-data check, and verified restore passed. An offline signed/encrypted recovery-kit drill recovered files after removing the original source and password. These checks do not qualify cloud providers, off-host custody, or terabyte-scale recovery.
- Native AMD64 Ubuntu 24.04/Python 3.12 and Ubuntu 26.04/Python 3.14 package drills passed installed capture/check/restore, active-dashboard upgrade refusal, interrupted-unpack blocking, damaged-payload refusal, and verified same-version repair with configuration and SQLite state preserved. ARM64, boot/reboot, and cross-application-version rollback remain unqualified.
2.0.0-alpha.1 - 2026-10-03
Keep a copy close. Keep a copy elsewhere. This preview introduces the restic-centered bbackup 2.0 workflow for Linux administrators and small teams. Backblaze B2 and Amazon S3 are supported repository destinations and restore sources; provider-specific recovery-protection qualification is still underway.
- Encrypted local restic capture, explicit snapshot replication with independent passwords, full-data repository checks, and verified restore into new directories.
- Transactional SQLite capture, native PostgreSQL and locked MySQL/MariaDB exports, and PostgreSQL restore into a new database using snapshot-time metadata.
- A mouse and keyboard Textual dashboard sharing the same operations service as the strict version-2 JSON CLI, with generated schemas and agent discovery.
- Bounded subprocesses, real process-group cancellation, private operation state, repository serialization, and explicit reconciliation of interrupted mutations.
- Signed, GnuPG-encrypted recovery kits and exact historical S3 object-version reconstruction that can operate without the original host ledger.
- Native Backblaze B2 inspection using the pinned vendor Python SDK, with SDK backoff inside a bounded cancellable process and no persisted credentials.
- A shorter README, a fresh visual identity, a practical documentation hub, local-to-cloud recipes, and clear recovery and release boundaries.
- Legacy uploads now report partial failures truthfully and preserve local artifacts when all required remote uploads have not succeeded.
- Legacy filesystem restore rejects escaping source paths and returns structured failures for unavailable destinations or failed copies.
- Legacy dashboard terminal restoration and operation finalization are more reliable; unattended backups no longer assume an interactive terminal.
- S3 inventory and recovery use bounded standard SDK retries with five total attempts per request. Native B2 inspection delegates protocol retries to b2sdk.
- Dependencies are locked; urllib3 is updated to 2.8.0 for the maintainer's fixes.
- The optional Google Drive OAuth client requires oauthlib 4.0.0 or newer, incorporating the upstream fixes for CVE-2026-49264 and CVE-2026-49265.
- Preview features remain under
bbackup production. Existing 1.x commands and configuration remain available while their replacements are completed.
This is an alpha prerelease, not the production-qualified 2.0 release. Local restic and Garage S3 capture → copy → check → restore cycles passed. Database-client fixtures, independent recovery drills, and headless dashboard checks passed; live B2/AWS and native database qualification remain outstanding. Docker recovery, retention enforcement, complete UI flows, and Ubuntu packages are still under development. See implementation status.
1.8.6 - 2026-08-04
- Optional secure Google Drive OAuth setup through
bbman auth-gdrive, including dry-run and JSON output, redacted diagnostics, and headless SSH callback guidance. The helper configures My Drive remotes; live Google authorization is not exercised in automated tests. - A repository-wide GitHub Markdown standard, capabilities reference, review checklist, provenance manifest, and CI/pre-push validator now govern public documentation.
- Pytest uses bounded xdist auto-workers and isolated Docker integration resources to reduce runtime without overcommitting shared hosts.
- CI and release validation install checksum-pinned restic 0.19.1 so native snapshot lifecycle tests cannot silently skip.
- Snapshot runs apply configured active-repository and include-path retention through scoped, conjunctive tag selectors.
- Snapshot retirement and purge planning isolate snapshots by host and repository, reconcile removed IDs without losing history, and use exact ledger snapshot IDs.
- Generated schedule services share a user-runtime lock so backup, maintenance, and verification jobs do not overlap.
- Google Drive configuration handles rclone continuation responses, bounds continuation calls, loads optional support lazily, and defaults to My Drive without exposing shared-drive selection.
- Removed the unused GitPython dependency and its
gitdbandsmmaptransitive packages, eliminating the repository's exposure to their known advisories. - Raised the
cryptographydependency floor to 50.0.0, the first release fixing GHSA-g6cj-pr64-35w5 / CVE-2026-69247, and made health/setup checks reject older or prerelease versions.
1.8.5 - 2026-07-09
- Native restic snapshot profiles with commands for
snapshot init,snapshot run,snapshot check,snapshot restore,snapshot retire,snapshot purge-plan, andsnapshot schedule. - Local restic integration coverage that initializes a temporary repository, snapshots a Git repo, checks the repository, restores content, and verifies the state ledger snapshot ID.
- Profile schedule rendering for daily backup, weekly non-destructive maintenance checks, and monthly verification checks with configurable
verification_read_data_subset. - Generated CLI skills metadata for the native snapshot command surface.
- Snapshot schedule units now render matching service/timer pairs, use
/usr/bin/env bbackup, and escape systemd percent specifiers. - Snapshot commands now accept required options from
--input-jsonconsistently for agent-driven workflows. - Retired-repo destructive cleanup remains dry-run-first/manual through
snapshot purge-plan. - The pytest
integrationmarker now covers external-tool integration tests such as Docker and restic.
- Google Drive rclone snapshot profiles without a dedicated
client_idremain rejected by default, whileallow_default_rclone_drive_client: trueprovides a conservative profile-local opt-in. - Non-dry snapshot operations now enforce profile safety preflight checks before running restic.
- Git repo identity no longer changes on every commit; legacy head-derived repo IDs migrate safely, and unknown active same-path identity conflicts block history merging.
list-backupsand restore dry-run planning no longer initialize Docker for file-only planning paths.- Restore dry-runs now validate filesystem destination and multi-filesystem constraints before returning a success plan.
1.8.4 - 2026-06-22
- Raised the
cryptographyruntime dependency floor to48.0.1to pick up patched OpenSSL wheels for GHSA-537c-gmf6-5ccf.
- Release publishing now uploads only the bbackup wheel and source archive artifacts.
1.8.3 - 2026-06-22
- Backup runs now include a compressed
metadata.tar.*archive of Docker config and network metadata when those metadata directories exist.
- CI now tests Python 3.12, 3.13, and 3.14 and uses
actions/checkout@v7. - Ruff release checks now include tests and the generated CLI skills script.
- TUI headers now display the package version instead of a hardcoded
1.0.0. - Username-only GitHub public-key lookup now uses standard repositories only; explicit Gist IDs remain supported.
restore --all --dry-runnow discovers containers, volumes, networks, and filesystem targets from solid archive backup files.- Non-dry-run filesystem restores now reject missing or ambiguous destinations before any restore mutation runs.
1.8.2 - 2026-06-09
- Simplified the GitHub install and redeploy documentation around the single
uv tool install --force git+https://github.com/CruxExperts/BestBackup.gitcommand. - Moved the sudo
UV_TOOL_DIR/UV_TOOL_BIN_DIRdeployment form out of the README and Quickstart path, keeping it only as an advanced system-wide install option inINSTALL.md.
1.8.1 - 2026-06-09
- Solid archive backups now remove the expanded staging directory after the archive is created, so local solid mode leaves a single
.tar.*artifact instead of both the archive and the unpacked backup tree. - Rclone uploads of solid archive files now use
rclone copytoto create one remote file, instead ofrclone copycreating a destination folder for the file.
1.8.0 - 2026-06-09
backup_manifest.jsongeneration for non-cancelled backups, including schema version, source scope, filesystem source paths, volume artifacts, item results, errors, file sizes, and SHA-256 hashes.- Restore-time manifest verification that fails before mutation when files are missing, changed, unlisted, or outside the backup root.
- Temp-to-final promotion for local, SFTP, rclone, and solid-archive writes so partial uploads are not exposed as completed backups.
- GitHub-facing documentation graphics and Mermaid diagrams for the backup pipeline and release/readiness flow.
- Successful encrypted backups now remove plaintext staging and report encryption based on actual output state.
- Rclone remote listing now uses top-level
lsfoutput so retention targets backup directories and archive files instead of individual nested files. - Existing Docker volume restore uses a staging-volume copy preflight before removing the original volume.
- Direct
--pathsand configured filesystem sets now reject duplicate target names that would overwrite each other. init-encryptionnow rejects unsupported generated-key passwords before creating key directories.- Generated asymmetric keys are RSA-4096 only; ECDSA is no longer advertised as a backup encryption option.
- Docker volume backup and restore now propagate failed
docker cpreturn codes. - Failed Docker volume backup attempts remove incomplete local volume artifacts.
- Solid archive failures preserve an existing final archive and remove partial files.
- Partial backup JSON no longer reports encrypted output when encryption was skipped due to item failures.
1.7.0 - 2026-03-06
- Solid archive mode: optional single compressed tarball (and optional whole-file encryption) before upload so remotes receive one file instead of many. Config
backup.solid_archiveand CLI--solid-archive/--no-solid-archive. Restore accepts a backup path that is a file: it unpacks to a temp dir, restores selected items, then cleans up. Listing and retention treat directories and archive files (e.g.backup_*.tar.gz,backup_*.tar.gz.enc) the same. Staging cleanup runs only after at least one successful upload. Seeconfig.yaml.exampleand docs/architecture.md.
1.6.0 - 2026-03-04
- Rclone transfer and concurrency options: config-driven
transfersandcheckersfor all rclone operations (upload, list, size, purge). Per-remote optionalrclone_optionsand optional top-levelrclone.default_options; recommended defaults 8/8, cap 32. Seeconfig.yaml.exampleand docs/architecture.md.
1.5.0 - 2026-03-02
is_venv()helper inbbackup/management/dependencies.py: detects whether the current Python is running inside a virtual environment by checkingsys.real_prefixandsys.base_prefix- PEP 668 guard in
install_python_packages(): on Ubuntu 22.04+ and Debian 12+ (externally-managed system Python), the function now prints a clear activation message and returnsFalseinstead of letting pip fail with an unhelpful error bbackup/cli_metadata.py: unified metadata layer describing CLI commands, parameters, JSON fields, and examples forbbackupandbbmanscripts/generate_cli_skills.py: generator fordocs/cli-skills.mdanddocs/cli-skills-index.json, producing a versioned CLI skills catalog from metadatadocs/cli-skills.md: agent-friendly, generated skills catalog for all corebbackup/bbmancommands, with CLI + JSON examples- Per-command
--skillsflags on corebbackup/bbmancommands to print their skills section fromdocs/cli-skills.md - CI step in
.github/workflows/ci.ymlthat runspython scripts/generate_cli_skills.py --checkto ensure skills docs are up to date
bbackup/management/setup_wizard.py: the "Install missing packages?" branch now delegates toinstall_python_packages()fromdependencies.pyinstead of callingsubprocess.run(pip install ...)directly, consolidating the venv check and error handling in one placeINSTALL.md: pipx is now the recommended install method; dedicated PEP 668 troubleshooting section points users to pipx; manual venv install documented for development useQUICKSTART.mdStep 1: installation example updated to use pipx, with a server-wide pipx variant for shared installsREADME.mdinstallation section: updated to show pipx-based install for single user and server-wide setups, pointing toINSTALL.mdfor alternativesREADME.mdanddocs/README.md: link the newdocs/cli-skills.mdcatalog from the documentation tables
1.4.0 - 2026-02-28
- README overhauled: centered hero header, GitHub Alerts (
[!TIP]), icon column in feature table, collapsible CLI sections via<details>, docs table, and install one-liner at top of page - Version badge in README updated to reflect current release
1.3.3 - 2026-02-27
- AI-agent-friendly JSON I/O layer across all
bbackupandbbmancommands --output [text|json]on every command: emits a versioned JSON envelope to stdout; all diagnostic text goes to stderr--input-json JSONon every command: accepts all parameters as a single flat JSON object; merges over CLI flags; unknown keys silently ignored (forward-compatible)--dry-runonbbackup backupandbbackup restore: resolves targets and returns a plan without executingbbackup skillsandbbman skillssubcommands for progressive AI agent capability discovery; each skill includes step-by-step guidance and per-stepinput_json_schemaBBACKUP_OUTPUT=jsonenv var: sets JSON mode globally for all subprocesses without passing--output jsonto each commandBBACKUP_NO_INTERACTIVE=1env var: suppresses TUI, prompts, and pagers system-wide--no-interactiveflag onbbman setup: skip wizard and return config state as JSON (agent mode)bbackup/cli_utils.py: shared foundation module with decorators, envelope builder,merge_json_input,json_error,flatten_health_tuples, and semantic exit constants (0-5)bbackup/skills.py: static skill descriptors for 6bbackupskills and 4bbmanskills with per-stepinput_json_schema(JSON Schema)- 30 new tests in
tests/test_cli.pyacross 6 classes:TestJSONOutputMode,TestInputJSON,TestSkillsCommand,TestDryRun,TestEnvVars,TestExitCodes - Agent integration section in
README.mdwith quickstart, envelope spec, env var table, exit code table, skills protocol, and dry-run example
bbman diagnostics --output(file path) renamed tobbman diagnostics --report-fileto free--outputfor the universal format selectorbbman --versionnow reports the actual package version frombbackup.__version__instead of the hardcoded"1.0.0"- All
sys.exit(1)calls replaced with semantic exit constants:EXIT_USER_ERROR=1,EXIT_CONFIG_ERROR=2,EXIT_SYSTEM_ERROR=3,EXIT_PARTIAL=4,EXIT_CANCELLED=5 bbman healthandbbman check-depsJSON output uses named sub-dicts ({"ok": bool, "message": "..."}) instead of positional tuplesbbackup list-containersJSON output now includes the"id"field for each containerbbackup list-backup-setsJSON output now includes the full"scope"dict per set- Error output from pre-run validation (unknown backup set, missing path, etc.) routed to stderr in text mode and to the
errorsarray in JSON mode; stdout is reserved for the JSON envelope only
- TUI no longer blocks agents:
--output jsonorBBACKUP_NO_INTERACTIVE=1automatically bypassesrun_with_live_dashboard() backupcommand now captures and uses the return value fromrunner.run_backup()for the JSON result payloadbbman statusin JSON mode returns structured data directly instead of returningNonebbman cleanupJSON output uses.get("kept", 0)to guarantee a stable shape regardless of cleanup module version
1.3.2 - 2026-02-27
- Documentation updates aligned with v1.3.0 and v1.3.1: README, INSTALL, QUICKSTART, docs/architecture.md, docs/management.md, docs/encryption.md updated to reflect filesystem backup, restore options, CLI changes, and project structure
1.3.1 - 2026-02-27
- 53 unit tests for filesystem backup and restore in
tests/test_filesystem_backup.py, coveringFilesystemBackup,restore_filesystem_path,restore_backupfilesystem loop, andBackupRunnerintegration - 7 real-rsync integration tests in
tests/integration/test_docker_integration.py: basic backup, exclude patterns, incremental hardlinks, progress callback, and roundtrip restore --yes/-yflag onmaintenance/release.pyfor non-interactive (agent/CI) execution
FilesystemBackup._build_rsync_cmdwas passing the current run directory as the staging directory to_find_previous_backup, causing incremental backups to use--link-destpointing at themselves_find_previous_backupnow acceptscurrent_run_dirand excludes it from the candidate scan so a backup never links to itself
1.3.0 - 2026-02-26
- Filesystem backup: back up arbitrary host paths and directory trees with rsync, gitignore-style exclude patterns, and incremental
--link-destsupport - New
bbackup/filesystem_backup.pymodule withFilesystemBackupclass FilesystemTargetandFilesystemBackupSetdataclasses inconfig.pyfilesystems:section inconfig.yaml.examplewith annotated examples--paths,--exclude,--filesystem-setoptions onbbackup backup--filesystem,--filesystem-destinationoptions onbbackup restorebbackup list-filesystem-setssubcommand- Filesystem panel in live TUI dashboard (third column alongside containers and volumes)
1.2.1 - 2026-02-26
- Expanded test coverage from 59% to 76% across all core modules
- Resolved all ruff lint violations in the
bbackuppackage
BackupRunner._parse_rsync_progresshoisted from closure to method for reuseBackupStatus.update()no longer receivestransfer_speedas a kwarg (set directly)
1.2.0 - 2026-02-26
- Full CI testing suite: 289 unit tests covering all
bbackup/modules scripts/run_tests.pyagentic sandbox test runner with Docker isolation and self-healing debug loopDockerfile.testfor sandboxed test executionrequirements-dev.txtwith pytest, pytest-cov, pytest-mock- GitHub Actions CI workflow with unit and integration test jobs
- LICENSE file (MIT)
- CHANGELOG.md following Keep a Changelog format
- Community health files: CONTRIBUTING.md, CODE_OF_CONDUCT.md, issue templates, PR template
- Project identity system: copyright footer stamped across all public-facing docs
maintenance/release.pyautomated release workflow with doc validationmaintenance/check_docs.pystale-doc detection with agent-driven auto-update supportmaintenance/bump_version.pyconventional-commit version bumping
1.1.0 - 2026-02-26
- Rich TUI with BTOP-style live dashboard and real-time transfer metrics (speed, bytes, file count, ETA)
- Docker backup for containers, volumes, networks, and configuration metadata
- Incremental backups using rsync
--link-dest(hardlinks unchanged files instead of copying) - AES-256-GCM symmetric encryption at rest
- RSA-4096 / ECDSA P-384 asymmetric encryption with public/private key separation
- GitHub key hosting: reference public keys by
github:USERNAME/gist:IDshortcut - Remote storage: Google Drive via rclone, SFTP via paramiko, local directory
- Time-based backup rotation with daily/weekly/monthly retention and storage quota enforcement
- Full restore of containers, volumes, and networks with optional rename on restore
- Backup sets: named container groups defined in config for repeatable runs
- Selective backup:
--config-only,--volumes-only,--no-networksflags bbmanmanagement CLI: setup wizard, health checks, dependency management, diagnostics, self-update- Interactive container selection with TUI dialog
- Keyboard controls in TUI: Q (quit), P (pause/resume), S (skip), H (help)
- YAML configuration with priority chain and CLI override support
- Rotating file logger via
get_logger()factory
- Project structured for standalone GitHub distribution
The Unreleased comparison is a live HEAD link for navigation, not an immutable historical citation.
Slavic Kozyuk
© 2026 Crux Experts LLC — MIT License