Related user story
#28108
Task
Apply first-added-wins everywhere a host could match more than one package: self-service, manual install, policy auto-install, and setup experience. Make the policy automation reference a specific package, and make setup experience install the first-added version without double-queuing.
First-added-wins is a fallback for overlapping label scopes, not a routing engine. The admin scopes labels to avoid overlap; when a host still matches more than one package, install the first-added one (smallest installer_id). Depends on the data-model foundation; parallel with the API and GitOps sub-issues.
Precedence helper
Install paths
- Self-service and manual install: route
InstallSoftwareTitle (and the host install endpoint) through the resolver instead of assuming one installer.
- Policy auto-install: a policy's install automation must reference a specific package. Default the policy to the first-added package; let the automation store the chosen
installer_id. Confirm the policy → installer link carries installer_id (not just title_id) so the selected package is honored on policy failure.
Setup experience
- Setup experience installs the first-added package per title and must not queue both versions (the
server/.../setup_experience.go:~125 double-queue regression). Labels do not apply during setup.
Condition of satisfaction
- Overlap fallback: a host matching two packages installs the first-added one via self-service, manual install, and policy auto-install (consistent across all three).
- Correct scoping: a correctly-scoped host always gets its matching package and never falls into the fallback (e.g. an Intel host never receives an Arm package).
- Policy: a policy with a chosen package installs that package on failure; default selection is first-added.
- Setup experience: only the first-added package is queued during setup; no double-queue; non-targeted labels are ignored during setup.
MYSQL_TEST=1 REDIS_TEST=1 go test ./server/service/... ./server/worker/... passes, including an end-to-end test: two label-scoped packages → host matching both → first-added installed across each path.
Related user story
#28108
Task
Apply first-added-wins everywhere a host could match more than one package: self-service, manual install, policy auto-install, and setup experience. Make the policy automation reference a specific package, and make setup experience install the first-added version without double-queuing.
First-added-wins is a fallback for overlapping label scopes, not a routing engine. The admin scopes labels to avoid overlap; when a host still matches more than one package, install the first-added one (smallest
installer_id). Depends on the data-model foundation; parallel with the API and GitOps sub-issues.Precedence helper
(host, team, title), returns the install target: filter the title's packages by per-package label scope (isSoftwareLabelScoped,server/datastore/mysql/software_installers.go:~3738), then pick first-added (installer_id ASC). Reuse Multiple packages: data model, migration, hash-dedupe guard, and multi-active regressions #48396's list-all read.Install paths
InstallSoftwareTitle(and the host install endpoint) through the resolver instead of assuming one installer.installer_id. Confirm the policy → installer link carriesinstaller_id(not justtitle_id) so the selected package is honored on policy failure.Setup experience
server/.../setup_experience.go:~125double-queue regression). Labels do not apply during setup.Condition of satisfaction
MYSQL_TEST=1 REDIS_TEST=1 go test ./server/service/... ./server/worker/...passes, including an end-to-end test: two label-scoped packages → host matching both → first-added installed across each path.