fix: resolve v0.4.0 audit — CI, Action, cache/fail-on bugs, packaging#10
Merged
Conversation
Two independent matrix breakages (the version `CI` job was red on main since 06-20; `Live tests` was unaffected): - Py3.9: `tests/test_preprint.py` and `tests/test_venue.py` used `list[str] | None` / `str | None` in function default-arg annotations, which 3.9 evaluates at definition time -> TypeError (GenericAlias | None). Add `from __future__ import annotations` so annotations stay strings. - Py3.13: `tests/test_cli_semantic.py` imports `from tests.test_cli import FakeClient`, but `tests/` was not an importable package. Add empty `tests/__init__.py`. Verified: `pytest -m "not live"` passes on 3.9 and 3.13 (290 passed, 2 skipped), ruff clean. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HjKoaVFk7CFQfdkS18TWHm
Addresses the full v0.4.0 audit (Critical 1-9 + quick wins). Correctness fixes: - cache: get() now reads back is_preprint/has_preprint_relation, so a preprint served from a warm cache is downgraded identically to a cold lookup (was an intermittent false-positive Tier B year failure). - --fail-on: validate tier names at parse time — a typo (e.g. "retractions") used to silently empty the fail-set and turn the CI gate into a no-op. - compare: markdown/DOI-list entries (no parsed title) no longer emit a misleading "possibly wrong DOI" on author mismatch — neutral message instead. - crossref/openalex: URL-encode DOIs before splicing into request URLs so a DOI containing '#' isn't truncated into a different query. - cli: --json --dry-run now emits valid JSON. Action / multi-file input: - CLI accepts multiple paths and walks directories for *.bib/*.md (hidden dirs skipped), so the Action's default `paths: .` works as documented. Findings are attributed with their filename (text path:Lnn, JSON `file`) when >1 file. - action.yml: pass inputs via env (no shell interpolation), pin the install, default fail-on gains `title`. - release.yml: force-move the `v1` major tag to each release commit. - pre-commit hook: pass_filenames now that the CLI takes multiple files. CI / packaging: - release.yml gains a test gate (build needs test) — no publish on red. - .claude/ git-ignored + excluded from sdist (was leaking worktrees into `uv build`); added Typing :: Typed classifier; CI matrix +3.10/3.12. - test_semantic_live.py gains the `live` marker; live-tests sets GHOSTCITE_LIVE=1. Test collection / housekeeping: - merged the CI-collection fix (tests/__init__.py + py3.9 annotation imports); FakeClient moved to tests/conftest.py instead of cross-importing test modules. Docs: CITATION.cff->0.4.0, README pre-commit rev->v0.4.0, example outputs gain the retractions: line, fetch-retractions shown in --help, schema_version added to --json, CHANGELOG [Unreleased] section. 305 passed / 5 skipped, ruff+mypy+format clean, coverage 90.6%. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AS7DtpsXwhB2eevQyqFxxe
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Resolves the full v0.4.0 audit (Critical 1–9 + quick wins; net-new features intentionally out of scope). Every claim was verified against live source before patching.
Critical
tests/__init__.py+ py3.9 annotation imports) and movedFakeClientintotests/conftest.pyinstead of cross-importing test modules. Barepytestnow collects and passes.*.bib/*.md(hidden dirs skipped), sopaths: .works as documented. Findings are attributed with their filename (textpath:Lnn, JSONfile) when >1 file is scanned.release.ymlnow force-moves thev1major tag on each release.DoiCache.get()reads backis_preprint/has_preprint_relation; a preprint from a warm cache is downgraded identically to a cold lookup (was an intermittent false-positive Tier B year failure).--fail-onvalidated — a typo like--fail-on retractionsused to silently no-op the CI gate; it now errors at parse time (like--cross-check).Important
doi.orgURLs (a#no longer truncates into a different query)..claude/git-ignored + excluded from the sdist (was leaking worktrees intouv build); verified the built sdist is clean. AddedTyping :: Typed.release.ymlgains a test gate (buildneedstest) — no publish on red; Action inputs passed viaenv:(no shell injection) and the install is pinned.--json --dry-runemits valid JSON;test_semantic_live.pygains thelivemarker and the weekly workflow setsGHOSTCITE_LIVE=1.Quick wins
CITATION.cff → 0.4.0 · README pre-commit
rev→ v0.4.0 +pass_filenames: true· example outputs gain theretractions:line · actionfail-ondefault gainstitle·fetch-retractionsshown in--help· CI matrix +3.10/3.12 ·schema_versionin--json· CHANGELOG[Unreleased]section.Deliberately skipped
uv.lock— it's intentionally.gitignored (library-lockfile decision left to you).--ignore-doi, config file, concurrency, library README) — out of scope per request.Verification
305 passed / 5 skipped, ruff + mypy +ruff format --checkclean, coverage 90.6% (>85 gate). Built sdist confirmed to contain no.claude// worktree files. Real-execution walkthroughs:ghostcite .,--json --dry-run,--fail-ontypo, and markdown neutral-message all behave as intended.🤖 Generated with Claude Code