Adds a track concept to bakery (separate from the existing bakery/pacman
distribution channel): stable (unchanged tag-triggered releases), beta
(deliberate beta-v* tag promotion), and dev (published on every push to
dev). Each track gets its own signed index + artifact tree under
dl.breadway.dev so stable's paths and existing installs are untouched.
- bakery: new Track type, a global track preference in installed.json
(defaults to stable via serde, no migration needed), `bakery track
show`/`set`, a BAKERY_INDEX_BASE_URL override for testing, and a real
semver comparison in `update` (was a plain string-equality check before).
ANSI-colored/aligned CLI output (TTY + NO_COLOR aware).
- gen-index.sh: TRACK env var selects which subtree to read/write.
- CI: dev-bakery.yml/beta-bakery.yml/dev-bread-theme.yml/beta-bread-theme.yml
publish those two products on the new tracks; dev/beta skip the GitHub
Release upload step (no per-commit release spam).
- docs/release-channels.md documents the three-track policy.
The old bakery-signing-key.minisign-sec on hestia was password-encrypted
and the password was lost, so scripts/gen-index.sh never actually signed
index.json (silent no-op warning). bakery/src/manifest.rs (0.3.0+) hard-
requires that signature, so every bakery command has been failing with
'fetching index.json.minisig — the index must be signed before it can be
trusted' since the signing enforcement shipped.
Generated a new no-password minisign keypair on hestia
(~/.secrets/bakery-signing-key-2.minisign-sec), updated the hardcoded
PUBKEY in manifest.rs and get.sh to match, wired
BAKERY_MINISIGN_SEC_KEY_PATH as a Forgejo Actions secret so future CI
releases sign automatically, and manually signed+published the current
index.json on hestia so bakery works immediately.
bread-utils extracts genuinely duplicated logic found across breadbox,
breadclip, breadmon, breadcrumbs, bos-settings, and breadhelp:
- hypr: Hyprland socket1 request/response client (breadbox's
get_active_workspace + breadclip's position.rs hyprctl_json were
near-identical), socket2 path resolution (breadmon), and a
version-tolerant `fullscreen` field parser (Hyprland has shipped both
bool and int representations across versions).
- singleton: correct flock-based single-instance toggle, replacing the
TOCTOU-prone read-pid/check-proc/kill/write-pid pattern duplicated
verbatim between breadbox and breadclip (breadclip's own comment says
"matches breadbox pattern").
- proc: breadcrumbs' timeout-guarded subprocess runner, promoted verbatim
as the one implementation in the ecosystem that already got this right.
- atomic + xdg: atomic (temp-then-rename) file writes with an optional
.bak-before-overwrite variant, and XDG path helpers that never fall back
to a literal "~/..." string (the exact breadclip-core and
breadpad-shared bug: PathBuf never expands `~`).
- tomlcfg (feature "toml"): the load_doc/save_doc TOML-editing discipline
bos-settings and breadhelp both implemented byte-for-byte identically in
the same fix pass that introduced it.
- gtk_popup (feature "gtk"): layer-shell overlay window setup, visible-row
navigation, and click-outside-close, deduplicated from breadbox and
breadclip (~150 duplicated lines, per both apps' own "same as breadbox"
comments).
bread-onnx extracts the embedding pipeline (tokenize -> tensor build ->
mean-pool -> L2-normalize) duplicated near-verbatim between breadarr and
breadsearch, a shared execution-provider session builder with loud EP-
registration logging, and a model download+integrity helper. Defaults AMD
iGPU acceleration to ort::ep::MIGraphX (not ROCm) per this machine's own
breadsearch-gpu-backends lesson: ROCMExecutionProvider silently no-ops to
CPU on distro ROCm onnxruntime builds compiled with --use_migraphx.
Both crates build and pass their own test suites standalone. Consumer
migrations follow in subsequent commits.
- Add minisign-based signing/verification for the bakery index:
scripts/gen-index.sh signs index.json (MINISIGN_SEC_KEY env var, dormant
no-op with a loud warning until a key is provisioned); bakery/src/manifest.rs
fetches index.json.minisig and verifies it with minisign-verify against a
hardcoded PUBKEY before parsing/caching, and re-verifies the cached copy
on every load (falls back to one re-fetch if the cache predates signing
or fails verification; a fresh fetch that fails verification is a hard
error).
- Close the previously-unchecksummed config-example and systemd-unit
downloads in bakery/src/install.rs (scaffold_config, install_service):
index.json now carries `sha256`/`example_sha256` for these artifacts
(computed in gen-index.sh), verified via the same download::verify_sha256
used for binaries. Downloads without a matching sha256 in the index are
refused rather than installed unverified.
- scripts/get.sh now verifies the bakery release binary itself against a
pinned minisign public key before installing it (falls back to the
existing sha256-only check with a loud warning if no .minisig is
published yet or minisign isn't installed; a present-but-invalid
signature is a hard failure).
- Add dormant "sign release binary" steps to the bakery and bread-theme
release workflows (.github/workflows/release.yml,
.forgejo/workflows/release-bread-theme.yml), gated on secrets that are
not yet configured — binaries ship unsigned exactly as before until the
owner wires up the secret.
- .gitignore: add *.minisign-sec / minisign.key so the signing key can
never be committed by accident.
- bread-theme: fix stale docs describing a "Catppuccin Mocha fallback"
(BREAD_DESIGN_SYSTEM.md, README.md, Cargo.toml/bakery.toml/registry
descriptions) — the actual implementation (palette.rs) uses a fixed BOS
dark base with only accent colors from pywal.
- bread-theme: fix the legacy css_vars() path, which had its own
hand-written @define-color block that predated the `accent` and computed
`on-*` ink colors used by the rest of the stylesheet — any caller whose
CSS referenced those names against css_vars()'s output would hit
undefined colors (the illegible-text bug). css_vars() now delegates to
the same define_colors() the full stylesheet uses, so the two can't
drift apart again.
Critical fixes:
- gen-index.sh: emit services, config, optional_system_deps from bakery.toml;
parse product list from registry TOML instead of hardcoded array; fail loudly
when bakery.toml is missing (was silently producing empty metadata in prod)
- install.rs: download service units and example configs from dl server at
install time (were never fetched); check systemctl exit codes (were swallowed);
save state before file cleanup in remove_package (was inconsistent on error)
- doctor.rs: rewrite dep detection to use `pacman -Q` as primary (no more
dependency on `which` or pkg-config name mismatches); add optional_system_deps
support returning (missing, warnings) — warnings print but never block install
- get.sh: fix GitHub fallback URL (was 404 for both latest and versioned
releases); add SHA-256 checksum verification using published .sha256 file
High priority fixes:
- bakery doctor <unknown-pkg>: exit non-zero (was silently passing)
- bakery update: add --all flag (documented in README but missing from CLI);
add doctor gate before update (was bypassing dep check)
- bread_deps: now resolved recursively with cycle detection (was ignored)
- manifest.rs: add artifact_urls() helper and optional_system_deps field
- state.rs: atomic save via tmp+rename; cmd_info shows optional_system_deps
Tests: 17 new unit tests across doctor, download, install, state modules;
scripts/test-gen-index.sh fixture test for full pipeline