feat(repository): assert brand SVGs parse as well-formed XML
The two canonical brand SVGs were invalid XML for months and nothing noticed. standards/repository/check.sh asserted they exist and banned a bare year in the copyright line, but never that they parse. There is no xmllint anywhere in scripts/, justfile, or .gitlab-ci.yml.
This is the architectural half of the fix that just landed. That MR repaired the instances; this stops the class recurring.
Why a new primitive rather than a regex
None of the nine existing check primitives can express "this file parses as XML". check_file_contains and check_file_lacks are grep -E over raw text, so the only expressible version is a regex banning the one byte sequence we already know about (-- inside a comment). That refights the last bug and catches none of the next ones: unclosed tags, bad entities, mismatched quoting.
So this adds a tenth primitive, following _lib.sh's own documented process for a vocabulary extension rather than bypassing the whitelist:
check_xml_wellformed(path)
PASS xmllint --noout succeeds
FAIL file missing or malformed
SKIP xmllint absentThe SKIP-on-absent-tool posture matches the three existing primitives that need external tools (check_toml_key, check_json_key, check_gitlab_setting). Added to scripts/guard-checks.sh's PRIMITIVES whitelist; just guard passes with 0 violations across all 22 check.sh files.
Wired into standards/repository/check.sh for avatar.svg, hero.svg and favicon.svg.
Red-then-green, at the primitive level
A check that cannot fail is the defect this estate keeps finding, so this one was proven both directions rather than read:
- red — sourced
_lib.shagainst the pre-fix canonicalhero.svgandavatar.svg: FAIL on both, PASS onfavicon.svg, which was never broken - green — same check against the fixed files: PASS on all three
- integration —
just check-one STANDARD=repositorynow reports 17 passed, 0 failed, 0 skipped, up from 14. The three new assertions fire rather than skip.
xmllint had to be added to one job, and only one
xmllint is present on macOS via system libxml2 but absent from the CI image. libxml2-utils provides it on alpine:3.24.
Added to the self-conformance job only. That is the job that actually runs just check via check-with-deviations.sh against this repo's own SVGs. The validate job never calls any check.sh, only the validate-* scripts, so it needed no change and adding the package there would have installed something nothing uses.
Also in here
CHANGELOG.md records the primitive. Two pieces of adjacent doc drift found while editing the same list: README.md's check-primitives table was already missing applies_when_file from an earlier addition, and standards/repository/SKILL.md's manual rsvg-convert validation step now notes the automated equivalent.
Flagged, not fixed
_lib_need() in _lib.sh is dead code. It is defined and documented as the tool-presence-check convention, but no primitive calls it; all three that need external tools use inline command -v plus _skip. This predates the change. I followed the working pattern rather than the documented-but-unused one, and left the mismatch alone so this MR stays scoped.