a8524e5ff4
Verified the Docker SDK v28.5.2+incompatible ServiceList signature via go doc before implementing: the options type is swarm.ServiceListOptions, not types.ServiceListOptions as the brief assumed. Everything else (Service.ID, Service.Spec via embedded Annotations for Name/Labels, TaskTemplate.ContainerSpec.Image) matched the brief exactly. Reuses discovery.ImagesMatch and discovery.HasOptIn rather than duplicating matching/opt-in logic. Opt-in label is read from the service spec's own labels since Swarm services have no local compose file to anchor a STACKS_ROOT path check against (unlike Compose mode).