Skip to content
Kosh Docs

Upgrading to v0.3.0

What changed in Kosh v0.3.0, the automatic vault migration, and the new debug logging switch.

Kosh v0.3.0 introduces multi-profile vaults. Upgrading is automatic and requires no action from you, but there are two changes worth knowing about before you run the new binary.


Before v0.3.0 there was a single vault at ~/.kosh/kosh.db. Now every vault is a profile, and profiles live under ~/.kosh/profiles/.

Kosh performs this migration itself, once, on the first run of v0.3.0:

(default) [!] legacy vault found
(default) [✓] migrating to multi-profile system
(default) [✓] migrated to multi-profile system

Your old vault becomes the default profile:

~/.kosh/kosh.db → ~/.kosh/profiles/default.db
  • It is a rename, not a copy. The file is moved on disk.
  • Nothing is re-encrypted. Your master password is unchanged and all credentials, IDs, access counts and timestamps are preserved exactly.
  • It runs on every startup but exits immediately once ~/.kosh/profiles/default.db exists, so it happens exactly once.
  • If you have no legacy kosh.db — a fresh install — nothing happens, and kosh init creates a new vault.

Debug logging moved to an environment variable

Section titled “Debug logging moved to an environment variable”

This is a breaking change if you ever built Kosh with debug output enabled.

Previously, debug logging required a rebuild with an ldflags injection:

Terminal window
# no longer works
go build -ldflags="-X git.plutolab.org/plutolab/kosh/internal/logger.BuildMode=debug"

Now it is controlled by the KOSH_DEBUG environment variable, so released binaries can be debugged without rebuilding anything:

Terminal window
# bash / zsh
KOSH_DEBUG=1 kosh list
Terminal window
# PowerShell
$env:KOSH_DEBUG=1; kosh list

Any truthy value works (1, t, true, T, TRUE). Logs are structured, go to stderr, and carry file:line source locations. Secrets, nonces and ephemeral keys are redacted as [REDACTED] by construction — a debug log cannot leak them.

See Troubleshooting for details.


One vault became many. Each profile is a separate encrypted file with its own master password, and profiles are cryptographically isolated from each other.

Four new commands: kosh use, kosh profile (list, create, delete), and kosh copy. See the Profiles guide.

Your existing setup keeps working unchanged — you are simply on the default profile now.

Search was reworked twice, with no change to any command or flag — results are just better.

  • Match quality now beats usage habit. Recency and frequency previously competed with the match itself and could outvote it. They now act as a multiplier, so a heavily-used credential can no longer be ranked above one that actually matches what you typed.
  • Transposed letters count as one typocrat finds cart.
  • Abbreviations matchgpat finds git_personal_access_token.

If you had memorised how your vault ranks, expect the ordering to change for the better. See Adaptive Search Algorithm.

  • Every line is prefixed with the active profile: (work) [✓] credential saved successfully.
  • kosh list now renders an auto-sized table that no longer truncates columns, with relative timestamps (02d 04h ago, just now, never).
  • Destructive actions show a caution block and require a typed confirmation phrase.

If you script around Kosh’s output, the profile prefix and the reworded messages are the things that will trip you up. The Troubleshooting page lists the renamed strings.

The Wayland-specific wl-copy code path was removed. All platforms now use a single cross-platform implementation, so wl-clipboard is no longer needed. Linux clipboard support still requires a running display server — this change simplifies the implementation, it does not add support where none existed.

  • kosh profile delete overwrites the vault file with random bytes and syncs to disk before unlinking it.
  • Interrupting a password prompt with Ctrl+C now restores your terminal state and exits 130, instead of leaving the shell with echo disabled.
  • Master-password and secret confirmations are compared in constant time.

See the Encryption Architecture page for the full model.


Four genuine fixes to behaviour that shipped in v0.2.3:

Fix Effect
SIGINT during password entry The terminal is restored and Kosh exits 130, instead of leaving echo disabled
kosh generate --lower help text Previously read “include uppercase letters”
Search ranking bias Usage metrics could outrank the actual match; they now modulate it
NaN score for two empty strings Two empty strings are now treated as a perfect match

Terminal window
# 1. (optional but recommended) back up your vault
cp ~/.kosh/kosh.db ~/.kosh/kosh.db.bak
# 2. install v0.3.0
go install git.plutolab.org/plutolab/kosh@latest
# 3. run any command — the migration happens automatically
kosh list
# 4. confirm where you are
kosh profile list
Profile Status
------- --------
> default active

That’s it. Everything you had is in the default profile.