Add paths-ignore ['.gitea/**', '.planning/**'] to publish.yml's push trigger. Doc/CI-only pushes to main (planning docs push straight to main; workflow edits merge via PR) produce a byte-identical image (.dockerignore already excludes .planning), so the build + :latest re-push was wasted. paths-ignore skips only when every changed file matches; mixed code+docs pushes still publish.