ADR 015: Native Telemetry Validation
Status: Active
Decider: Architecture Lead
Date: 2026-05-30
Context
zenzic score --stamp writes the current DQS score as a Shields.io badge URL into any file
listed in badge_stamp_files. This mechanism is deterministic and Git-native: the badge is
crystallised in each commit, requiring no external service.
However, before this decision, Zenzic had no native mechanism to verify that the committed badge matched the computed score. The only enforcement path was an external bash gate added manually to CI workflows:
# Typical pre-ADR-015 CI pattern
git diff HEAD --quiet README.md README.it.md || exit 1
This pattern had four structural defects:
- Hardcoded filenames — the gate did not honor
badge_stamp_files. A project configuringREADME.it.mdas an additional stamp target had to update the CI script manually. - Zero portability — the gate required both
gitandbash. Non-bash CI environments and shallow clones introduced false passes. - Undiscoverable — first-time Zenzic users had no hint that this gate was required.
The
--stampdocumentation described how to write badges; the enforcement was a tribal convention not surfaced byzenzic --help. - Violated the Zero-Config Default pillar — users who opted into badge stamping had to configure external CI infrastructure for a Zenzic-owned feature. The engine should own the full lifecycle of its own artefacts.
Decision
Zenzic validates its own artefacts natively. The
--check-stampflag computes the expected Shields.io URL for the current score, readsbadge_stamp_filesfrom configuration, and exits 1 with a precise, actionable error message if any configured file contains a stale badge URL.
The invariant: if both markers (<!-- zenzic:audit-badge -->, <!-- zenzic:score-badge -->) are absent from a file, --check-stamp
returns True (pass). The gate activates only when the user has explicitly opted into badge
stamping. No opt-out configuration is required from users who do not use badges.
--stamp (write) and --check-stamp (verify) are mutually exclusive. This prevents ambiguous
invocations and enforces the read/write boundary between the two modes.
Rationale
1. Zero-Config Default enforcement
The Zero-Config Default pillar requires that users can adopt Zenzic features without configuring
external tooling. Under the pre-ADR-015 model, badge stamping was an Opt-In feature (user inserts
the marker) that secretly required a corresponding Opt-In in CI (user writes the git diff gate).
The second opt-in was invisible.
--check-stamp closes the loop: the user inserts the marker once, and Zenzic handles both
writing (--stamp) and verifying (--check-stamp) the badge. zenzic-action runs --check-stamp
automatically after check all (opt-out: check-stamp: 'false'). The default CI experience
is zero-configuration.
2. Config-aware gate
--check-stamp reads badge_stamp_files from .zenzic.toml — the same key that controls
--stamp. Adding a new file to badge_stamp_files automatically extends the freshness gate
to that file. No CI script edits, no git diff README.it.md additions.
3. Git-agnostic implementation
_check_stamp_file(path, marker, expected_url) reads the file from disk, locates the requested
marker using the same parser as _stamp_file(), extracts the badge URL via _SHIELDS_URL_RE,
and compares it to the expected URL. No subprocess, no git diff, no shell dependency.
The gate works in any environment where Python and the repository checkout are present.
4. Progressive disclosure
When --check-stamp detects a stale badge, the error names the specific file and prescribes
the exact remediation step:
[FAILED] Badge (score) in README.md is stale. Run 'zenzic score --stamp' locally and commit the result.
The user receives a complete action: the problem, the file, and the fix — without reading documentation.
Invariants
_check_stamp_file(path, marker, expected_url)returns True (pass) when:- The file does not exist.
- The target marker is absent.
- The marker is present but no Shields.io badge URL follows.
- The badge URL matches
expected_urlexactly.
_check_stamp_filereturns False (stale) only when the marker is present and the badge URL differs fromexpected_url.--stampand--check-stampraise a fatal error if invoked together (mutual exclusion).zenzic-actionskips--check-stampwhenZENZIC_AUDIT=true(audit mode produces no scored artefacts).
Consequences
- The bash
_badge-freshness-checkrecipe injust verifyis replaced by a single native invocation:zenzic score --check-stamp --no-header. - CI users of
zenzic-actionreceive the badge freshness gate automatically without any workflow YAML change. - The
badge_stamp_filesconfiguration key is now the single source of truth for both stamping and verification — no duplication between.zenzic.tomland CI scripts. - The Zero-Config Default pillar is fully honored: badge stamping is plug-and-play from marker insertion to CI enforcement.
Related
- ADR 009: Path Sovereignty — same principle applied to config path resolution.
- ADR 005: Agnostic Universalism — portability as a first-class design constraint.