Files
Dominik Schulz 49dddf751f fix: address A-5, S-1, S-2, S-3, S-4, S-6 and I-1 from code quality audit
A-5: Simplify CleanMountAlias
  The previous implementation used nested TrimPrefix/TrimSuffix calls
  inside a loop. Replaced with a single strings.Trim(alias, "/\\") call
  which achieves the same result in one pass.

S-1: Capitalize out.Errorf messages consistently
  User-facing out.Errorf messages should start with an uppercase letter
  since they are displayed directly to the user. Capitalised the following:
  - 'fsck failed on sub/root store' in store/root/fsck.go
  - 'failed to read recipient list' in store/leaf/recipients.go
  - 'failed to export/add public key' in store/leaf/recipients.go
  - 'failed to decrypt' in action/grep.go

S-2: Replace 'can not' with 'cannot' throughout
  Standard English and the Go style guide prefer 'cannot' (one word).
  Fixed all occurrences in production code: store/err.go, store/root/move.go,
  create/wizard.go, updater/updateable.go, store/leaf/recipients.go,
  store/leaf/write.go, backend/storage/fs/link.go, cui/recipients.go,
  backend/crypto/age/keyring.go, action/delete.go, action/update.go,
  action/clone.go and updater/update.go.

S-3: Replace sort.Strings with slices.Sort (Go 1.21+)
  Replaced all sort.Strings() calls in non-test production code with
  slices.Sort() and updated the 'sort' import to 'slices' in the five
  affected files: store/leaf/fsck.go, store/leaf/templates.go,
  pkg/pwgen/cryptic.go, pkg/pwgen/pwrules/aliases.go and
  pkg/pwgen/pwrules/pwrules.go.

S-4: Eliminate context.TODO() from production code
  - fs.Store: cache the module version in the struct field at New() time
    and use the cached value in String(); Version() also returns the cached
    field, avoiding repeated module lookups.
  - gitfs.Git.String(): context.TODO() → context.Background() (version
    is obtained by running 'git version', a short-lived external command
    where Background is semantically correct).
  - fossilfs.Fossil.String(): same change as gitfs.
  - pkig/pinentry/cli.GetPIN(): context.TODO() → context.Background().

S-6: Protect autosyncLastRun with a sync.Mutex
  autosyncLastRun is a package-level variable accessed in autoSync()
  (write) and sync() (read). Added autosyncMu sync.Mutex and wrapped all
  accesses. This eliminates the theoretical data race in concurrent usage.

I-1: Unified secret name validation
  Added store.ValidateSecretName(name string) error in
  internal/store/validate.go. The function rejects:
  - Names containing '//' (consecutive slashes).
  - Names starting with '/' (absolute paths, likely a mistake).
  - Names whose filepath components include '..' (path traversal).
  The existing ad-hoc 'strings.Contains(name, "//")' check in
  leaf/write.go (the primary write boundary) is replaced with a call to
  the new function, which now also covers path traversal.
2026-04-12 09:44:52 +02:00
..