Skip to content

feat(cli): add audit — repo Zenodo config-hygiene check#20

Merged
jcschaff merged 1 commit into
mainfrom
feat/audit
Jul 3, 2026
Merged

feat(cli): add audit — repo Zenodo config-hygiene check#20
jcschaff merged 1 commit into
mainfrom
feat/audit

Conversation

@jcschaff

@jcschaff jcschaff commented Jul 3, 2026

Copy link
Copy Markdown
Member

What

Adds a first-class audit subcommand that codifies the manual monitored-repo audit — the config-hygiene sibling of doctor (which covers webhook / competing-concept / drift).

GH_TOKEN=$(gh auth token) zenodo-maint audit                          # one repo
GH_TOKEN=$(gh auth token) zenodo-maint audit --monitored monitored.json  # fan out

Per repo it checks:

  • filesCITATION.cff and .zenodo.json present
  • workflows — both reusable workflows are pinned at the floating @vN. A @vX.Y.Z or SHA pin silently freezes a consumer on old code, so this is the check that protects the moving-major-tag strategy (nothing else catches it today).
  • metadata.zenodo.json creators and title match the published Zenodo record. Both are hard problems: the title is what people see on the DOI landing page, so we drive it to consistency.

Design decisions

  • No CITATION.cff diff. Comparing .zenodo.json to CITATION.cff needs a YAML parser this stdlib-only tool deliberately avoids, and is really cffconvert's job. Instead we compare .zenodo.json to the published record — the ground truth, and pure JSON.
  • Uses $GH_TOKEN when set. Tokenless works, but GitHub's 60-req/hour unauthenticated limit is blown by a multi-repo fan-out that fetches every workflow file. Reads $GH_TOKEN/$GITHUB_TOKEN like doctor does.
  • Exits non-zero on problems → usable as a CI/monitor gate.

Live run (all 12 monitored repos)

Surfaces 9 problems: vcell-solvers unonboarded (×4), biosimulations missing .zenodo.json (its PR is open), and 4 title mismatchespyvcellpyVCell, platform, runutils (casing), and vcell (Virtual Cell (VCell) vs the curated Virtual Cell 8.0). The vcell case is the curated-title pattern: it flags until its .zenodo.json title is reconciled with what should be displayed.

Tests / checks

ruff + mypy --strict clean; 34 unit tests pass (added reusable_refs / is_major_pin). api helpers github_file/github_dir are thin public-API readers; the pinning logic is pure and unit-tested.

monitor.yml wiring left as a follow-up, as agreed.

🤖 Generated with Claude Code

https://claude.ai/code/session_01BZx7w9BexQc9wWU5JoHYaF

Codifies the manual monitored-repo audit as a first-class command, the
config-hygiene sibling of `doctor` (which covers webhook/competing-concept/
drift). For one repo or an entire monitored.json (`--monitored`), it checks:

- the standard files (CITATION.cff, .zenodo.json) are present
- both reusable workflows are pinned at the floating @vn — a @vX.Y.Z or SHA pin
  silently freezes a consumer on old code, so this directly protects the
  moving-major-tag strategy
- .zenodo.json creators AND title match the published Zenodo record (both hard
  problems: the title is what people see on the DOI landing page, so drive it to
  consistency; a curated repo whose record shows a per-version title flags until
  its .zenodo.json title is reconciled)

Deliberately does NOT diff .zenodo.json against CITATION.cff: that needs a YAML
parser this stdlib-only tool avoids, and is cffconvert's job. The published
record is the ground truth, and it's pure JSON.

Tokenless against public APIs, but reads $GH_TOKEN/$GITHUB_TOKEN when set —
GitHub's 60-req/hour unauthenticated limit is blown by a multi-repo fan-out that
fetches every workflow file. Exits non-zero on problems (CI/monitor gate).

- api: github_file/github_dir (public, optional token), reusable_refs and
  is_major_pin (pure, unit-tested)
- cli: cmd_audit + _audit_one; new `audit` subcommand with `--monitored`
- tests: reusable_refs / is_major_pin
- README + SKILL: document the command

monitor.yml wiring left as a follow-up.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BZx7w9BexQc9wWU5JoHYaF
@jcschaff jcschaff merged commit e704b34 into main Jul 3, 2026
1 check passed
@jcschaff jcschaff deleted the feat/audit branch July 3, 2026 11:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant