Summary
PackageSource.IsInstalled returns true only when the repository contains at least one executable command. It does not inspect installed packages or repository initialization state.
Affected code
internal/backend/package-source.go:81 — uses len(src.Repo.InstalledCommands()) > 0
cmd/root.go:261 — calls initial installation for every source considered uninstalled
Trigger and impact
A valid source containing only group commands, system hooks, metadata-only packages, or packages with zero regular commands is considered uninstalled on every startup. Initial installation and enabled setup hooks can therefore run repeatedly.
Suggested correction
Define installation state from repository/package metadata (or an explicit initialized marker), not from the count of executable commands. Keep empty-but-initialized repositories distinguishable from never-initialized ones.
Acceptance criteria
- Hook-only, group-only, and zero-command packages are installed once.
- An initialized empty repository does not reinstall on every startup unless policy requires it.
- Tests cover each package shape and a genuinely uninitialized source.
Summary
PackageSource.IsInstalledreturns true only when the repository contains at least one executable command. It does not inspect installed packages or repository initialization state.Affected code
internal/backend/package-source.go:81— useslen(src.Repo.InstalledCommands()) > 0cmd/root.go:261— calls initial installation for every source considered uninstalledTrigger and impact
A valid source containing only group commands, system hooks, metadata-only packages, or packages with zero regular commands is considered uninstalled on every startup. Initial installation and enabled setup hooks can therefore run repeatedly.
Suggested correction
Define installation state from repository/package metadata (or an explicit initialized marker), not from the count of executable commands. Keep empty-but-initialized repositories distinguishable from never-initialized ones.
Acceptance criteria